diff --git a/Gemfile b/Gemfile index 51b974ddc06..1933f5df2fe 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" } ruby "~> #{File.read('.ruby-version').strip}" -gem 'rails', '~> 6.1.6.1' +gem 'rails', '~> 7.0.0' gem 'ahoy_matey', '~> 3.0' gem 'aws-sdk-kms', '~> 1.4' @@ -26,7 +26,7 @@ gem 'foundation_emails' gem 'good_job', '~> 2.99.0' gem 'hashie', '~> 4.1' gem 'http_accept_language' -gem 'identity-hostdata', github: '18F/identity-hostdata', tag: 'v3.4.0' +gem 'identity-hostdata', github: '18F/identity-hostdata', tag: 'v3.4.1' gem 'identity-logging', github: '18F/identity-logging', tag: 'v0.1.0' gem 'identity_validations', github: '18F/identity-validations', tag: 'v0.7.2' gem 'jsbundling-rails', '~> 1.0.0' @@ -60,6 +60,7 @@ gem 'safe_target_blank', '>= 1.0.2' gem 'saml_idp', github: '18F/saml_idp', tag: '0.17.0-18f' gem 'scrypt' gem 'simple_form', '>= 5.0.2' +gem 'sprockets-rails' gem 'stringex', require: false gem 'strong_migrations', '>= 0.4.2' gem 'subprocess', require: false @@ -89,7 +90,7 @@ end group :development, :test do gem 'aws-sdk-cloudwatchlogs', require: false gem 'brakeman', require: false - gem 'bullet', '>= 6.0.2' + gem 'bullet', '~> 7.0' gem 'capybara-webmock', git: 'https://github.com/hashrocket/capybara-webmock.git', ref: '63d790a0' gem 'data_uri', require: false gem 'erb_lint', '~> 0.1.0', require: false @@ -103,7 +104,7 @@ group :development, :test do gem 'pry-rails' gem 'psych' gem 'puma' - gem 'rspec-rails', '~> 4.0' + gem 'rspec-rails', '6.0.0.rc1' gem 'rubocop', '~> 1.29.1', require: false gem 'rubocop-performance', '~> 1.12.0', require: false gem 'rubocop-rails', '>= 2.5.2', require: false @@ -117,7 +118,7 @@ group :test do gem 'simplecov-cobertura' gem 'simplecov_json_formatter' gem 'email_spec' - gem 'factory_bot_rails', '>= 5.2.0' + gem 'factory_bot_rails', '>= 6.2.0' gem 'faker' gem 'rack_session_access', '>= 0.2.0' gem 'rack-test', '>= 1.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 42b8d6df000..bc44ebe8851 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,10 @@ GIT remote: https://github.com/18F/identity-hostdata.git - revision: c69cca28c5e9dd35c66c1bfbdb5c2218b560e14b - tag: v3.4.0 + revision: 25a7e98919b1eb0d61dbcce314807a412aff62ad + tag: v3.4.1 specs: - identity-hostdata (3.4.0) - activesupport (~> 6.1) + identity-hostdata (3.4.1) + activesupport (>= 6.1, < 8) aws-sdk-s3 (~> 1.8) GIT @@ -52,65 +52,71 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (6.1.6.1) - actionpack (= 6.1.6.1) - activesupport (= 6.1.6.1) + actioncable (7.0.3.1) + actionpack (= 7.0.3.1) + activesupport (= 7.0.3.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.6.1) - actionpack (= 6.1.6.1) - activejob (= 6.1.6.1) - activerecord (= 6.1.6.1) - activestorage (= 6.1.6.1) - activesupport (= 6.1.6.1) + actionmailbox (7.0.3.1) + actionpack (= 7.0.3.1) + activejob (= 7.0.3.1) + activerecord (= 7.0.3.1) + activestorage (= 7.0.3.1) + activesupport (= 7.0.3.1) mail (>= 2.7.1) - actionmailer (6.1.6.1) - actionpack (= 6.1.6.1) - actionview (= 6.1.6.1) - activejob (= 6.1.6.1) - activesupport (= 6.1.6.1) + net-imap + net-pop + net-smtp + actionmailer (7.0.3.1) + actionpack (= 7.0.3.1) + actionview (= 7.0.3.1) + activejob (= 7.0.3.1) + activesupport (= 7.0.3.1) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.6.1) - actionview (= 6.1.6.1) - activesupport (= 6.1.6.1) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.3.1) + actionview (= 7.0.3.1) + activesupport (= 7.0.3.1) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.6.1) - actionpack (= 6.1.6.1) - activerecord (= 6.1.6.1) - activestorage (= 6.1.6.1) - activesupport (= 6.1.6.1) + actiontext (7.0.3.1) + actionpack (= 7.0.3.1) + activerecord (= 7.0.3.1) + activestorage (= 7.0.3.1) + activesupport (= 7.0.3.1) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.6.1) - activesupport (= 6.1.6.1) + actionview (7.0.3.1) + activesupport (= 7.0.3.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.6.1) - activesupport (= 6.1.6.1) + activejob (7.0.3.1) + activesupport (= 7.0.3.1) globalid (>= 0.3.6) - activemodel (6.1.6.1) - activesupport (= 6.1.6.1) - activerecord (6.1.6.1) - activemodel (= 6.1.6.1) - activesupport (= 6.1.6.1) - activestorage (6.1.6.1) - actionpack (= 6.1.6.1) - activejob (= 6.1.6.1) - activerecord (= 6.1.6.1) - activesupport (= 6.1.6.1) + activemodel (7.0.3.1) + activesupport (= 7.0.3.1) + activerecord (7.0.3.1) + activemodel (= 7.0.3.1) + activesupport (= 7.0.3.1) + activestorage (7.0.3.1) + actionpack (= 7.0.3.1) + activejob (= 7.0.3.1) + activerecord (= 7.0.3.1) + activesupport (= 7.0.3.1) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.6.1) + activesupport (7.0.3.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) ahoy_matey (3.3.0) @@ -122,17 +128,17 @@ GEM ast (2.4.2) awrence (1.2.1) aws-eventstream (1.2.0) - aws-partitions (1.540.0) + aws-partitions (1.543.0) aws-sdk-cloudwatchlogs (1.49.0) aws-sdk-core (~> 3, >= 3.122.0) aws-sigv4 (~> 1.1) - aws-sdk-core (3.124.0) + aws-sdk-core (3.125.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-kms (1.52.0) - aws-sdk-core (~> 3, >= 3.122.0) + aws-sdk-kms (1.53.0) + aws-sdk-core (~> 3, >= 3.125.0) aws-sigv4 (~> 1.1) aws-sdk-pinpoint (1.62.0) aws-sdk-core (~> 3, >= 3.122.0) @@ -140,10 +146,10 @@ GEM aws-sdk-pinpointsmsvoice (1.29.0) aws-sdk-core (~> 3, >= 3.122.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.87.0) - aws-sdk-core (~> 3, >= 3.109.0) + aws-sdk-s3 (1.110.0) + aws-sdk-core (~> 3, >= 3.125.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.1) + aws-sigv4 (~> 1.4) aws-sdk-ses (1.44.0) aws-sdk-core (~> 3, >= 3.122.0) aws-sigv4 (~> 1.1) @@ -185,18 +191,19 @@ GEM blueprinter (0.25.3) bootsnap (1.9.3) msgpack (~> 1.0) - brakeman (5.2.0) + brakeman (5.2.1) browser (5.3.1) builder (3.2.4) - bullet (6.1.5) + bullet (7.0.1) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) bundler-audit (0.9.0.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) byebug (11.1.3) - capybara (3.35.3) + capybara (3.36.0) addressable + matrix mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) @@ -246,7 +253,8 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.4.4) + diff-lcs (1.5.0) + digest (3.1.0) docile (1.4.0) dotiw (5.3.2) activesupport @@ -269,7 +277,7 @@ GEM et-orbi (1.2.7) tzinfo execjs (2.8.1) - factory_bot (6.2.0) + factory_bot (6.2.1) activesupport (>= 5.0.0) factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) @@ -345,7 +353,7 @@ GEM http_accept_language (2.1.1) i18n (1.12.0) concurrent-ruby (~> 1.0) - i18n-tasks (0.9.35) + i18n-tasks (0.9.37) activesupport (>= 4.0.2) ast (>= 2.1.0) erubi @@ -387,6 +395,7 @@ GEM mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.2) + matrix (0.4.2) maxminddb (0.1.22) memory_profiler (0.9.14) method_source (1.0.0) @@ -398,8 +407,22 @@ GEM multipart-post (2.1.1) multiset (0.5.3) nenv (0.3.0) + net-imap (0.2.3) + digest + net-protocol + strscan + net-pop (0.1.1) + digest + net-protocol + timeout + net-protocol (0.1.3) + timeout net-sftp (3.0.0) net-ssh (>= 5.0.0, < 7.0.0) + net-smtp (0.3.1) + digest + net-protocol + timeout net-ssh (6.1.0) newrelic_rpm (8.8.0) nio4r (2.5.8) @@ -468,21 +491,20 @@ GEM rack_session_access (0.2.0) builder (>= 2.0.0) rack (>= 1.0.0) - rails (6.1.6.1) - actioncable (= 6.1.6.1) - actionmailbox (= 6.1.6.1) - actionmailer (= 6.1.6.1) - actionpack (= 6.1.6.1) - actiontext (= 6.1.6.1) - actionview (= 6.1.6.1) - activejob (= 6.1.6.1) - activemodel (= 6.1.6.1) - activerecord (= 6.1.6.1) - activestorage (= 6.1.6.1) - activesupport (= 6.1.6.1) + rails (7.0.3.1) + actioncable (= 7.0.3.1) + actionmailbox (= 7.0.3.1) + actionmailer (= 7.0.3.1) + actionpack (= 7.0.3.1) + actiontext (= 7.0.3.1) + actionview (= 7.0.3.1) + activejob (= 7.0.3.1) + activemodel (= 7.0.3.1) + activerecord (= 7.0.3.1) + activestorage (= 7.0.3.1) + activesupport (= 7.0.3.1) bundler (>= 1.15.0) - railties (= 6.1.6.1) - sprockets-rails (>= 2.0.0) + railties (= 7.0.3.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -497,15 +519,16 @@ GEM ruby-graphviz (~> 1.2) rails-html-sanitizer (1.4.3) loofah (~> 2.3) - rails-i18n (6.0.0) + rails-i18n (7.0.3) i18n (>= 0.7, < 2) - railties (>= 6.0.0, < 7) - railties (6.1.6.1) - actionpack (= 6.1.6.1) - activesupport (= 6.1.6.1) + railties (>= 6.0.0, < 8) + railties (7.0.3.1) + actionpack (= 7.0.3.1) + activesupport (= 7.0.3.1) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rainbow (3.1.1) rake (13.0.6) rb-fsevent (0.10.4) @@ -533,29 +556,29 @@ GEM chunky_png (~> 1.0) rqrcode_core (~> 1.0) rqrcode_core (1.2.0) - rspec (3.10.0) - rspec-core (~> 3.10.0) - rspec-expectations (~> 3.10.0) - rspec-mocks (~> 3.10.0) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec (3.11.0) + rspec-core (~> 3.11.0) + rspec-expectations (~> 3.11.0) + rspec-mocks (~> 3.11.0) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.2) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-rails (4.1.2) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-support (~> 3.11.0) + rspec-rails (6.0.0.rc1) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.11) + rspec-expectations (~> 3.11) + rspec-mocks (~> 3.11) + rspec-support (~> 3.11) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.10.3) + rspec-support (3.11.0) rubocop (1.29.1) parallel (~> 1.10) parser (>= 3.1.0.0) @@ -616,7 +639,7 @@ GEM simpleidn (0.2.1) unf (~> 0.1.4) smart_properties (1.17.0) - sprockets (4.1.1) + sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.4.2) @@ -624,14 +647,16 @@ GEM activesupport (>= 5.2) sprockets (>= 3.0.0) stringex (2.8.5) - strong_migrations (0.7.9) - activerecord (>= 5) + strong_migrations (0.8.0) + activerecord (>= 5.2) + strscan (3.0.1) subprocess (1.5.5) systemu (2.6.5) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) thor (1.2.1) thread_safe (0.3.6) + timeout (0.3.0) tpm-key_attestation (0.10.0) bindata (~> 2.4) openssl-signature_algorithm (~> 1.0) @@ -716,7 +741,7 @@ DEPENDENCIES bootsnap (~> 1.9.0) brakeman browser - bullet (>= 6.0.2) + bullet (~> 7.0) bundler-audit capybara-selenium (>= 0.0.6) capybara-webmock! @@ -728,7 +753,7 @@ DEPENDENCIES dotiw (>= 4.0.1) email_spec erb_lint (~> 0.1.0) - factory_bot_rails (>= 5.2.0) + factory_bot_rails (>= 6.2.0) faker faraday faraday_middleware @@ -773,7 +798,7 @@ DEPENDENCIES rack-test (>= 1.1.0) rack-timeout rack_session_access (>= 0.2.0) - rails (~> 6.1.6.1) + rails (~> 7.0.0) rails-controller-testing (>= 1.0.4) rails-erd (>= 1.6.0) redacted_struct @@ -783,7 +808,7 @@ DEPENDENCIES retries rotp (~> 6.1) rqrcode - rspec-rails (~> 4.0) + rspec-rails (= 6.0.0.rc1) rspec-retry rubocop (~> 1.29.1) rubocop-performance (~> 1.12.0) @@ -798,6 +823,7 @@ DEPENDENCIES simplecov (~> 0.21.0) simplecov-cobertura simplecov_json_formatter + sprockets-rails stringex strong_migrations (>= 0.4.2) subprocess diff --git a/Makefile b/Makefile index 27bb4dcb9e8..7c451433afc 100644 --- a/Makefile +++ b/Makefile @@ -62,8 +62,6 @@ lint: ## Runs all lint tests make lint_analytics_events @echo "--- brakeman ---" bundle exec brakeman - @echo "--- zeitwerk check ---" - bin/rails zeitwerk:check @echo "--- bundler-audit ---" bundle exec bundler-audit check --update # JavaScript diff --git a/app/controllers/openid_connect/authorization_controller.rb b/app/controllers/openid_connect/authorization_controller.rb index ba2446c1dab..90202919ff2 100644 --- a/app/controllers/openid_connect/authorization_controller.rb +++ b/app/controllers/openid_connect/authorization_controller.rb @@ -66,7 +66,7 @@ def ial_context def handle_successful_handoff track_events SpHandoffBounce::AddHandoffTimeToSession.call(sp_session) - redirect_to @authorize_form.success_redirect_uri + redirect_to @authorize_form.success_redirect_uri, allow_other_host: true delete_branded_experience end @@ -113,7 +113,7 @@ def validate_authorize_form return if result.success? if (redirect_uri = result.extra[:redirect_uri]) - redirect_to redirect_uri + redirect_to redirect_uri, allow_other_host: true else render :error end diff --git a/app/controllers/openid_connect/logout_controller.rb b/app/controllers/openid_connect/logout_controller.rb index 0ec7dc359c7..b25132f0d9a 100644 --- a/app/controllers/openid_connect/logout_controller.rb +++ b/app/controllers/openid_connect/logout_controller.rb @@ -13,7 +13,12 @@ def index if result.success? && (redirect_uri = result.extra[:redirect_uri]) sign_out - redirect_to redirect_uri unless logout_params[:prevent_logout_redirect] == 'true' + unless logout_params[:prevent_logout_redirect] == 'true' + redirect_to( + redirect_uri, + allow_other_host: true, + ) + end else render :error end diff --git a/app/controllers/redirect/redirect_controller.rb b/app/controllers/redirect/redirect_controller.rb index d51f850a695..ad103661aef 100644 --- a/app/controllers/redirect/redirect_controller.rb +++ b/app/controllers/redirect/redirect_controller.rb @@ -15,7 +15,7 @@ def redirect_to_and_log(url, event: nil, tracker_method: analytics.method(:exter else tracker_method.call(redirect_url: url, **location_params) end - redirect_to(url) + redirect_to(url, allow_other_host: true) end end end diff --git a/app/controllers/redirect/return_to_sp_controller.rb b/app/controllers/redirect/return_to_sp_controller.rb index 119ec31cbd8..a1a18f0ca9a 100644 --- a/app/controllers/redirect/return_to_sp_controller.rb +++ b/app/controllers/redirect/return_to_sp_controller.rb @@ -5,14 +5,14 @@ class ReturnToSpController < Redirect::RedirectController def cancel redirect_url = sp_return_url_resolver.return_to_sp_url analytics.return_to_sp_cancelled(redirect_url: redirect_url, **location_params) - redirect_to(redirect_url) + redirect_to(redirect_url, allow_other_host: true) end def failure_to_proof redirect_url = sp_return_url_resolver.failure_to_proof_url analytics.return_to_sp_failure_to_proof(redirect_url: redirect_url, **location_params) - redirect_to(redirect_url) + redirect_to(redirect_url, allow_other_host: true) end private diff --git a/app/controllers/sign_out_controller.rb b/app/controllers/sign_out_controller.rb index 8eb656e5f08..95c2062b1a5 100644 --- a/app/controllers/sign_out_controller.rb +++ b/app/controllers/sign_out_controller.rb @@ -6,7 +6,7 @@ def destroy url_after_cancellation = decorated_session.cancel_link_url sign_out flash[:success] = t('devise.sessions.signed_out') - redirect_to url_after_cancellation + redirect_to(url_after_cancellation, allow_other_host: true) delete_branded_experience end end diff --git a/app/controllers/sign_up/completions_controller.rb b/app/controllers/sign_up/completions_controller.rb index a48828f9e53..c6e77351c08 100644 --- a/app/controllers/sign_up/completions_controller.rb +++ b/app/controllers/sign_up/completions_controller.rb @@ -21,7 +21,10 @@ def update if decider.go_back_to_mobile_app? sign_user_out_and_instruct_to_go_back_to_mobile_app else - redirect_to(sp_session_request_url_with_updated_params || account_url) + redirect_to( + sp_session_request_url_with_updated_params || account_url, + allow_other_host: true, + ) end end diff --git a/app/controllers/two_factor_authentication/piv_cac_verification_controller.rb b/app/controllers/two_factor_authentication/piv_cac_verification_controller.rb index 4ed00032819..4a44fa98e5a 100644 --- a/app/controllers/two_factor_authentication/piv_cac_verification_controller.rb +++ b/app/controllers/two_factor_authentication/piv_cac_verification_controller.rb @@ -20,7 +20,7 @@ def redirect_to_piv_cac_service redirect_to PivCacService.piv_cac_service_link( nonce: piv_cac_nonce, redirect_uri: login_two_factor_piv_cac_url, - ) + ), allow_other_host: true end private diff --git a/app/controllers/users/authorization_confirmation_controller.rb b/app/controllers/users/authorization_confirmation_controller.rb index 9160b3e641a..7c674a6aa12 100644 --- a/app/controllers/users/authorization_confirmation_controller.rb +++ b/app/controllers/users/authorization_confirmation_controller.rb @@ -16,7 +16,7 @@ def new def create analytics.authentication_confirmation_continue - redirect_to sp_session_request_url_with_updated_params + redirect_to sp_session_request_url_with_updated_params, allow_other_host: true end def destroy diff --git a/app/controllers/users/piv_cac_authentication_setup_controller.rb b/app/controllers/users/piv_cac_authentication_setup_controller.rb index 8741abefb08..90d610f2923 100644 --- a/app/controllers/users/piv_cac_authentication_setup_controller.rb +++ b/app/controllers/users/piv_cac_authentication_setup_controller.rb @@ -44,7 +44,7 @@ def submit_new_piv_cac if good_nickname user_session[:piv_cac_nickname] = params[:name] create_piv_cac_nonce - redirect_to piv_cac_service_url_with_redirect + redirect_to piv_cac_service_url_with_redirect, allow_other_host: true else flash[:error] = I18n.t('errors.piv_cac_setup.unique_name') render_prompt diff --git a/app/controllers/users/piv_cac_login_controller.rb b/app/controllers/users/piv_cac_login_controller.rb index 6e8c945881c..2b3a8641d37 100644 --- a/app/controllers/users/piv_cac_login_controller.rb +++ b/app/controllers/users/piv_cac_login_controller.rb @@ -17,7 +17,7 @@ def redirect_to_piv_cac_service redirect_to PivCacService.piv_cac_service_link( nonce: piv_cac_nonce, redirect_uri: login_piv_cac_url, - ) + ), allow_other_host: true end def account_not_found; end diff --git a/app/models/backup_code_configuration.rb b/app/models/backup_code_configuration.rb index 05138a035e5..5db2cc84f40 100644 --- a/app/models/backup_code_configuration.rb +++ b/app/models/backup_code_configuration.rb @@ -14,7 +14,7 @@ def self.unused end def mfa_enabled? - user.backup_code_configurations.unused.any? if user + persisted? && used_at.nil? end def selection_presenters diff --git a/app/views/account_reset/pending/confirm.html.erb b/app/views/account_reset/pending/confirm.html.erb index 4ef46167b20..872066ff582 100644 --- a/app/views/account_reset/pending/confirm.html.erb +++ b/app/views/account_reset/pending/confirm.html.erb @@ -3,6 +3,7 @@ <%= button_to( account_reset_pending_cancel_path, class: 'usa-button usa-button--wide usa-button--big margin-bottom-2', + method: :post, ) { t('forms.buttons.continue') } %> <%= link_to(t('links.go_back'), account_reset_pending_path) %> diff --git a/app/views/account_reset/request/show.html.erb b/app/views/account_reset/request/show.html.erb index e324060b477..bfcceb2a086 100644 --- a/app/views/account_reset/request/show.html.erb +++ b/app/views/account_reset/request/show.html.erb @@ -23,6 +23,7 @@ <%= button_to( account_reset_request_path, class: 'usa-button usa-button--unstyled', + method: :post, ) { t('account_reset.request.yes_continue') } %> <%= render PageFooterComponent.new do %> diff --git a/app/views/users/authorization_confirmation/new.html.erb b/app/views/users/authorization_confirmation/new.html.erb index 8e4287bc166..d13ab57eb32 100644 --- a/app/views/users/authorization_confirmation/new.html.erb +++ b/app/views/users/authorization_confirmation/new.html.erb @@ -30,7 +30,7 @@
- <%= button_to(user_authorization_confirmation_path, class: 'usa-button usa-button--big usa-button--wide') { t('user_authorization_confirmation.continue') } %> + <%= button_to(user_authorization_confirmation_path, class: 'usa-button usa-button--big usa-button--wide', method: :post) { t('user_authorization_confirmation.continue') } %>
<%= t('user_authorization_confirmation.or') %> diff --git a/config/application.rb b/config/application.rb index 21855158294..703d4ac6ce7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -48,7 +48,9 @@ class Application < Rails::Application end end - config.load_defaults '6.1' + config.load_defaults '7.0' + # Delete after deploying once + config.active_support.cache_format_version = 6.1 config.active_record.belongs_to_required_by_default = false config.active_record.legacy_connection_handling = false config.assets.unknown_asset_fallback = true @@ -78,12 +80,6 @@ class Application < Rails::Application config.time_zone = 'UTC' - # Generate CSRF tokens that are encoded in URL-safe Base64. - # - # This change is not backwards compatible with earlier Rails versions. - # It's best enabled when your entire app is migrated and stable on 6.1. - Rails.application.config.action_controller.urlsafe_csrf_tokens = false - config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{yml}')] config.i18n.available_locales = %w[en es fr] config.i18n.default_locale = :en diff --git a/config/environments/test.rb b/config/environments/test.rb index 19b5f8d9c59..711fe6db86a 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -55,6 +55,7 @@ :webauthn_configurations, :email_addresses, :proofing_component, + :account_reset_request, ].each do |association| Bullet.add_safelist(type: :n_plus_one_query, class_name: 'User', association: association) end diff --git a/spec/controllers/api/verify/document_capture_controller_spec.rb b/spec/controllers/api/verify/document_capture_controller_spec.rb index 48faa73128f..573fae40621 100644 --- a/spec/controllers/api/verify/document_capture_controller_spec.rb +++ b/spec/controllers/api/verify/document_capture_controller_spec.rb @@ -75,16 +75,18 @@ it 'returns inprogress status when create is called' do agent = instance_double(Idv::Agent) allow(Idv::Agent).to receive(:new).with( - user_uuid: user.uuid, - uuid_prefix: nil, - document_arguments: { - 'encryption_key' => encryption_key, - 'front_image_iv' => front_image_iv, - 'back_image_iv' => back_image_iv, - 'selfie_image_iv' => selfie_image_iv, - 'front_image_url' => front_image_url, - 'back_image_url' => back_image_url, - 'selfie_image_url' => selfie_image_url, + { + user_uuid: user.uuid, + uuid_prefix: nil, + document_arguments: { + 'encryption_key' => encryption_key, + 'front_image_iv' => front_image_iv, + 'back_image_iv' => back_image_iv, + 'selfie_image_iv' => selfie_image_iv, + 'front_image_url' => front_image_url, + 'back_image_url' => back_image_url, + 'selfie_image_url' => selfie_image_url, + }, }, ).and_return(agent) diff --git a/spec/controllers/idv/phone_controller_spec.rb b/spec/controllers/idv/phone_controller_spec.rb index e80f5700f48..7bc08e7106c 100644 --- a/spec/controllers/idv/phone_controller_spec.rb +++ b/spec/controllers/idv/phone_controller_spec.rb @@ -389,17 +389,18 @@ end it 'tracks throttled event' do - put :create, params: { idv_phone_form: { phone: bad_phone } } - stub_analytics allow(@analytics).to receive(:track_event) expect(@analytics).to receive(:track_event).with( 'Throttler Rate Limit Triggered', - throttle_type: :proof_address, - step_name: a_kind_of(Symbol), + { + throttle_type: :proof_address, + step_name: :phone, + }, ) + put :create, params: { idv_phone_form: { phone: bad_phone } } get :new end end diff --git a/spec/controllers/idv/review_controller_spec.rb b/spec/controllers/idv/review_controller_spec.rb index efc94e05bd9..89b39740096 100644 --- a/spec/controllers/idv/review_controller_spec.rb +++ b/spec/controllers/idv/review_controller_spec.rb @@ -207,7 +207,10 @@ def show expect(flash.now[:success]).to eq( t( 'idv.messages.review.info_verified_html', - phone_message: "#{t('idv.messages.phone.phone_of_record')}", + phone_message: ActionController::Base.helpers.content_tag( + :strong, + t('idv.messages.phone.phone_of_record'), + ), ), ) end diff --git a/spec/controllers/openid_connect/token_controller_spec.rb b/spec/controllers/openid_connect/token_controller_spec.rb index 03be4f8b7a8..c1ca44c68f7 100644 --- a/spec/controllers/openid_connect/token_controller_spec.rb +++ b/spec/controllers/openid_connect/token_controller_spec.rb @@ -53,11 +53,12 @@ it 'tracks a successful event in analytics' do stub_analytics expect(@analytics).to receive(:track_event). - with('OpenID Connect: token', - success: true, - client_id: client_id, - user_id: user.uuid, - errors: {}) + with('OpenID Connect: token', { + success: true, + client_id: client_id, + user_id: user.uuid, + errors: {}, + }) action end end @@ -77,12 +78,13 @@ it 'tracks an unsuccessful event in analytics' do stub_analytics expect(@analytics).to receive(:track_event). - with('OpenID Connect: token', - success: false, - client_id: client_id, - user_id: user.uuid, - errors: hash_including(:grant_type), - error_details: hash_including(:grant_type)) + with('OpenID Connect: token', { + success: false, + client_id: client_id, + user_id: user.uuid, + errors: hash_including(:grant_type), + error_details: hash_including(:grant_type), + }) action end diff --git a/spec/controllers/saml_idp_controller_spec.rb b/spec/controllers/saml_idp_controller_spec.rb index 89b45b4876a..9eda5cf5a2f 100644 --- a/spec/controllers/saml_idp_controller_spec.rb +++ b/spec/controllers/saml_idp_controller_spec.rb @@ -537,27 +537,28 @@ def name_id_version(format_urn) it 'tracks IAL2 authentication events' do stub_analytics expect(@analytics).to receive(:track_event). - with('SAML Auth Request', - requested_ial: authn_context, - service_provider: sp1_issuer) + with('SAML Auth Request', { + requested_ial: authn_context, + service_provider: sp1_issuer, + }) expect(@analytics).to receive(:track_event). - with('SAML Auth', - success: true, - errors: {}, - nameid_format: Saml::Idp::Constants::NAME_ID_FORMAT_PERSISTENT, - authn_context: [authn_context], - authn_context_comparison: 'exact', - requested_ial: authn_context, - service_provider: sp1_issuer, - endpoint: '/api/saml/auth2022', - idv: false, - finish_profile: false) + with('SAML Auth', { + success: true, + errors: {}, + nameid_format: Saml::Idp::Constants::NAME_ID_FORMAT_PERSISTENT, + authn_context: [authn_context], + authn_context_comparison: 'exact', + requested_ial: authn_context, + service_provider: sp1_issuer, + endpoint: '/api/saml/auth2022', + idv: false, + finish_profile: false, + }) expect(@analytics).to receive(:track_event). - with( - 'SP redirect initiated', + with('SP redirect initiated', { ial: ial, billed_ial: [ial, 2].min, - ) + }) allow(controller).to receive(:identity_needs_verification?).and_return(false) saml_get_auth(ial2_settings) @@ -694,27 +695,25 @@ def name_id_version(format_urn) it 'tracks IAL2 authentication events' do stub_analytics expect(@analytics).to receive(:track_event). - with('SAML Auth Request', - requested_ial: 'ialmax', - service_provider: sp1_issuer) + with('SAML Auth Request', { + requested_ial: 'ialmax', + service_provider: sp1_issuer, + }) expect(@analytics).to receive(:track_event). - with('SAML Auth', - success: true, - errors: {}, - nameid_format: Saml::Idp::Constants::NAME_ID_FORMAT_PERSISTENT, - authn_context: ['http://idmanagement.gov/ns/assurance/ial/1'], - authn_context_comparison: 'minimum', - requested_ial: 'ialmax', - service_provider: sp1_issuer, - endpoint: '/api/saml/auth2022', - idv: false, - finish_profile: false) + with('SAML Auth', { + success: true, + errors: {}, + nameid_format: Saml::Idp::Constants::NAME_ID_FORMAT_PERSISTENT, + authn_context: ['http://idmanagement.gov/ns/assurance/ial/1'], + authn_context_comparison: 'minimum', + requested_ial: 'ialmax', + service_provider: sp1_issuer, + endpoint: '/api/saml/auth2022', + idv: false, + finish_profile: false, + }) expect(@analytics).to receive(:track_event). - with( - 'SP redirect initiated', - ial: 0, - billed_ial: 2, - ) + with('SP redirect initiated', { ial: 0, billed_ial: 2 }) allow(controller).to receive(:identity_needs_verification?).and_return(false) saml_get_auth(ialmax_settings) @@ -1380,9 +1379,10 @@ def name_id_version(format_urn) it 'logs SAML Auth Request but does not log SAML Auth' do stub_analytics expect(@analytics).to receive(:track_event). - with('SAML Auth Request', - requested_ial: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, - service_provider: 'http://localhost:3000') + with('SAML Auth Request', { + requested_ial: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, + service_provider: 'http://localhost:3000', + }) saml_get_auth(saml_settings) end @@ -1828,9 +1828,10 @@ def stub_auth } expect(@analytics).to receive(:track_event). - with('SAML Auth Request', - requested_ial: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, - service_provider: 'http://localhost:3000') + with('SAML Auth Request', { + requested_ial: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, + service_provider: 'http://localhost:3000', + }) expect(@analytics).to receive(:track_event). with('SAML Auth', analytics_hash) @@ -1870,16 +1871,13 @@ def stub_requested_attributes } expect(@analytics).to receive(:track_event). - with('SAML Auth Request', - requested_ial: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, - service_provider: 'http://localhost:3000') + with('SAML Auth Request', { + requested_ial: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, + service_provider: 'http://localhost:3000', + }) expect(@analytics).to receive(:track_event).with('SAML Auth', analytics_hash) expect(@analytics).to receive(:track_event). - with( - 'SP redirect initiated', - ial: 1, - billed_ial: 1, - ) + with('SP redirect initiated', { ial: 1, billed_ial: 1 }) generate_saml_response(user) end @@ -1907,16 +1905,16 @@ def stub_requested_attributes } expect(@analytics).to receive(:track_event). - with('SAML Auth Request', - requested_ial: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, - service_provider: 'http://localhost:3000') + with('SAML Auth Request', { + requested_ial: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, + service_provider: 'http://localhost:3000', + }) expect(@analytics).to receive(:track_event).with('SAML Auth', analytics_hash) expect(@analytics).to receive(:track_event). - with( - 'SP redirect initiated', + with('SP redirect initiated', { ial: 1, billed_ial: 1, - ) + }) generate_saml_response(user) end diff --git a/spec/controllers/users/webauthn_setup_controller_spec.rb b/spec/controllers/users/webauthn_setup_controller_spec.rb index 29ed30cf21a..662955546e5 100644 --- a/spec/controllers/users/webauthn_setup_controller_spec.rb +++ b/spec/controllers/users/webauthn_setup_controller_spec.rb @@ -68,6 +68,7 @@ before do allow(IdentityConfig.store).to receive(:domain_name).and_return('localhost:3000') + request.host = 'localhost:3000' controller.user_session[:webauthn_challenge] = webauthn_challenge end @@ -86,21 +87,19 @@ with('Multi-Factor Authentication Setup', result) expect(@analytics).to receive(:track_event). - with( - 'Multi-Factor Authentication: Added webauthn', + with('Multi-Factor Authentication: Added webauthn', { enabled_mfa_methods_count: 3, method_name: :webauthn, platform_authenticator: false, - ) + }) expect(@analytics).to receive(:track_event). - with( - 'User Registration: MFA Setup Complete', + with('User Registration: MFA Setup Complete', { enabled_mfa_methods_count: 3, mfa_method_counts: { auth_app: 1, phone: 1, webauthn: 1 }, pii_like_keypaths: [[:mfa_method_counts, :phone]], success: true, - ) + }) patch :confirm, params: params end @@ -172,6 +171,7 @@ stub_analytics stub_sign_in(user) allow(IdentityConfig.store).to receive(:domain_name).and_return('localhost:3000') + request.host = 'localhost:3000' controller.user_session[:webauthn_challenge] = webauthn_challenge end context ' Multiple MFA options turned on' do diff --git a/spec/helpers/link_helper_spec.rb b/spec/helpers/link_helper_spec.rb index 52fddb42a47..b19b8d8dccf 100644 --- a/spec/helpers/link_helper_spec.rb +++ b/spec/helpers/link_helper_spec.rb @@ -39,7 +39,8 @@ it 'renders a form' do expect(subject).to have_selector("form[action='#{url}']") expect(subject).to have_selector("input[name='_method'][value='#{method}']", visible: :all) - expect(subject).to have_selector("input.#{css_class}[type='submit'][value='#{text}']") + expect(subject).to have_selector("button.#{css_class}[type='submit']") + expect(subject).to have_text(text) end end end diff --git a/spec/helpers/script_helper_spec.rb b/spec/helpers/script_helper_spec.rb index 57173e5a241..1483415be93 100644 --- a/spec/helpers/script_helper_spec.rb +++ b/spec/helpers/script_helper_spec.rb @@ -43,9 +43,9 @@ 'script[type="application/json"][data-asset-map]', visible: :all, text: { - 'clock.svg' => '/clock.svg', + 'clock.svg' => 'http://test.host/clock.svg', 'identity-style-guide/dist/assets/img/sprite.svg' => - '/identity-style-guide/dist/assets/img/sprite.svg', + 'http://test.host/identity-style-guide/dist/assets/img/sprite.svg', }.to_json, ) end diff --git a/spec/jobs/reports/sp_user_counts_report_spec.rb b/spec/jobs/reports/sp_user_counts_report_spec.rb index 55721544347..4d818298ad1 100644 --- a/spec/jobs/reports/sp_user_counts_report_spec.rb +++ b/spec/jobs/reports/sp_user_counts_report_spec.rb @@ -18,28 +18,36 @@ freeze_time do timestamp = Time.zone.now.iso8601 expect(subject).to receive(:write_hash_to_reports_log).with( - app_id: app_id, - ial1_user_total: 3, - ial2_user_total: 0, - issuer: issuer, - name: 'Report SP User Counts', - time: timestamp, - user_total: 3, + { + app_id: app_id, + ial1_user_total: 3, + ial2_user_total: 0, + issuer: issuer, + name: 'Report SP User Counts', + time: timestamp, + user_total: 3, + }, ) expect(subject).to receive(:write_hash_to_reports_log).with( - name: 'Report Registered Users Count', - time: timestamp, - count: 0, + { + name: 'Report Registered Users Count', + time: timestamp, + count: 0, + }, ) expect(subject).to receive(:write_hash_to_reports_log).with( - name: 'Report IAL1 Users Linked to SPs Count', - time: timestamp, - count: 2, + { + name: 'Report IAL1 Users Linked to SPs Count', + time: timestamp, + count: 2, + }, ) expect(subject).to receive(:write_hash_to_reports_log).with( - name: 'Report IAL2 Users Linked to SPs Count', - time: timestamp, - count: 1, + { + name: 'Report IAL2 Users Linked to SPs Count', + time: timestamp, + count: 1, + }, ) subject.perform(Time.zone.today) end diff --git a/spec/models/backup_code_configuration_spec.rb b/spec/models/backup_code_configuration_spec.rb index d6a14ad1773..9a346dd7278 100644 --- a/spec/models/backup_code_configuration_spec.rb +++ b/spec/models/backup_code_configuration_spec.rb @@ -25,9 +25,10 @@ user = User.new user.save BackupCodeGenerator.new(user).create - backup_code_config = BackupCodeConfiguration.new(user_id: user.id) - expect(backup_code_config.mfa_enabled?).to be_truthy + user.backup_code_configurations.each do |backup_code_config| + expect(backup_code_config.mfa_enabled?).to be_truthy + end end end diff --git a/spec/presenters/two_factor_auth_code/phone_delivery_presenter_spec.rb b/spec/presenters/two_factor_auth_code/phone_delivery_presenter_spec.rb index 25afbc384b9..8e96f5b4510 100644 --- a/spec/presenters/two_factor_auth_code/phone_delivery_presenter_spec.rb +++ b/spec/presenters/two_factor_auth_code/phone_delivery_presenter_spec.rb @@ -50,7 +50,7 @@ it 'specifies when the code will expire' do text = t( 'instructions.mfa.sms.number_message_html', - number: "#{data[:phone_number]}", + number: ActionController::Base.helpers.content_tag(:strong, data[:phone_number]), expiration: TwoFactorAuthenticatable::DIRECT_OTP_VALID_FOR_MINUTES, ) expect(presenter.phone_number_message).to eq text diff --git a/spec/services/encryption/encryptors/pii_encryptor_spec.rb b/spec/services/encryption/encryptors/pii_encryptor_spec.rb index fba039cb9d8..1c68f366901 100644 --- a/spec/services/encryption/encryptors/pii_encryptor_spec.rb +++ b/spec/services/encryption/encryptors/pii_encryptor_spec.rb @@ -44,7 +44,7 @@ and_return('aes_ciphertext') expect(subject.send(:kms_client)).to receive(:encrypt). - with('aes_ciphertext', 'context' => 'pii-encryption', 'user_uuid' => 'uuid-123-abc'). + with('aes_ciphertext', { 'context' => 'pii-encryption', 'user_uuid' => 'uuid-123-abc' }). and_return('kms_ciphertext') expected_ciphertext = Base64.strict_encode64('kms_ciphertext') diff --git a/spec/services/encryption/password_verifier_spec.rb b/spec/services/encryption/password_verifier_spec.rb index a5f25e230d9..36a1f2d34d2 100644 --- a/spec/services/encryption/password_verifier_spec.rb +++ b/spec/services/encryption/password_verifier_spec.rb @@ -43,7 +43,7 @@ kms_client = Encryption::KmsClient.new expect(kms_client).to receive(:encrypt).with( encoded_scrypt_password, - 'user_uuid' => user_uuid, 'context' => 'password-digest', + { 'user_uuid' => user_uuid, 'context' => 'password-digest' }, ).and_return('kms_ciphertext') expect(Encryption::KmsClient).to receive(:new).and_return(kms_client) diff --git a/spec/services/usps_in_person_proofing/proofer_spec.rb b/spec/services/usps_in_person_proofing/proofer_spec.rb index eae11156194..f73cd103af0 100644 --- a/spec/services/usps_in_person_proofing/proofer_spec.rb +++ b/spec/services/usps_in_person_proofing/proofer_spec.rb @@ -125,14 +125,12 @@ def check_facility(facility) enrollment_code: '123456789', ) - expect( - -> do - subject.request_proofing_results( - applicant.unique_id, - applicant.enrollment_code, - ) - end, - ).to raise_error( + expect do + subject.request_proofing_results( + applicant.unique_id, + applicant.enrollment_code, + ) + end.to raise_error( an_instance_of(Faraday::BadRequestError). and(having_attributes( response: include( diff --git a/spec/support/matchers/have_actions.rb b/spec/support/matchers/have_actions.rb index e349af88807..70583f08a51 100644 --- a/spec/support/matchers/have_actions.rb +++ b/spec/support/matchers/have_actions.rb @@ -38,7 +38,7 @@ callbacks = controller._process_action_callbacks.select { |callback| callback.kind == kind } actions = callbacks.each_with_object([]) do |f, result| - result << f.filter unless action_has_only_option?(f) || action_has_except_option?(f) + result << f.filter result << [f.filter, only: parsed_only_action(f)] if action_has_only_option?(f) result << [f.filter, if: parsed_only_action(f)] if action_has_only_option?(f) result << [f.filter, except: parsed_except_action(f)] if action_has_except_option?(f) @@ -67,9 +67,7 @@ def unless_option_for(action) end def parsed_only_action(action) - only_option = if_option_for(action)[0] - - "#{only_option.class}OptionParser".constantize.new(only_option).parse + if_option_for(action)[0] end def parsed_except_action(action)