From fc1d32e63a99aa0545c148b281b908e3c7149da3 Mon Sep 17 00:00:00 2001 From: Jonathan Hooper Date: Sun, 20 Aug 2017 23:21:02 -0500 Subject: [PATCH 01/24] Increase width of USPS confirmation code input **Why**: So that the input is wide enough to display 10 alpha-numeric characters --- app/inputs/inline_input.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/inputs/inline_input.rb b/app/inputs/inline_input.rb index 34cec13f070..06426f535b0 100644 --- a/app/inputs/inline_input.rb +++ b/app/inputs/inline_input.rb @@ -3,7 +3,7 @@ def input(_wrapper_options) input_html_classes.push('col-10 field monospace') template.content_tag( :div, builder.text_field(attribute_name, input_html_options), - class: 'col col-12 sm-col-4 mb4 sm-mb0' + class: 'col col-12 sm-col-5 mb4 sm-mb0' ) end From b44fccc5e643ae6e7a4675f59b0cb8b04b584703 Mon Sep 17 00:00:00 2001 From: Jonathan Hooper Date: Mon, 21 Aug 2017 09:01:52 -0500 Subject: [PATCH 02/24] Don't create Profile in ProfileMaker#new **Why**: So that a database write does not happen as the side-effect of a service class's initializer --- app/services/idv/profile_maker.rb | 23 +++++++++++++++---- app/services/idv/session.rb | 2 +- .../verify/confirmations_controller_spec.rb | 2 +- spec/services/idv/profile_maker_spec.rb | 4 ++-- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/services/idv/profile_maker.rb b/app/services/idv/profile_maker.rb index 28e2f8aaa5a..983e5601640 100644 --- a/app/services/idv/profile_maker.rb +++ b/app/services/idv/profile_maker.rb @@ -1,18 +1,31 @@ module Idv class ProfileMaker - attr_reader :pii_attributes, :profile + attr_reader :pii_attributes def initialize(applicant:, user:, normalized_applicant:, vendor:, phone_confirmed:) - @profile = Profile.new(user: user, deactivation_reason: :verification_pending) - @pii_attributes = pii_from_applicant(applicant, normalized_applicant) + self.pii_attributes = pii_from_applicant(applicant, normalized_applicant) + self.user = user + self.vendor = vendor + self.phone_confirmed = phone_confirmed + end + + def save_profile + profile = Profile.new( + deactivation_reason: :verification_pending, + phone_confirmed: phone_confirmed, + user: user, + vendor: vendor + ) profile.encrypt_pii(user.user_access_key, pii_attributes) - profile.vendor = vendor - profile.phone_confirmed = phone_confirmed profile.save! + profile end private + attr_accessor :user, :vendor, :phone_confirmed + attr_writer :pii_attributes + # rubocop:disable MethodLength, AbcSize # This method is single statement spread across many lines for readability def pii_from_applicant(appl, norm_appl) diff --git a/app/services/idv/session.rb b/app/services/idv/session.rb index 269517ffba9..4f59d95d5bd 100644 --- a/app/services/idv/session.rb +++ b/app/services/idv/session.rb @@ -49,7 +49,7 @@ def proofing_started? end def cache_applicant_profile_id - profile = profile_maker.profile + profile = profile_maker.save_profile self.pii = profile_maker.pii_attributes self.profile_id = profile.id self.personal_key = profile.personal_key diff --git a/spec/controllers/verify/confirmations_controller_spec.rb b/spec/controllers/verify/confirmations_controller_spec.rb index 824dbe8d680..eb285d672de 100644 --- a/spec/controllers/verify/confirmations_controller_spec.rb +++ b/spec/controllers/verify/confirmations_controller_spec.rb @@ -23,7 +23,7 @@ def stub_idv_session vendor: :mock, phone_confirmed: true ) - profile = profile_maker.profile + profile = profile_maker.save_profile idv_session.pii = profile_maker.pii_attributes idv_session.profile_id = profile.id idv_session.personal_key = profile.personal_key diff --git a/spec/services/idv/profile_maker_spec.rb b/spec/services/idv/profile_maker_spec.rb index 32961b4a65a..13041c3b950 100644 --- a/spec/services/idv/profile_maker_spec.rb +++ b/spec/services/idv/profile_maker_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' describe Idv::ProfileMaker do - describe '#new' do + describe '#save_profile' do it 'creates Profile with encrypted PII' do applicant = Proofer::Applicant.new first_name: 'Some', last_name: 'One' normalized_applicant = Proofer::Applicant.new first_name: 'Somebody', last_name: 'Oneatatime' @@ -16,7 +16,7 @@ phone_confirmed: false ) - profile = profile_maker.profile + profile = profile_maker.save_profile pii = profile_maker.pii_attributes expect(profile).to be_a Profile From 3505aef4bfbb0b7232b84a675a0d1e883ccf1f10 Mon Sep 17 00:00:00 2001 From: Moncef Belyamani Date: Mon, 21 Aug 2017 09:03:57 -0400 Subject: [PATCH 03/24] Replace Travis CI with Circle CI **Why**: Travis CI is no longer supported/allowed by 18F. --- .circleci/config.yml | 91 ++++++++++++++++++++++++ .travis.yml | 54 -------------- Gemfile.lock | 2 +- app/views/users/totp_setup/new.html.slim | 2 +- 4 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 .travis.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..7831750b738 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,91 @@ +# Ruby CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-ruby/ for more details +# +version: 2 +jobs: + build: + docker: + # Specify the Ruby version you desire here + - image: circleci/ruby:2.3.3-node-browsers + environment: + RAILS_ENV: test + CC_TEST_REPORTER_ID: faecd27e9aed532634b3f4d3e251542d7de9457cfca96a94208a63270ef9b42e + COVERAGE: true + + # Specify service dependencies here if necessary + # CircleCI maintains a library of pre-built images + # documented at https://circleci.com/docs/2.0/circleci-images/ + - image: circleci/postgres:9.4.12-alpine + environment: + POSTGRES_USER: circleci + + - image: redis:4.0.1 + + working_directory: ~/identity-idp + + steps: + - checkout + + - restore-cache: + key: identity-idp-{{ checksum "Gemfile.lock" }} + + - run: + name: Install dependencies + command: | + gem install bundler + bundle install --deployment --jobs=4 --retry=3 --without deploy development doc production --path vendor/bundle + - run: + name: Install phantomjs + command: | + sudo curl --output /tmp/phantomjs https://s3.amazonaws.com/circle-downloads/phantomjs-2.1.1 + sudo chmod ugo+x /tmp/phantomjs + sudo ln -sf /tmp/phantomjs /usr/local/bin/phantomjs + - run: + name: Install Code Climate Test Reporter + command: | + curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + chmod +x ./cc-test-reporter + + # Store bundle cache + - save-cache: + key: identity-idp-{{ checksum "Gemfile.lock" }} + paths: + - vendor/bundle + + - run: + name: Test Setup + command: | + npm install + npm run build + cp config/application.yml.example config/application.yml + cp certs/saml.crt.example certs/saml.crt + cp keys/saml.key.enc.example keys/saml.key.enc + cp keys/equifax_rsa.example keys/equifax_rsa + gpg --dearmor < keys/equifax_gpg.pub.example > keys/equifax_gpg.pub.bin + gpg --import keys/equifax_gpg.example + bundle exec rake db:setup --trace + bundle exec rake assets:precompile + + - run: + name: Run Tests + command: | + mkdir /tmp/test-results + ./cc-test-reporter before-build + + bundle exec rspec --format progress + bundle exec teaspoon + bundle exec slim-lint app/views + + - run: + name: Upload Test Results to Code Climate + command: | + ./cc-test-reporter format-coverage -t simplecov $CIRCLE_ARTIFACTS/coverage/.resultset.json + ./cc-test-reporter upload-coverage + + # collect reports + - store_test_results: + path: /tmp/test-results + - store_artifacts: + path: /tmp/test-results + destination: test-results diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a8d124fb2ba..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,54 +0,0 @@ -addons: - postgresql: 9.3 - code_climate: - repo_token: - secure: '0RG6L9Sfur37NAB4X9rZypo6tffcWQtTcTpuSi08SfLN9jgiG2nHArVvw0nfNcSg7EmJ27ZnQxQqRjXlG76ufndlmoxgVX6xs96VyDyCOEFzRecE+wziNis+B3ACZb5OHaoMpomzsYFA73nYoCnPkgKUPAQFReTIqW7IB2Z1t7auTZe6kYBkKP7yB37wAVD4HMUDwm0spT0U2ur2GzSi86EqFEXR4NfhzGu5o7Y/hzWPxyyz+CRrujXhdWZl1FNtMj0mUM0/zSEEgUuCRRClGkD31RECjDKQQrXUkgQ1b3O/Nbih/8EjDqs4udLGnBYbtoahZ0ogZ/SV5xj7n2umNBJeLLTZO/qhWyQA4YDPuAZCw61VK1jpyQE1uZKxawYkgXBScmTWCJeAwEqZ4V8z4H4W2y1ZgegAoBCYOhv2+Dq4d9IaBUaeH3ukhEKX9H38yF1DEkp2sXKfXOxyEgpr0g0IIII9YVYQ89WExNmnZnfgd6lBqMFlP4wj8pQkCAeMG8+e+O0QsewzwlVgDDp5pQCgHEYq5X3quvWv0bRJDBL68/4fU9kEjv+RAo8Wx99x3nrZSzJglBrSaPt2/+eoVf3VTIJX4p8oO3aC/gcpbrWZrsfcGfLgKCEiu/ggzhicYhWY+Aa+pdeOefrO51ki9BIu84PoMrP2I7EREp2s1vw=' - apt: - packages: - - jq -cache: - directories: - - "travis_phantomjs" -before_install: - - . $HOME/.nvm/nvm.sh - - nvm install stable - - nvm use stable - - npm install - - npm run build - # Install PhantomJS 2.1.1 manually - - "export PHANTOMJS_VERSION=2.1.1" - - "phantomjs --version" - - "export PATH=$PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64/bin:$PATH" - - "phantomjs --version" - - "if [ $(phantomjs --version) != '$PHANTOMJS_VERSION' ]; then rm -rf $PWD/travis_phantomjs; mkdir -p $PWD/travis_phantomjs; fi" - - "if [ $(phantomjs --version) != '$PHANTOMJS_VERSION' ]; then wget https://github.com/Medium/phantomjs/releases/download/v$PHANTOMJS_VERSION/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -O $PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2; fi" - - "if [ $(phantomjs --version) != '$PHANTOMJS_VERSION' ]; then tar -xvf $PWD/travis_phantomjs/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -C $PWD/travis_phantomjs; fi" - - "phantomjs --version" -before_script: - - cp config/application.yml.example config/application.yml - - cp certs/saml.crt.example certs/saml.crt - - cp keys/saml.key.enc.example keys/saml.key.enc - - cp keys/equifax_rsa.example keys/equifax_rsa - - gpg --dearmor < keys/equifax_gpg.pub.example > keys/equifax_gpg.pub.bin - - gpg --import keys/equifax_gpg.example - - bin/rake db:setup --trace - - bin/rake assets:precompile -bundler_args: "--deployment --jobs=3 --retry=3 --without deploy development doc production" -cache: bundler -language: ruby -matrix: - fast_finish: true -notifications: - email: false -rvm: - - ruby-2.3.3 -sudo: false -script: - - make test - - bundle exec slim-lint app/views - - bundle exec codeclimate-test-reporter -services: - - redis-server -env: - global: - - COVERAGE=true diff --git a/Gemfile.lock b/Gemfile.lock index 11b4e223359..3f41932a403 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -759,4 +759,4 @@ RUBY VERSION ruby 2.3.3p222 BUNDLED WITH - 1.15.3 + 1.15.4 diff --git a/app/views/users/totp_setup/new.html.slim b/app/views/users/totp_setup/new.html.slim index 7401123403a..f38640339ed 100644 --- a/app/views/users/totp_setup/new.html.slim +++ b/app/views/users/totp_setup/new.html.slim @@ -26,7 +26,7 @@ ul.list-reset = accordion('totp-info', t('instructions.mfa.authenticator.accordion_header'), wrapper_css: 'mb2 col-12 fs-16p') do .center - = image_tag @qrcode, alt: t('users.totp_setup.new.qr_img_alt') + = image_tag @qrcode, alt: t('users.totp_setup.new.qr_img_alt'), skip_pipeline: true li.py2.border-top .mb2 .mr1.inline-block.circle.circle-number.bg-blue.white From b633290bd3288e72cb57b1feec80d17acb85110a Mon Sep 17 00:00:00 2001 From: Brian Hurst Date: Tue, 22 Aug 2017 10:49:31 -0400 Subject: [PATCH 04/24] Remove style-guide dependency (again) --- .gitignore | 6 - app/assets/stylesheets/_vendor.scss | 8 + app/assets/stylesheets/application.css.scss | 7 +- app/assets/stylesheets/components/_abbr.scss | 3 + .../stylesheets/components/_accordion.scss | 87 ++++++ app/assets/stylesheets/components/_alert.scss | 58 ++++ .../stylesheets/components/_background.scss | 9 + .../stylesheets/components/_border.scss | 16 ++ app/assets/stylesheets/components/_btn.scss | 80 ++++++ app/assets/stylesheets/components/_card.scss | 23 ++ app/assets/stylesheets/components/_color.scss | 3 + .../stylesheets/components/_container.scss | 7 + .../stylesheets/components/_footer.scss | 31 ++ app/assets/stylesheets/components/_form.scss | 272 ++++++++++++++++++ .../components/_i18n-dropdown.scss | 36 +++ app/assets/stylesheets/components/_icon.scss | 33 +++ app/assets/stylesheets/components/_list.scss | 62 ++++ .../stylesheets/components/_loading.scss | 4 + app/assets/stylesheets/components/_modal.scss | 129 +++++++++ app/assets/stylesheets/components/_nav.scss | 23 ++ .../stylesheets/components/_password.scss | 32 +++ .../stylesheets/components/_personal-key.scss | 36 +++ .../stylesheets/components/_position.scss | 2 + .../components/_profile-section.scss | 19 ++ .../stylesheets/components/_space-addon.scss | 69 +++++ .../stylesheets/components/_space-misc.scss | 31 ++ .../stylesheets/components/_tooltip.scss | 50 ++++ .../stylesheets/components/_typography.scss | 48 ++++ app/assets/stylesheets/components/_util.scss | 51 ++++ .../components/_verification-badge.scss | 25 ++ app/assets/stylesheets/components/all.scss | 29 ++ app/assets/stylesheets/email.css.scss | 3 +- app/assets/stylesheets/variables/_app.scss | 105 +++++++ app/assets/stylesheets/variables/_colors.scss | 24 ++ app/assets/stylesheets/variables/_email.scss | 145 ++++++++++ package.json | 11 +- public/android-chrome-192x192.png | Bin 0 -> 6993 bytes public/apple-touch-icon.png | Bin 0 -> 3902 bytes public/browserconfig.xml | 9 + public/favicon-16x16.png | Bin 0 -> 911 bytes public/favicon-32x32.png | Bin 0 -> 1365 bytes public/favicon.ico | Bin 0 -> 15086 bytes public/manifest.json | 12 + public/mstile-150x150.png | Bin 0 -> 3751 bytes public/safari-pinned-tab.svg | 22 ++ .../fonts/merriweather-bold-webfont.eot | Bin 0 -> 30040 bytes .../fonts/merriweather-bold-webfont.ttf | Bin 0 -> 60116 bytes .../fonts/merriweather-bold-webfont.woff | Bin 0 -> 34148 bytes .../fonts/merriweather-bold-webfont.woff2 | Bin 0 -> 27028 bytes .../fonts/merriweather-italic-webfont.eot | Bin 0 -> 61196 bytes .../fonts/merriweather-italic-webfont.ttf | Bin 0 -> 61088 bytes .../fonts/merriweather-italic-webfont.woff | Bin 0 -> 32640 bytes .../fonts/merriweather-italic-webfont.woff2 | Bin 0 -> 25724 bytes .../fonts/merriweather-light-webfont.eot | Bin 0 -> 29810 bytes .../fonts/merriweather-light-webfont.ttf | Bin 0 -> 61376 bytes .../fonts/merriweather-light-webfont.woff | Bin 0 -> 33916 bytes .../fonts/merriweather-light-webfont.woff2 | Bin 0 -> 27036 bytes .../fonts/merriweather-regular-webfont.eot | Bin 0 -> 27962 bytes .../fonts/merriweather-regular-webfont.ttf | Bin 0 -> 60020 bytes .../fonts/merriweather-regular-webfont.woff | Bin 0 -> 32056 bytes .../fonts/merriweather-regular-webfont.woff2 | Bin 0 -> 25176 bytes .../fonts/sourcesanspro-bold-webfont.eot | Bin 0 -> 28017 bytes .../fonts/sourcesanspro-bold-webfont.ttf | Bin 0 -> 65244 bytes .../fonts/sourcesanspro-bold-webfont.woff | Bin 0 -> 29360 bytes .../fonts/sourcesanspro-bold-webfont.woff2 | Bin 0 -> 23368 bytes .../fonts/sourcesanspro-italic-webfont.eot | Bin 0 -> 20839 bytes .../fonts/sourcesanspro-italic-webfont.ttf | Bin 0 -> 44868 bytes .../fonts/sourcesanspro-italic-webfont.woff | Bin 0 -> 22260 bytes .../fonts/sourcesanspro-italic-webfont.woff2 | Bin 0 -> 17472 bytes .../fonts/sourcesanspro-light-webfont.eot | Bin 0 -> 28305 bytes .../fonts/sourcesanspro-light-webfont.ttf | Bin 0 -> 66008 bytes .../fonts/sourcesanspro-light-webfont.woff | Bin 0 -> 29668 bytes .../fonts/sourcesanspro-light-webfont.woff2 | Bin 0 -> 23608 bytes .../fonts/sourcesanspro-regular-webfont.eot | Bin 0 -> 28337 bytes .../fonts/sourcesanspro-regular-webfont.ttf | Bin 0 -> 65672 bytes .../fonts/sourcesanspro-regular-webfont.woff | Bin 0 -> 29724 bytes .../fonts/sourcesanspro-regular-webfont.woff2 | Bin 0 -> 23684 bytes vendor/assets/stylesheets/basscss/_btn.scss | 117 ++++++++ .../assets/stylesheets/basscss/_margin.scss | 96 +++++++ .../assets/stylesheets/basscss/_padding.scss | 82 ++++++ .../basscss/_responsive-margin.scss | 174 +++++++++++ .../basscss/_responsive-padding.scss | 147 ++++++++++ .../stylesheets/basscss/_typography.scss | 65 +++++ 83 files changed, 2284 insertions(+), 17 deletions(-) create mode 100644 app/assets/stylesheets/_vendor.scss create mode 100644 app/assets/stylesheets/components/_abbr.scss create mode 100644 app/assets/stylesheets/components/_accordion.scss create mode 100644 app/assets/stylesheets/components/_alert.scss create mode 100644 app/assets/stylesheets/components/_background.scss create mode 100644 app/assets/stylesheets/components/_border.scss create mode 100644 app/assets/stylesheets/components/_btn.scss create mode 100644 app/assets/stylesheets/components/_card.scss create mode 100644 app/assets/stylesheets/components/_color.scss create mode 100644 app/assets/stylesheets/components/_container.scss create mode 100644 app/assets/stylesheets/components/_footer.scss create mode 100644 app/assets/stylesheets/components/_form.scss create mode 100644 app/assets/stylesheets/components/_i18n-dropdown.scss create mode 100644 app/assets/stylesheets/components/_icon.scss create mode 100644 app/assets/stylesheets/components/_list.scss create mode 100644 app/assets/stylesheets/components/_loading.scss create mode 100644 app/assets/stylesheets/components/_modal.scss create mode 100644 app/assets/stylesheets/components/_nav.scss create mode 100644 app/assets/stylesheets/components/_password.scss create mode 100644 app/assets/stylesheets/components/_personal-key.scss create mode 100644 app/assets/stylesheets/components/_position.scss create mode 100644 app/assets/stylesheets/components/_profile-section.scss create mode 100644 app/assets/stylesheets/components/_space-addon.scss create mode 100644 app/assets/stylesheets/components/_space-misc.scss create mode 100644 app/assets/stylesheets/components/_tooltip.scss create mode 100644 app/assets/stylesheets/components/_typography.scss create mode 100644 app/assets/stylesheets/components/_util.scss create mode 100644 app/assets/stylesheets/components/_verification-badge.scss create mode 100644 app/assets/stylesheets/components/all.scss create mode 100644 app/assets/stylesheets/variables/_app.scss create mode 100644 app/assets/stylesheets/variables/_colors.scss create mode 100644 app/assets/stylesheets/variables/_email.scss create mode 100644 public/android-chrome-192x192.png create mode 100644 public/apple-touch-icon.png create mode 100644 public/browserconfig.xml create mode 100644 public/favicon-16x16.png create mode 100644 public/favicon-32x32.png create mode 100644 public/favicon.ico create mode 100644 public/manifest.json create mode 100644 public/mstile-150x150.png create mode 100644 public/safari-pinned-tab.svg create mode 100755 vendor/assets/fonts/merriweather-bold-webfont.eot create mode 100755 vendor/assets/fonts/merriweather-bold-webfont.ttf create mode 100755 vendor/assets/fonts/merriweather-bold-webfont.woff create mode 100755 vendor/assets/fonts/merriweather-bold-webfont.woff2 create mode 100755 vendor/assets/fonts/merriweather-italic-webfont.eot create mode 100755 vendor/assets/fonts/merriweather-italic-webfont.ttf create mode 100755 vendor/assets/fonts/merriweather-italic-webfont.woff create mode 100755 vendor/assets/fonts/merriweather-italic-webfont.woff2 create mode 100755 vendor/assets/fonts/merriweather-light-webfont.eot create mode 100755 vendor/assets/fonts/merriweather-light-webfont.ttf create mode 100755 vendor/assets/fonts/merriweather-light-webfont.woff create mode 100755 vendor/assets/fonts/merriweather-light-webfont.woff2 create mode 100755 vendor/assets/fonts/merriweather-regular-webfont.eot create mode 100755 vendor/assets/fonts/merriweather-regular-webfont.ttf create mode 100755 vendor/assets/fonts/merriweather-regular-webfont.woff create mode 100755 vendor/assets/fonts/merriweather-regular-webfont.woff2 create mode 100644 vendor/assets/fonts/sourcesanspro-bold-webfont.eot create mode 100644 vendor/assets/fonts/sourcesanspro-bold-webfont.ttf create mode 100644 vendor/assets/fonts/sourcesanspro-bold-webfont.woff create mode 100644 vendor/assets/fonts/sourcesanspro-bold-webfont.woff2 create mode 100644 vendor/assets/fonts/sourcesanspro-italic-webfont.eot create mode 100644 vendor/assets/fonts/sourcesanspro-italic-webfont.ttf create mode 100644 vendor/assets/fonts/sourcesanspro-italic-webfont.woff create mode 100644 vendor/assets/fonts/sourcesanspro-italic-webfont.woff2 create mode 100644 vendor/assets/fonts/sourcesanspro-light-webfont.eot create mode 100644 vendor/assets/fonts/sourcesanspro-light-webfont.ttf create mode 100644 vendor/assets/fonts/sourcesanspro-light-webfont.woff create mode 100644 vendor/assets/fonts/sourcesanspro-light-webfont.woff2 create mode 100644 vendor/assets/fonts/sourcesanspro-regular-webfont.eot create mode 100644 vendor/assets/fonts/sourcesanspro-regular-webfont.ttf create mode 100644 vendor/assets/fonts/sourcesanspro-regular-webfont.woff create mode 100644 vendor/assets/fonts/sourcesanspro-regular-webfont.woff2 create mode 100644 vendor/assets/stylesheets/basscss/_btn.scss create mode 100644 vendor/assets/stylesheets/basscss/_margin.scss create mode 100644 vendor/assets/stylesheets/basscss/_padding.scss create mode 100644 vendor/assets/stylesheets/basscss/_responsive-margin.scss create mode 100644 vendor/assets/stylesheets/basscss/_responsive-padding.scss create mode 100644 vendor/assets/stylesheets/basscss/_typography.scss diff --git a/.gitignore b/.gitignore index b18320e46b5..aebd7c9ecef 100644 --- a/.gitignore +++ b/.gitignore @@ -50,17 +50,11 @@ Vagrantfile /kitchen/cookbooks /log/* /private_certs/* -/public/*.ico -/public/*.png -/public/*.svg -/public/browserconfig.xml -/public/manifest.json /public/system /public/user_flows /spec/tmp /test /tmp/* -/vendor/assets/fonts /vendor/bundle /node_modules diff --git a/app/assets/stylesheets/_vendor.scss b/app/assets/stylesheets/_vendor.scss new file mode 100644 index 00000000000..241ef017389 --- /dev/null +++ b/app/assets/stylesheets/_vendor.scss @@ -0,0 +1,8 @@ +@import 'normalize.css/normalize'; +@import 'hint.css/hint'; + +@import 'basscss-sass/basscss'; +@import 'basscss/margin'; +@import 'basscss/padding'; +@import 'basscss/responsive-margin'; +@import 'basscss/responsive-padding'; diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index 36142a61986..f47af41e55b 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -1,5 +1,6 @@ @import 'fonts'; - -@import 'identity-style-guide/src/css/app'; - +@import 'variables/colors'; +@import 'variables/app'; +@import 'vendor'; +@import 'components/all'; @import 'print'; diff --git a/app/assets/stylesheets/components/_abbr.scss b/app/assets/stylesheets/components/_abbr.scss new file mode 100644 index 00000000000..6048d5e322b --- /dev/null +++ b/app/assets/stylesheets/components/_abbr.scss @@ -0,0 +1,3 @@ +// normalize.css adds a text underline by default +// scss-lint:disable QualifyingElement +abbr[title] { text-decoration: none; } diff --git a/app/assets/stylesheets/components/_accordion.scss b/app/assets/stylesheets/components/_accordion.scss new file mode 100644 index 00000000000..3a59a7e044c --- /dev/null +++ b/app/assets/stylesheets/components/_accordion.scss @@ -0,0 +1,87 @@ +.no-js { + .accordion { + .accordion-header { + cursor: initial; + } + + .accordion-footer { + display: none; + } + + .accordion-content { + display: block; + } + + [class*="btn-"] { + display: none; + } + } +} + +.accordion { + border: $border-width solid $border-color; + border-radius: $border-radius-md; + + .accordion-header { + color: $blue; + cursor: pointer; + position: relative; + + img { + position: absolute; + right: 1rem; + top: .8rem; + } + } + + .accordion-content { + border-top: $border-width solid $border-color; + display: none; + opacity: 1; + + &.shown { + display: block; + } + } + + .accordion-footer { + background-color: $blue-lightest; + border-top: $border-width solid $border-color; + color: $blue; + cursor: pointer; + text-align: center; + + img { + margin-top: -2px; + vertical-align: middle; + } + } +} + +.animate-in { + animation: accordionIn .2s normal ease-in both 1; +} + +.animate-out { + animation: accordionOut .15s normal ease-out both 1; +} + +@keyframes accordionIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes accordionOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} diff --git a/app/assets/stylesheets/components/_alert.scss b/app/assets/stylesheets/components/_alert.scss new file mode 100644 index 00000000000..48dd85515eb --- /dev/null +++ b/app/assets/stylesheets/components/_alert.scss @@ -0,0 +1,58 @@ +$ico-size: 1rem; +$ico-offset: 1rem; + +.alert { + background-color: $blue-lighter; + border-radius: $space-1; + color: #5b616a; + font-size: 1rem; + line-height: 1.5rem; + margin-bottom: $space-4; + padding: 12px $space-2; + position: relative; + + &::before { + background-image: none; + background-repeat: no-repeat; + content: ''; + height: $ico-size; + left: $ico-offset; + position: absolute; + top: $ico-offset; + width: $ico-size; + } +} + +.alert-success { + background-color: #ebfcef; + padding-left: $space-4; + + &::before { background-image: url(image-path('alert/success.svg')); } +} + +.alert-thumb { + background-color: #ebfcef; + padding-left: $space-4; + + &::before { background-image: url(image-path('alert/ico-thumb.svg')); } +} + +.alert-error, +.alert-alert { + background-color: #fff0f3; + padding-left: $space-4; + + &::before { background-image: url(image-path('alert/error.svg')); } +} + +.alert-warning { + background-color: #fffdd7; + padding-left: $space-4; + + &::before { background-image: url(image-path('alert/warning.svg')); } +} + +.alert-notice { + padding-left: $space-4; + &::before { background-image: url(image-path('alert/notice.svg')); } +} diff --git a/app/assets/stylesheets/components/_background.scss b/app/assets/stylesheets/components/_background.scss new file mode 100644 index 00000000000..9c26230e10c --- /dev/null +++ b/app/assets/stylesheets/components/_background.scss @@ -0,0 +1,9 @@ +.bg-gray-lighter { background-color: $gray-lighter; } +.bg-light-blue { background-color: $blue-light; } +.bg-lightest-blue { background-color: $blue-lightest; } + +@media #{$breakpoint-sm} { + .sm-bg-light-blue { background-color: $blue-light; } + .sm-bg-none { background-color: transparent; } + .sm-bg-navy { background-color: $navy; } +} diff --git a/app/assets/stylesheets/components/_border.scss b/app/assets/stylesheets/components/_border.scss new file mode 100644 index 00000000000..12256d68ed6 --- /dev/null +++ b/app/assets/stylesheets/components/_border.scss @@ -0,0 +1,16 @@ +.bw1 { border-width: 1px; } +.bw2 { border-width: 2px; } +.bw3 { border-width: 3px; } +.bw4 { border-width: 4px; } + +.border-dashed { border-style: dashed; } + +.rounded-md { border-radius: $border-radius-md; } +.rounded-lg { border-radius: $border-radius-lg; } +.rounded-xl { border-radius: $border-radius-xl; } +.rounded-xxl { border-radius: $border-radius-xxl; } + +@media #{$breakpoint-sm} { + .sm-border-none { border: 0; } + .sm-rounded-md { border-radius: $border-radius-md; } +} diff --git a/app/assets/stylesheets/components/_btn.scss b/app/assets/stylesheets/components/_btn.scss new file mode 100644 index 00000000000..f8f473d80fb --- /dev/null +++ b/app/assets/stylesheets/components/_btn.scss @@ -0,0 +1,80 @@ +@media #{$breakpoint-sm} { + .btn { font-size: $button-font-size-sm; } +} + +.btn { + white-space: normal; +} + +%btn-basic { + background: transparent; + border: 0; + box-shadow: none; + color: $blue; + font-size: $base-font-size; + font-weight: normal; + line-height: $line-height; + outline: none; + padding: 0; +} + +.btn-primary { + border-radius: $border-radius-lg; +} + +.btn-secondary { + border: 1px solid $blue; + border-radius: $border-radius-lg; + color: $blue; + + &:hover { + background-color: $blue-lightest; + } +} + +.btn-wide { + box-sizing: border-box; + min-width: 220px; + text-align: center; +} + +.btn-transparent { + @extend %btn-basic; + cursor: pointer; +} + +.btn-link { + @extend %btn-basic; + text-decoration: underline; + vertical-align: baseline; + + &:active, + &:focus, + &:hover, { + border: 0; + box-shadow: none; + text-decoration: underline; + } +} + +.btn-border { + border-color: $border-color; + border-radius: $border-radius-lg; + border-style: solid; + border-width: $border-width; + box-sizing: border-box; + display: inline-block; + padding: $space-1 $space-2; + + // &.is-focused { + // border-color: $field-focus-color; + // box-shadow: 0 0 0 2px rgba($field-focus-color, .5); + // outline: none; + // } +} + +.btn-disabled { + background-color: $gray-light; + border-color: $gray; + color: $gray; +} diff --git a/app/assets/stylesheets/components/_card.scss b/app/assets/stylesheets/components/_card.scss new file mode 100644 index 00000000000..017d0addade --- /dev/null +++ b/app/assets/stylesheets/components/_card.scss @@ -0,0 +1,23 @@ +.card { + background-color: $white; + max-width: $container-skinny-width; + + &-wide { + max-width: 100%; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + } + + @media #{$breakpoint-sm} { + border-radius: 5px; + + &-wide { + margin-top: $space-4; + max-width: 100%; + padding-bottom: 0; + padding-left: 0; + padding-right: 0; + } + } +} diff --git a/app/assets/stylesheets/components/_color.scss b/app/assets/stylesheets/components/_color.scss new file mode 100644 index 00000000000..572de70adf1 --- /dev/null +++ b/app/assets/stylesheets/components/_color.scss @@ -0,0 +1,3 @@ +@media #{$breakpoint-sm} { + .sm-white { color: $white; } +} diff --git a/app/assets/stylesheets/components/_container.scss b/app/assets/stylesheets/components/_container.scss new file mode 100644 index 00000000000..5bed3a6d2c0 --- /dev/null +++ b/app/assets/stylesheets/components/_container.scss @@ -0,0 +1,7 @@ +.cntnr-skinny { max-width: $container-skinny-width; } +.cntnr-xskinny { max-width: $container-xskinny-width; } +.cntnr-xxskinny { max-width: $container-xxskinny-width; } + +@media #{$breakpoint-sm} { + .cntnr-xxskinny { max-width: $container-xskinny-width; } +} diff --git a/app/assets/stylesheets/components/_footer.scss b/app/assets/stylesheets/components/_footer.scss new file mode 100644 index 00000000000..4b9e8042f51 --- /dev/null +++ b/app/assets/stylesheets/components/_footer.scss @@ -0,0 +1,31 @@ +// 1. Avoid the IE 10-11 `min-height` bug. +// 2. Set `flex-shrink` to `0` to prevent some browsers from +// letting these items shrink to smaller than their content's default +// minimum size. See http://bit.ly/1Mn35US for details. +// 3. Use `%` instead of `vh` since `vh` is buggy in older mobile Safari. +html { + height: 100%; +} + +.site { + display: flex; + flex-direction: column; + height: 100%; // 1, 3 +} + +.footer { + flex: none; // 2 + position: relative; +} + +.site-wrap { + flex: 1 0 auto; // 2 + width: 100%; +} + +.site-wrap::after { + content: '\00a0'; //   + display: block; + height: 0; + visibility: hidden; +} diff --git a/app/assets/stylesheets/components/_form.scss b/app/assets/stylesheets/components/_form.scss new file mode 100644 index 00000000000..71df7c2435c --- /dev/null +++ b/app/assets/stylesheets/components/_form.scss @@ -0,0 +1,272 @@ +$radio-checkbox-space: 1.5rem; + +@media #{$breakpoint-sm} { + input, + select, + textarea { + font-size: $form-field-font-size-sm; + } +} + +label { + display: inline-block; + margin-bottom: $space-tiny; +} + +textarea { + resize: vertical; +} + +.field { + background-color: #f2f9ff; + color: $gray; + font-weight: $bold-font-weight; + + &[type=number], + &.phone { + font-family: $monospace-font-family; + } + + &:focus, + &.is-focused { + border-color: $field-focus-color; + box-shadow: 0 0 0 2px rgba($field-focus-color, .5); + outline: none; + } + + &:invalid, + &.is-error { + border-color: $border-color; + } +} + +.radio-extra { + margin-left: $radio-checkbox-space; +} + + +// error states +.has-error input { + background-image: url(image-path('alert/error.svg')); + background-position: center right $form-field-padding-x; + background-repeat: no-repeat; + background-size: 1rem 1rem; + border-color: $red; + + &.date, + &.select { + background-image: none; + } + + &:focus { + border-color: $red; + box-shadow: 0 0 0 2px rgba($red, .5); + } +} + +// hide number field input spin box as per: +// http://stackoverflow.com/questions/3790935/can-i-hide-the-html5-number-input-s-spin-box +// and added .mfa class selector as per CodeClimate warning to: +// 'Avoid qualifying attribute selectors with an element.' +.mfa { + -moz-appearance: textfield; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + + +// wtf-forms.css +.checkbox, +.radio { + cursor: pointer; + padding-left: 24px; + position: relative; +} + +.checkbox input, +.radio input, { + opacity: 0; + position: absolute; + z-index: -1; +} + +// scss-lint:disable VendorPrefix +.indicator { + background-position: center center; + background-repeat: no-repeat; + background-size: .5rem .5rem; + box-sizing: border-box; + display: block; + font-size: 65%; + height: 1rem; + left: 0; + line-height: 1rem; + position: absolute; + text-align: center; + top: .25rem; + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + user-select: none; + width: 1rem; +} + +.checkbox input:focus ~ .indicator, +.radio input:focus ~ .indicator { + box-shadow: 0 0 0 2px rgba($blue, .5); +} + +.checkbox input:checked ~ .indicator, +.radio input:checked ~ .indicator { + background-color: $blue; + color: $white; +} + +.checkbox input:active ~ .indicator, +.radio input:active ~ .indicator { + background-color: $blue-light; + color: $white; +} + +.checkbox .indicator { + background-color: $white; + border: $border-width solid $blue; + border-radius: .25rem; +} + +.checkbox input:checked ~ .indicator { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=); +} + +.radio .indicator { + background-color: #f2f9ff; + border: $border-width solid $blue; + border-radius: 50%; +} + +.radio input:checked ~ .indicator { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==); +} + +.radio input:disabled ~ .indicator { + background-color: $gray-light; + border-color: $gray; +} + +.select-alt { + color: $white; + display: inline-block; + position: relative; + width: 100%; + + select { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + background-color: $navy; + border-right: 1px solid $blue; + color: $white; + cursor: pointer; + display: inline-block; + font-weight: normal; + line-height: 1.5; + padding-right: 2.25rem; + width: 100%; + } + + // Undo the Firefox inner focus ring + select:focus:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 $white; + } + + select:active { + background-color: $navy; + color: $white; + } + + // Hide the arrow in IE10 and up + select::-ms-expand { + display: none; + } + + // Separator + &::before { + border-right: 1px solid $blue; + content: ''; + height: -moz-calc(3rem - 2px); + height: -webkit-calc(3rem - 2px); + height: calc(3rem - 2px); + position: absolute; + right: 3rem; + top: 1px; + width: 0; + } + + // Dropdown arrow + &::after { + border-bottom: .35rem solid transparent; + border-left: .35rem solid transparent; + border-right: .35rem solid transparent; + border-top: .35rem solid; + content: ''; + display: inline-block; + height: 0; + margin-top: -.15rem; + pointer-events: none; + position: absolute; + right: 1.25rem; + top: 50%; + width: 0; + } +} + +// Media query to target Firefox only +@-moz-document url-prefix() { + // Firefox hack to hide the arrow + .select-alt select { + padding-right: 1rem; + text-indent: .01px; + text-overflow: ''; + } + + //