diff --git a/Gemfile b/Gemfile index 0179b2f46ff..59332294205 100644 --- a/Gemfile +++ b/Gemfile @@ -56,7 +56,7 @@ gem 'premailer-rails', '>= 1.12.0' gem 'profanity_filter' gem 'propshaft' gem 'rack', '>= 3.0' -gem 'rack-attack', '>= 6.2.1' +gem 'rack-attack', github: 'rack/rack-attack', ref: 'd9fedfae4f7f6409f33857763391f4e18a6d7467' gem 'rack-cors', '>= 1.0.5', require: 'rack/cors' gem 'rack-headers_filter' gem 'rack-timeout', require: false @@ -112,8 +112,8 @@ group :development, :test do gem 'psych' gem 'rspec', '~> 3.12.0' gem 'rspec-rails', '~> 6.0' - gem 'rubocop', '~> 1.55.1', require: false - gem 'rubocop-performance', '~> 1.19.0', require: false + gem 'rubocop', '~> 1.59.0', require: false + gem 'rubocop-performance', '~> 1.20.2', require: false gem 'rubocop-rails', '>= 2.5.2', require: false gem 'rubocop-rspec', require: false end diff --git a/Gemfile.lock b/Gemfile.lock index af282c95219..632fe2405b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -57,6 +57,14 @@ GIT selenium-webdriver (>= 4.0) webrick (>= 1.7) +GIT + remote: https://github.com/rack/rack-attack.git + revision: d9fedfae4f7f6409f33857763391f4e18a6d7467 + ref: d9fedfae4f7f6409f33857763391f4e18a6d7467 + specs: + rack-attack (6.7.0) + rack (>= 1.0, < 4) + GEM remote: https://rubygems.org/ specs: @@ -137,7 +145,7 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) ahoy_matey (3.3.0) activesupport (>= 5) @@ -222,11 +230,11 @@ GEM bundler (>= 1.2.0, < 3) thor (~> 1.0) byebug (11.1.3) - capybara (3.39.2) + capybara (3.40.0) addressable matrix mini_mime (>= 0.1.3) - nokogiri (~> 1.8) + nokogiri (~> 1.11) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) @@ -435,7 +443,7 @@ GEM openssl-signature_algorithm (1.2.1) openssl (> 2.0, < 3.1) orm_adapter (0.5.0) - parallel (1.23.0) + parallel (1.24.0) parser (3.3.0.0) ast (~> 2.4.1) racc @@ -471,14 +479,12 @@ GEM pry (>= 0.10.4) psych (5.1.2) stringio - public_suffix (5.0.3) + public_suffix (5.0.4) puma (6.4.2) nio4r (~> 2.0) raabro (1.4.0) racc (1.7.3) rack (3.0.8) - rack-attack (6.7.0) - rack (>= 1.0, < 4) rack-cors (2.0.1) rack (>= 2.0.0) rack-headers_filter (0.0.1) @@ -546,7 +552,7 @@ GEM redis-client (>= 0.9.0) redis-client (0.14.1) connection_pool - regexp_parser (2.8.2) + regexp_parser (2.9.0) reline (0.4.1) io-console (~> 0.5) request_store (1.5.1) @@ -591,15 +597,15 @@ GEM rspec-support (3.12.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.55.1) + rubocop (1.59.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.30.0) @@ -608,9 +614,9 @@ GEM rubocop (~> 1.41) rubocop-factory_bot (2.24.0) rubocop (~> 1.33) - rubocop-performance (1.19.1) - rubocop (>= 1.7.0, < 2.0) - rubocop-ast (>= 0.4.0) + rubocop-performance (1.20.2) + rubocop (>= 1.48.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) rubocop-rails (2.20.2) activesupport (>= 4.2.0) rack (>= 1.1) @@ -805,7 +811,7 @@ DEPENDENCIES psych puma (~> 6.0) rack (>= 3.0) - rack-attack (>= 6.2.1) + rack-attack! rack-cors (>= 1.0.5) rack-headers_filter rack-mini-profiler (>= 1.1.3) @@ -824,8 +830,8 @@ DEPENDENCIES rspec-rails (~> 6.0) rspec-retry rspec_junit_formatter - rubocop (~> 1.55.1) - rubocop-performance (~> 1.19.0) + rubocop (~> 1.59.0) + rubocop-performance (~> 1.20.2) rubocop-rails (>= 2.5.2) rubocop-rspec ruby-progressbar diff --git a/app/assets/images/us_flag.svg b/app/assets/images/us_flag.svg deleted file mode 100644 index 275d57b9735..00000000000 --- a/app/assets/images/us_flag.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/assets/stylesheets/components/_alert.scss b/app/assets/stylesheets/components/_alert.scss index 7ee4d8f7837..1a145ebb8ba 100644 --- a/app/assets/stylesheets/components/_alert.scss +++ b/app/assets/stylesheets/components/_alert.scss @@ -19,8 +19,3 @@ .usa-alert__text > p:last-child { margin-bottom: 0; } - -// Upstream fix: https://github.com/uswds/uswds/pull/5187 -.usa-alert .usa-alert__body::before { - height: units(2); -} diff --git a/app/assets/stylesheets/components/_btn.scss b/app/assets/stylesheets/components/_btn.scss index c0e0873d926..e4e09fd6748 100644 --- a/app/assets/stylesheets/components/_btn.scss +++ b/app/assets/stylesheets/components/_btn.scss @@ -30,32 +30,3 @@ @include set-text-and-bg('primary-darker', $context: 'Button'); } } - -// Upstream: https://github.com/18F/identity-design-system/pull/383 -.usa-button--danger.usa-button--outline { - &:not(:disabled, [aria-disabled='true']) { - background-color: color('white'); - box-shadow: inset 0 0 0 $theme-button-stroke-width color('secondary'); - color: color('secondary'); - - &:hover, - &.usa-button--hover { - background-color: color('secondary-lightest'); - box-shadow: inset 0 0 0 $theme-button-stroke-width color('secondary-dark'); - color: color('secondary-dark'); - } - } - - &:active, - &.usa-button--active { - &, - &:focus, - &.usa-button--focus, - &:hover, - &.usa-button--hover { - background-color: color('secondary-lighter'); - box-shadow: inset 0 0 0 $theme-button-stroke-width color('secondary-darker'); - color: color('secondary-darker'); - } - } -} diff --git a/app/components/status_page_component.rb b/app/components/status_page_component.rb index 66e55392edd..6733a92978b 100644 --- a/app/components/status_page_component.rb +++ b/app/components/status_page_component.rb @@ -30,7 +30,7 @@ def initialize(status: :error, icon: nil) def icon_name if @icon - "#{status}_#{icon}".to_sym + :"#{status}_#{icon}" else status.to_sym end diff --git a/app/controllers/concerns/idv_session.rb b/app/controllers/concerns/idv_session_concern.rb similarity index 98% rename from app/controllers/concerns/idv_session.rb rename to app/controllers/concerns/idv_session_concern.rb index 94a7aef8fc3..0b024537584 100644 --- a/app/controllers/concerns/idv_session.rb +++ b/app/controllers/concerns/idv_session_concern.rb @@ -1,4 +1,4 @@ -module IdvSession +module IdvSessionConcern extend ActiveSupport::Concern included do diff --git a/app/controllers/concerns/idv_step_concern.rb b/app/controllers/concerns/idv_step_concern.rb index 7701aca863f..9a17add16e9 100644 --- a/app/controllers/concerns/idv_step_concern.rb +++ b/app/controllers/concerns/idv_step_concern.rb @@ -1,7 +1,7 @@ module IdvStepConcern extend ActiveSupport::Concern - include IdvSession + include IdvSessionConcern include RateLimitConcern include FraudReviewConcern include Idv::AbTestAnalyticsConcern diff --git a/app/controllers/idv/by_mail/enter_code_controller.rb b/app/controllers/idv/by_mail/enter_code_controller.rb index 1b84019752b..6dbb94bd0d5 100644 --- a/app/controllers/idv/by_mail/enter_code_controller.rb +++ b/app/controllers/idv/by_mail/enter_code_controller.rb @@ -2,7 +2,7 @@ module Idv module ByMail class EnterCodeController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include Idv::StepIndicatorConcern include FraudReviewConcern diff --git a/app/controllers/idv/by_mail/enter_code_rate_limited_controller.rb b/app/controllers/idv/by_mail/enter_code_rate_limited_controller.rb index fdf614e5a68..70b2ee69844 100644 --- a/app/controllers/idv/by_mail/enter_code_rate_limited_controller.rb +++ b/app/controllers/idv/by_mail/enter_code_rate_limited_controller.rb @@ -2,7 +2,7 @@ module Idv module ByMail class EnterCodeRateLimitedController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include FraudReviewConcern before_action :confirm_two_factor_authenticated diff --git a/app/controllers/idv/by_mail/letter_enqueued_controller.rb b/app/controllers/idv/by_mail/letter_enqueued_controller.rb index aef641aaa05..ee4df2ed592 100644 --- a/app/controllers/idv/by_mail/letter_enqueued_controller.rb +++ b/app/controllers/idv/by_mail/letter_enqueued_controller.rb @@ -2,7 +2,7 @@ module Idv module ByMail class LetterEnqueuedController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include Idv::StepIndicatorConcern before_action :confirm_two_factor_authenticated diff --git a/app/controllers/idv/cancellations_controller.rb b/app/controllers/idv/cancellations_controller.rb index 8da8d988e77..9dcaa382bf7 100644 --- a/app/controllers/idv/cancellations_controller.rb +++ b/app/controllers/idv/cancellations_controller.rb @@ -1,7 +1,7 @@ module Idv class CancellationsController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include GoBackHelper before_action :confirm_idv_needed diff --git a/app/controllers/idv/confirm_start_over_controller.rb b/app/controllers/idv/confirm_start_over_controller.rb index e28e4fb795d..923a34de6f6 100644 --- a/app/controllers/idv/confirm_start_over_controller.rb +++ b/app/controllers/idv/confirm_start_over_controller.rb @@ -1,7 +1,7 @@ module Idv class ConfirmStartOverController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include StepIndicatorConcern include GoBackHelper diff --git a/app/controllers/idv/forgot_password_controller.rb b/app/controllers/idv/forgot_password_controller.rb index 9056f0eeb45..fa939fdec10 100644 --- a/app/controllers/idv/forgot_password_controller.rb +++ b/app/controllers/idv/forgot_password_controller.rb @@ -1,7 +1,7 @@ module Idv class ForgotPasswordController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern before_action :confirm_two_factor_authenticated before_action :confirm_idv_needed diff --git a/app/controllers/idv/in_person/ready_to_verify_controller.rb b/app/controllers/idv/in_person/ready_to_verify_controller.rb index a5b44b5478d..e2b83b121f1 100644 --- a/app/controllers/idv/in_person/ready_to_verify_controller.rb +++ b/app/controllers/idv/in_person/ready_to_verify_controller.rb @@ -2,7 +2,7 @@ module Idv module InPerson class ReadyToVerifyController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include RenderConditionConcern include StepIndicatorConcern include OptInHelper diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb index 7e8d05fc4f1..3a5af3aa4e8 100644 --- a/app/controllers/idv/in_person/verify_info_controller.rb +++ b/app/controllers/idv/in_person/verify_info_controller.rb @@ -75,7 +75,7 @@ def pii user_session.dig('idv/in_person', :pii_from_user) end - # override IdvSession concern + # override IdvSessionConcern def flow_session user_session.fetch('idv/in_person', {}) end diff --git a/app/controllers/idv/in_person_controller.rb b/app/controllers/idv/in_person_controller.rb index 68ed9499026..12644b08a09 100644 --- a/app/controllers/idv/in_person_controller.rb +++ b/app/controllers/idv/in_person_controller.rb @@ -8,7 +8,7 @@ class InPersonController < ApplicationController before_action :confirm_two_factor_authenticated before_action :redirect_unless_enrollment - include IdvSession + include IdvSessionConcern include Flow::FlowStateMachine include Idv::ThreatMetrixConcern diff --git a/app/controllers/idv/mail_only_warning_controller.rb b/app/controllers/idv/mail_only_warning_controller.rb index aad49565bdb..6da575a5061 100644 --- a/app/controllers/idv/mail_only_warning_controller.rb +++ b/app/controllers/idv/mail_only_warning_controller.rb @@ -1,7 +1,7 @@ module Idv class MailOnlyWarningController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include StepIndicatorConcern before_action :confirm_two_factor_authenticated diff --git a/app/controllers/idv/resend_otp_controller.rb b/app/controllers/idv/resend_otp_controller.rb index 0b07250a210..43c28cde358 100644 --- a/app/controllers/idv/resend_otp_controller.rb +++ b/app/controllers/idv/resend_otp_controller.rb @@ -1,7 +1,7 @@ module Idv class ResendOtpController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include PhoneOtpRateLimitable include PhoneOtpSendable diff --git a/app/controllers/idv/session_errors_controller.rb b/app/controllers/idv/session_errors_controller.rb index a3f0d613f32..7fbbc145f75 100644 --- a/app/controllers/idv/session_errors_controller.rb +++ b/app/controllers/idv/session_errors_controller.rb @@ -1,7 +1,7 @@ module Idv class SessionErrorsController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern include StepIndicatorConcern before_action :confirm_two_factor_authenticated_or_user_id_in_session diff --git a/app/controllers/idv/sessions_controller.rb b/app/controllers/idv/sessions_controller.rb index 620e1024e84..3eaefe7598c 100644 --- a/app/controllers/idv/sessions_controller.rb +++ b/app/controllers/idv/sessions_controller.rb @@ -1,7 +1,7 @@ module Idv class SessionsController < ApplicationController include Idv::AvailabilityConcern - include IdvSession + include IdvSessionConcern before_action :confirm_two_factor_authenticated diff --git a/app/controllers/idv_controller.rb b/app/controllers/idv_controller.rb index 5b3ed71852d..a86a445ebc3 100644 --- a/app/controllers/idv_controller.rb +++ b/app/controllers/idv_controller.rb @@ -1,5 +1,5 @@ class IdvController < ApplicationController - include IdvSession + include IdvSessionConcern include AccountReactivationConcern include VerifyProfileConcern include RateLimitConcern diff --git a/app/controllers/redirect/policy_controller.rb b/app/controllers/redirect/policy_controller.rb index 9e75c5dfd79..959204edd94 100644 --- a/app/controllers/redirect/policy_controller.rb +++ b/app/controllers/redirect/policy_controller.rb @@ -7,4 +7,4 @@ def show ) end end - end +end diff --git a/app/forms/idv/address_form.rb b/app/forms/idv/address_form.rb index 71aa2d16a22..87c45ba41d2 100644 --- a/app/forms/idv/address_form.rb +++ b/app/forms/idv/address_form.rb @@ -34,7 +34,7 @@ def submit(params) def consume_params(params) params.each do |key, value| raise_invalid_address_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) - send("#{key}=", value) + send(:"#{key}=", value) if send(key) != @pii[key] && (send(key).present? || @pii[key].present?) @address_edited = true end diff --git a/app/forms/idv/api_image_upload_form.rb b/app/forms/idv/api_image_upload_form.rb index e93651a7176..37399c27cbd 100644 --- a/app/forms/idv/api_image_upload_form.rb +++ b/app/forms/idv/api_image_upload_form.rb @@ -188,7 +188,7 @@ def determine_response(form_response:, client_response:, doc_pii_response:) return form_response unless form_response.success? # doc_pii validation failed - return doc_pii_response if (doc_pii_response.present? && !doc_pii_response.success?) + return doc_pii_response if doc_pii_response.present? && !doc_pii_response.success? client_response end diff --git a/app/forms/idv/in_person/address_form.rb b/app/forms/idv/in_person/address_form.rb index 6bfd7493462..d0dadd4780e 100644 --- a/app/forms/idv/in_person/address_form.rb +++ b/app/forms/idv/in_person/address_form.rb @@ -32,7 +32,7 @@ def submit(params) def consume_params(params) params.each do |key, value| raise_invalid_address_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) - send("#{key}=", value) + send(:"#{key}=", value) end end diff --git a/app/forms/idv/ssn_format_form.rb b/app/forms/idv/ssn_format_form.rb index 175ae695671..12e725f8f11 100644 --- a/app/forms/idv/ssn_format_form.rb +++ b/app/forms/idv/ssn_format_form.rb @@ -36,7 +36,7 @@ def updating_ssn? def consume_params(params) params.each do |key, value| raise_invalid_ssn_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) - send("#{key}=", value) + send(:"#{key}=", value) end end diff --git a/app/forms/idv/state_id_form.rb b/app/forms/idv/state_id_form.rb index 2225225344a..dc901868abb 100644 --- a/app/forms/idv/state_id_form.rb +++ b/app/forms/idv/state_id_form.rb @@ -38,7 +38,7 @@ def submit(params) def consume_params(params) params.each do |key, value| raise_invalid_state_id_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) - send("#{key}=", value) + send(:"#{key}=", value) end end diff --git a/app/javascript/packages/build-sass/index.js b/app/javascript/packages/build-sass/index.js index 8722afaadee..3f2c88c59d9 100644 --- a/app/javascript/packages/build-sass/index.js +++ b/app/javascript/packages/build-sass/index.js @@ -26,7 +26,7 @@ const TARGETS = browserslistToTargets( * Compiles a given Sass file. * * @param {string} file File to build. - * @param {BuildOptions & SyncSassOptions} options Build options. + * @param {Partial & SyncSassOptions} options Build options. * * @return {Promise} */ diff --git a/app/javascript/packages/clipboard-button/package.json b/app/javascript/packages/clipboard-button/package.json index 52fa0f36bf9..8b468540391 100644 --- a/app/javascript/packages/clipboard-button/package.json +++ b/app/javascript/packages/clipboard-button/package.json @@ -3,6 +3,6 @@ "version": "1.0.0", "private": true, "dependencies": { - "@18f/identity-design-system": "^8.0.1" + "@18f/identity-design-system": "^8.1.2" } } diff --git a/app/javascript/packages/rails-i18n-webpack-plugin/rails-i18n-webpack-plugin.js b/app/javascript/packages/rails-i18n-webpack-plugin/rails-i18n-webpack-plugin.js index 4ff8fef0b10..db6ab0e9ad8 100644 --- a/app/javascript/packages/rails-i18n-webpack-plugin/rails-i18n-webpack-plugin.js +++ b/app/javascript/packages/rails-i18n-webpack-plugin/rails-i18n-webpack-plugin.js @@ -27,7 +27,7 @@ const ExtractKeysWebpackPlugin = require('./extract-keys-webpack-plugin.js'); * // 'foo' * ``` * - * @param {Record} object + * @param {undefined|Record} object * @param {string[]} keyPath * * @return {any} @@ -136,7 +136,7 @@ class RailsI18nWebpackPlugin extends ExtractKeysWebpackPlugin { * @param {string} domain * @param {string} locale * - * @return {Promise>} + * @return {Promise>} */ getLocaleData(domain, locale) { if (!(domain in this.localeData)) { diff --git a/app/javascript/packs/click-immediate.ts b/app/javascript/packs/click-immediate.ts new file mode 100644 index 00000000000..adc6889ab67 --- /dev/null +++ b/app/javascript/packs/click-immediate.ts @@ -0,0 +1,3 @@ +document + .querySelectorAll('[data-click-immediate]') + .forEach((element) => element.click()); diff --git a/app/javascript/packs/openid-connect-redirect.ts b/app/javascript/packs/openid-connect-redirect.ts deleted file mode 100644 index 42be24f47da..00000000000 --- a/app/javascript/packs/openid-connect-redirect.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { forceRedirect } from '@18f/identity-url'; - -document.body.classList.add('usa-sr-only'); -const link = document.querySelector('#openid-connect-redirect')!; -forceRedirect(link.href); diff --git a/app/javascript/packs/saml-post.js b/app/javascript/packs/saml-post.js deleted file mode 100644 index 6c807265d08..00000000000 --- a/app/javascript/packs/saml-post.js +++ /dev/null @@ -1,4 +0,0 @@ -document.addEventListener('DOMContentLoaded', function () { - document.body.className += ' usa-sr-only'; - document.getElementById('saml-post-binding').submit(); -}); diff --git a/app/jobs/get_usps_proofing_results_job.rb b/app/jobs/get_usps_proofing_results_job.rb index 0368a69232a..fe136a9409b 100644 --- a/app/jobs/get_usps_proofing_results_job.rb +++ b/app/jobs/get_usps_proofing_results_job.rb @@ -99,7 +99,6 @@ def check_enrollment(enrollment) status_check_attempted_at = Time.zone.now enrollment_outcomes[:enrollments_checked] += 1 - response = nil response = proofer.request_proofing_results( enrollment.unique_id, enrollment.enrollment_code @@ -305,6 +304,15 @@ def handle_expired_status_update(enrollment, response, response_message) end end + def handle_fraud_review_pending(enrollment) + enrollment.profile.deactivate_for_fraud_review + + analytics(user: enrollment.user). + idv_in_person_usps_proofing_results_job_user_sent_to_fraud_review( + **enrollment_analytics_attributes(enrollment, complete: true), + ) + end + def handle_unexpected_response(enrollment, response_message, reason:, cancel: true) enrollment.cancelled! if cancel @@ -363,21 +371,24 @@ def handle_successful_status_update(enrollment, response) reason: 'Successful status update', job_name: self.class.name, ) - enrollment.profile.activate_after_passing_in_person enrollment.update( status: :passed, proofed_at: proofed_at, status_check_completed_at: Time.zone.now, ) - # send SMS and email - send_enrollment_status_sms_notification(enrollment: enrollment) - send_verified_email(enrollment.user, enrollment) - analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_email_initiated( - **email_analytics_attributes(enrollment), - email_type: 'Success', - job_name: self.class.name, - ) + unless fraud_result_pending?(enrollment) + enrollment.profile&.activate_after_passing_in_person + + # send SMS and email + send_enrollment_status_sms_notification(enrollment: enrollment) + send_verified_email(enrollment.user, enrollment) + analytics(user: enrollment.user).idv_in_person_usps_proofing_results_job_email_initiated( + **email_analytics_attributes(enrollment), + email_type: 'Success', + job_name: self.class.name, + ) + end end def handle_unsupported_secondary_id(enrollment, response) @@ -405,12 +416,23 @@ def handle_unsupported_secondary_id(enrollment, response) ) end + def fraud_result_pending?(enrollment) + IdentityConfig.store.in_person_proofing_enforce_tmx && + enrollment.profile&.fraud_pending_reason.present? + end + def process_enrollment_response(enrollment, response) unless response.is_a?(Hash) handle_response_is_not_a_hash(enrollment) return end + # We want to deactivate them regardless of status, but then allow the + # case statement below to pick up the correct flow. + if fraud_result_pending?(enrollment) + handle_fraud_review_pending(enrollment) + end + case response['status'] when IPP_STATUS_PASSED if passed_with_unsupported_secondary_id_type?(response) diff --git a/app/models/concerns/encryptable_attribute.rb b/app/models/concerns/encryptable_attribute.rb index ee0588e9004..0ff599f51db 100644 --- a/app/models/concerns/encryptable_attribute.rb +++ b/app/models/concerns/encryptable_attribute.rb @@ -86,6 +86,6 @@ def build_encrypted_attribute_from_plain(name, plain_value) end def encrypted_attribute_name(name) - "encrypted_#{name}".to_sym + :"encrypted_#{name}" end end diff --git a/app/models/gpo_confirmation.rb b/app/models/gpo_confirmation.rb index 8fa29039aaf..8edfdd3eb7e 100644 --- a/app/models/gpo_confirmation.rb +++ b/app/models/gpo_confirmation.rb @@ -3,7 +3,7 @@ class GpoConfirmation < ApplicationRecord ENTRY_ATTRIBUTES = %i[otp address1 city state zipcode] ENTRY_ATTRIBUTES.each do |attr| - define_method("entry_#{attr}".to_sym) do + define_method(:"entry_#{attr}") do entry[attr] end end diff --git a/app/models/profile.rb b/app/models/profile.rb index 2215f638668..31bc0dfff34 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -96,7 +96,7 @@ def activate(reason_deactivated: nil) activated_at: now, } - attrs[:verified_at] = now unless (reason_deactivated == :password_reset || verified_at) + attrs[:verified_at] = now unless reason_deactivated == :password_reset || verified_at transaction do Profile.where(user_id: user_id).update_all(active: false) diff --git a/app/models/service_provider_request.rb b/app/models/service_provider_request.rb index 06f39863ddf..d3e132c9068 100644 --- a/app/models/service_provider_request.rb +++ b/app/models/service_provider_request.rb @@ -12,7 +12,9 @@ def initialize( ial: nil, aal: nil, requested_attributes: [], - biometric_comparison_required: false + biometric_comparison_required: false, + acr_values: nil, # rubocop:disable Lint/UnusedMethodArgument + vtr: nil # rubocop:disable Lint/UnusedMethodArgument ) @uuid = uuid @issuer = issuer diff --git a/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb b/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb index 546d2415e51..e61593d7567 100644 --- a/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb +++ b/app/presenters/two_factor_auth_code/generic_delivery_presenter.rb @@ -8,7 +8,7 @@ class GenericDeliveryPresenter def initialize(data:, view:, service_provider:, remember_device_default: true) data.each do |key, value| - instance_variable_set("@#{key}", value) + instance_variable_set(:"@#{key}", value) end @view = view @service_provider = service_provider diff --git a/app/presenters/two_factor_authentication/sign_in_phone_selection_presenter.rb b/app/presenters/two_factor_authentication/sign_in_phone_selection_presenter.rb index f9c27d2409b..c36193f4aa9 100644 --- a/app/presenters/two_factor_authentication/sign_in_phone_selection_presenter.rb +++ b/app/presenters/two_factor_authentication/sign_in_phone_selection_presenter.rb @@ -10,7 +10,7 @@ def initialize(user:, configuration:, delivery_method:) def type if MfaContext.new(configuration&.user).phone_configurations.many? - "#{delivery_method}_#{configuration.id}".to_sym + :"#{delivery_method}_#{configuration.id}" else delivery_method || :phone end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 186c17149e9..eff2e191771 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -1015,6 +1015,37 @@ def idv_doc_auth_submitted_image_upload_form( # @param [Float] vendor_request_time_in_ms Time it took to upload images & get a response. # @param [String] front_image_fingerprint Fingerprint of front image data # @param [String] back_image_fingerprint Fingerprint of back image data + # @param [Boolean] attention_with_barcode + # @param [Boolean] doc_type_supported + # @param [Boolean] doc_auth_success + # @param [Boolean] selfie_success + # @param [String] vendor + # @param [String] conversation_id + # @param [String] reference + # @param [String] transaction_status + # @param [String] transaction_reason_code + # @param [String] product_status + # @param [String] decision_product_status + # @param [Array] processed_alerts + # @param [Integer] alert_failure_count + # @param [Hash] log_alert_results + # @param [Hash] portrait_match_results + # @param [Hash] image_metrics + # @param [Boolean] address_line2_present + # @option extra [String] 'DocumentName' + # @option extra [String] 'DocAuthResult' + # @option extra [String] 'DocIssuerCode' + # @option extra [String] 'DocIssuerName' + # @option extra [String] 'DocIssuerType' + # @option extra [String] 'DocClassCode' + # @option extra [String] 'DocClass' + # @option extra [String] 'DocClassName' + # @option extra [Boolean] 'DocIsGeneric' + # @option extra [String] 'DocIssue' + # @option extra [String] 'DocIssueType' + # @option extra [String] 'ClassificationMode' + # @option extra [Boolean] 'OrientationChanged' + # @option extra [Boolean] 'PresentationChanged' # The document capture image was uploaded to vendor during the IDV process def idv_doc_auth_submitted_image_upload_vendor( success:, @@ -1022,7 +1053,8 @@ def idv_doc_auth_submitted_image_upload_vendor( exception:, state:, state_id_type:, - async:, attempts:, + async:, + attempts:, remaining_attempts:, client_image_metrics:, flow_path:, @@ -1031,25 +1063,59 @@ def idv_doc_auth_submitted_image_upload_vendor( vendor_request_time_in_ms: nil, front_image_fingerprint: nil, back_image_fingerprint: nil, + attention_with_barcode: nil, + doc_type_supported: nil, + doc_auth_success: nil, + selfie_success: nil, + vendor: nil, + conversation_id: nil, + reference: nil, + transaction_status: nil, + transaction_reason_code: nil, + product_status: nil, + decision_product_status: nil, + processed_alerts: nil, + alert_failure_count: nil, + log_alert_results: nil, + portrait_match_results: nil, + image_metrics: nil, + address_line2_present: nil, **extra ) track_event( 'IdV: doc auth image upload vendor submitted', - success: success, - errors: errors, - exception: exception, - billed: billed, - doc_auth_result: doc_auth_result, - state: state, - state_id_type: state_id_type, - async: async, - attempts: attempts, - remaining_attempts: remaining_attempts, - client_image_metrics: client_image_metrics, - flow_path: flow_path, - vendor_request_time_in_ms: vendor_request_time_in_ms, - front_image_fingerprint: front_image_fingerprint, - back_image_fingerprint: back_image_fingerprint, + success:, + errors:, + exception:, + billed:, + doc_auth_result:, + state:, + state_id_type:, + async:, + attempts:, + remaining_attempts:, + client_image_metrics:, + flow_path:, + vendor_request_time_in_ms:, + front_image_fingerprint:, + back_image_fingerprint:, + attention_with_barcode:, + doc_type_supported:, + doc_auth_success:, + selfie_success:, + vendor:, + conversation_id:, + reference:, + transaction_status:, + transaction_reason_code:, + product_status:, + decision_product_status:, + processed_alerts:, + alert_failure_count:, + log_alert_results:, + portrait_match_results:, + image_metrics:, + address_line2_present:, **extra, ) end @@ -1133,6 +1199,7 @@ def idv_doc_auth_welcome_visited(**extra) # @param [Boolean] in_person_verification_pending # @param [Idv::ProofingComponentsLogging] proofing_components User's current proofing components # @param [String, nil] deactivation_reason Reason user's profile was deactivated, if any. + # @identity.idp.previous_event_name IdV: review info visited def idv_enter_password_submitted( success:, fraud_review_pending:, @@ -1161,6 +1228,7 @@ def idv_enter_password_submitted( # @param [String] address_verification_method The method (phone or gpo) being # used to verify the user's identity # User visited IDV password confirm page + # @identity.idp.previous_event_name IdV: review info visited def idv_enter_password_visited( proofing_components: nil, address_verification_method: nil, @@ -2246,6 +2314,19 @@ def idv_in_person_usps_proofing_results_job_unexpected_response( ) end + # A user has been moved to fraud review after completing proofing at the USPS + # @param [String] enrollment_id + def idv_in_person_usps_proofing_results_job_user_sent_to_fraud_review( + enrollment_id:, + **extra + ) + track_event( + :idv_in_person_usps_proofing_results_job_user_sent_to_fraud_review, + enrollment_id: enrollment_id, + **extra, + ) + end + # Tracks if USPS in-person proofing enrollment request fails # @param [String] context # @param [String] reason @@ -3965,6 +4046,7 @@ def reactivate_account_visit # @param [String] validator_class Class name of validator # @param [String, nil] exception_class Class name of exception, if error occurred # @param [String, nil] phone_country_code Country code associated with reCAPTCHA phone result + # @param [String] recaptcha_version def recaptcha_verify_result_received( recaptcha_result:, score_threshold:, @@ -3972,6 +4054,7 @@ def recaptcha_verify_result_received( validator_class:, exception_class:, phone_country_code: nil, + recaptcha_version: nil, **extra ) track_event( @@ -3983,6 +4066,7 @@ def recaptcha_verify_result_received( validator_class:, exception_class:, phone_country_code:, + recaptcha_version:, **extra, }.compact, ) diff --git a/app/services/authn_context_resolver.rb b/app/services/authn_context_resolver.rb new file mode 100644 index 00000000000..bf892438b46 --- /dev/null +++ b/app/services/authn_context_resolver.rb @@ -0,0 +1,68 @@ +class AuthnContextResolver + attr_reader :service_provider, :vtr, :acr_values + + def initialize(service_provider:, vtr:, acr_values:) + @service_provider = service_provider + @vtr = vtr + @acr_values = acr_values + end + + def resolve + if vtr.present? + vot_parser_result + else + acr_result_with_sp_defaults + end + end + + private + + def vot_parser_result + @vot_result = Vot::Parser.new( + vector_of_trust: vtr&.first, + acr_values: acr_values, + ).parse + end + + def acr_result_with_sp_defaults + result_with_sp_aal_defaults( + result_with_sp_ial_defaults( + vot_parser_result, + ), + ) + end + + def result_with_sp_aal_defaults(result) + if acr_aal_component_values.any? + result + elsif service_provider&.default_aal.to_i == 2 + result.with(aal2?: true) + elsif service_provider&.default_aal.to_i >= 3 + result.with(aal2?: true, phishing_resistant?: true) + else + result + end + end + + def result_with_sp_ial_defaults(result) + if acr_ial_component_values.any? + result + elsif service_provider&.ial.to_i >= 2 + result.with(identity_proofing?: true, aal2?: true) + else + result + end + end + + def acr_aal_component_values + vot_parser_result.component_values.filter do |component_value| + component_value.name.include?('aal') + end + end + + def acr_ial_component_values + vot_parser_result.component_values.filter do |component_value| + component_value.name.include?('ial') || component_value.name.include?('loa') + end + end +end diff --git a/app/services/browser_support.rb b/app/services/browser_support.rb index ee74ad3f604..83ea8482bfe 100644 --- a/app/services/browser_support.rb +++ b/app/services/browser_support.rb @@ -1,22 +1,20 @@ class BrowserSupport @cache = LruRedux::Cache.new(1_000) - # rubocop:disable Layout/LineLength BROWSERSLIST_TO_BROWSER_MAP = { - and_chr: ->(browser, version) { browser.android? && !browser.platform.android_webview? && browser.chrome?(version) }, + and_chr: ->(browser, version) { browser.android? && browser.chrome?(version) }, and_uc: ->(browser, version) { browser.android? && browser.uc_browser?(version) }, - android: ->(browser, version) { browser.platform.android_webview? && browser.send(:detect_version?, browser.version, version) }, - chrome: ->(browser, version) { !browser.platform.android_webview? && browser.chrome?(version) }, + android: ->(browser, version) { browser.send(:detect_version?, browser.version, version) }, + chrome: ->(browser, version) { browser.chrome?(version) }, edge: ->(browser, version) { browser.edge?(version) }, firefox: ->(browser, version) { browser.firefox?(version) }, - ios_saf: ->(browser, version) { browser.ios? && browser.safari?(version) }, + ios_saf: ->(browser, version) { browser.ios?(version) }, op_mini: ->(browser, version) { browser.opera_mini?(version) }, op_mob: ->(browser, version) { browser.platform.android? && browser.opera?(version) }, opera: ->(browser, version) { browser.opera?(version) }, safari: ->(browser, version) { browser.safari?(version) }, samsung: ->(browser, version) { browser.samsung_browser?(version) }, - }.with_indifferent_access.freeze - # rubocop:enable Layout/LineLength + }.freeze class << self def supported?(user_agent) @@ -24,7 +22,8 @@ def supported?(user_agent) return true if browser_support_config.nil? cache.getset(user_agent) do - matchers.any? { |matcher| matcher.call(BrowserCache.parse(user_agent)) } + browser = BrowserCache.parse(user_agent) + matchers_for_browser(browser).any? { |_key, matcher| matcher.call(browser) } end end @@ -38,15 +37,28 @@ def clear_cache! attr_reader :cache + def matchers_for_browser(browser) + if browser.ios? + matchers.slice(:ios_saf) + elsif browser.platform.android_webview? + matchers.slice(:android) + else + matchers + end + end + def matchers - @matchers ||= browser_support_config.flat_map do |config_entry| + @matchers ||= browser_support_config.each_with_object({}) do |config_entry, result| key, version = config_entry.split(' ', 2) + key = key.to_sym browser_matcher = BROWSERSLIST_TO_BROWSER_MAP[key] - next [] if !browser_matcher + next if !browser_matcher low_version, _high_version = version.split('-', 2) low_version = nil if !numeric?(low_version) - proc { |browser| browser_matcher.call(browser, low_version && ">= #{low_version}") } + version_test = low_version && ">= #{low_version}" + matcher = proc { |browser| browser_matcher.call(browser, version_test) } + result[key] = matcher end end diff --git a/app/services/doc_auth/lexis_nexis/request.rb b/app/services/doc_auth/lexis_nexis/request.rb index ec3dad05f80..99961c3e452 100644 --- a/app/services/doc_auth/lexis_nexis/request.rb +++ b/app/services/doc_auth/lexis_nexis/request.rb @@ -54,7 +54,11 @@ def handle_connection_error(exception) success: false, errors: { network: true }, exception: exception, - extra: { vendor: 'TrueID' }, + extra: { + vendor: 'TrueID', + selfie_live: false, + selfie_quality_good: false, + }, ) end diff --git a/app/services/doc_auth/mock/result_response.rb b/app/services/doc_auth/mock/result_response.rb index ccc79ed34f9..3e4202ca213 100644 --- a/app/services/doc_auth/mock/result_response.rb +++ b/app/services/doc_auth/mock/result_response.rb @@ -163,8 +163,8 @@ def doc_auth_result_from_uploaded_file def portrait_match_results parsed_data_from_uploaded_file.dig('portrait_match_results')&. - transform_keys! { |key| key.to_s.camelize }&. - deep_symbolize_keys + transform_keys! { |key| key.to_s.camelize }&. + deep_symbolize_keys end def classification_info diff --git a/app/services/document_capture_session_result.rb b/app/services/document_capture_session_result.rb index 61257d88631..3a8c527afee 100644 --- a/app/services/document_capture_session_result.rb +++ b/app/services/document_capture_session_result.rb @@ -29,13 +29,13 @@ def selfie_status alias_method :pii_from_doc, :pii %w[front back].each do |side| - define_method("add_failed_#{side}_image!") do |fingerprint| + define_method(:"add_failed_#{side}_image!") do |fingerprint| member_name = "failed_#{side}_image_fingerprints" self[member_name] ||= [] self[member_name] << fingerprint end - define_method("failed_#{side}_image?") do |fingerprint| + define_method(:"failed_#{side}_image?") do |fingerprint| member_name = "failed_#{side}_image_fingerprints" return false unless self[member_name]&.is_a?(Array) return self[member_name]&.include?(fingerprint) diff --git a/app/services/funnel/doc_auth/register_submit_step.rb b/app/services/funnel/doc_auth/register_submit_step.rb index f62c85b283a..59f7e2221df 100644 --- a/app/services/funnel/doc_auth/register_submit_step.rb +++ b/app/services/funnel/doc_auth/register_submit_step.rb @@ -8,17 +8,17 @@ def self.call(doc_auth_log, issuer, token, success) end def self.update_submit_count(doc_auth_log, issuer, token) - method = "#{token}_submit_count".to_sym + method = :"#{token}_submit_count" return unless doc_auth_log.respond_to?(method) doc_auth_log[method] += 1 - method = "#{token}_submit_at".to_sym + method = :"#{token}_submit_at" doc_auth_log[method] = Time.zone.now if doc_auth_log.respond_to?(method) doc_auth_log.issuer = issuer end private_class_method :update_submit_count def self.update_error_count(doc_auth_log, token, success) - error_count = "#{token}_error_count".to_sym + error_count = :"#{token}_error_count" return unless doc_auth_log.respond_to?(error_count) && !success doc_auth_log[error_count] += 1 end diff --git a/app/services/idv/phone_step.rb b/app/services/idv/phone_step.rb index 74f208b7f32..5635e5f37cc 100644 --- a/app/services/idv/phone_step.rb +++ b/app/services/idv/phone_step.rb @@ -108,7 +108,7 @@ def phone_param def otp_delivery_preference preference = idv_session.previous_phone_step_params[:otp_delivery_preference] - return :sms if (preference.nil? || preference.empty?) + return :sms if preference.nil? || preference.empty? preference.to_sym end diff --git a/app/services/idv/profile_maker.rb b/app/services/idv/profile_maker.rb index 3d77d93f857..597e3d19714 100644 --- a/app/services/idv/profile_maker.rb +++ b/app/services/idv/profile_maker.rb @@ -35,7 +35,8 @@ def save_profile( profile.save! profile.deactivate_for_gpo_verification if gpo_verification_needed - if fraud_pending_reason.present? && !gpo_verification_needed + + if fraud_pending_reason.present? && !gpo_verification_needed && !in_person_verification_needed profile.deactivate_for_fraud_review end profile diff --git a/app/services/user_profiles_encryptor.rb b/app/services/user_profiles_encryptor.rb index 5f86d3bf58a..751f6b1a1c7 100644 --- a/app/services/user_profiles_encryptor.rb +++ b/app/services/user_profiles_encryptor.rb @@ -1,4 +1,7 @@ class UserProfilesEncryptor + class MissingPiiError < StandardError + end + attr_reader :personal_key def initialize(user:, user_session:, password:) @@ -11,8 +14,13 @@ def encrypt if user.active_profile.present? encrypt_pii_for_profile(user.active_profile) end + if user.pending_profile.present? - encrypt_pii_for_profile(user.pending_profile) + begin + encrypt_pii_for_profile(user.pending_profile) + rescue MissingPiiError + user.pending_profile.deactivate(:encryption_error) + end end end @@ -21,7 +29,10 @@ def encrypt attr_reader :user, :password, :user_session def encrypt_pii_for_profile(profile) - pii = Pii::Cacher.new(user, user_session).fetch(profile.id) + pii_cache = Pii::Cacher.new(user, user_session) + pii = pii_cache.fetch(profile.id) + raise MissingPiiError unless pii + @personal_key = profile.encrypt_pii(pii, password) profile.save! end diff --git a/app/services/vot/component_value.rb b/app/services/vot/component_value.rb new file mode 100644 index 00000000000..e724d49c06f --- /dev/null +++ b/app/services/vot/component_value.rb @@ -0,0 +1,3 @@ +module Vot + ComponentValue = Data.define(:name, :description, :implied_component_values, :requirements) +end diff --git a/app/services/vot/legacy_component_values.rb b/app/services/vot/legacy_component_values.rb new file mode 100644 index 00000000000..034edb6d40b --- /dev/null +++ b/app/services/vot/legacy_component_values.rb @@ -0,0 +1,86 @@ +module Vot + module LegacyComponentValues + ## Identity proofing ACR values + LOA1 = ComponentValue.new( + name: Saml::Idp::Constants::LOA1_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy LOA1', + implied_component_values: [], + requirements: [], + ) + LOA3 = ComponentValue.new( + name: Saml::Idp::Constants::LOA3_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy LOA3', + implied_component_values: [], + requirements: [:aal2, :identity_proofing], + ) + IAL1 = ComponentValue.new( + name: Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy IAL1', + implied_component_values: [], + requirements: [], + ) + IAL2 = ComponentValue.new( + name: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy IAL2', + implied_component_values: [], + requirements: [:aal2, :identity_proofing], + ) + IALMAX = ComponentValue.new( + name: Saml::Idp::Constants::IALMAX_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy IALMAX', + implied_component_values: [], + requirements: [:aal2, :ialmax], + ) + + ## Authentication ACR values + DEFAULT = ComponentValue.new( + name: Saml::Idp::Constants::DEFAULT_AAL_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy default authentication', + implied_component_values: [], + requirements: [], + ) + AAL1 = ComponentValue.new( + name: Saml::Idp::Constants::AAL1_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy AAL1', + implied_component_values: [], + requirements: [], + ) + AAL2 = ComponentValue.new( + name: Saml::Idp::Constants::AAL2_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy AAL2', + implied_component_values: [], + requirements: [:aal2], + ) + AAL2_PHISHING_RESISTANT = ComponentValue.new( + name: Saml::Idp::Constants::AAL2_PHISHING_RESISTANT_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy AAL2 with phishing resitance', + implied_component_values: [], + requirements: [:aal2, :phishing_resistant], + ) + AAL2_HSPD12 = ComponentValue.new( + name: Saml::Idp::Constants::AAL2_HSPD12_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy AAL2 with HSPD12', + implied_component_values: [], + requirements: [:aal2, :hspd12], + ) + AAL3 = ComponentValue.new( + name: Saml::Idp::Constants::AAL3_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy AAL3', + implied_component_values: [], + requirements: [:aal2, :hspd12], + ) + AAL3_HSPD12 = ComponentValue.new( + name: Saml::Idp::Constants::AAL3_HSPD12_AUTHN_CONTEXT_CLASSREF, + description: 'Legacy AAL3 with HSPD12', + implied_component_values: [], + requirements: [:aal2, :hspd12], + ) + + def self.by_name + @by_name ||= constants.map do |constant| + component_value = const_get(constant) + [component_value.name, component_value] + end.to_h + end + end +end diff --git a/app/services/vot/parser.rb b/app/services/vot/parser.rb new file mode 100644 index 00000000000..3fa71a67a1a --- /dev/null +++ b/app/services/vot/parser.rb @@ -0,0 +1,101 @@ +module Vot + class Parser + class ParseException < StandardError; end + Result = Data.define( + :component_values, + :aal2?, + :phishing_resistant?, + :hspd12?, + :identity_proofing?, + :biometric_comparison?, + :ialmax?, + ) + + attr_reader :vector_of_trust, :acr_values + + def initialize(vector_of_trust: nil, acr_values: nil) + @vector_of_trust = vector_of_trust + @acr_values = acr_values + end + + def parse + initial_components = + if vector_of_trust.present? + map_initial_vector_of_trust_components_to_component_values + elsif acr_values.present? + map_initial_acr_values_to_component_values + end + expand_components_with_initial_components(initial_components) + end + + private + + def map_initial_vector_of_trust_components_to_component_values + vector_of_trust.split('.').map do |component_value_name| + SupportedComponentValues.by_name.fetch(component_value_name) + rescue KeyError + raise_unsupported_component_exception(component_value_name) + end + end + + def map_initial_acr_values_to_component_values + acr_values.split(' ').map do |component_value_name| + LegacyComponentValues.by_name.fetch(component_value_name) + rescue KeyError + raise_unsupported_component_exception(component_value_name) + end + end + + def expand_components_with_initial_components(initial_components) + validate_component_uniqueness!(initial_components) + resulting_components = add_implied_components(initial_components).sort_by(&:name) + requirement_list = resulting_components.flat_map(&:requirements) + Result.new( + component_values: resulting_components, + aal2?: requirement_list.include?(:aal2), + phishing_resistant?: requirement_list.include?(:phishing_resistant), + hspd12?: requirement_list.include?(:hspd12), + identity_proofing?: requirement_list.include?(:identity_proofing), + biometric_comparison?: requirement_list.include?(:biometric_comparison), + ialmax?: requirement_list.include?(:ialmax), + ) + end + + def validate_component_uniqueness!(component_values) + if component_values.length != component_values.uniq.length + raise_duplicate_component_exception + end + end + + def add_implied_components(component_values) + component_values.flat_map do |component_value| + component_with_implied_components(component_value) + end.uniq + end + + def component_with_implied_components(component_value) + [ + component_value, + *component_value.implied_component_values.map do |implied_component_value| + component_with_implied_components(implied_component_value) + end, + ].flatten + end + + def raise_unsupported_component_exception(component_value_name) + if vector_of_trust.present? + raise ParseException, "#{vector_of_trust} contains unkown component #{component_value_name}" + else + raise ParseException, "#{acr_values} contains unkown acr value #{component_value_name}" + end + end + + def raise_duplicate_component_exception + if vector_of_trust.present? + raise ParseException, "#{vector_of_trust} contains duplicate components" + else + raise ParseException, "#{acr_values} ontains duplicate acr values" + end + end + end +end diff --git a/app/services/vot/supported_component_values.rb b/app/services/vot/supported_component_values.rb new file mode 100644 index 00000000000..ee8ba8e862e --- /dev/null +++ b/app/services/vot/supported_component_values.rb @@ -0,0 +1,47 @@ +module Vot + module SupportedComponentValues + C1 = ComponentValue.new( + name: 'C1', + description: 'Multi-factor authentication', + implied_component_values: [], + requirements: [], + ) + C2 = ComponentValue.new( + name: 'C2', + description: 'AAL2 conformant features are engaged', + implied_component_values: [C1], + requirements: [:aal2], + ) + Ca = ComponentValue.new( + name: 'Ca', + description: 'A phishing resistant authenticator is required', + implied_component_values: [C1], + requirements: [:phishing_resistant], + ) + Cb = ComponentValue.new( + name: 'Cb', + description: 'A PIV/CAC card is required', + implied_component_values: [C1], + requirements: [:hspd12], + ) + P1 = ComponentValue.new( + name: 'P1', + description: 'Identity proofing is performed', + implied_component_values: [C2], + requirements: [:identity_proofing], + ) + Pb = ComponentValue.new( + name: 'Pb', + description: 'A biometric comparison is required as part of identity proofing', + implied_component_values: [P1], + requirements: [:biometric_comparison], + ) + + def self.by_name + @by_name ||= constants.map do |constant| + component_value = const_get(constant) + [component_value.name, component_value] + end.to_h + end + end +end diff --git a/app/services/x509/attributes.rb b/app/services/x509/attributes.rb index d1a2aa8aed2..69753e5a867 100644 --- a/app/services/x509/attributes.rb +++ b/app/services/x509/attributes.rb @@ -29,10 +29,12 @@ def []=(key, value) private + # rubocop:disable Lint/SelfAssignment def assign_all_members self.class.members.each do |member| self[member] = self[member] end end + # rubocop:enable Lint/SelfAssignment end end diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index c6b5251951c..571d6cc8ef5 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -18,7 +18,7 @@ <%= title %> | <%= APP_NAME %> <%= javascript_tag(nonce: true) do %> - document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/, 'js'); + document.documentElement.classList.replace('no-js', 'js'); <% end %> <%= preload_link_tag font_url('public-sans/PublicSans-Bold.woff2') %> <%= preload_link_tag font_url('public-sans/PublicSans-Regular.woff2') %> diff --git a/app/views/openid_connect/shared/redirect_js.html.erb b/app/views/openid_connect/shared/redirect_js.html.erb index 1ef3ce51ab3..79613be8c0b 100644 --- a/app/views/openid_connect/shared/redirect_js.html.erb +++ b/app/views/openid_connect/shared/redirect_js.html.erb @@ -1,13 +1,16 @@ - + <%= t('headings.redirecting') %> | <%= APP_NAME %> + <%= javascript_tag(nonce: true) do %> + document.documentElement.classList.replace('no-js', 'js'); + <% end %> <%= stylesheet_link_tag 'application', media: 'all' %> <%= render_stylesheet_once_tags %> -
+
<%= render PageHeadingComponent.new.with_content(t('saml_idp.shared.saml_post_binding.heading')) %> @@ -16,10 +19,10 @@ <%= t('saml_idp.shared.saml_post_binding.no_js') %>

- <%= link_to(t('forms.buttons.continue'), @oidc_redirect_uri, class: 'usa-button usa-button--wide usa-button--big', id: 'openid-connect-redirect') %> + <%= link_to(t('forms.buttons.continue'), @oidc_redirect_uri, class: 'usa-button usa-button--wide usa-button--big', data: { click_immediate: '' }) %>
- <%= render_javascript_pack_once_tags 'openid-connect-redirect' %> + <%= render_javascript_pack_once_tags 'click-immediate' %> diff --git a/app/views/saml_idp/shared/saml_post_binding.html.erb b/app/views/saml_idp/shared/saml_post_binding.html.erb index eb827e26bf8..ae607743875 100644 --- a/app/views/saml_idp/shared/saml_post_binding.html.erb +++ b/app/views/saml_idp/shared/saml_post_binding.html.erb @@ -1,15 +1,17 @@ - + <%= t('headings.redirecting') %> | <%= APP_NAME %> + <%= javascript_tag(nonce: true) do %> + document.documentElement.classList.replace('no-js', 'js'); + <% end %> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all' %> <%= render_stylesheet_once_tags %> - <%= render_javascript_pack_once_tags 'saml-post' %> -
+
<%= render PageHeadingComponent.new.with_content(t('.heading')) %> @@ -18,16 +20,16 @@ <%= t('.no_js') %>

- <%= form_tag action_url, id: 'saml-post-binding' do %> - <%= hidden_field_tag('csp_uris', csp_uris) if Rails.env.test? %> + <%= simple_form_for('', url: action_url) do |f| %> <%= hidden_field_tag(type, message) %> <% if params.key?(:RelayState) %> <%= hidden_field_tag('RelayState', params[:RelayState]) %> <% end %> - <%= submit_tag t('forms.buttons.submit.default'), class: 'usa-button usa-button--wide usa-button--big' %> + <%= f.submit t('forms.buttons.submit.default'), data: { click_immediate: '' } %> <% end %>
+ <%= render_javascript_pack_once_tags 'click-immediate' %> diff --git a/app/views/shared/saml_post_form.html.erb b/app/views/shared/saml_post_form.html.erb index d07998cc503..b305dff895d 100644 --- a/app/views/shared/saml_post_form.html.erb +++ b/app/views/shared/saml_post_form.html.erb @@ -1,14 +1,16 @@ - + + <%= javascript_tag(nonce: true) do %> + document.documentElement.classList.replace('no-js', 'js'); + <% end %> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all' %> <%= render_stylesheet_once_tags %> - <%= render_javascript_pack_once_tags 'saml-post' %> -
+
<%= render PageHeadingComponent.new.with_content(t('saml_idp.shared.saml_post_binding.heading')) %> @@ -17,14 +19,15 @@ <%= t('saml_idp.shared.saml_post_binding.no_js') %>

- <%= form_tag action_url, id: 'saml-post-binding' do %> + <%= simple_form_for('', url: action_url) do |f| %> <% form_params.each do |key, val| %> <%= hidden_field_tag(key, val) %> <% end %> - <%= submit_tag t('forms.buttons.submit.default'), class: 'usa-button usa-button--wide usa-button--big' %> + <%= f.submit t('forms.buttons.submit.default'), data: { click_immediate: '' } %> <% end %>
+ <%= render_javascript_pack_once_tags 'click-immediate' %> diff --git a/config/application.yml.default b/config/application.yml.default index 57e056755b6..e848e7bc7fe 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -133,6 +133,7 @@ in_person_email_reminder_early_benchmark_in_days: 11 in_person_email_reminder_final_benchmark_in_days: 1 in_person_email_reminder_late_benchmark_in_days: 4 in_person_proofing_enabled: false +in_person_proofing_enforce_tmx: false in_person_proofing_opt_in_enabled: false in_person_enrollment_validity_in_days: 30 in_person_enrollments_ready_job_email_body_pattern: '\A\s*(?\d{16})\s*\Z' @@ -392,6 +393,7 @@ development: hmac_fingerprinter_key_queue: '["11111111111111111111111111111111", "22222222222222222222222222222222"]' identity_pki_local_dev: true in_person_proofing_enabled: true + in_person_proofing_enforce_tmx: true in_person_send_proofing_notifications_enabled: true logins_per_ip_limit: 5 logo_upload_enabled: true diff --git a/lib/analytics_events_documenter.rb b/lib/analytics_events_documenter.rb index 9e749314fd2..5bdae731f39 100644 --- a/lib/analytics_events_documenter.rb +++ b/lib/analytics_events_documenter.rb @@ -132,12 +132,20 @@ def missing_documentation def as_json events_json_summary = analytics_methods.map do |method_object| attributes = method_object.tags('param').map do |tag| + next if tag.name == 'extra' + { name: tag.name, types: tag.types, description: tag.text.presence, } - end.compact + end.compact + method_object.tags('option').map do |tag| + { + name: tag.pair.name.tr(%('"), ''), + types: tag.pair.types, + description: tag.pair.text.presence, + } + end { event_name: extract_event_name(method_object), diff --git a/lib/identity_config.rb b/lib/identity_config.rb index d0fd50ae922..8d07bde22cf 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -257,6 +257,7 @@ def self.build_store(config_map) config.add(:in_person_outage_expected_update_date, type: :string) config.add(:in_person_outage_message_enabled, type: :boolean) config.add(:in_person_proofing_enabled, type: :boolean) + config.add(:in_person_proofing_enforce_tmx, type: :boolean) config.add(:in_person_proofing_opt_in_enabled, type: :boolean) config.add(:in_person_public_address_search_enabled, type: :boolean) config.add(:in_person_results_delay_in_hours, type: :integer) diff --git a/lib/reporting/drop_off_report.rb b/lib/reporting/drop_off_report.rb new file mode 100644 index 00000000000..05b5b34768b --- /dev/null +++ b/lib/reporting/drop_off_report.rb @@ -0,0 +1,467 @@ +# frozen_string_literal: true + +require 'csv' +begin + require 'reporting/cloudwatch_client' + require 'reporting/cloudwatch_query_quoting' + require 'reporting/command_line_options' + require 'reporting/identity_verification_report' +rescue LoadError => e + warn 'could not load paths, try running with "bundle exec rails runner"' + raise e +end + +module Reporting + class DropOffReport + include Reporting::CloudwatchQueryQuoting + + attr_reader :issuers, :time_range + + def initialize( + issuers:, + time_range:, + verbose: false, + progress: false, + slice: 3.hours, + threads: 5 + ) + @issuers = issuers + @time_range = time_range + @verbose = verbose + @progress = progress + @slice = slice + @threads = threads + end + + module Events + IDV_DOC_AUTH_WELCOME = 'IdV: doc auth welcome visited' + IDV_DOC_AUTH_WELCOME_SUBMITTED = 'IdV: doc auth welcome submitted' + IDV_DOC_AUTH_IMAGE_UPLOAD = 'IdV: doc auth image upload vendor submitted' + IDV_DOC_AUTH_CAPTURED = 'IdV: doc auth document_capture visited' + IDV_DOC_AUTH_SSN_VISITED = 'IdV: doc auth ssn visited' + IDV_DOC_AUTH_VERIFY_VISITED = 'IdV: doc auth verify visited' + IDV_DOC_AUTH_VERIFY_SUBMITTED = 'IdV: doc auth verify submitted' + IDV_DOC_AUTH_PHONE_VISITED = 'IdV: phone of record visited' + IDV_ENTER_PASSWORD_VISITED = 'idv_enter_password_visited' + OLD_IDV_ENTER_PASSWORD_VISITED = 'IdV: review info visited' + IDV_ENTER_PASSWORD_SUBMITTED = 'idv_enter_password_submitted' + OLD_IDV_ENTER_PASSWORD_SUBMITTED = 'IdV: review complete' + IDV_PERSONAL_KEY_SUBMITTED = 'IdV: personal key submitted' + + def self.all_events + constants.map { |c| const_get(c) } + end + end + + def as_emailable_reports + [ + Reporting::EmailableReport.new( + title: 'Proofing Funnel Definitions', + table: proofing_definition_table, + ), + Reporting::EmailableReport.new( + title: 'Step Definitions', + table: step_definition_table, + ), + Reporting::EmailableReport.new( + title: 'Overview', + table: overview_table, + ), + Reporting::EmailableReport.new( + title: 'DropOff Metrics', + table: dropoff_metrics_table, + float_as_percent: true, + ), + ] + end + + def overview_table + [ + ['Report Timeframe', "#{time_range.begin} to #{time_range.end}"], + # This needs to be Date.today so it works when run on the command line + ['Report Generated', Date.today.to_s], # rubocop:disable Rails/Date + ['Issuer', issuers.join(', ')], + ] + end + + def dropoff_metrics_table + [ + ['Step', 'Unique user count', 'Users lost', 'Dropoff from last step', + 'Users left from start'], + [ + 'Welcome (page viewed)', + idv_started, + ], + [ + 'User agreement (page viewed)', + idv_doc_auth_welcome_submitted, + dropoff = idv_started - idv_doc_auth_welcome_submitted, + percent( + numerator: dropoff, + denominator: idv_started, + ), + percent(numerator: idv_doc_auth_welcome_submitted, denominator: idv_started), + ], + [ + 'Capture Document (page viewed)', + idv_doc_auth_document_captured, + dropoff = idv_doc_auth_welcome_submitted - + idv_doc_auth_document_captured, + percent( + numerator: dropoff, + denominator: idv_doc_auth_welcome_submitted, + ), + percent( + numerator: idv_doc_auth_document_captured, + denominator: idv_started, + ), + ], + [ + 'Document submitted (event)', + idv_doc_auth_image_vendor_submitted, + dropoff = idv_doc_auth_document_captured - + idv_doc_auth_image_vendor_submitted, + percent( + numerator: dropoff, + denominator: idv_doc_auth_document_captured, + ), + percent( + numerator: idv_doc_auth_image_vendor_submitted, + denominator: idv_started, + ), + ], + [ + 'SSN (page view)', + idv_doc_auth_ssn_visited, + dropoff = idv_doc_auth_image_vendor_submitted - + idv_doc_auth_ssn_visited, + percent( + numerator: dropoff, + denominator: idv_doc_auth_image_vendor_submitted, + ), + percent( + numerator: idv_doc_auth_ssn_visited, + denominator: idv_started, + ), + ], + [ + 'Verify Info (page view)', + idv_doc_auth_verify_visited, + dropoff = idv_doc_auth_ssn_visited - + idv_doc_auth_verify_visited, + percent( + numerator: dropoff, + denominator: idv_doc_auth_ssn_visited, + ), + percent( + numerator: idv_doc_auth_verify_visited, + denominator: idv_started, + ), + ], + [ + 'Verify submit (event)', + idv_doc_auth_verify_submitted, + dropoff = idv_doc_auth_verify_visited - + idv_doc_auth_verify_submitted, + percent( + numerator: dropoff, + denominator: idv_doc_auth_verify_visited, + ), + percent( + numerator: idv_doc_auth_verify_submitted, + denominator: idv_started, + ), + ], + [ + 'Phone finder (page view)', + idv_doc_auth_phone_visited, + dropoff = idv_doc_auth_verify_submitted - + idv_doc_auth_phone_visited, + percent( + numerator: dropoff, + denominator: idv_doc_auth_verify_submitted, + ), + percent( + numerator: idv_doc_auth_phone_visited, + denominator: idv_started, + ), + ], + [ + 'Encrypt account: enter password (page view)', + idv_enter_password_visited, + dropoff = idv_doc_auth_phone_visited - + idv_enter_password_visited, + percent( + numerator: dropoff, + denominator: idv_doc_auth_phone_visited, + ), + percent( + numerator: idv_enter_password_visited, + denominator: idv_started, + ), + ], + [ + 'Personal key input (page view)', + idv_enter_password_submitted, + dropoff = idv_enter_password_visited - + idv_enter_password_submitted, + percent( + numerator: dropoff, + denominator: idv_enter_password_visited, + ), + percent( + numerator: idv_enter_password_submitted, + denominator: idv_started, + ), + ], + [ + 'Verified (event)', + idv_personal_key_submitted, + dropoff = idv_enter_password_submitted - + idv_personal_key_submitted, + percent( + numerator: dropoff, + denominator: idv_enter_password_submitted, + ), + percent( + numerator: idv_personal_key_submitted, + denominator: idv_started, + ), + ], + [ + 'Blanket proofing rate', + '', + '', + '', + percent( + numerator: idv_personal_key_submitted, + denominator: idv_doc_auth_welcome_submitted, + ), + ], + [ + 'Actual proofing rate', + '', + '', + '', + percent( + numerator: idv_enter_password_visited, + denominator: idv_doc_auth_image_vendor_submitted, + ), + ], + [ + 'Verified proofing rate', + '', + '', + '', + percent( + numerator: idv_personal_key_submitted, + denominator: idv_doc_auth_image_vendor_submitted, + ), + ], + ] + end + + # rubocop:disable Layout/LineLength + def proofing_definition_table + [ + ['Term', 'Description', 'Definition', 'Calculated'], + [ + 'Blanket Proofing', + 'Full funnel: People who started proofing from welcome screen, successfully got verified credential and encrypted account', + 'Percentage of users that successfully proofed over the total number of users that began the proofing process', + 'Steps: "Verified" divided by "User agreement"', + ], + [ + 'Actual Proofing', + 'Proofing funnel: People that submit and get verified', + 'Percentage of users who submitted documents, passed instant verify and phone finder', + 'Steps: "Encrypt account: enter password" divided by "Document submitted"', + ], + [ + 'Verified Proofing', + 'Proofing + encryption: People that get verified, encypt account and are passed back to Service Provider', + 'Number of users who submitted documents, passed instant verify and phone finder, encrypted account, and sent to consent screen for sharing data with Service Provider', + 'Steps: "Verified" divided by "Document submitted"', + ], + ] + end + # rubocop:enable Layout/LineLength + + def step_definition_table + [ + ['Step', 'Definition'], + [ + 'Welcome (page viewed)', + 'Start of proofing process', + ], + [ + 'User agreement (page viewer)', + 'Users who clicked "Continue" on the welcome page', + ], + [ + 'Capture Document (page viewed)', + 'Users who check the consent checkbox and click "Continue"', + ], + [ + 'Document submitted (event)', + 'Users who upload a front and back image and click "Submit" ', + ], + [ + 'SSN (page view)', + 'Users whose ID is authenticated by Acuant', + ], + [ + 'Verify Info (page view)', + 'Users who enter an SSN and continue', + ], + [ + 'Verify submit (event)', + 'Users who verify their information and submit it for Identity Verification (LN)', + ], + [ + 'Phone finder (page view)', + 'Users who successfuly had their identities verified by LN', + ], + [ + 'Encrypt account: enter password (page view)', + 'Users who were able to complete the physicality check using PhoneFinder', + ], + [ + 'Personal key input (page view)', + 'Users who enter their password to encrypt their PII', + ], + [ + 'Verified (event)', + 'Users who confirm their personal key and complete setting up their verified account', + ], + ] + end + + def idv_started + data[Events::IDV_DOC_AUTH_WELCOME].count + end + + def idv_doc_auth_welcome_submitted + data[Events::IDV_DOC_AUTH_WELCOME_SUBMITTED].count + end + + def idv_doc_auth_document_captured + data[Events::IDV_DOC_AUTH_CAPTURED].count + end + + def idv_doc_auth_image_vendor_submitted + data[Events::IDV_DOC_AUTH_IMAGE_UPLOAD].count + end + + def idv_doc_auth_ssn_visited + data[Events::IDV_DOC_AUTH_SSN_VISITED].count + end + + def idv_doc_auth_verify_visited + data[Events::IDV_DOC_AUTH_VERIFY_VISITED].count + end + + def idv_doc_auth_verify_submitted + data[Events::IDV_DOC_AUTH_VERIFY_SUBMITTED].count + end + + def idv_doc_auth_phone_visited + data[Events::IDV_DOC_AUTH_PHONE_VISITED].count + end + + def idv_enter_password_visited + (data[Events::IDV_ENTER_PASSWORD_VISITED] + + data[Events::OLD_IDV_ENTER_PASSWORD_VISITED]).count + end + + def idv_enter_password_submitted + (data[Events::IDV_ENTER_PASSWORD_SUBMITTED] + + data[Events::OLD_IDV_ENTER_PASSWORD_SUBMITTED]).count + end + + def idv_personal_key_submitted + data[Events::IDV_PERSONAL_KEY_SUBMITTED].count + end + + def as_tables + [ + proofing_definition_table, + step_definition_table, + overview_table, + dropoff_metrics_table, + ] + end + + def to_csvs + as_tables.map do |table| + CSV.generate do |csv| + table.each do |row| + csv << row + end + end + end + end + + # @return [Float] + def percent(numerator:, denominator:) + (numerator.to_f / denominator.to_f) + end + + def fetch_results + cloudwatch_client.fetch(query:, from: time_range.begin, to: time_range.end) + end + + def query + params = { + issuers: issuers.present? && quote(issuers), + event_names: quote(Events.all_events), + } + + format(<<~QUERY, params) + fields + name + , properties.user_id AS user_id + , coalesce(properties.event_properties.success, 0) AS success + #{issuers.present? ? '| filter properties.service_provider IN %{issuers}' : ''} + | filter name in %{event_names} + | limit 10000 + QUERY + end + + # event name => set(user ids) + # @return Hash> + def data + @data ||= begin + event_users = Hash.new do |h, uuid| + h[uuid] = Set.new + end + + fetch_results.each do |row| + event_users[row['name']] << row['user_id'] + end + + event_users + end + end + + def cloudwatch_client + @cloudwatch_client ||= Reporting::CloudwatchClient.new( + num_threads: @threads, + ensure_complete_logs: true, + slice_interval: @slice, + progress: false, + logger: nil, + ) + end + end +end + +# rubocop:disable Rails/Output +if __FILE__ == $PROGRAM_NAME + options = Reporting::CommandLineOptions.new.parse!(ARGV, require_issuer: false) + + Reporting::DropOffReport.new(**options).to_csvs.each do |csv| + puts csv + end +end +# rubocop:enable Rails/Output diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index 795fd5bc7e2..e56ce40347e 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -90,7 +90,7 @@ namespace :dev do ) end random = Random.new(num_users) - raw_enrollment_status = (ENV['ENROLLMENT_STATUS'] || InPersonEnrollment::STATUS_PENDING) + raw_enrollment_status = ENV['ENROLLMENT_STATUS'] || InPersonEnrollment::STATUS_PENDING enrollment_status = InPersonEnrollment.statuses[raw_enrollment_status] is_established = [ InPersonEnrollment::STATUS_PENDING, diff --git a/package.json b/package.json index d00534af1de..1ccfc748444 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "build:css": "build-sass app/assets/stylesheets/*.css.scss app/components/*.scss --load-path=app/assets/stylesheets --out-dir=app/assets/builds" }, "dependencies": { - "@18f/identity-design-system": "^8.0.1", + "@18f/identity-design-system": "^8.1.2", "@babel/core": "^7.20.7", "@babel/preset-env": "^7.15.6", "@babel/preset-react": "^7.14.5", diff --git a/spec/controllers/account_reset/cancel_controller_spec.rb b/spec/controllers/account_reset/cancel_controller_spec.rb index 41677ed6cd4..9818f7502ec 100644 --- a/spec/controllers/account_reset/cancel_controller_spec.rb +++ b/spec/controllers/account_reset/cancel_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe AccountReset::CancelController do +RSpec.describe AccountReset::CancelController, allowed_extra_analytics: [:*] do include AccountResetHelper let(:user) { create(:user, :fully_registered) } diff --git a/spec/controllers/account_reset/request_controller_spec.rb b/spec/controllers/account_reset/request_controller_spec.rb index 59cdb211f05..09c7484d905 100644 --- a/spec/controllers/account_reset/request_controller_spec.rb +++ b/spec/controllers/account_reset/request_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe AccountReset::RequestController do +RSpec.describe AccountReset::RequestController, allowed_extra_analytics: [:*] do let(:user) { create(:user, :with_authentication_app) } describe '#show' do it 'renders the page' do diff --git a/spec/controllers/accounts/personal_keys_controller_spec.rb b/spec/controllers/accounts/personal_keys_controller_spec.rb index c507679ceca..2c1df26e39e 100644 --- a/spec/controllers/accounts/personal_keys_controller_spec.rb +++ b/spec/controllers/accounts/personal_keys_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Accounts::PersonalKeysController do +RSpec.describe Accounts::PersonalKeysController, allowed_extra_analytics: [:*] do describe 'before_actions' do it 'require recent reauthn' do expect(subject).to have_actions( diff --git a/spec/controllers/concerns/idv/step_indicator_concern_spec.rb b/spec/controllers/concerns/idv/step_indicator_concern_spec.rb index 071532addc3..998b74c649a 100644 --- a/spec/controllers/concerns/idv/step_indicator_concern_spec.rb +++ b/spec/controllers/concerns/idv/step_indicator_concern_spec.rb @@ -2,7 +2,7 @@ RSpec.describe Idv::StepIndicatorConcern, type: :controller do controller ApplicationController do - include IdvSession + include IdvSessionConcern include Idv::StepIndicatorConcern end diff --git a/spec/controllers/concerns/mfa_setup_concern_spec.rb b/spec/controllers/concerns/mfa_setup_concern_spec.rb index c5714409d3a..7c874508702 100644 --- a/spec/controllers/concerns/mfa_setup_concern_spec.rb +++ b/spec/controllers/concerns/mfa_setup_concern_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'MfaSetupConcern' do +RSpec.describe MfaSetupConcern, allowed_extra_analytics: [:*] do controller ApplicationController do include MfaSetupConcern end diff --git a/spec/controllers/concerns/rate_limit_concern_spec.rb b/spec/controllers/concerns/rate_limit_concern_spec.rb index 69c14e681d8..87480dbca80 100644 --- a/spec/controllers/concerns/rate_limit_concern_spec.rb +++ b/spec/controllers/concerns/rate_limit_concern_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'RateLimitConcern' do +RSpec.describe RateLimitConcern, allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered, email: 'old_email@example.com') } idv_step_controller_class = Class.new(ApplicationController) do @@ -9,7 +9,7 @@ def self.name end include RateLimitConcern - include IdvSession + include IdvSessionConcern def show render plain: 'Hello' diff --git a/spec/controllers/idv/agreement_controller_spec.rb b/spec/controllers/idv/agreement_controller_spec.rb index 5c2e3bb9bdf..9568b4053dc 100644 --- a/spec/controllers/idv/agreement_controller_spec.rb +++ b/spec/controllers/idv/agreement_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::AgreementController do +RSpec.describe Idv::AgreementController, allowed_extra_analytics: [:*] do include FlowPolicyHelper let(:user) { create(:user) } diff --git a/spec/controllers/idv/by_mail/enter_code_controller_spec.rb b/spec/controllers/idv/by_mail/enter_code_controller_spec.rb index 4d87883c6b5..985d1628185 100644 --- a/spec/controllers/idv/by_mail/enter_code_controller_spec.rb +++ b/spec/controllers/idv/by_mail/enter_code_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::ByMail::EnterCodeController do +RSpec.describe Idv::ByMail::EnterCodeController, allowed_extra_analytics: [:*] do let(:good_otp) { 'ABCDE12345' } let(:bad_otp) { 'bad-otp' } let(:threatmetrix_enabled) { false } diff --git a/spec/controllers/idv/by_mail/request_letter_controller_spec.rb b/spec/controllers/idv/by_mail/request_letter_controller_spec.rb index 80b7e4e2f4c..ddfe3cd5495 100644 --- a/spec/controllers/idv/by_mail/request_letter_controller_spec.rb +++ b/spec/controllers/idv/by_mail/request_letter_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::ByMail::RequestLetterController do +RSpec.describe Idv::ByMail::RequestLetterController, allowed_extra_analytics: [:*] do let(:user) { create(:user) } let(:ab_test_args) do @@ -30,7 +30,7 @@ ) end - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/cancellations_controller_spec.rb b/spec/controllers/idv/cancellations_controller_spec.rb index a4ed53a1a0d..610362f0142 100644 --- a/spec/controllers/idv/cancellations_controller_spec.rb +++ b/spec/controllers/idv/cancellations_controller_spec.rb @@ -2,7 +2,7 @@ RSpec.describe Idv::CancellationsController do describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/document_capture_controller_spec.rb b/spec/controllers/idv/document_capture_controller_spec.rb index 11e96483dc6..1ac440d0004 100644 --- a/spec/controllers/idv/document_capture_controller_spec.rb +++ b/spec/controllers/idv/document_capture_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::DocumentCaptureController do +RSpec.describe Idv::DocumentCaptureController, allowed_extra_analytics: [:*] do include FlowPolicyHelper let(:document_capture_session_requested_at) { Time.zone.now } diff --git a/spec/controllers/idv/enter_password_controller_spec.rb b/spec/controllers/idv/enter_password_controller_spec.rb index c61dd934811..efc5251385d 100644 --- a/spec/controllers/idv/enter_password_controller_spec.rb +++ b/spec/controllers/idv/enter_password_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::EnterPasswordController do +RSpec.describe Idv::EnterPasswordController, allowed_extra_analytics: [:*] do include UspsIppHelper let(:user) do @@ -65,7 +65,7 @@ ) end - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/forgot_password_controller_spec.rb b/spec/controllers/idv/forgot_password_controller_spec.rb index 90547f3f9a8..4c7c0e0d454 100644 --- a/spec/controllers/idv/forgot_password_controller_spec.rb +++ b/spec/controllers/idv/forgot_password_controller_spec.rb @@ -2,7 +2,7 @@ RSpec.describe Idv::ForgotPasswordController do describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/hybrid_handoff_controller_spec.rb b/spec/controllers/idv/hybrid_handoff_controller_spec.rb index 90bb5f04ccf..e1162284d01 100644 --- a/spec/controllers/idv/hybrid_handoff_controller_spec.rb +++ b/spec/controllers/idv/hybrid_handoff_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::HybridHandoffController do +RSpec.describe Idv::HybridHandoffController, allowed_extra_analytics: [:*] do include FlowPolicyHelper let(:user) { create(:user) } diff --git a/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb b/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb index 207063208db..7a6f99e6e67 100644 --- a/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb +++ b/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::HybridMobile::DocumentCaptureController do +RSpec.describe Idv::HybridMobile::DocumentCaptureController, allowed_extra_analytics: [:*] do let(:user) { create(:user) } let!(:document_capture_session) do diff --git a/spec/controllers/idv/image_uploads_controller_spec.rb b/spec/controllers/idv/image_uploads_controller_spec.rb index cce66a44b26..4ee86c00895 100644 --- a/spec/controllers/idv/image_uploads_controller_spec.rb +++ b/spec/controllers/idv/image_uploads_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::ImageUploadsController do +RSpec.describe Idv::ImageUploadsController, allowed_extra_analytics: [:*] do include DocPiiHelper let(:document_filename_regex) { /^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}\.[a-z]+$/ } @@ -442,6 +442,20 @@ liveness_checking_required: boolean, selfie_live: boolean, selfie_quality_good: boolean, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) expect(@analytics).to receive(:track_event).with( @@ -625,6 +639,20 @@ liveness_checking_required: boolean, selfie_live: true, selfie_quality_good: true, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) expect(@analytics).to receive(:track_event).with( @@ -721,6 +749,20 @@ liveness_checking_required: boolean, selfie_live: true, selfie_quality_good: true, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) expect(@analytics).to receive(:track_event).with( @@ -817,6 +859,20 @@ liveness_checking_required: boolean, selfie_live: true, selfie_quality_good: true, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) expect(@analytics).to receive(:track_event).with( @@ -910,6 +966,20 @@ liveness_checking_required: boolean, selfie_live: true, selfie_quality_good: true, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) expect(@analytics).to receive(:track_event).with( @@ -1028,6 +1098,20 @@ liveness_checking_required: boolean, selfie_live: true, selfie_quality_good: true, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) action @@ -1104,6 +1188,20 @@ liveness_checking_required: boolean, selfie_live: boolean, selfie_quality_good: boolean, + address_line2_present: nil, + alert_failure_count: nil, + conversation_id: nil, + decision_product_status: nil, + image_metrics: nil, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, + selfie_success: nil, + transaction_reason_code: nil, + transaction_status: nil, + vendor: nil, ) action diff --git a/spec/controllers/idv/in_person/usps_locations_controller_spec.rb b/spec/controllers/idv/in_person/usps_locations_controller_spec.rb index 5ac877f8432..bbbed4e4798 100644 --- a/spec/controllers/idv/in_person/usps_locations_controller_spec.rb +++ b/spec/controllers/idv/in_person/usps_locations_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::InPerson::UspsLocationsController do +RSpec.describe Idv::InPerson::UspsLocationsController, allowed_extra_analytics: [:*] do let(:user) { create(:user) } let(:sp) { nil } let(:in_person_proofing_enabled) { true } diff --git a/spec/controllers/idv/in_person/verify_info_controller_spec.rb b/spec/controllers/idv/in_person/verify_info_controller_spec.rb index 55f9ead4f99..23f0a584cdf 100644 --- a/spec/controllers/idv/in_person/verify_info_controller_spec.rb +++ b/spec/controllers/idv/in_person/verify_info_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::InPerson::VerifyInfoController do +RSpec.describe Idv::InPerson::VerifyInfoController, allowed_extra_analytics: [:*] do let(:pii_from_user) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID.dup } let(:flow_session) do { pii_from_user: pii_from_user } diff --git a/spec/controllers/idv/mail_only_warning_controller_spec.rb b/spec/controllers/idv/mail_only_warning_controller_spec.rb index 2b8e375e7d1..fd41e819c50 100644 --- a/spec/controllers/idv/mail_only_warning_controller_spec.rb +++ b/spec/controllers/idv/mail_only_warning_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::MailOnlyWarningController do +RSpec.describe Idv::MailOnlyWarningController, allowed_extra_analytics: [:*] do let(:user) { create(:user) } before do diff --git a/spec/controllers/idv/otp_verification_controller_spec.rb b/spec/controllers/idv/otp_verification_controller_spec.rb index cb968aa1d43..508faf79ee3 100644 --- a/spec/controllers/idv/otp_verification_controller_spec.rb +++ b/spec/controllers/idv/otp_verification_controller_spec.rb @@ -53,7 +53,7 @@ end describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/personal_key_controller_spec.rb b/spec/controllers/idv/personal_key_controller_spec.rb index 483e9405306..93e919f8665 100644 --- a/spec/controllers/idv/personal_key_controller_spec.rb +++ b/spec/controllers/idv/personal_key_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::PersonalKeyController do +RSpec.describe Idv::PersonalKeyController, allowed_extra_analytics: [:*] do include FlowPolicyHelper include SamlAuthHelper include PersonalKeyValidator @@ -181,7 +181,7 @@ def assert_personal_key_generated_for_profiles(*profile_pii_pairs) ) end - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions( :before, :redirect_unless_sp_requested_verification, diff --git a/spec/controllers/idv/phone_controller_spec.rb b/spec/controllers/idv/phone_controller_spec.rb index 4d3952f75be..d99e86bb5af 100644 --- a/spec/controllers/idv/phone_controller_spec.rb +++ b/spec/controllers/idv/phone_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::PhoneController do +RSpec.describe Idv::PhoneController, allowed_extra_analytics: [:*] do include FlowPolicyHelper let(:max_attempts) { RateLimiter.max_attempts(:proof_address) } @@ -36,7 +36,7 @@ end describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/phone_errors_controller_spec.rb b/spec/controllers/idv/phone_errors_controller_spec.rb index 697d8326044..010f7530b20 100644 --- a/spec/controllers/idv/phone_errors_controller_spec.rb +++ b/spec/controllers/idv/phone_errors_controller_spec.rb @@ -33,7 +33,7 @@ shared_examples_for 'an idv phone errors controller action' do describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/resend_otp_controller_spec.rb b/spec/controllers/idv/resend_otp_controller_spec.rb index 4d0ccced7ef..48fab6d9a30 100644 --- a/spec/controllers/idv/resend_otp_controller_spec.rb +++ b/spec/controllers/idv/resend_otp_controller_spec.rb @@ -25,7 +25,7 @@ end describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/session_errors_controller_spec.rb b/spec/controllers/idv/session_errors_controller_spec.rb index e7fac844696..39ddf77063e 100644 --- a/spec/controllers/idv/session_errors_controller_spec.rb +++ b/spec/controllers/idv/session_errors_controller_spec.rb @@ -134,7 +134,7 @@ end describe 'before_actions' do - it 'includes before_actions from IdvSession' do + it 'includes before_actions from IdvSessionConcern' do expect(subject).to have_actions(:before, :redirect_unless_sp_requested_verification) end end diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index fcee63bdc1b..f0cbb78fc7f 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::VerifyInfoController do +RSpec.describe Idv::VerifyInfoController, allowed_extra_analytics: [:*] do include FlowPolicyHelper let(:user) { create(:user) } diff --git a/spec/controllers/idv/welcome_controller_spec.rb b/spec/controllers/idv/welcome_controller_spec.rb index 21472040a11..b49808f3217 100644 --- a/spec/controllers/idv/welcome_controller_spec.rb +++ b/spec/controllers/idv/welcome_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::WelcomeController do +RSpec.describe Idv::WelcomeController, allowed_extra_analytics: [:*] do let(:user) { create(:user) } let(:ab_test_args) do diff --git a/spec/controllers/idv_controller_spec.rb b/spec/controllers/idv_controller_spec.rb index 7593d4ffd65..94000a0af5c 100644 --- a/spec/controllers/idv_controller_spec.rb +++ b/spec/controllers/idv_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe IdvController do +RSpec.describe IdvController, allowed_extra_analytics: [:*] do before do stub_sign_in end diff --git a/spec/controllers/openid_connect/authorization_controller_spec.rb b/spec/controllers/openid_connect/authorization_controller_spec.rb index 42f5514fff1..da601abc81e 100644 --- a/spec/controllers/openid_connect/authorization_controller_spec.rb +++ b/spec/controllers/openid_connect/authorization_controller_spec.rb @@ -1,7 +1,7 @@ # rubocop:disable Layout/LineLength require 'rails_helper' -RSpec.describe OpenidConnect::AuthorizationController do +RSpec.describe OpenidConnect::AuthorizationController, allowed_extra_analytics: [:*] do include WebAuthnHelper before do # All the tests here were written prior to the interstitial diff --git a/spec/controllers/openid_connect/token_controller_spec.rb b/spec/controllers/openid_connect/token_controller_spec.rb index 8ae304586c8..8cfa99033d0 100644 --- a/spec/controllers/openid_connect/token_controller_spec.rb +++ b/spec/controllers/openid_connect/token_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe OpenidConnect::TokenController do +RSpec.describe OpenidConnect::TokenController, allowed_extra_analytics: [:*] do include Rails.application.routes.url_helpers describe '#create' do diff --git a/spec/controllers/openid_connect/user_info_controller_spec.rb b/spec/controllers/openid_connect/user_info_controller_spec.rb index 28b26dd8b9e..11991e412af 100644 --- a/spec/controllers/openid_connect/user_info_controller_spec.rb +++ b/spec/controllers/openid_connect/user_info_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe OpenidConnect::UserInfoController do +RSpec.describe OpenidConnect::UserInfoController, allowed_extra_analytics: [:*] do let(:json_response) { JSON.parse(response.body).with_indifferent_access } describe '#show' do diff --git a/spec/controllers/risc/security_events_controller_spec.rb b/spec/controllers/risc/security_events_controller_spec.rb index a41f2d9d908..8799871775b 100644 --- a/spec/controllers/risc/security_events_controller_spec.rb +++ b/spec/controllers/risc/security_events_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Risc::SecurityEventsController do +RSpec.describe Risc::SecurityEventsController, allowed_extra_analytics: [:*] do include Rails.application.routes.url_helpers let(:user) { create(:user) } diff --git a/spec/controllers/saml_idp_controller_spec.rb b/spec/controllers/saml_idp_controller_spec.rb index 5d06fb301c6..511195be937 100644 --- a/spec/controllers/saml_idp_controller_spec.rb +++ b/spec/controllers/saml_idp_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe SamlIdpController do +RSpec.describe SamlIdpController, allowed_extra_analytics: [:*] do include SamlAuthHelper render_views diff --git a/spec/controllers/saml_signed_message_spec.rb b/spec/controllers/saml_signed_message_spec.rb index 33717b3f1de..afb73f2bfe9 100644 --- a/spec/controllers/saml_signed_message_spec.rb +++ b/spec/controllers/saml_signed_message_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe SamlIdpController do +RSpec.describe SamlIdpController, allowed_extra_analytics: [:*] do include SamlAuthHelper before do diff --git a/spec/controllers/sign_up/completions_controller_spec.rb b/spec/controllers/sign_up/completions_controller_spec.rb index 102d3d4bc1e..bc6fe2fc3f4 100644 --- a/spec/controllers/sign_up/completions_controller_spec.rb +++ b/spec/controllers/sign_up/completions_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe SignUp::CompletionsController do +RSpec.describe SignUp::CompletionsController, allowed_extra_analytics: [:*] do let(:temporary_email) { 'name@temporary.com' } describe '#show' do diff --git a/spec/controllers/sign_up/passwords_controller_spec.rb b/spec/controllers/sign_up/passwords_controller_spec.rb index 8f48a43c5bc..55058d0673e 100644 --- a/spec/controllers/sign_up/passwords_controller_spec.rb +++ b/spec/controllers/sign_up/passwords_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe SignUp::PasswordsController do +RSpec.describe SignUp::PasswordsController, allowed_extra_analytics: [:*] do let(:token) { 'new token' } describe '#create' do diff --git a/spec/controllers/sign_up/registrations_controller_spec.rb b/spec/controllers/sign_up/registrations_controller_spec.rb index 33296dd4589..8fda4aeaf55 100644 --- a/spec/controllers/sign_up/registrations_controller_spec.rb +++ b/spec/controllers/sign_up/registrations_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe SignUp::RegistrationsController, devise: true do +RSpec.describe SignUp::RegistrationsController, devise: true, allowed_extra_analytics: [:*] do describe '#new' do it 'allows user to visit the sign up page' do get :new diff --git a/spec/controllers/two_factor_authentication/options_controller_spec.rb b/spec/controllers/two_factor_authentication/options_controller_spec.rb index a2d42dfe554..ca715171b2a 100644 --- a/spec/controllers/two_factor_authentication/options_controller_spec.rb +++ b/spec/controllers/two_factor_authentication/options_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe TwoFactorAuthentication::OptionsController do +RSpec.describe TwoFactorAuthentication::OptionsController, allowed_extra_analytics: [:*] do describe '#index' do it 'renders the page' do sign_in_before_2fa diff --git a/spec/controllers/two_factor_authentication/otp_verification_controller_spec.rb b/spec/controllers/two_factor_authentication/otp_verification_controller_spec.rb index 608a57dc45f..380284b7f4a 100644 --- a/spec/controllers/two_factor_authentication/otp_verification_controller_spec.rb +++ b/spec/controllers/two_factor_authentication/otp_verification_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe TwoFactorAuthentication::OtpVerificationController do +RSpec.describe TwoFactorAuthentication::OtpVerificationController, allowed_extra_analytics: [:*] do describe '#show' do context 'when resource is not fully authenticated yet' do before do diff --git a/spec/controllers/two_factor_authentication/personal_key_verification_controller_spec.rb b/spec/controllers/two_factor_authentication/personal_key_verification_controller_spec.rb index e39edbf07e9..9ec58b054c0 100644 --- a/spec/controllers/two_factor_authentication/personal_key_verification_controller_spec.rb +++ b/spec/controllers/two_factor_authentication/personal_key_verification_controller_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe TwoFactorAuthentication::PersonalKeyVerificationController do +RSpec.describe TwoFactorAuthentication::PersonalKeyVerificationController, + allowed_extra_analytics: [:*] do let(:personal_key) { { personal_key: 'foo' } } let(:payload) { { personal_key_form: personal_key } } diff --git a/spec/controllers/two_factor_authentication/piv_cac_verification_controller_spec.rb b/spec/controllers/two_factor_authentication/piv_cac_verification_controller_spec.rb index 0bb7aa5bf03..e294b9c4d80 100644 --- a/spec/controllers/two_factor_authentication/piv_cac_verification_controller_spec.rb +++ b/spec/controllers/two_factor_authentication/piv_cac_verification_controller_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe TwoFactorAuthentication::PivCacVerificationController do +RSpec.describe TwoFactorAuthentication::PivCacVerificationController, + allowed_extra_analytics: [:*] do let(:user) do create( :user, :fully_registered, :with_piv_or_cac, diff --git a/spec/controllers/two_factor_authentication/sms_opt_in_controller_spec.rb b/spec/controllers/two_factor_authentication/sms_opt_in_controller_spec.rb index 3f95b22769b..6fa02cccaf4 100644 --- a/spec/controllers/two_factor_authentication/sms_opt_in_controller_spec.rb +++ b/spec/controllers/two_factor_authentication/sms_opt_in_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe TwoFactorAuthentication::SmsOptInController do +RSpec.describe TwoFactorAuthentication::SmsOptInController, allowed_extra_analytics: [:*] do describe '#new' do subject(:action) { get :new, params: { opt_out_uuid: opt_out_uuid } } diff --git a/spec/controllers/users/backup_code_setup_controller_spec.rb b/spec/controllers/users/backup_code_setup_controller_spec.rb index 862178c5c11..d4a16b6ee13 100644 --- a/spec/controllers/users/backup_code_setup_controller_spec.rb +++ b/spec/controllers/users/backup_code_setup_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::BackupCodeSetupController do +RSpec.describe Users::BackupCodeSetupController, allowed_extra_analytics: [:*] do describe 'before_actions' do it 'includes appropriate before_actions' do expect(subject).to have_actions( diff --git a/spec/controllers/users/email_confirmations_controller_spec.rb b/spec/controllers/users/email_confirmations_controller_spec.rb index b6495043c2b..72f97396d26 100644 --- a/spec/controllers/users/email_confirmations_controller_spec.rb +++ b/spec/controllers/users/email_confirmations_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::EmailConfirmationsController do +RSpec.describe Users::EmailConfirmationsController, allowed_extra_analytics: [:*] do describe '#create' do describe 'Valid email confirmation tokens' do it 'tracks a valid email confirmation token event' do diff --git a/spec/controllers/users/email_language_controller_spec.rb b/spec/controllers/users/email_language_controller_spec.rb index 1aaccdaf48b..eac8d20e0fd 100644 --- a/spec/controllers/users/email_language_controller_spec.rb +++ b/spec/controllers/users/email_language_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::EmailLanguageController do +RSpec.describe Users::EmailLanguageController, allowed_extra_analytics: [:*] do describe 'before_actions' do it 'includes appropriate before_actions' do expect(subject).to have_actions( diff --git a/spec/controllers/users/passwords_controller_spec.rb b/spec/controllers/users/passwords_controller_spec.rb index 924ec949f07..32832b706aa 100644 --- a/spec/controllers/users/passwords_controller_spec.rb +++ b/spec/controllers/users/passwords_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::PasswordsController do +RSpec.describe Users::PasswordsController, allowed_extra_analytics: [:*] do context 'user visits add an email address page' do let(:user) { create(:user) } before do diff --git a/spec/controllers/users/phone_setup_controller_spec.rb b/spec/controllers/users/phone_setup_controller_spec.rb index 868bd72fc47..7c22f889843 100644 --- a/spec/controllers/users/phone_setup_controller_spec.rb +++ b/spec/controllers/users/phone_setup_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::PhoneSetupController do +RSpec.describe Users::PhoneSetupController, allowed_extra_analytics: [:*] do let(:mfa_selections) { ['voice'] } before do allow(IdentityConfig.store).to receive(:phone_service_check).and_return(true) diff --git a/spec/controllers/users/piv_cac_authentication_setup_controller_spec.rb b/spec/controllers/users/piv_cac_authentication_setup_controller_spec.rb index 4c294a70f4c..0de160d48a7 100644 --- a/spec/controllers/users/piv_cac_authentication_setup_controller_spec.rb +++ b/spec/controllers/users/piv_cac_authentication_setup_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::PivCacAuthenticationSetupController do +RSpec.describe Users::PivCacAuthenticationSetupController, allowed_extra_analytics: [:*] do describe 'before_actions' do it 'includes appropriate before_actions' do expect(subject).to have_actions( diff --git a/spec/controllers/users/reset_passwords_controller_spec.rb b/spec/controllers/users/reset_passwords_controller_spec.rb index c77a019caf3..a3a6ab9b346 100644 --- a/spec/controllers/users/reset_passwords_controller_spec.rb +++ b/spec/controllers/users/reset_passwords_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::ResetPasswordsController, devise: true do +RSpec.describe Users::ResetPasswordsController, devise: true, allowed_extra_analytics: [:*] do let(:password_error_message) do t('errors.attributes.password.too_short.other', count: Devise.password_length.first) end diff --git a/spec/controllers/users/rules_of_use_controller_spec.rb b/spec/controllers/users/rules_of_use_controller_spec.rb index 012635be0b7..9877d11e30b 100644 --- a/spec/controllers/users/rules_of_use_controller_spec.rb +++ b/spec/controllers/users/rules_of_use_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::RulesOfUseController do +RSpec.describe Users::RulesOfUseController, allowed_extra_analytics: [:*] do let(:rules_of_use_updated_at) { 1.day.ago } let(:accepted_terms_at) { nil } let(:user) { create(:user, :fully_registered, accepted_terms_at: accepted_terms_at) } diff --git a/spec/controllers/users/two_factor_authentication_controller_spec.rb b/spec/controllers/users/two_factor_authentication_controller_spec.rb index e5e924b1183..20129412a2f 100644 --- a/spec/controllers/users/two_factor_authentication_controller_spec.rb +++ b/spec/controllers/users/two_factor_authentication_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::TwoFactorAuthenticationController do +RSpec.describe Users::TwoFactorAuthenticationController, allowed_extra_analytics: [:*] do include ActionView::Helpers::DateHelper include UserAgentHelper diff --git a/spec/controllers/users/two_factor_authentication_setup_controller_spec.rb b/spec/controllers/users/two_factor_authentication_setup_controller_spec.rb index f1234ffd6b6..c90a627609b 100644 --- a/spec/controllers/users/two_factor_authentication_setup_controller_spec.rb +++ b/spec/controllers/users/two_factor_authentication_setup_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::TwoFactorAuthenticationSetupController do +RSpec.describe Users::TwoFactorAuthenticationSetupController, allowed_extra_analytics: [:*] do describe 'GET index' do it 'tracks the visit in analytics' do stub_sign_in_before_2fa diff --git a/spec/controllers/users/verify_personal_key_controller_spec.rb b/spec/controllers/users/verify_personal_key_controller_spec.rb index e852fcc0c08..b23c536d6bd 100644 --- a/spec/controllers/users/verify_personal_key_controller_spec.rb +++ b/spec/controllers/users/verify_personal_key_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::VerifyPersonalKeyController do +RSpec.describe Users::VerifyPersonalKeyController, allowed_extra_analytics: [:*] do let(:user) { create(:user, personal_key: personal_key) } let!(:profiles) { [] } let(:personal_key) { 'key' } diff --git a/spec/controllers/users/webauthn_setup_controller_spec.rb b/spec/controllers/users/webauthn_setup_controller_spec.rb index 483c02b6cdc..8c934b4dd05 100644 --- a/spec/controllers/users/webauthn_setup_controller_spec.rb +++ b/spec/controllers/users/webauthn_setup_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Users::WebauthnSetupController do +RSpec.describe Users::WebauthnSetupController, allowed_extra_analytics: [:*] do include WebAuthnHelper describe 'before_actions' do diff --git a/spec/features/accessibility/idv_pages_spec.rb b/spec/features/accessibility/idv_pages_spec.rb index 774b8750155..295b25f7db3 100644 --- a/spec/features/accessibility/idv_pages_spec.rb +++ b/spec/features/accessibility/idv_pages_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'axe-rspec' -RSpec.feature 'Accessibility on IDV pages', :js do +RSpec.feature 'Accessibility on IDV pages', :js, allowed_extra_analytics: [:*] do describe 'IDV pages' do include IdvStepHelper diff --git a/spec/features/accessibility/static_pages_spec.rb b/spec/features/accessibility/static_pages_spec.rb index 5d79ae1a766..00e934557d0 100644 --- a/spec/features/accessibility/static_pages_spec.rb +++ b/spec/features/accessibility/static_pages_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'axe-rspec' -RSpec.feature 'Accessibility on static pages', :js do +RSpec.feature 'Accessibility on static pages', :js, allowed_extra_analytics: [:*] do scenario 'not found page', allow_browser_log: true do visit '/non_existent_page' diff --git a/spec/features/accessibility/user_pages_spec.rb b/spec/features/accessibility/user_pages_spec.rb index de7fa0b1a95..bd909ec6123 100644 --- a/spec/features/accessibility/user_pages_spec.rb +++ b/spec/features/accessibility/user_pages_spec.rb @@ -1,7 +1,8 @@ require 'rails_helper' require 'axe-rspec' -RSpec.feature 'Accessibility on pages that require authentication', :js do +RSpec.feature 'Accessibility on pages that require authentication', :js, + allowed_extra_analytics: [:*] do scenario 'user registration page' do email = 'test@example.com' sign_up_with(email) diff --git a/spec/features/accessibility/visitor_pages_spec.rb b/spec/features/accessibility/visitor_pages_spec.rb index ad6c980d1d3..b63b5def181 100644 --- a/spec/features/accessibility/visitor_pages_spec.rb +++ b/spec/features/accessibility/visitor_pages_spec.rb @@ -1,7 +1,8 @@ require 'rails_helper' require 'axe-rspec' -RSpec.feature 'Accessibility on pages that do not require authentication', :js do +RSpec.feature 'Accessibility on pages that do not require authentication', :js, + allowed_extra_analytics: [:*] do scenario 'login / root path' do visit root_path diff --git a/spec/features/account/backup_codes_spec.rb b/spec/features/account/backup_codes_spec.rb index 74f1dc1f4da..0fdbeda4419 100644 --- a/spec/features/account/backup_codes_spec.rb +++ b/spec/features/account/backup_codes_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Backup codes' do +RSpec.feature 'Backup codes', allowed_extra_analytics: [:*] do before do sign_in_and_2fa_user(user) visit account_two_factor_authentication_path diff --git a/spec/features/account/device_spec.rb b/spec/features/account/device_spec.rb index 0921759c89c..0df71b4ed3c 100644 --- a/spec/features/account/device_spec.rb +++ b/spec/features/account/device_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Devices' do +RSpec.describe 'Devices', allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered) } before do user = create(:user, :fully_registered, otp_delivery_preference: 'sms') diff --git a/spec/features/account/unphishable_badge_spec.rb b/spec/features/account/unphishable_badge_spec.rb index 75a2413d43e..d33cf92b432 100644 --- a/spec/features/account/unphishable_badge_spec.rb +++ b/spec/features/account/unphishable_badge_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Unphishable account badge' do +RSpec.feature 'Unphishable account badge', allowed_extra_analytics: [:*] do before do sign_in_and_2fa_user(user) end diff --git a/spec/features/account_connected_apps_spec.rb b/spec/features/account_connected_apps_spec.rb index 702f3cdf3c2..f4ac013270c 100644 --- a/spec/features/account_connected_apps_spec.rb +++ b/spec/features/account_connected_apps_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Account connected applications' do +RSpec.describe 'Account connected applications', allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered, created_at: Time.zone.now - 100.days) } let(:identity_with_link) do create( @@ -37,7 +37,7 @@ expect(page).to have_content(t('headings.account.connected_accounts')) visit account_history_path - expect(page).to have_content( \ + expect(page).to have_content( t('event_types.authenticated_at', service_provider: identity_without_link.display_name), ) expect(page).to_not have_link(identity_without_link.display_name) diff --git a/spec/features/account_creation/multiple_browsers_spec.rb b/spec/features/account_creation/multiple_browsers_spec.rb index 73080c84394..0a4b6c5d2da 100644 --- a/spec/features/account_creation/multiple_browsers_spec.rb +++ b/spec/features/account_creation/multiple_browsers_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'account creation across multiple browsers' do +RSpec.feature 'account creation across multiple browsers', allowed_extra_analytics: [:*] do include SpAuthHelper include SamlAuthHelper include OidcAuthHelper diff --git a/spec/features/account_creation/sp_return_log_spec.rb b/spec/features/account_creation/sp_return_log_spec.rb index 2513b1fda4b..aaba214caf7 100644 --- a/spec/features/account_creation/sp_return_log_spec.rb +++ b/spec/features/account_creation/sp_return_log_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SP return logs' do +RSpec.feature 'SP return logs', allowed_extra_analytics: [:*] do include SamlAuthHelper let(:email) { 'test@test.com' } diff --git a/spec/features/account_email_language_spec.rb b/spec/features/account_email_language_spec.rb index a43cba59786..8d817c7f285 100644 --- a/spec/features/account_email_language_spec.rb +++ b/spec/features/account_email_language_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Account email language' do +RSpec.describe 'Account email language', allowed_extra_analytics: [:*] do let(:user) { user_with_2fa } let(:original_email_language) { 'es' } diff --git a/spec/features/account_history_spec.rb b/spec/features/account_history_spec.rb index a5dd94df942..7d23a72ac06 100644 --- a/spec/features/account_history_spec.rb +++ b/spec/features/account_history_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Account history' do +RSpec.describe 'Account history', allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered, created_at: Time.zone.now - 100.days) } let(:account_created_event) { create(:event, user: user, created_at: Time.zone.now - 98.days) } let(:gpo_mail_sent_event) do diff --git a/spec/features/account_reset/cancel_request_spec.rb b/spec/features/account_reset/cancel_request_spec.rb index 06fdcdae6db..92a8b588261 100644 --- a/spec/features/account_reset/cancel_request_spec.rb +++ b/spec/features/account_reset/cancel_request_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Account Reset Request: Cancellation' do +RSpec.describe 'Account Reset Request: Cancellation', allowed_extra_analytics: [:*] do context 'user cancels from the second email after the request has been granted' do it 'cancels the request and does not delete the user', email: true do user = create(:user, :fully_registered) diff --git a/spec/features/account_reset/delete_account_spec.rb b/spec/features/account_reset/delete_account_spec.rb index 924a67c25eb..53a3aa545e9 100644 --- a/spec/features/account_reset/delete_account_spec.rb +++ b/spec/features/account_reset/delete_account_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe 'Account Reset Request: Delete Account', email: true do +RSpec.describe 'Account Reset Request: Delete Account', email: true, + allowed_extra_analytics: [:*] do include PushNotificationsHelper include OidcAuthHelper include IrsAttemptsApiTrackingHelper diff --git a/spec/features/account_reset/pending_request_spec.rb b/spec/features/account_reset/pending_request_spec.rb index 123606c65b2..42dbe1a9657 100644 --- a/spec/features/account_reset/pending_request_spec.rb +++ b/spec/features/account_reset/pending_request_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Pending account reset request sign in' do +RSpec.feature 'Pending account reset request sign in', allowed_extra_analytics: [:*] do it 'gives the option to cancel the request on sign in' do allow(IdentityConfig.store).to receive(:otp_delivery_blocklist_maxretry).and_return(999) diff --git a/spec/features/device_tracking_spec.rb b/spec/features/device_tracking_spec.rb index af02ba5a64b..0e3795e8b0f 100644 --- a/spec/features/device_tracking_spec.rb +++ b/spec/features/device_tracking_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Device tracking' do +RSpec.describe 'Device tracking', allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered) } let(:now) { Time.zone.now } let(:device) { create(:device, user: user, last_ip: '4.3.2.1', last_used_at: now) } diff --git a/spec/features/event_disavowal_spec.rb b/spec/features/event_disavowal_spec.rb index 41fc36ea09c..3aabe629d12 100644 --- a/spec/features/event_disavowal_spec.rb +++ b/spec/features/event_disavowal_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'disavowing an action' do +RSpec.feature 'disavowing an action', allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered, :with_personal_key) } scenario 'disavowing a password reset' do diff --git a/spec/features/ialmax/saml_sign_in_spec.rb b/spec/features/ialmax/saml_sign_in_spec.rb index cf6aa2a6545..9111adfb23e 100644 --- a/spec/features/ialmax/saml_sign_in_spec.rb +++ b/spec/features/ialmax/saml_sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML IALMAX sign in' do +RSpec.feature 'SAML IALMAX sign in', allowed_extra_analytics: [:*] do include SamlAuthHelper context 'with an ial2 SP' do diff --git a/spec/features/idv/account_creation_spec.rb b/spec/features/idv/account_creation_spec.rb index 76bf8d6fc12..ffb7475f902 100644 --- a/spec/features/idv/account_creation_spec.rb +++ b/spec/features/idv/account_creation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'IAL2 account creation' do +RSpec.describe 'IAL2 account creation', allowed_extra_analytics: [:*] do include IdvHelper include DocAuthHelper include SamlAuthHelper diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index ee5cf7e76f2..b68ae4480a6 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'csv' -RSpec.feature 'Analytics Regression', js: true do +RSpec.feature 'Analytics Regression', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include InPersonHelper diff --git a/spec/features/idv/cancel_spec.rb b/spec/features/idv/cancel_spec.rb index bdddde878f4..87b3c6f7593 100644 --- a/spec/features/idv/cancel_spec.rb +++ b/spec/features/idv/cancel_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'cancel IdV' do +RSpec.describe 'cancel IdV', allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper include InteractionHelper diff --git a/spec/features/idv/clearing_and_restarting_spec.rb b/spec/features/idv/clearing_and_restarting_spec.rb index 8e752b26ee4..a7e5915c625 100644 --- a/spec/features/idv/clearing_and_restarting_spec.rb +++ b/spec/features/idv/clearing_and_restarting_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'clearing IdV and restarting' do +RSpec.describe 'clearing IdV and restarting', allowed_extra_analytics: [:*] do include IdvStepHelper let(:user) { user_with_2fa } diff --git a/spec/features/idv/confirm_start_over_spec.rb b/spec/features/idv/confirm_start_over_spec.rb index 5d04e342c87..ab59f07e73f 100644 --- a/spec/features/idv/confirm_start_over_spec.rb +++ b/spec/features/idv/confirm_start_over_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'idv gpo confirm start over', js: true do +RSpec.feature 'idv gpo confirm start over', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper diff --git a/spec/features/idv/doc_auth/address_step_spec.rb b/spec/features/idv/doc_auth/address_step_spec.rb index ed8969a8409..0fa48a3299b 100644 --- a/spec/features/idv/doc_auth/address_step_spec.rb +++ b/spec/features/idv/doc_auth/address_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'doc auth verify step', :js do +RSpec.feature 'doc auth verify step', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper diff --git a/spec/features/idv/doc_auth/agreement_spec.rb b/spec/features/idv/doc_auth/agreement_spec.rb index 36222de0fab..37e06ce726d 100644 --- a/spec/features/idv/doc_auth/agreement_spec.rb +++ b/spec/features/idv/doc_auth/agreement_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'agreement step error checking' do +RSpec.feature 'agreement step error checking', allowed_extra_analytics: [:*] do include DocAuthHelper context 'skipping hybrid_handoff step', :js, driver: :headless_chrome_mobile do let(:fake_analytics) { FakeAnalytics.new } diff --git a/spec/features/idv/doc_auth/document_capture_spec.rb b/spec/features/idv/doc_auth/document_capture_spec.rb index 6c08f36450b..340aa1fdbb4 100644 --- a/spec/features/idv/doc_auth/document_capture_spec.rb +++ b/spec/features/idv/doc_auth/document_capture_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'document capture step', :js do +RSpec.feature 'document capture step', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper include DocCaptureHelper diff --git a/spec/features/idv/doc_auth/how_to_verify_spec.rb b/spec/features/idv/doc_auth/how_to_verify_spec.rb index 8b1b06cf1fa..10d1c157503 100644 --- a/spec/features/idv/doc_auth/how_to_verify_spec.rb +++ b/spec/features/idv/doc_auth/how_to_verify_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'how to verify step', js: true do +RSpec.feature 'how to verify step', js: true, allowed_extra_analytics: [:*] do include IdvHelper include DocAuthHelper diff --git a/spec/features/idv/doc_auth/hybrid_handoff_spec.rb b/spec/features/idv/doc_auth/hybrid_handoff_spec.rb index 6668c7aab95..53f1bbd5248 100644 --- a/spec/features/idv/doc_auth/hybrid_handoff_spec.rb +++ b/spec/features/idv/doc_auth/hybrid_handoff_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'hybrid_handoff step send link and errors' do +RSpec.feature 'hybrid_handoff step send link and errors', allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper include ActionView::Helpers::DateHelper diff --git a/spec/features/idv/doc_auth/link_sent_spec.rb b/spec/features/idv/doc_auth/link_sent_spec.rb index 82a5b0e76cc..a8ffd86fa08 100644 --- a/spec/features/idv/doc_auth/link_sent_spec.rb +++ b/spec/features/idv/doc_auth/link_sent_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'doc auth link sent step' do +RSpec.feature 'doc auth link sent step', allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper include DocCaptureHelper diff --git a/spec/features/idv/doc_auth/redo_document_capture_spec.rb b/spec/features/idv/doc_auth/redo_document_capture_spec.rb index 2bd63a927cf..fae43a730d8 100644 --- a/spec/features/idv/doc_auth/redo_document_capture_spec.rb +++ b/spec/features/idv/doc_auth/redo_document_capture_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'doc auth redo document capture', js: true do +RSpec.feature 'doc auth redo document capture', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper include DocCaptureHelper @@ -186,6 +186,8 @@ complete_doc_auth_steps_before_document_capture_step mock_doc_auth_trueid_http_non2xx_status(438) attach_and_submit_images + # verify it's a network error + expect(page).to have_content(I18n.t('doc_auth.errors.general.network_error')) click_try_again end @@ -199,6 +201,8 @@ complete_doc_auth_steps_before_document_capture_step mock_doc_auth_trueid_http_non2xx_status(500) attach_and_submit_images + # verify it's a network error + expect(page).to have_content(I18n.t('doc_auth.errors.general.network_error')) click_try_again end it_behaves_like 'image re-upload allowed' diff --git a/spec/features/idv/doc_auth/ssn_step_spec.rb b/spec/features/idv/doc_auth/ssn_step_spec.rb index e71d256f10e..36c5388e991 100644 --- a/spec/features/idv/doc_auth/ssn_step_spec.rb +++ b/spec/features/idv/doc_auth/ssn_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'ssn step mock proofer', :js do +RSpec.feature 'ssn step mock proofer', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper diff --git a/spec/features/idv/doc_auth/test_credentials_spec.rb b/spec/features/idv/doc_auth/test_credentials_spec.rb index 849236666e8..0a23423ab07 100644 --- a/spec/features/idv/doc_auth/test_credentials_spec.rb +++ b/spec/features/idv/doc_auth/test_credentials_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'doc auth test credentials', :js do +RSpec.feature 'doc auth test credentials', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper diff --git a/spec/features/idv/doc_auth/verify_info_step_spec.rb b/spec/features/idv/doc_auth/verify_info_step_spec.rb index 533a9c96fd0..18b728c952e 100644 --- a/spec/features/idv/doc_auth/verify_info_step_spec.rb +++ b/spec/features/idv/doc_auth/verify_info_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'verify_info step and verify_info_concern', :js do +RSpec.feature 'verify_info step and verify_info_concern', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include DocAuthHelper diff --git a/spec/features/idv/doc_auth/welcome_spec.rb b/spec/features/idv/doc_auth/welcome_spec.rb index dd94e83f215..2b4c4ac186a 100644 --- a/spec/features/idv/doc_auth/welcome_spec.rb +++ b/spec/features/idv/doc_auth/welcome_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'welcome step' do +RSpec.feature 'welcome step', allowed_extra_analytics: [:*] do include IdvHelper include DocAuthHelper diff --git a/spec/features/idv/end_to_end_idv_spec.rb b/spec/features/idv/end_to_end_idv_spec.rb index 778fc1d7462..397021e9937 100644 --- a/spec/features/idv/end_to_end_idv_spec.rb +++ b/spec/features/idv/end_to_end_idv_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Identity verification', :js do +RSpec.describe 'Identity verification', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include InPersonHelper diff --git a/spec/features/idv/gpo_disabled_spec.rb b/spec/features/idv/gpo_disabled_spec.rb index ba63a1a8912..322ed785490 100644 --- a/spec/features/idv/gpo_disabled_spec.rb +++ b/spec/features/idv/gpo_disabled_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'disabling GPO address verification' do +RSpec.feature 'disabling GPO address verification', allowed_extra_analytics: [:*] do include IdvStepHelper context 'with GPO address verification disabled' do diff --git a/spec/features/idv/hybrid_mobile/entry_spec.rb b/spec/features/idv/hybrid_mobile/entry_spec.rb index c7ea02d73da..1bafd59bf40 100644 --- a/spec/features/idv/hybrid_mobile/entry_spec.rb +++ b/spec/features/idv/hybrid_mobile/entry_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'mobile hybrid flow entry', js: true do +RSpec.feature 'mobile hybrid flow entry', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper let(:link_sent_via_sms) do diff --git a/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb b/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb index 48ca2240ab5..fb39426ece8 100644 --- a/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb +++ b/spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Hybrid Flow', :allow_net_connect_on_start do +RSpec.describe 'Hybrid Flow', :allow_net_connect_on_start, allowed_extra_analytics: [:*] do include IdvHelper include IdvStepHelper include DocAuthHelper diff --git a/spec/features/idv/in_person_spec.rb b/spec/features/idv/in_person_spec.rb index 2b53b94c834..9b167c6ed4c 100644 --- a/spec/features/idv/in_person_spec.rb +++ b/spec/features/idv/in_person_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'axe-rspec' -RSpec.describe 'In Person Proofing', js: true do +RSpec.describe 'In Person Proofing', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include SpAuthHelper include InPersonHelper diff --git a/spec/features/idv/outage_spec.rb b/spec/features/idv/outage_spec.rb index 791ae9545e2..4258e9d900d 100644 --- a/spec/features/idv/outage_spec.rb +++ b/spec/features/idv/outage_spec.rb @@ -12,7 +12,7 @@ def sign_in_with_idv_required(user:, sms_or_totp: :sms) click_submit_default end -RSpec.feature 'IdV Outage Spec' do +RSpec.feature 'IdV Outage Spec', allowed_extra_analytics: [:*] do include PersonalKeyHelper include IdvStepHelper @@ -53,7 +53,7 @@ def sign_in_with_idv_required(user:, sms_or_totp: :sms) before do # Wire up various let()s to configuration keys vendors.each do |service| - vendor_status_key = "vendor_status_#{service}".to_sym + vendor_status_key = :"vendor_status_#{service}" allow(IdentityConfig.store).to receive(vendor_status_key). and_return(send(vendor_status_key)) end @@ -239,7 +239,7 @@ def sign_in_with_idv_required(user:, sms_or_totp: :sms) %w[acuant lexisnexis_instant_verify lexisnexis_trueid].each do |service| context "vendor_status_#{service} set to full_outage", js: true do - let("vendor_status_#{service}".to_sym) { :full_outage } + let(:"vendor_status_#{service}") { :full_outage } it_behaves_like 'IDV is unavailable' diff --git a/spec/features/idv/pending_profile_password_reset_spec.rb b/spec/features/idv/pending_profile_password_reset_spec.rb index bc42be34212..c9b994bad30 100644 --- a/spec/features/idv/pending_profile_password_reset_spec.rb +++ b/spec/features/idv/pending_profile_password_reset_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Resetting password with a pending profile' do +RSpec.describe 'Resetting password with a pending profile', allowed_extra_analytics: [:*] do include OidcAuthHelper let(:sp_name) { 'Test SP' } diff --git a/spec/features/idv/phone_errors_spec.rb b/spec/features/idv/phone_errors_spec.rb index f9f3d5cdf48..4b33e565e77 100644 --- a/spec/features/idv/phone_errors_spec.rb +++ b/spec/features/idv/phone_errors_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' -RSpec.feature 'phone errors', :js do +RSpec.feature 'phone errors', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include IdvHelper diff --git a/spec/features/idv/phone_input_spec.rb b/spec/features/idv/phone_input_spec.rb index 1dfcf9fc3c1..aa5e7ab07b1 100644 --- a/spec/features/idv/phone_input_spec.rb +++ b/spec/features/idv/phone_input_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'IdV phone number input', :js do +RSpec.feature 'IdV phone number input', :js, allowed_extra_analytics: [:*] do include IdvStepHelper before do diff --git a/spec/features/idv/phone_otp_rate_limiting_spec.rb b/spec/features/idv/phone_otp_rate_limiting_spec.rb index c5d3c14ba72..a1ccdce5b88 100644 --- a/spec/features/idv/phone_otp_rate_limiting_spec.rb +++ b/spec/features/idv/phone_otp_rate_limiting_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'phone otp rate limiting', :js do +RSpec.feature 'phone otp rate limiting', :js, allowed_extra_analytics: [:*] do include IdvStepHelper let(:user) { user_with_2fa } diff --git a/spec/features/idv/proof_address_rate_limit_spec.rb b/spec/features/idv/proof_address_rate_limit_spec.rb index f1605506b0e..52ed6b61ed6 100644 --- a/spec/features/idv/proof_address_rate_limit_spec.rb +++ b/spec/features/idv/proof_address_rate_limit_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'address proofing rate limit' do +RSpec.feature 'address proofing rate limit', allowed_extra_analytics: [:*] do include IdvStepHelper include IdvHelper diff --git a/spec/features/idv/proofing_components_spec.rb b/spec/features/idv/proofing_components_spec.rb index a12f58ad57f..9849497c69d 100644 --- a/spec/features/idv/proofing_components_spec.rb +++ b/spec/features/idv/proofing_components_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'proofing components' do +RSpec.describe 'proofing components', allowed_extra_analytics: [:*] do include DocAuthHelper include IdvHelper include SamlAuthHelper diff --git a/spec/features/idv/puerto_rican_address_spec.rb b/spec/features/idv/puerto_rican_address_spec.rb index 8bb24149a5b..fa57bae9717 100644 --- a/spec/features/idv/puerto_rican_address_spec.rb +++ b/spec/features/idv/puerto_rican_address_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'proofing flow with a Puerto Rican document', :js do +RSpec.describe 'proofing flow with a Puerto Rican document', :js, allowed_extra_analytics: [:*] do include DocAuthHelper include IdvStepHelper diff --git a/spec/features/idv/sp_handoff_spec.rb b/spec/features/idv/sp_handoff_spec.rb index e72e00cdf73..a9a6c8ece96 100644 --- a/spec/features/idv/sp_handoff_spec.rb +++ b/spec/features/idv/sp_handoff_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'IdV SP handoff', :email do +RSpec.feature 'IdV SP handoff', :email, allowed_extra_analytics: [:*] do include SamlAuthHelper include IdvStepHelper diff --git a/spec/features/idv/sp_requested_attributes_spec.rb b/spec/features/idv/sp_requested_attributes_spec.rb index 4140120f3fb..c8b1ef926e6 100644 --- a/spec/features/idv/sp_requested_attributes_spec.rb +++ b/spec/features/idv/sp_requested_attributes_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'sp requested IdV attributes', :email do +RSpec.feature 'sp requested IdV attributes', :email, allowed_extra_analytics: [:*] do context 'oidc' do it_behaves_like 'sp requesting attributes', :oidc end diff --git a/spec/features/idv/steps/enter_code_step_spec.rb b/spec/features/idv/steps/enter_code_step_spec.rb index 8692460b7d5..e588be2aa4d 100644 --- a/spec/features/idv/steps/enter_code_step_spec.rb +++ b/spec/features/idv/steps/enter_code_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'idv enter letter code step' do +RSpec.feature 'idv enter letter code step', allowed_extra_analytics: [:*] do include IdvStepHelper let(:otp) { 'ABC123' } diff --git a/spec/features/idv/steps/enter_password_step_spec.rb b/spec/features/idv/steps/enter_password_step_spec.rb index 4b73c10d855..b53a3e3c126 100644 --- a/spec/features/idv/steps/enter_password_step_spec.rb +++ b/spec/features/idv/steps/enter_password_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'idv enter password step', :js do +RSpec.feature 'idv enter password step', :js, allowed_extra_analytics: [:*] do include IdvStepHelper context 'choosing to confirm address with gpo' do diff --git a/spec/features/idv/steps/forgot_password_step_spec.rb b/spec/features/idv/steps/forgot_password_step_spec.rb index 91d8f18986e..67f66c84f9a 100644 --- a/spec/features/idv/steps/forgot_password_step_spec.rb +++ b/spec/features/idv/steps/forgot_password_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'forgot password step', :js do +RSpec.feature 'forgot password step', :js, allowed_extra_analytics: [:*] do include IdvStepHelper it 'goes to the forgot password page from the enter password page' do diff --git a/spec/features/idv/steps/in_person/address_spec.rb b/spec/features/idv/steps/in_person/address_spec.rb index 503965eb627..5d9f8e31593 100644 --- a/spec/features/idv/steps/in_person/address_spec.rb +++ b/spec/features/idv/steps/in_person/address_spec.rb @@ -1,6 +1,8 @@ require 'rails_helper' -RSpec.describe 'doc auth In person proofing residential address step', js: true do +RSpec.describe 'doc auth In person proofing residential address step', + js: true, + allowed_extra_analytics: [:*] do include IdvStepHelper include InPersonHelper diff --git a/spec/features/idv/steps/in_person/ssn_spec.rb b/spec/features/idv/steps/in_person/ssn_spec.rb index 31e35137481..364ba60dd80 100644 --- a/spec/features/idv/steps/in_person/ssn_spec.rb +++ b/spec/features/idv/steps/in_person/ssn_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'doc auth IPP ssn step', js: true do +RSpec.describe 'doc auth IPP ssn step', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include InPersonHelper diff --git a/spec/features/idv/steps/in_person/state_id_step_spec.rb b/spec/features/idv/steps/in_person/state_id_step_spec.rb index 3689d08a687..69c5ed42783 100644 --- a/spec/features/idv/steps/in_person/state_id_step_spec.rb +++ b/spec/features/idv/steps/in_person/state_id_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'doc auth IPP state ID step', js: true do +RSpec.describe 'doc auth IPP state ID step', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include InPersonHelper diff --git a/spec/features/idv/steps/in_person/verify_info_spec.rb b/spec/features/idv/steps/in_person/verify_info_spec.rb index 5bc85ffad17..ed6c547ad55 100644 --- a/spec/features/idv/steps/in_person/verify_info_spec.rb +++ b/spec/features/idv/steps/in_person/verify_info_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'axe-rspec' -RSpec.describe 'doc auth IPP VerifyInfo', js: true do +RSpec.describe 'doc auth IPP VerifyInfo', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include InPersonHelper diff --git a/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb b/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb index e87dd7c0d38..b8f3f6a1dff 100644 --- a/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb +++ b/spec/features/idv/steps/in_person_opt_in_ipp_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'axe-rspec' -RSpec.describe 'In Person Proofing - Opt-in IPP ', js: true do +RSpec.describe 'In Person Proofing - Opt-in IPP ', js: true, allowed_extra_analytics: [:*] do include IdvStepHelper include SpAuthHelper include InPersonHelper diff --git a/spec/features/idv/steps/phone_otp_verification_step_spec.rb b/spec/features/idv/steps/phone_otp_verification_step_spec.rb index 5b397d0fcfd..06420ce6e87 100644 --- a/spec/features/idv/steps/phone_otp_verification_step_spec.rb +++ b/spec/features/idv/steps/phone_otp_verification_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'phone otp verification step spec', :js do +RSpec.feature 'phone otp verification step spec', :js, allowed_extra_analytics: [:*] do include IdvStepHelper it 'requires the user to enter the correct otp before continuing' do diff --git a/spec/features/idv/steps/phone_step_spec.rb b/spec/features/idv/steps/phone_step_spec.rb index 0cc49fbda6f..a9e25ad98c7 100644 --- a/spec/features/idv/steps/phone_step_spec.rb +++ b/spec/features/idv/steps/phone_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'idv phone step', :js do +RSpec.feature 'idv phone step', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include IdvHelper diff --git a/spec/features/idv/steps/request_letter_step_spec.rb b/spec/features/idv/steps/request_letter_step_spec.rb index b6cf6938eb2..17c03d15e20 100644 --- a/spec/features/idv/steps/request_letter_step_spec.rb +++ b/spec/features/idv/steps/request_letter_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'idv request letter step' do +RSpec.feature 'idv request letter step', allowed_extra_analytics: [:*] do include IdvStepHelper include OidcAuthHelper diff --git a/spec/features/idv/threat_metrix_pending_spec.rb b/spec/features/idv/threat_metrix_pending_spec.rb index 8ba41abd991..2a00c7ba78e 100644 --- a/spec/features/idv/threat_metrix_pending_spec.rb +++ b/spec/features/idv/threat_metrix_pending_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Users pending ThreatMetrix review', :js do +RSpec.feature 'Users pending ThreatMetrix review', :js, allowed_extra_analytics: [:*] do include IdvStepHelper include OidcAuthHelper include IrsAttemptsApiTrackingHelper diff --git a/spec/features/idv/uak_password_spec.rb b/spec/features/idv/uak_password_spec.rb index 61bdbd335ee..ec66f31775e 100644 --- a/spec/features/idv/uak_password_spec.rb +++ b/spec/features/idv/uak_password_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'A user with a UAK passwords attempts IdV' do +RSpec.feature 'A user with a UAK passwords attempts IdV', allowed_extra_analytics: [:*] do include IdvStepHelper it 'allows the user to continue to the SP', js: true do diff --git a/spec/features/legacy_passwords_spec.rb b/spec/features/legacy_passwords_spec.rb index 44751d51310..9bf2bbf552b 100644 --- a/spec/features/legacy_passwords_spec.rb +++ b/spec/features/legacy_passwords_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'legacy passwords' do +RSpec.feature 'legacy passwords', allowed_extra_analytics: [:*] do scenario 'signing in with a password digested by the uak verifier updates the digest' do user = create(:user, :fully_registered) user.update!( diff --git a/spec/features/load_testing/email_sign_up_spec.rb b/spec/features/load_testing/email_sign_up_spec.rb index 62f3d1039de..f2b41c24919 100644 --- a/spec/features/load_testing/email_sign_up_spec.rb +++ b/spec/features/load_testing/email_sign_up_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Email sign up' do +RSpec.feature 'Email sign up', allowed_extra_analytics: [:*] do scenario 'Load testing feature is on' do allow(IdentityConfig.store).to receive(:enable_load_testing_mode).and_return(true) email = 'test@example.com' diff --git a/spec/features/multi_factor_authentication/mfa_cta_spec.rb b/spec/features/multi_factor_authentication/mfa_cta_spec.rb index b37dd57847f..ea529cb9187 100644 --- a/spec/features/multi_factor_authentication/mfa_cta_spec.rb +++ b/spec/features/multi_factor_authentication/mfa_cta_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'mfa cta banner' do +RSpec.feature 'mfa cta banner', allowed_extra_analytics: [:*] do include DocAuthHelper include SamlAuthHelper diff --git a/spec/features/multiple_emails/add_email_spec.rb b/spec/features/multiple_emails/add_email_spec.rb index 4cf06b60b1e..4c27b02aeff 100644 --- a/spec/features/multiple_emails/add_email_spec.rb +++ b/spec/features/multiple_emails/add_email_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'adding email address' do +RSpec.feature 'adding email address', allowed_extra_analytics: [:*] do let(:email) { 'test@test.com' } it 'allows the user to add an email and confirm with an active session' do diff --git a/spec/features/multiple_emails/email_management_spec.rb b/spec/features/multiple_emails/email_management_spec.rb index 4018460e401..e0620dfd6c6 100644 --- a/spec/features/multiple_emails/email_management_spec.rb +++ b/spec/features/multiple_emails/email_management_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'managing email address' do +RSpec.feature 'managing email address', allowed_extra_analytics: [:*] do context 'show one email address if only one is configured' do scenario 'shows one email address for a user with only one' do user = create(:user, :fully_registered, :with_multiple_emails) diff --git a/spec/features/multiple_emails/reset_password_spec.rb b/spec/features/multiple_emails/reset_password_spec.rb index 443478d8b9e..9199a201ca2 100644 --- a/spec/features/multiple_emails/reset_password_spec.rb +++ b/spec/features/multiple_emails/reset_password_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'reset password with multiple emails' do +RSpec.describe 'reset password with multiple emails', allowed_extra_analytics: [:*] do scenario 'it sends the reset instruction to the email the user enters' do user = create(:user, :with_multiple_emails) email1, email2 = user.reload.email_addresses.map(&:email) diff --git a/spec/features/multiple_emails/sign_in_spec.rb b/spec/features/multiple_emails/sign_in_spec.rb index e047eb50bbb..4a642b78ce6 100644 --- a/spec/features/multiple_emails/sign_in_spec.rb +++ b/spec/features/multiple_emails/sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'sign in with any email address' do +RSpec.feature 'sign in with any email address', allowed_extra_analytics: [:*] do scenario 'signing in with any email address' do user = create(:user, :fully_registered, :with_multiple_emails) diff --git a/spec/features/multiple_emails/sp_sign_in_spec.rb b/spec/features/multiple_emails/sp_sign_in_spec.rb index dbae13eb376..00daef7251b 100644 --- a/spec/features/multiple_emails/sp_sign_in_spec.rb +++ b/spec/features/multiple_emails/sp_sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'signing into an SP with multiple emails enabled' do +RSpec.feature 'signing into an SP with multiple emails enabled', allowed_extra_analytics: [:*] do include SamlAuthHelper include OidcAuthHelper diff --git a/spec/features/new_device_tracking_spec.rb b/spec/features/new_device_tracking_spec.rb index d4a35e0f83a..f96cf4ce5e1 100644 --- a/spec/features/new_device_tracking_spec.rb +++ b/spec/features/new_device_tracking_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'New device tracking' do +RSpec.describe 'New device tracking', allowed_extra_analytics: [:*] do include SamlAuthHelper let(:user) { create(:user, :fully_registered) } diff --git a/spec/features/openid_connect/authorization_confirmation_spec.rb b/spec/features/openid_connect/authorization_confirmation_spec.rb index 40e1aeccb17..15a4fbf8a91 100644 --- a/spec/features/openid_connect/authorization_confirmation_spec.rb +++ b/spec/features/openid_connect/authorization_confirmation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'OIDC Authorization Confirmation' do +RSpec.feature 'OIDC Authorization Confirmation', allowed_extra_analytics: [:*] do include OidcAuthHelper before do diff --git a/spec/features/openid_connect/openid_connect_spec.rb b/spec/features/openid_connect/openid_connect_spec.rb index b7b56b2e59e..907d281cf22 100644 --- a/spec/features/openid_connect/openid_connect_spec.rb +++ b/spec/features/openid_connect/openid_connect_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'query_tracker' -RSpec.describe 'OpenID Connect' do +RSpec.describe 'OpenID Connect', allowed_extra_analytics: [:*] do include IdvHelper include OidcAuthHelper include SamlAuthHelper diff --git a/spec/features/openid_connect/phishing_resistant_required_spec.rb b/spec/features/openid_connect/phishing_resistant_required_spec.rb index 45ed9cb2fd8..0bb2a5c3cbd 100644 --- a/spec/features/openid_connect/phishing_resistant_required_spec.rb +++ b/spec/features/openid_connect/phishing_resistant_required_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe 'Phishing-resistant authentication required in an OIDC context' do +RSpec.describe 'Phishing-resistant authentication required in an OIDC context', + allowed_extra_analytics: [:*] do include OidcAuthHelper include WebAuthnHelper diff --git a/spec/features/openid_connect/redirect_uri_validation_spec.rb b/spec/features/openid_connect/redirect_uri_validation_spec.rb index 9815881d9d1..17f76594690 100644 --- a/spec/features/openid_connect/redirect_uri_validation_spec.rb +++ b/spec/features/openid_connect/redirect_uri_validation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'redirect_uri validation' do +RSpec.describe 'redirect_uri validation', allowed_extra_analytics: [:*] do include OidcAuthHelper context 'when the redirect_uri in the request does not match one that is registered' do diff --git a/spec/features/phone/add_phone_spec.rb b/spec/features/phone/add_phone_spec.rb index 56b0ad11357..9ee08661408 100644 --- a/spec/features/phone/add_phone_spec.rb +++ b/spec/features/phone/add_phone_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Add a new phone number' do +RSpec.describe 'Add a new phone number', allowed_extra_analytics: [:*] do scenario 'Adding and confirming a new phone number allows the phone number to be used for MFA' do user = create(:user, :fully_registered) phone = '+1 (225) 278-1234' diff --git a/spec/features/phone/confirmation_spec.rb b/spec/features/phone/confirmation_spec.rb index 04478724e63..678cb6b5819 100644 --- a/spec/features/phone/confirmation_spec.rb +++ b/spec/features/phone/confirmation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'phone otp confirmation' do +RSpec.describe 'phone otp confirmation', allowed_extra_analytics: [:*] do let(:phone) { '2025551234' } let(:formatted_phone) { PhoneFormatter.format(phone) } diff --git a/spec/features/phone/default_phone_selection_spec.rb b/spec/features/phone/default_phone_selection_spec.rb index 40340bda191..f87c3e58cc2 100644 --- a/spec/features/phone/default_phone_selection_spec.rb +++ b/spec/features/phone/default_phone_selection_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'default phone selection' do +RSpec.describe 'default phone selection', allowed_extra_analytics: [:*] do let(:user) { create(:user, :with_phone) } let(:phone_config2) do create( diff --git a/spec/features/phone/edit_phone_spec.rb b/spec/features/phone/edit_phone_spec.rb index bf47084f1e1..b776d8420b3 100644 --- a/spec/features/phone/edit_phone_spec.rb +++ b/spec/features/phone/edit_phone_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'editing a phone' do +RSpec.describe 'editing a phone', allowed_extra_analytics: [:*] do it 'allows a user to edit one of their phone numbers' do user = create(:user, :fully_registered) phone_configuration = user.phone_configurations.first diff --git a/spec/features/phone/rate_limitting_spec.rb b/spec/features/phone/rate_limitting_spec.rb index a89b085ee98..cd98c6007e1 100644 --- a/spec/features/phone/rate_limitting_spec.rb +++ b/spec/features/phone/rate_limitting_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'phone rate limitting' do +RSpec.describe 'phone rate limitting', allowed_extra_analytics: [:*] do let(:phone) { '2025551234' } context 'on sign up' do diff --git a/spec/features/phone/remove_phone_spec.rb b/spec/features/phone/remove_phone_spec.rb index 292dc84e43f..9a688c1c8b7 100644 --- a/spec/features/phone/remove_phone_spec.rb +++ b/spec/features/phone/remove_phone_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'removing a phone number from an account' do +RSpec.feature 'removing a phone number from an account', allowed_extra_analytics: [:*] do scenario 'deleting a phone number' do user = create(:user, :fully_registered, :with_piv_or_cac) phone_configuration = user.phone_configurations.first diff --git a/spec/features/remember_device/cookie_expiration_spec.rb b/spec/features/remember_device/cookie_expiration_spec.rb index b5ca20f1c93..ea1b30e6bed 100644 --- a/spec/features/remember_device/cookie_expiration_spec.rb +++ b/spec/features/remember_device/cookie_expiration_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe 'signing in with remember device and closing browser' do +RSpec.describe 'signing in with remember device and closing browser', + allowed_extra_analytics: [:*] do include SamlAuthHelper let(:user) { user_with_2fa } diff --git a/spec/features/remember_device/phone_spec.rb b/spec/features/remember_device/phone_spec.rb index 5b16b37a8af..54e7bbbc8e9 100644 --- a/spec/features/remember_device/phone_spec.rb +++ b/spec/features/remember_device/phone_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Remembering a phone' do +RSpec.feature 'Remembering a phone', allowed_extra_analytics: [:*] do include IdvStepHelper before do diff --git a/spec/features/remember_device/revocation_spec.rb b/spec/features/remember_device/revocation_spec.rb index 1c83a366484..df8b654fced 100644 --- a/spec/features/remember_device/revocation_spec.rb +++ b/spec/features/remember_device/revocation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'taking an action that revokes remember device' do +RSpec.feature 'taking an action that revokes remember device', allowed_extra_analytics: [:*] do include NavigationHelper before do diff --git a/spec/features/remember_device/session_expiration_spec.rb b/spec/features/remember_device/session_expiration_spec.rb index 1fea732eb4d..664823fec24 100644 --- a/spec/features/remember_device/session_expiration_spec.rb +++ b/spec/features/remember_device/session_expiration_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe 'signing in with remember device and idling on the sign in page' do +RSpec.describe 'signing in with remember device and idling on the sign in page', + allowed_extra_analytics: [:*] do include SamlAuthHelper include OidcAuthHelper diff --git a/spec/features/remember_device/signed_in_sp_expiration_spec.rb b/spec/features/remember_device/signed_in_sp_expiration_spec.rb index 034cde39285..57246264d93 100644 --- a/spec/features/remember_device/signed_in_sp_expiration_spec.rb +++ b/spec/features/remember_device/signed_in_sp_expiration_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SP expiration while signed in' do +RSpec.feature 'SP expiration while signed in', allowed_extra_analytics: [:*] do include SamlAuthHelper ## diff --git a/spec/features/remember_device/sp_expiration_spec.rb b/spec/features/remember_device/sp_expiration_spec.rb index 99af39df96f..525a21008d4 100644 --- a/spec/features/remember_device/sp_expiration_spec.rb +++ b/spec/features/remember_device/sp_expiration_spec.rb @@ -83,7 +83,7 @@ def visit_sp(protocol, aal) end end -RSpec.feature 'remember device sp expiration' do +RSpec.feature 'remember device sp expiration', allowed_extra_analytics: [:*] do include SamlAuthHelper aal1_remember_device_expiration = diff --git a/spec/features/remember_device/totp_spec.rb b/spec/features/remember_device/totp_spec.rb index f3de6d554bc..005f83b0600 100644 --- a/spec/features/remember_device/totp_spec.rb +++ b/spec/features/remember_device/totp_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Remembering a TOTP device' do +RSpec.describe 'Remembering a TOTP device', allowed_extra_analytics: [:*] do before do allow(IdentityConfig.store).to receive(:otp_delivery_blocklist_maxretry).and_return(1000) end diff --git a/spec/features/remember_device/user_opted_preference_spec.rb b/spec/features/remember_device/user_opted_preference_spec.rb index c6cee94e1cc..d163cc4bcb8 100644 --- a/spec/features/remember_device/user_opted_preference_spec.rb +++ b/spec/features/remember_device/user_opted_preference_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' # rubocop:disable Layout/LineLength -RSpec.describe 'Unchecking remember device' do +RSpec.describe 'Unchecking remember device', allowed_extra_analytics: [:*] do describe '2fa setup' do context 'when the 2fa is totp' do before do diff --git a/spec/features/remember_device/webauthn_spec.rb b/spec/features/remember_device/webauthn_spec.rb index 70d2ad62b85..316d560b349 100644 --- a/spec/features/remember_device/webauthn_spec.rb +++ b/spec/features/remember_device/webauthn_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Remembering a webauthn device' do +RSpec.describe 'Remembering a webauthn device', allowed_extra_analytics: [:*] do include WebAuthnHelper before do diff --git a/spec/features/reports/authorization_count_spec.rb b/spec/features/reports/authorization_count_spec.rb index a82067f5d68..44be18cd863 100644 --- a/spec/features/reports/authorization_count_spec.rb +++ b/spec/features/reports/authorization_count_spec.rb @@ -33,7 +33,7 @@ def visit_idp_from_ial2_saml_sp(issuer:) ) end -RSpec.describe 'authorization count' do +RSpec.describe 'authorization count', allowed_extra_analytics: [:*] do include IdvFromSpHelper include OidcAuthHelper include DocAuthHelper diff --git a/spec/features/reports/monthly_gpo_letter_requests_report_spec.rb b/spec/features/reports/monthly_gpo_letter_requests_report_spec.rb index 8498508cd2c..4503e0ce51d 100644 --- a/spec/features/reports/monthly_gpo_letter_requests_report_spec.rb +++ b/spec/features/reports/monthly_gpo_letter_requests_report_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Monthly gpo letter requests report' do +RSpec.feature 'Monthly gpo letter requests report', allowed_extra_analytics: [:*] do it 'runs when there are not entries' do results_hash = JSON.parse(Reports::MonthlyGpoLetterRequestsReport.new.perform(Time.zone.today)) expect(results_hash['total_letter_requests']).to eq(0) diff --git a/spec/features/reports/sp_active_users_report_spec.rb b/spec/features/reports/sp_active_users_report_spec.rb index caae13a6856..663db74a256 100644 --- a/spec/features/reports/sp_active_users_report_spec.rb +++ b/spec/features/reports/sp_active_users_report_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'sp active users report' do +RSpec.feature 'sp active users report', allowed_extra_analytics: [:*] do include SamlAuthHelper include OidcAuthHelper include IdvHelper diff --git a/spec/features/saml/authorization_confirmation_spec.rb b/spec/features/saml/authorization_confirmation_spec.rb index a9e075f2ad6..9771877c953 100644 --- a/spec/features/saml/authorization_confirmation_spec.rb +++ b/spec/features/saml/authorization_confirmation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML Authorization Confirmation' do +RSpec.feature 'SAML Authorization Confirmation', allowed_extra_analytics: [:*] do include SamlAuthHelper before do diff --git a/spec/features/saml/ial1/account_creation_spec.rb b/spec/features/saml/ial1/account_creation_spec.rb index 34f0d952511..5db52287217 100644 --- a/spec/features/saml/ial1/account_creation_spec.rb +++ b/spec/features/saml/ial1/account_creation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Canceling Account Creation' do +RSpec.feature 'Canceling Account Creation', allowed_extra_analytics: [:*] do include SamlAuthHelper context 'From the enter email page', email: true do diff --git a/spec/features/saml/ial1_sso_spec.rb b/spec/features/saml/ial1_sso_spec.rb index e2ca596dfe9..24a49e5fa04 100644 --- a/spec/features/saml/ial1_sso_spec.rb +++ b/spec/features/saml/ial1_sso_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'IAL1 Single Sign On' do +RSpec.feature 'IAL1 Single Sign On', allowed_extra_analytics: [:*] do include SamlAuthHelper context 'First time registration', email: true do diff --git a/spec/features/saml/ial2_sso_spec.rb b/spec/features/saml/ial2_sso_spec.rb index 137f98b68a5..e1367a68579 100644 --- a/spec/features/saml/ial2_sso_spec.rb +++ b/spec/features/saml/ial2_sso_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'IAL2 Single Sign On' do +RSpec.feature 'IAL2 Single Sign On', allowed_extra_analytics: [:*] do include SamlAuthHelper include IdvStepHelper include DocAuthHelper diff --git a/spec/features/saml/multiple_endpoints_spec.rb b/spec/features/saml/multiple_endpoints_spec.rb index 1cd42bcfba9..6d5e92fca62 100644 --- a/spec/features/saml/multiple_endpoints_spec.rb +++ b/spec/features/saml/multiple_endpoints_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'multiple saml endpoints' do +RSpec.describe 'multiple saml endpoints', allowed_extra_analytics: [:*] do include SamlAuthHelper include IdvHelper diff --git a/spec/features/saml/phishing_resistant_required_spec.rb b/spec/features/saml/phishing_resistant_required_spec.rb index 329dddd5709..8221c039731 100644 --- a/spec/features/saml/phishing_resistant_required_spec.rb +++ b/spec/features/saml/phishing_resistant_required_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe 'Phishing-resistant authentication required in an SAML context' do +RSpec.describe 'Phishing-resistant authentication required in an SAML context', + allowed_extra_analytics: [:*] do include SamlAuthHelper include WebAuthnHelper diff --git a/spec/features/saml/redirect_uri_validation_spec.rb b/spec/features/saml/redirect_uri_validation_spec.rb index 1677f6c0eac..71c09e9fcb6 100644 --- a/spec/features/saml/redirect_uri_validation_spec.rb +++ b/spec/features/saml/redirect_uri_validation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'redirect_uri validation' do +RSpec.describe 'redirect_uri validation', allowed_extra_analytics: [:*] do include SamlAuthHelper context 'when redirect_uri param is included in SAML request' do diff --git a/spec/features/saml/saml_logout_spec.rb b/spec/features/saml/saml_logout_spec.rb index a0d483596a1..d8e000f9365 100644 --- a/spec/features/saml/saml_logout_spec.rb +++ b/spec/features/saml/saml_logout_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML logout' do +RSpec.feature 'SAML logout', allowed_extra_analytics: [:*] do include SamlAuthHelper let(:user) { create(:user, :fully_registered) } diff --git a/spec/features/saml/saml_relay_state_spec.rb b/spec/features/saml/saml_relay_state_spec.rb index 4c4293d78ca..0081a5b53e7 100644 --- a/spec/features/saml/saml_relay_state_spec.rb +++ b/spec/features/saml/saml_relay_state_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SAML RelayState' do +RSpec.feature 'SAML RelayState', allowed_extra_analytics: [:*] do include SamlAuthHelper context 'when RelayState is passed in authn request' do diff --git a/spec/features/saml/saml_spec.rb b/spec/features/saml/saml_spec.rb index a8870235201..d00093f67e8 100644 --- a/spec/features/saml/saml_spec.rb +++ b/spec/features/saml/saml_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'saml api' do +RSpec.feature 'saml api', allowed_extra_analytics: [:*] do include SamlAuthHelper include IdvHelper diff --git a/spec/features/session/decryption_spec.rb b/spec/features/session/decryption_spec.rb index 6e63e80a5d1..b961d076b03 100644 --- a/spec/features/session/decryption_spec.rb +++ b/spec/features/session/decryption_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Session decryption' do +RSpec.feature 'Session decryption', allowed_extra_analytics: [:*] do context 'when there is a session decryption error' do it 'should raise an error and log the user out' do sign_in_and_2fa_user diff --git a/spec/features/session/timeout_spec.rb b/spec/features/session/timeout_spec.rb index 789db94b387..4468dd481b3 100644 --- a/spec/features/session/timeout_spec.rb +++ b/spec/features/session/timeout_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Session Timeout' do +RSpec.feature 'Session Timeout', allowed_extra_analytics: [:*] do context 'when SP info no longer in session but request_id params exists' do it 'preserves the branded experience' do issuer = 'http://localhost:3000' diff --git a/spec/features/sign_in/banned_users_spec.rb b/spec/features/sign_in/banned_users_spec.rb index aecb624ae3a..3d745b607fb 100644 --- a/spec/features/sign_in/banned_users_spec.rb +++ b/spec/features/sign_in/banned_users_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Banning users for an SP' do +RSpec.feature 'Banning users for an SP', allowed_extra_analytics: [:*] do include SamlAuthHelper include OidcAuthHelper diff --git a/spec/features/sign_in/remember_device_default_spec.rb b/spec/features/sign_in/remember_device_default_spec.rb index 6679e98eca3..933759d99ff 100644 --- a/spec/features/sign_in/remember_device_default_spec.rb +++ b/spec/features/sign_in/remember_device_default_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'Remember device checkbox' do +RSpec.describe 'Remember device checkbox', allowed_extra_analytics: [:*] do include SamlAuthHelper context 'when the user signs in and arrives at the 2FA page' do diff --git a/spec/features/sign_in/sp_return_log_spec.rb b/spec/features/sign_in/sp_return_log_spec.rb index 93e7b185515..cdf0d48e8e3 100644 --- a/spec/features/sign_in/sp_return_log_spec.rb +++ b/spec/features/sign_in/sp_return_log_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SP return logs' do +RSpec.feature 'SP return logs', allowed_extra_analytics: [:*] do include SamlAuthHelper it 'updates user id after user authenticates so we can track any user back to issuer', :email do diff --git a/spec/features/sign_in/two_factor_options_spec.rb b/spec/features/sign_in/two_factor_options_spec.rb index 3650b4c9ea2..4f75f432b97 100644 --- a/spec/features/sign_in/two_factor_options_spec.rb +++ b/spec/features/sign_in/two_factor_options_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'when using PIV/CAC to sign in' do +RSpec.describe 'when using PIV/CAC to sign in', allowed_extra_analytics: [:*] do let(:user) { user_with_piv_cac } it 'does not show any MFA options' do @@ -9,7 +9,7 @@ end end -RSpec.describe '2FA options when signing in' do +RSpec.describe '2FA options when signing in', allowed_extra_analytics: [:*] do context 'when the user only has SMS configured' do it 'only displays SMS and Voice' do user = create(:user, :fully_registered, otp_delivery_preference: 'sms') diff --git a/spec/features/sp_cost_tracking_spec.rb b/spec/features/sp_cost_tracking_spec.rb index 38b908e6baf..9f5b0df8cbe 100644 --- a/spec/features/sp_cost_tracking_spec.rb +++ b/spec/features/sp_cost_tracking_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'SP Costing', :email do +RSpec.feature 'SP Costing', :email, allowed_extra_analytics: [:*] do include SpAuthHelper include SamlAuthHelper include IdvHelper diff --git a/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb b/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb index c7e03919a7f..f374cd512c0 100644 --- a/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb +++ b/spec/features/two_factor_authentication/backup_code_sign_up_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'sign up with backup code' do +RSpec.feature 'sign up with backup code', allowed_extra_analytics: [:*] do include DocAuthHelper include SamlAuthHelper diff --git a/spec/features/two_factor_authentication/change_factor_spec.rb b/spec/features/two_factor_authentication/change_factor_spec.rb index 1d49e668fcd..d1260108e04 100644 --- a/spec/features/two_factor_authentication/change_factor_spec.rb +++ b/spec/features/two_factor_authentication/change_factor_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Changing authentication factor' do +RSpec.feature 'Changing authentication factor', allowed_extra_analytics: [:*] do describe 'requires re-authenticating' do let(:user) { sign_up_and_2fa_ial1_user } diff --git a/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb b/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb index decc74817e7..7d1ef719e98 100644 --- a/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb +++ b/spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Multi Two Factor Authentication' do +RSpec.feature 'Multi Two Factor Authentication', allowed_extra_analytics: [:*] do include WebAuthnHelper describe 'When the user has not set up 2FA' do diff --git a/spec/features/two_factor_authentication/multiple_tabs_spec.rb b/spec/features/two_factor_authentication/multiple_tabs_spec.rb index f8bb55bdef0..2644baef556 100644 --- a/spec/features/two_factor_authentication/multiple_tabs_spec.rb +++ b/spec/features/two_factor_authentication/multiple_tabs_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.feature 'user interacts with 2FA across multiple browser tabs' do +RSpec.feature 'user interacts with 2FA across multiple browser tabs', + allowed_extra_analytics: [:*] do include SpAuthHelper include SamlAuthHelper diff --git a/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb b/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb index b2d15ec3e93..434261f55b8 100644 --- a/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb +++ b/spec/features/two_factor_authentication/second_mfa_reminder_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Second MFA Reminder' do +RSpec.feature 'Second MFA Reminder', allowed_extra_analytics: [:*] do include OidcAuthHelper let(:service_provider) { ServiceProvider.find_by(issuer: OidcAuthHelper::OIDC_IAL1_ISSUER) } diff --git a/spec/features/two_factor_authentication/sign_in_spec.rb b/spec/features/two_factor_authentication/sign_in_spec.rb index 56a86cf4b21..d635017367b 100644 --- a/spec/features/two_factor_authentication/sign_in_spec.rb +++ b/spec/features/two_factor_authentication/sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Two Factor Authentication' do +RSpec.feature 'Two Factor Authentication', allowed_extra_analytics: [:*] do describe 'When the user has not set up 2FA' do scenario 'user is prompted to set up two factor authentication at account creation' do user = sign_in_before_2fa diff --git a/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb b/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb index 986ef899a32..9622afd5071 100644 --- a/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb +++ b/spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Signing in via one-time use personal key' do +RSpec.feature 'Signing in via one-time use personal key', allowed_extra_analytics: [:*] do it 'destroys old key, does not offer new one' do user = create( :user, :fully_registered, :with_phone, :with_personal_key, diff --git a/spec/features/users/password_recovery_via_recovery_code_spec.rb b/spec/features/users/password_recovery_via_recovery_code_spec.rb index f4ac1cf8fa8..ec68610d145 100644 --- a/spec/features/users/password_recovery_via_recovery_code_spec.rb +++ b/spec/features/users/password_recovery_via_recovery_code_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Password recovery via personal key' do +RSpec.feature 'Password recovery via personal key', allowed_extra_analytics: [:*] do include PersonalKeyHelper include IdvStepHelper include SamlAuthHelper diff --git a/spec/features/users/password_reset_with_pending_profile_spec.rb b/spec/features/users/password_reset_with_pending_profile_spec.rb index 84ab1af904d..5518b59ca71 100644 --- a/spec/features/users/password_reset_with_pending_profile_spec.rb +++ b/spec/features/users/password_reset_with_pending_profile_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'reset password with pending profile' do +RSpec.feature 'reset password with pending profile', allowed_extra_analytics: [:*] do include PersonalKeyHelper let(:user) { create(:user, :fully_registered) } diff --git a/spec/features/users/piv_cac_management_spec.rb b/spec/features/users/piv_cac_management_spec.rb index 26ea4315e19..7ff12100047 100644 --- a/spec/features/users/piv_cac_management_spec.rb +++ b/spec/features/users/piv_cac_management_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'PIV/CAC Management' do +RSpec.feature 'PIV/CAC Management', allowed_extra_analytics: [:*] do def find_form(page, attributes) page.all('form').detect do |form| attributes.all? { |key, value| form[key] == value } diff --git a/spec/features/users/profile_recovery_for_gpo_verified_spec.rb b/spec/features/users/profile_recovery_for_gpo_verified_spec.rb index d260e4e0d50..81d664d1f96 100644 --- a/spec/features/users/profile_recovery_for_gpo_verified_spec.rb +++ b/spec/features/users/profile_recovery_for_gpo_verified_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.feature 'Password recovery via personal key for a GPO-verified user' do +RSpec.feature 'Password recovery via personal key for a GPO-verified user', + allowed_extra_analytics: [:*] do include IdvStepHelper let(:email) { 'cool_beagle@example.org' } diff --git a/spec/features/users/regenerate_personal_key_spec.rb b/spec/features/users/regenerate_personal_key_spec.rb index 822f7f1a452..37a66d43164 100644 --- a/spec/features/users/regenerate_personal_key_spec.rb +++ b/spec/features/users/regenerate_personal_key_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'View personal key' do +RSpec.feature 'View personal key', allowed_extra_analytics: [:*] do include XPathHelper include PersonalKeyHelper include SamlAuthHelper diff --git a/spec/features/users/sign_in_spec.rb b/spec/features/users/sign_in_spec.rb index 2b0dcc3ba62..c5c8251ecae 100644 --- a/spec/features/users/sign_in_spec.rb +++ b/spec/features/users/sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Sign in' do +RSpec.feature 'Sign in', allowed_extra_analytics: [:*] do include SessionTimeoutWarningHelper include ActionView::Helpers::DateHelper include PersonalKeyHelper diff --git a/spec/features/users/sign_out_spec.rb b/spec/features/users/sign_out_spec.rb index b23c74ac240..10debc852a5 100644 --- a/spec/features/users/sign_out_spec.rb +++ b/spec/features/users/sign_out_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Sign out' do +RSpec.feature 'Sign out', allowed_extra_analytics: [:*] do scenario 'user signs out successfully' do sign_in_and_2fa_user click_button(t('links.sign_out'), match: :first) diff --git a/spec/features/users/sign_up_spec.rb b/spec/features/users/sign_up_spec.rb index 8ac814fe613..8df50751872 100644 --- a/spec/features/users/sign_up_spec.rb +++ b/spec/features/users/sign_up_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Sign Up' do +RSpec.feature 'Sign Up', allowed_extra_analytics: [:*] do include SamlAuthHelper include OidcAuthHelper include DocAuthHelper diff --git a/spec/features/users/totp_management_spec.rb b/spec/features/users/totp_management_spec.rb index 49b43395fb2..ca400b234a9 100644 --- a/spec/features/users/totp_management_spec.rb +++ b/spec/features/users/totp_management_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'totp management' do +RSpec.describe 'totp management', allowed_extra_analytics: [:*] do context 'when the user has totp enabled' do let(:user) { create(:user, :fully_registered, :with_authentication_app) } diff --git a/spec/features/users/user_edit_spec.rb b/spec/features/users/user_edit_spec.rb index f59179ed579..9d7b61fca39 100644 --- a/spec/features/users/user_edit_spec.rb +++ b/spec/features/users/user_edit_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'User edit' do +RSpec.feature 'User edit', allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered) } context 'editing password' do diff --git a/spec/features/users/user_profile_spec.rb b/spec/features/users/user_profile_spec.rb index edc060d8b99..5f92e87a97d 100644 --- a/spec/features/users/user_profile_spec.rb +++ b/spec/features/users/user_profile_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'User profile' do +RSpec.feature 'User profile', allowed_extra_analytics: [:*] do include IdvStepHelper include NavigationHelper include PersonalKeyHelper diff --git a/spec/features/users/verify_profile_spec.rb b/spec/features/users/verify_profile_spec.rb index b201f4db785..2dd3240bff8 100644 --- a/spec/features/users/verify_profile_spec.rb +++ b/spec/features/users/verify_profile_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'verify profile with OTP' do +RSpec.feature 'verify profile with OTP', allowed_extra_analytics: [:*] do include IdvStepHelper let(:user) { create(:user, :fully_registered) } diff --git a/spec/features/visitors/bad_password_spec.rb b/spec/features/visitors/bad_password_spec.rb index 7c93b499149..fdeccbf9188 100644 --- a/spec/features/visitors/bad_password_spec.rb +++ b/spec/features/visitors/bad_password_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.feature 'Visitor signs in with bad passwords and gets locked out' do +RSpec.feature 'Visitor signs in with bad passwords and gets locked out', + allowed_extra_analytics: [:*] do let(:bad_email) { 'bad@email.com' } let(:bad_password) { 'badpassword' } diff --git a/spec/features/visitors/email_confirmation_spec.rb b/spec/features/visitors/email_confirmation_spec.rb index 5b243d5e2c8..9e86c14bc27 100644 --- a/spec/features/visitors/email_confirmation_spec.rb +++ b/spec/features/visitors/email_confirmation_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Email confirmation during sign up' do +RSpec.feature 'Email confirmation during sign up', allowed_extra_analytics: [:*] do scenario 'confirms valid email and sets valid password' do allow(IdentityConfig.store).to receive(:participate_in_dap).and_return(true) reset_email diff --git a/spec/features/visitors/email_language_preference_spec.rb b/spec/features/visitors/email_language_preference_spec.rb index cf45ee6d841..dba37c98f64 100644 --- a/spec/features/visitors/email_language_preference_spec.rb +++ b/spec/features/visitors/email_language_preference_spec.rb @@ -27,7 +27,7 @@ end end - it 'sends emails in the selected language' do + it 'sends emails in the selected language', allowed_extra_analytics: [:*] do email = 'test@example.com' visit sign_up_email_path diff --git a/spec/features/visitors/i18n_spec.rb b/spec/features/visitors/i18n_spec.rb index f02559428b2..6b56244932e 100644 --- a/spec/features/visitors/i18n_spec.rb +++ b/spec/features/visitors/i18n_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Internationalization' do +RSpec.feature 'Internationalization', allowed_extra_analytics: [:*] do context 'visit homepage with no locale set' do it 'displays a header in the default locale' do visit root_path diff --git a/spec/features/visitors/password_recovery_spec.rb b/spec/features/visitors/password_recovery_spec.rb index 80ce19fb844..39254b4a36a 100644 --- a/spec/features/visitors/password_recovery_spec.rb +++ b/spec/features/visitors/password_recovery_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Password Recovery' do +RSpec.feature 'Password Recovery', allowed_extra_analytics: [:*] do include IdvHelper include PersonalKeyHelper include SamlAuthHelper diff --git a/spec/features/visitors/resend_email_confirmation_spec.rb b/spec/features/visitors/resend_email_confirmation_spec.rb index 74804aa7e01..9864029c032 100644 --- a/spec/features/visitors/resend_email_confirmation_spec.rb +++ b/spec/features/visitors/resend_email_confirmation_spec.rb @@ -1,7 +1,8 @@ require 'rails_helper' require 'email_spec' -RSpec.feature 'Visit requests confirmation instructions again during sign up' do +RSpec.feature 'Visit requests confirmation instructions again during sign up', + allowed_extra_analytics: [:*] do include(EmailSpec::Helpers) include(EmailSpec::Matchers) diff --git a/spec/features/visitors/set_password_spec.rb b/spec/features/visitors/set_password_spec.rb index 6c7edfe9d99..a0f92e90f2e 100644 --- a/spec/features/visitors/set_password_spec.rb +++ b/spec/features/visitors/set_password_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Visitor sets password during signup' do +RSpec.feature 'Visitor sets password during signup', allowed_extra_analytics: [:*] do scenario 'visitor is redirected back to password form when password is blank' do create(:user, :unconfirmed) confirm_last_user diff --git a/spec/features/visitors/sign_up_with_email_spec.rb b/spec/features/visitors/sign_up_with_email_spec.rb index 409b324821f..1459feb84b5 100644 --- a/spec/features/visitors/sign_up_with_email_spec.rb +++ b/spec/features/visitors/sign_up_with_email_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'Visitor signs up with email address' do +RSpec.feature 'Visitor signs up with email address', allowed_extra_analytics: [:*] do scenario 'visitor can sign up with valid email address' do email = 'test@example.com' sign_up_with(email) diff --git a/spec/features/webauthn/hidden_spec.rb b/spec/features/webauthn/hidden_spec.rb index 7b1f67bae47..6a2c0f43436 100644 --- a/spec/features/webauthn/hidden_spec.rb +++ b/spec/features/webauthn/hidden_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'webauthn hide' do +RSpec.describe 'webauthn hide', allowed_extra_analytics: [:*] do include JavascriptDriverHelper include WebAuthnHelper diff --git a/spec/features/webauthn/management_spec.rb b/spec/features/webauthn/management_spec.rb index 20e91e42226..8517527cae2 100644 --- a/spec/features/webauthn/management_spec.rb +++ b/spec/features/webauthn/management_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'webauthn management' do +RSpec.describe 'webauthn management', allowed_extra_analytics: [:*] do include WebAuthnHelper let(:user) { create(:user, :fully_registered, with: { phone: '+1 202-555-1212' }) } diff --git a/spec/features/webauthn/sign_in_spec.rb b/spec/features/webauthn/sign_in_spec.rb index 69f86e4c0fc..117bd7d8407 100644 --- a/spec/features/webauthn/sign_in_spec.rb +++ b/spec/features/webauthn/sign_in_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'webauthn sign in' do +RSpec.feature 'webauthn sign in', allowed_extra_analytics: [:*] do include WebAuthnHelper before do diff --git a/spec/features/webauthn/sign_up_spec.rb b/spec/features/webauthn/sign_up_spec.rb index a2a68ffe5a5..64a31c370fd 100644 --- a/spec/features/webauthn/sign_up_spec.rb +++ b/spec/features/webauthn/sign_up_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.feature 'webauthn sign up' do +RSpec.feature 'webauthn sign up', allowed_extra_analytics: [:*] do include OidcAuthHelper include WebAuthnHelper diff --git a/spec/forms/gpo_verify_form_spec.rb b/spec/forms/gpo_verify_form_spec.rb index 8f87d03ff51..a012923a40b 100644 --- a/spec/forms/gpo_verify_form_spec.rb +++ b/spec/forms/gpo_verify_form_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe GpoVerifyForm do +RSpec.describe GpoVerifyForm, allowed_extra_analytics: [:*] do subject(:form) do GpoVerifyForm.new(user: user, pii: applicant, otp: entered_otp) end diff --git a/spec/forms/idv/api_image_upload_form_spec.rb b/spec/forms/idv/api_image_upload_form_spec.rb index cfd292b4090..ad79ed7cf8b 100644 --- a/spec/forms/idv/api_image_upload_form_spec.rb +++ b/spec/forms/idv/api_image_upload_form_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::ApiImageUploadForm do +RSpec.describe Idv::ApiImageUploadForm, allowed_extra_analytics: [:*] do include DocPiiHelper subject(:form) do @@ -132,6 +132,8 @@ async: false, attempts: 1, attention_with_barcode: false, + address_line2_present: nil, + alert_failure_count: nil, billed: true, client_image_metrics: { back: { @@ -147,7 +149,10 @@ width: 40, }, }, + image_metrics: nil, + conversation_id: nil, doc_auth_result: 'Passed', + decision_product_status: nil, errors: {}, exception: nil, flow_path: anything, @@ -161,10 +166,19 @@ back_image_fingerprint: an_instance_of(String), doc_type_supported: boolean, liveness_checking_required: boolean, + log_alert_results: nil, + portrait_match_results: nil, + processed_alerts: nil, + product_status: nil, + reference: nil, selfie_live: boolean, selfie_quality_good: boolean, + selfie_success: nil, doc_auth_success: boolean, selfie_status: anything, + vendor: nil, + transaction_status: nil, + transaction_reason_code: nil, ) end @@ -268,8 +282,10 @@ extra: { remaining_attempts: IdentityConfig.store.doc_auth_max_attempts - 1 }, ) end + let(:doc_auth_client) { double(DocAuth::LexisNexis::LexisNexisClient) } before do - allow(subject).to receive(:post_images_to_client).and_return(failed_response) + subject.instance_variable_set(:@doc_auth_client, doc_auth_client) + allow(doc_auth_client).to receive(:post_images) { failed_response } end it 'is not successful' do @@ -279,6 +295,7 @@ expect(response.success?).to eq(false) expect(response.attention_with_barcode?).to eq(false) expect(response.pii_from_doc).to eq({}) + expect(response.doc_auth_success?).to eq(false) end it 'includes remaining_attempts' do @@ -300,6 +317,24 @@ expect(response.errors).to have_key(:front) expect(response.errors).to have_value([I18n.t('doc_auth.errors.doc.resubmit_failed_image')]) end + + it 'logs analytics event' do + form.submit + expect(fake_analytics).to have_logged_event( + 'IdV: doc auth image upload vendor submitted', + hash_including( + doc_auth_result: nil, + errors: { front: 'glare' }, + success: false, + doc_type_supported: boolean, + doc_auth_success: boolean, + liveness_checking_required: boolean, + selfie_status: :not_processed, + selfie_live: boolean, + selfie_quality_good: boolean, + ), + ) + end end context 'PII validation from client response fails' do diff --git a/spec/jobs/get_usps_proofing_results_job_spec.rb b/spec/jobs/get_usps_proofing_results_job_spec.rb index 087f4e9dad7..59250578295 100644 --- a/spec/jobs/get_usps_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_proofing_results_job_spec.rb @@ -174,7 +174,7 @@ end end -RSpec.describe GetUspsProofingResultsJob do +RSpec.describe GetUspsProofingResultsJob, allowed_extra_analytics: [:*] do include UspsIppHelper include ApproximatingHelper @@ -1148,6 +1148,94 @@ error_type: Faraday::NilStatusError, ) end + + context 'when a user was flagged with fraud_pending_reason' do + before(:each) do + pending_enrollment.profile.update!(fraud_pending_reason: 'threatmetrix_review') + stub_request_passed_proofing_results + end + + it 'updates the enrollment' do + freeze_time do + expect(pending_enrollment.status).to eq 'pending' + job.perform(Time.zone.now) + expect(pending_enrollment.reload.status).to eq 'passed' + end + end + + context 'when the in_person_proofing_enforce_tmx flag is false' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enforce_tmx). + and_return(false) + end + + it 'activates the profile' do + job.perform(Time.zone.now) + profile = pending_enrollment.reload.profile + expect(profile).to be_active + end + + it 'does not mark the user as fraud_review_pending_at' do + job.perform(Time.zone.now) + + profile = pending_enrollment.reload.profile + expect(profile).not_to be_fraud_review_pending + end + + it 'does not log a user_sent_to_fraud_review analytics event' do + job.perform(Time.zone.now) + + expect(job_analytics).not_to have_logged_event( + :idv_in_person_usps_proofing_results_job_user_sent_to_fraud_review, + ) + end + end + + context 'when the in_person_proofing_enforce_tmx flag is true' do + before do + allow(IdentityConfig.store).to receive(:in_person_proofing_enforce_tmx). + and_return(true) + end + + it 'preserves the fraud_pending_reason attribute' do + job.perform(Time.zone.now) + + expect(pending_enrollment.profile.fraud_pending_reason).to eq 'threatmetrix_review' + end + + it 'logs a user_sent_to_fraud_review analytics event' do + job.perform(Time.zone.now) + + expect(job_analytics).to have_logged_event( + :idv_in_person_usps_proofing_results_job_user_sent_to_fraud_review, + hash_including( + enrollment_code: pending_enrollment.enrollment_code, + ), + ) + end + + it 'does not send a success email' do + user = pending_enrollment.user + + freeze_time do + expect do + job.perform(Time.zone.now) + end.not_to have_enqueued_mail(UserMailer, :in_person_verified).with( + params: { user: user, email_address: user.email_addresses.first }, + args: [{ enrollment: pending_enrollment }], + ) + end + end + + it 'marks the user as fraud_review_pending_at' do + job.perform(Time.zone.now) + + profile = pending_enrollment.reload.profile + expect(profile.fraud_review_pending_at).not_to be_nil + expect(profile).not_to be_active + end + end + end end describe 'Proofed with secondary id' do diff --git a/spec/jobs/get_usps_ready_proofing_results_job_spec.rb b/spec/jobs/get_usps_ready_proofing_results_job_spec.rb index f85c706bf5f..0500a8fb50c 100644 --- a/spec/jobs/get_usps_ready_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_ready_proofing_results_job_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe GetUspsReadyProofingResultsJob do +RSpec.describe GetUspsReadyProofingResultsJob, allowed_extra_analytics: [:*] do include UspsIppHelper let(:reprocess_delay_minutes) { 2.0 } diff --git a/spec/jobs/get_usps_waiting_proofing_results_job_spec.rb b/spec/jobs/get_usps_waiting_proofing_results_job_spec.rb index e0a90b58bbc..57bf43b1389 100644 --- a/spec/jobs/get_usps_waiting_proofing_results_job_spec.rb +++ b/spec/jobs/get_usps_waiting_proofing_results_job_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe GetUspsWaitingProofingResultsJob do +RSpec.describe GetUspsWaitingProofingResultsJob, allowed_extra_analytics: [:*] do include UspsIppHelper let(:reprocess_delay_minutes) { 2.0 } diff --git a/spec/lib/analytics_events_documenter_spec.rb b/spec/lib/analytics_events_documenter_spec.rb index 71a9719dddc..29e231ce0de 100644 --- a/spec/lib/analytics_events_documenter_spec.rb +++ b/spec/lib/analytics_events_documenter_spec.rb @@ -210,8 +210,9 @@ class AnalyticsEvents # @param [Boolean] success # @param [Integer] count number of attempts # The event that does something with stuff - def some_event(success:, count:) - track_event('Some Event') + # @option extra [String] 'DocumentName' the document name + def some_event(success:, count:, **extra) + track_event('Some Event', **extra) end # @identity.idp.previous_event_name The Old Other Event @@ -232,10 +233,11 @@ def other_event attributes: [ { name: 'success', types: ['Boolean'], description: nil }, { name: 'count', types: ['Integer'], description: 'number of attempts' }, + { name: 'DocumentName', types: ['String'], description: 'the document name' }, ], method_name: :some_event, source_file: '(stdin)', - source_line: 5, + source_line: kind_of(Integer), source_sha: kind_of(String), }, { @@ -248,7 +250,7 @@ def other_event attributes: [], method_name: :other_event, source_file: '(stdin)', - source_line: 11, + source_line: kind_of(Integer), source_sha: kind_of(String), }, ], diff --git a/spec/lib/feature_management_spec.rb b/spec/lib/feature_management_spec.rb index d6e64c21958..ff3fb85232c 100644 --- a/spec/lib/feature_management_spec.rb +++ b/spec/lib/feature_management_spec.rb @@ -519,7 +519,7 @@ %w[acuant lexisnexis_instant_verify lexisnexis_trueid].each do |service| context "#{service} is in :full_outage" do - let("vendor_status_#{service}".to_sym) { :full_outage } + let(:"vendor_status_#{service}") { :full_outage } it 'returns false' do expect(FeatureManagement.idv_available?).to eql(false) end diff --git a/spec/lib/reporting/drop_off_report_spec.rb b/spec/lib/reporting/drop_off_report_spec.rb new file mode 100644 index 00000000000..a47087ffe08 --- /dev/null +++ b/spec/lib/reporting/drop_off_report_spec.rb @@ -0,0 +1,169 @@ +require 'rails_helper' +require 'reporting/drop_off_report' + +RSpec.describe Reporting::DropOffReport do + let(:issuer) { 'my:example:issuer' } + let(:time_range) { Date.new(2022, 1, 1).all_day } + + subject(:report) { Reporting::DropOffReport.new(issuers: [issuer], time_range:) } + + before do + cloudwatch_client = double( + 'Reporting::CloudwatchClient', + fetch: [ + # finishes funnel + { 'user_id' => 'user1', 'name' => 'IdV: doc auth welcome visited' }, + { 'user_id' => 'user1', 'name' => 'IdV: doc auth welcome submitted' }, + { 'user_id' => 'user1', 'name' => 'IdV: doc auth image upload vendor submitted' }, + { 'user_id' => 'user1', 'name' => 'IdV: doc auth document_capture visited' }, + { 'user_id' => 'user1', 'name' => 'IdV: doc auth ssn visited' }, + { 'user_id' => 'user1', 'name' => 'IdV: doc auth verify visited' }, + { 'user_id' => 'user1', 'name' => 'IdV: doc auth verify submitted' }, + { 'user_id' => 'user1', 'name' => 'IdV: phone of record visited' }, + { 'user_id' => 'user1', 'name' => 'idv_enter_password_visited' }, + { 'user_id' => 'user1', 'name' => 'idv_enter_password_submitted' }, + { 'user_id' => 'user1', 'name' => 'IdV: personal key submitted' }, + + # gets through phone finder, then drops + { 'user_id' => 'user2', 'name' => 'IdV: doc auth welcome visited' }, + { 'user_id' => 'user2', 'name' => 'IdV: doc auth welcome submitted' }, + { 'user_id' => 'user2', 'name' => 'IdV: doc auth image upload vendor submitted' }, + { 'user_id' => 'user2', 'name' => 'IdV: doc auth document_capture visited' }, + { 'user_id' => 'user2', 'name' => 'IdV: doc auth ssn visited' }, + { 'user_id' => 'user2', 'name' => 'IdV: doc auth verify visited' }, + { 'user_id' => 'user2', 'name' => 'IdV: doc auth verify submitted' }, + { 'user_id' => 'user2', 'name' => 'IdV: phone of record visited' }, + + # gets to SSN view, then drops + { 'user_id' => 'user3', 'name' => 'IdV: doc auth welcome visited' }, + { 'user_id' => 'user3', 'name' => 'IdV: doc auth welcome submitted' }, + { 'user_id' => 'user3', 'name' => 'IdV: doc auth image upload vendor submitted' }, + { 'user_id' => 'user3', 'name' => 'IdV: doc auth document_capture visited' }, + { 'user_id' => 'user3', 'name' => 'IdV: doc auth ssn visited' }, + + # uploads a document, then drops + { 'user_id' => 'user4', 'name' => 'IdV: doc auth welcome visited' }, + { 'user_id' => 'user4', 'name' => 'IdV: doc auth welcome submitted' }, + { 'user_id' => 'user4', 'name' => 'IdV: doc auth image upload vendor submitted' }, + { 'user_id' => 'user4', 'name' => 'IdV: doc auth document_capture visited' }, + + # bails after viewing the user agreement + { 'user_id' => 'user5', 'name' => 'IdV: doc auth welcome visited' }, + { 'user_id' => 'user5', 'name' => 'IdV: doc auth welcome submitted' }, + ], + ) + + allow(report).to receive(:cloudwatch_client).and_return(cloudwatch_client) + end + + describe '#as_tables' do + it 'generates the tabular csv data' do + expect(report.as_tables).to eq expected_tables + end + end + + describe '#as_emailable_reports' do + it 'adds a "first row" hash with a title for tables_report mailer' do + reports = report.as_emailable_reports + aggregate_failures do + reports.each do |report| + expect(report.title).to be_present + end + end + end + end + + describe '#to_csvs' do + it 'generates a csv' do + csv_string_list = report.to_csvs + expect(csv_string_list.count).to be 4 + + csvs = csv_string_list.map { |csv| CSV.parse(csv) } + + aggregate_failures do + csvs.map(&:to_a).zip(expected_tables(strings: true)).each do |actual, expected| + expect(actual).to eq(expected) + end + end + end + end + + describe '#cloudwatch_client' do + let(:opts) { {} } + let(:subject) { described_class.new(issuers: Array(issuer), time_range:, **opts) } + let(:default_args) do + { + num_threads: 5, + ensure_complete_logs: true, + slice_interval: 3.hours, + progress: false, + logger: nil, + } + end + + describe 'when all args are default' do + it 'creates a client with the default options' do + expect(Reporting::CloudwatchClient).to receive(:new).with(default_args) + + subject.cloudwatch_client + end + end + + describe 'when threads is passed in' do + let(:opts) { { threads: 17 } } + before { default_args[:num_threads] = 17 } + + it 'creates a client with the expected thread count' do + expect(Reporting::CloudwatchClient).to receive(:new).with(default_args) + + subject.cloudwatch_client + end + end + + describe 'when slice is passed in' do + let(:opts) { { slice: 2.weeks } } + before { default_args[:slice_interval] = 2.weeks } + + it 'creates a client with expected time slice' do + expect(Reporting::CloudwatchClient).to receive(:new).with(default_args) + + subject.cloudwatch_client + end + end + end + + def expected_tables(strings: false) + [ + # these two tables are static + report.proofing_definition_table, + report.step_definition_table, + [ + ['Report Timeframe', "#{time_range.begin} to #{time_range.end}"], + ['Report Generated', Date.today.to_s], # rubocop:disable Rails/Date + ['Issuer', issuer], + ], + [ + ['Step', 'Unique user count', 'Users lost', 'Dropoff from last step', + 'Users left from start'], + ['Welcome (page viewed)'] + string_or_num(strings, 5), + ['User agreement (page viewed)'] + string_or_num(strings, 5, 0, 0.0, 1.0), + ['Capture Document (page viewed)'] + string_or_num(strings, 4, 1, 0.2, 0.8), + ['Document submitted (event)'] + string_or_num(strings, 4, 0, 0.0, 0.8), + ['SSN (page view)'] + string_or_num(strings, 3, 1, 0.25, 0.6), + ['Verify Info (page view)'] + string_or_num(strings, 2, 1, 0.3333333333333333, 0.4), + ['Verify submit (event)'] + string_or_num(strings, 2, 0, 0.0, 0.4), + ['Phone finder (page view)'] + string_or_num(strings, 2, 0, 0.0, 0.4), + ['Encrypt account: enter password (page view)'] + string_or_num(strings, 1, 1, 0.5, 0.2), + ['Personal key input (page view)'] + string_or_num(strings, 1, 0, 0.0, 0.2), + ['Verified (event)'] + string_or_num(strings, 1, 0, 0.0, 0.2), + ['Blanket proofing rate', '', '', ''] + string_or_num(strings, 0.2), + ['Actual proofing rate', '', '', ''] + string_or_num(strings, 0.25), + ['Verified proofing rate', '', '', ''] + string_or_num(strings, 0.25), + ], + ] + end + + def string_or_num(strings, *values) + strings ? values.map(&:to_s) : values + end +end diff --git a/spec/lib/tasks/dev_rake_spec.rb b/spec/lib/tasks/dev_rake_spec.rb index 84a6e474e72..4eef8097ab9 100644 --- a/spec/lib/tasks/dev_rake_spec.rb +++ b/spec/lib/tasks/dev_rake_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' require 'rake' -RSpec.describe 'dev rake tasks' do +RSpec.describe 'dev rake tasks', allowed_extra_analytics: [:*] do include UspsIppHelper let(:env) do diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index 9b78c9b6926..367028a3d84 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -59,7 +59,7 @@ def new_device_sign_in UserMailer.with(user: user, email_address: email_address_record).new_device_sign_in( date: 'February 25, 2019 15:02', location: 'Washington, DC', - device_name: 'Chrome ABC on macOS 123', + device_name: 'Chrome 123 on macOS', disavowal_token: SecureRandom.hex, ) end diff --git a/spec/models/concerns/user_otp_methods_spec.rb b/spec/models/concerns/user_otp_methods_spec.rb index 5c71a1818ba..6c67a59a3fe 100644 --- a/spec/models/concerns/user_otp_methods_spec.rb +++ b/spec/models/concerns/user_otp_methods_spec.rb @@ -10,7 +10,7 @@ # minimal ActiveRecord impl def update(attrs) attrs.each do |key, value| - send("#{key}=", value) + send(:"#{key}=", value) end end end diff --git a/spec/presenters/two_factor_authentication/sign_in_phone_selection_presenter_spec.rb b/spec/presenters/two_factor_authentication/sign_in_phone_selection_presenter_spec.rb index c70580f29fb..5de1906cb8b 100644 --- a/spec/presenters/two_factor_authentication/sign_in_phone_selection_presenter_spec.rb +++ b/spec/presenters/two_factor_authentication/sign_in_phone_selection_presenter_spec.rb @@ -31,7 +31,7 @@ let(:user) { create(:user, :with_phone) } it 'returns delivery method appended with configuration id' do - expect(presenter.type).to eq "sms_#{configuration.id}".to_sym + expect(presenter.type).to eq :"sms_#{configuration.id}" end end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index cd31bb0e60a..3d64d596206 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -57,6 +57,7 @@ class Analytics prepend FakeAnalytics::PiiAlerter + prepend FakeAnalytics::UndocumentedParamsChecker end begin diff --git a/spec/requests/csp_spec.rb b/spec/requests/csp_spec.rb index 476717e53d1..73440a443ac 100644 --- a/spec/requests/csp_spec.rb +++ b/spec/requests/csp_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'content security policy' do +RSpec.describe 'content security policy', allowed_extra_analytics: [:*] do context 'on endpoints that will redirect to an SP' do context 'when openid_connect_content_security_form_action_enabled is enabled' do before do diff --git a/spec/requests/openid_connect_authorize_spec.rb b/spec/requests/openid_connect_authorize_spec.rb index 051b1061602..e30adf4f7dd 100644 --- a/spec/requests/openid_connect_authorize_spec.rb +++ b/spec/requests/openid_connect_authorize_spec.rb @@ -1,6 +1,7 @@ require 'rails_helper' -RSpec.describe 'user signs in partially and visits openid_connect/authorize' do +RSpec.describe 'user signs in partially and visits openid_connect/authorize', + allowed_extra_analytics: [:*] do let(:user) { create(:user, :fully_registered, with: { phone: '+1 (202) 555-1213' }) } it 'prompts the user to 2FA' do diff --git a/spec/requests/openid_connect_cors_spec.rb b/spec/requests/openid_connect_cors_spec.rb index 743c59f0a16..72ed9b02355 100644 --- a/spec/requests/openid_connect_cors_spec.rb +++ b/spec/requests/openid_connect_cors_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'CORS headers for OpenID Connect endpoints' do +RSpec.describe 'CORS headers for OpenID Connect endpoints', allowed_extra_analytics: [:*] do before { Rails.cache.clear } after { Rails.cache.clear } diff --git a/spec/requests/rack_attack_spec.rb b/spec/requests/rack_attack_spec.rb index 83800fa8419..a54d16a042e 100644 --- a/spec/requests/rack_attack_spec.rb +++ b/spec/requests/rack_attack_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe 'throttling requests' do +RSpec.describe 'throttling requests', allowed_extra_analytics: [:*] do before(:all) { Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new } before(:each) { Rack::Attack.cache.store.clear } diff --git a/spec/services/analytics_spec.rb b/spec/services/analytics_spec.rb index 1a0fcc2bc76..76247648bc7 100644 --- a/spec/services/analytics_spec.rb +++ b/spec/services/analytics_spec.rb @@ -180,4 +180,76 @@ analytics.track_event('Trackable Event') end end + + it 'errors when undocumented parameters are sent' do + expect do + analytics.idv_phone_confirmation_otp_submitted( + success: true, + errors: true, + code_expired: true, + code_matches: true, + second_factor_attempts_count: true, + second_factor_locked_at: true, + proofing_components: true, + some_new_undocumented_keyword: true, + ) + end.to raise_error(FakeAnalytics::UndocumentedParams, /some_new_undocumented_keyword/) + end + + it 'does not error when undocumented params are allowed', allowed_extra_analytics: [:fun_level] do + expect(ahoy).to receive(:track).with( + kind_of(String), + hash_including(event_properties: hash_including(:fun_level)), + ) + + analytics.idv_phone_confirmation_otp_submitted( + success: true, + errors: true, + code_expired: true, + code_matches: true, + second_factor_attempts_count: true, + second_factor_locked_at: true, + proofing_components: true, + fun_level: 1000, + ) + end + + it 'does not error when undocumented params are allowed via *', allowed_extra_analytics: [:*] do + expect(ahoy).to receive(:track).with( + kind_of(String), + hash_including(event_properties: hash_including(:fun_level)), + ) + + analytics.idv_phone_confirmation_otp_submitted( + success: true, + errors: true, + code_expired: true, + code_matches: true, + second_factor_attempts_count: true, + second_factor_locked_at: true, + proofing_components: true, + fun_level: 1000, + ) + end + + it 'does not error when string tags are documented as options' do + expect(ahoy).to receive(:track).with( + kind_of(String), + hash_including(event_properties: hash_including('DocumentName')), + ) + + analytics.idv_doc_auth_submitted_image_upload_vendor( + success: nil, + errors: nil, + exception: nil, + state: nil, + state_id_type: nil, + async: nil, + attempts: nil, + remaining_attempts: nil, + client_image_metrics: nil, + flow_path: nil, + 'DocumentName' => 'some_name', + ) + end end diff --git a/spec/services/authn_context_resolver_spec.rb b/spec/services/authn_context_resolver_spec.rb new file mode 100644 index 00000000000..b99755b3709 --- /dev/null +++ b/spec/services/authn_context_resolver_spec.rb @@ -0,0 +1,195 @@ +require 'rails_helper' + +RSpec.describe AuthnContextResolver do + context 'when the user uses a vtr param' do + it 'parses the vtr param into requirements' do + vtr = ['C2.Pb'] + + result = AuthnContextResolver.new( + service_provider: nil, + vtr: vtr, + acr_values: nil, + ).resolve + + expect(result.component_values.map(&:name).join('.')).to eq('C1.C2.P1.Pb') + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(false) + expect(result.identity_proofing?).to eq(true) + expect(result.biometric_comparison?).to eq(true) + expect(result.ialmax?).to eq(false) + end + + it 'ignores any acr_values params that are passed' do + vtr = ['C2.Pb'] + + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/2', + 'http://idmanagement.gov/ns/assurance/ial/2', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: nil, + vtr: vtr, + acr_values: acr_values, + ).resolve + + expect(result.component_values.map(&:name).join('.')).to eq('C1.C2.P1.Pb') + end + end + + context 'when users uses an acr_values param' do + context 'no service provider' do + it 'parses an ACR value into requirements' do + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/2', + 'http://idmanagement.gov/ns/assurance/ial/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: nil, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.component_values.map(&:name).join(' ')).to eq(acr_values) + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(false) + expect(result.identity_proofing?).to eq(false) + expect(result.biometric_comparison?).to eq(false) + expect(result.ialmax?).to eq(false) + end + + it 'properly parses an ACR value without an AAL ACR' do + acr_values = [ + 'http://idmanagement.gov/ns/assurance/ial/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: nil, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.component_values.map(&:name).join(' ')).to eq(acr_values) + expect(result.aal2?).to eq(false) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(false) + expect(result.identity_proofing?).to eq(false) + expect(result.biometric_comparison?).to eq(false) + expect(result.ialmax?).to eq(false) + end + + it 'properly parses an ACR value without an IAL ACR' do + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/2', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: nil, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.component_values.map(&:name).join(' ')).to eq(acr_values) + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(false) + expect(result.identity_proofing?).to eq(false) + expect(result.biometric_comparison?).to eq(false) + expect(result.ialmax?).to eq(false) + end + end + + context 'AAL2 service provider' do + it 'uses the AAL ACR if one is present' do + service_provider = build(:service_provider, default_aal: 2) + + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/1', + 'http://idmanagement.gov/ns/assurance/ial/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: service_provider, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.aal2?).to eq(false) + end + + it 'uses the default AAL at AAL 2 if no AAL ACR is present' do + service_provider = build(:service_provider, default_aal: 2) + + acr_values = [ + 'http://idmanagement.gov/ns/assurance/ial/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: service_provider, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + end + + it 'uses the default AAL at AAL 3 if no AAL ACR is present' do + service_provider = build(:service_provider, default_aal: 3) + + acr_values = [ + 'http://idmanagement.gov/ns/assurance/ial/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: service_provider, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(true) + end + end + + context 'IAL2 service provider' do + it 'uses the IAL ACR if one is present' do + service_provider = build(:service_provider, ial: 2) + + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/1', + 'http://idmanagement.gov/ns/assurance/ial/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: service_provider, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.identity_proofing?).to eq(false) + expect(result.aal2?).to eq(false) + end + + it 'uses the defaul IAL if no IAL ACR is present' do + service_provider = build(:service_provider, ial: 2) + + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/1', + ].join(' ') + + result = AuthnContextResolver.new( + service_provider: service_provider, + vtr: nil, + acr_values: acr_values, + ).resolve + + expect(result.identity_proofing?).to eq(true) + expect(result.aal2?).to eq(true) + end + end + end +end diff --git a/spec/services/browser_support_spec.rb b/spec/services/browser_support_spec.rb index e53b1d43376..5fb5f0bf541 100644 --- a/spec/services/browser_support_spec.rb +++ b/spec/services/browser_support_spec.rb @@ -147,6 +147,51 @@ end end + context 'with user agent for chrome on ios' do + # All browsers on iOS use the Safari browser engine, so we expect the specific browser + # version to be disregarded in favor of the iOS version. + + context 'with both chrome version and ios version below supported range' do + let(:user_agent) do + # Chrome 100 on iOS 14.0 + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 ' \ + '(KHTML, like Gecko) CriOS/100.0.0000.000 Mobile/15E148 Safari/604.1' + end + + it { expect(supported).to eq(false) } + end + + context 'with chrome version above supported range, ios version below supported range' do + let(:user_agent) do + # Chrome 120 on iOS 14.0 + 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 ' \ + '(KHTML, like Gecko) CriOS/120.0.0000.000 Mobile/15E148 Safari/604.1' + end + + it { expect(supported).to eq(false) } + end + + context 'with chrome version below supported range, ios version above supported range' do + let(:user_agent) do + # Chrome 100 on iOS 15.0 + 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 ' \ + '(KHTML, like Gecko) CriOS/120.0.0000.000 Mobile/15E148 Safari/604.1' + end + + it { expect(supported).to eq(true) } + end + + context 'with both chrome version and ios version above supported range' do + let(:user_agent) do + # Chrome 120 on iOS 17.3 + 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 ' \ + '(KHTML, like Gecko) CriOS/120.0.0000.000 Mobile/15E148 Safari/604.1' + end + + it { expect(supported).to eq(true) } + end + end + context 'with opera desktop user agent' do let(:user_agent) do # Opera 83 diff --git a/spec/services/doc_auth/lexis_nexis/lexis_nexis_client_spec.rb b/spec/services/doc_auth/lexis_nexis/lexis_nexis_client_spec.rb index db8afa1c1f6..692179b5306 100644 --- a/spec/services/doc_auth/lexis_nexis/lexis_nexis_client_spec.rb +++ b/spec/services/doc_auth/lexis_nexis/lexis_nexis_client_spec.rb @@ -17,6 +17,8 @@ trueid_account_id: 'test_account', trueid_noliveness_cropping_workflow: 'NOLIVENESS.CROPPING.WORKFLOW', trueid_noliveness_nocropping_workflow: 'NOLIVENESS.NOCROPPING.WORKFLOW', + trueid_liveness_cropping_workflow: 'LIVENESS.CROPPING.WORKFLOW', + trueid_liveness_nocropping_workflow: 'LIVENESS.NOCROPPING.WORKFLOW', ) end @@ -117,4 +119,85 @@ ) end end + + context 'with selfie check enabled' do + ## enable feature + let(:workflow) { 'LIVENESS.CROPPING.WORKFLOW' } + before do + allow(FeatureManagement).to receive(:idv_allow_selfie_check?).and_return(true) + end + describe 'when success response returned' do + before do + stub_request(:post, image_upload_url).to_return( + body: LexisNexisFixtures.true_id_response_success_with_liveness, + ) + end + it 'returns a successful response' do + result = client.post_images( + front_image: DocAuthImageFixtures.document_front_image, + back_image: DocAuthImageFixtures.document_back_image, + image_source: image_source, + selfie_image: DocAuthImageFixtures.selfie_image, + liveness_checking_required: true, + ) + expect(result.success?).to eq(true) + expect(result.class).to eq(DocAuth::LexisNexis::Responses::TrueIdResponse) + expect(result.doc_auth_success?).to eq(true) + expect(result.selfie_live?).to eq(true) + expect(result.selfie_quality_good?).to eq(true) + expect(result.selfie_check_performed?).to eq(true) + end + end + + describe 'when selfie failure response returned' do + before do + stub_request(:post, image_upload_url).to_return( + body: LexisNexisFixtures.true_id_response_failure_with_liveness, + ) + end + + it 'returns a response indicate all failures' do + result = client.post_images( + front_image: DocAuthImageFixtures.document_front_image, + back_image: DocAuthImageFixtures.document_back_image, + image_source: image_source, + selfie_image: DocAuthImageFixtures.selfie_image, + liveness_checking_required: true, + ) + expect(result.success?).to eq(false) + expect(result.class).to eq(DocAuth::LexisNexis::Responses::TrueIdResponse) + expect(result.doc_auth_success?).to eq(false) + result_hash = result.to_h + expect(result_hash[:selfie_status]).to eq(:fail) + expect(result.selfie_live?).to eq(true) + expect(result.selfie_quality_good?).to eq(false) + expect(result.selfie_check_performed?).to eq(true) + end + end + + describe 'when http request failed' do + it 'return failed response with correct statuses' do + stub_request(:post, image_upload_url).to_return(body: '', status: 401) + + result = client.post_images( + front_image: DocAuthImageFixtures.document_front_image, + back_image: DocAuthImageFixtures.document_back_image, + image_source: image_source, + selfie_image: DocAuthImageFixtures.selfie_image, + liveness_checking_required: true, + ) + + expect(result.success?).to eq(false) + expect(result.errors).to eq(network: true) + expect(result.exception.message).to eq( + 'DocAuth::LexisNexis::Requests::TrueIdRequest Unexpected HTTP response 401', + ) + result_hash = result.to_h + expect(result_hash[:vendor]).to eq('TrueID') + expect(result_hash[:doc_auth_success]).to eq(false) + expect(result_hash[:selfie_status]).to eq(:not_processed) + expect(result.class).to eq(DocAuth::Response) + end + end + end end diff --git a/spec/services/doc_auth/lexis_nexis/request_spec.rb b/spec/services/doc_auth/lexis_nexis/request_spec.rb index b108dde4e1a..5ed3f7c9fe4 100644 --- a/spec/services/doc_auth/lexis_nexis/request_spec.rb +++ b/spec/services/doc_auth/lexis_nexis/request_spec.rb @@ -87,13 +87,18 @@ expect(response.class).to eq(DocAuth::Response) end - it 'includes information on the error' do - response = subject.fetch + it 'includes information on the error and notifies NewRelic' do expected_message = [ subject.class.name, 'Unexpected HTTP response', status, ].join(' ') + expect(NewRelic::Agent).to receive(:notice_error) do |arg| + expect(arg).to be_an_instance_of(DocAuth::RequestError) + expect(arg.message).to eq(expected_message) + expect(arg.error_code).to eq(status) + end + response = subject.fetch expect(response.exception.message).to eq(expected_message) end diff --git a/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb b/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb index b16b387df7d..56f97ea60e3 100644 --- a/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb +++ b/spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb @@ -3,19 +3,24 @@ RSpec.describe DocAuth::LexisNexis::Requests::TrueIdRequest do let(:image_source) { nil } let(:account_id) { 'test_account' } - let(:workflow) { nil } let(:base_url) { 'https://lexis.nexis.example.com' } + let(:workflow) { subject.send(:workflow) } let(:path) { "/restws/identity/v3/accounts/#{account_id}/workflows/#{workflow}/conversations" } let(:full_url) { base_url + path } let(:applicant) { { uuid: SecureRandom.uuid, uuid_prefix: '123' } } + let(:non_cropping_non_liveness_flow) { 'test_workflow' } + let(:cropping_non_liveness_flow) { 'test_workflow_cropping' } + let(:non_cropping_liveness_flow) { 'test_workflow_liveness' } + let(:cropping_liveness_flow) { 'test_workflow_liveness_cropping' } + let(:config) do DocAuth::LexisNexis::Config.new( trueid_account_id: account_id, base_url: base_url, - trueid_noliveness_cropping_workflow: 'test_workflow_cropping', - trueid_noliveness_nocropping_workflow: 'test_workflow', - trueid_liveness_cropping_workflow: 'test_workflow_liveness_cropping', - trueid_liveness_nocropping_workflow: 'test_workflow_liveness', + trueid_noliveness_cropping_workflow: cropping_non_liveness_flow, + trueid_noliveness_nocropping_workflow: non_cropping_non_liveness_flow, + trueid_liveness_cropping_workflow: cropping_liveness_flow, + trueid_liveness_nocropping_workflow: non_cropping_liveness_flow, ) end let(:selfie_image) { DocAuthImageFixtures.selfie_image } @@ -100,10 +105,11 @@ def include_liveness_expected context 'when liveness checking is NOT required' do let(:liveness_checking_required) { false } context 'with acuant image source' do - let(:workflow) { 'test_workflow' } let(:image_source) { DocAuth::ImageSources::ACUANT_SDK } it_behaves_like 'a successful request' - + it 'uses non-cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(non_cropping_non_liveness_flow) + end it 'does not include a nil selfie in the request body sent to TrueID' do body_as_json = subject.send(:body) body_as_hash = JSON.parse(body_as_json) @@ -111,9 +117,10 @@ def include_liveness_expected end end context 'with unknown image source' do - let(:workflow) { 'test_workflow_cropping' } let(:image_source) { DocAuth::ImageSources::UNKNOWN } - + it 'uses cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end end @@ -121,14 +128,17 @@ def include_liveness_expected context 'when liveness checking is required' do let(:liveness_checking_required) { true } context 'with acuant image source' do - let(:workflow) { 'test_workflow' } let(:image_source) { DocAuth::ImageSources::ACUANT_SDK } + it 'uses non-cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(non_cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end context 'with unknown image source' do - let(:workflow) { 'test_workflow_cropping' } let(:image_source) { DocAuth::ImageSources::UNKNOWN } - + it 'uses cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end end @@ -144,14 +154,17 @@ def include_liveness_expected context 'when liveness checking is NOT required' do let(:liveness_checking_required) { false } context 'with acuant image source' do - let(:workflow) { 'test_workflow' } let(:image_source) { DocAuth::ImageSources::ACUANT_SDK } + it 'use non-cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(non_cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end context 'with unknown image source' do - let(:workflow) { 'test_workflow_cropping' } let(:image_source) { DocAuth::ImageSources::UNKNOWN } - + it 'use cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end end @@ -159,29 +172,34 @@ def include_liveness_expected context 'when liveness checking is required' do let(:liveness_checking_required) { true } context 'with acuant image source' do - let(:workflow) { 'test_workflow_liveness' } let(:image_source) { DocAuth::ImageSources::ACUANT_SDK } - + it 'use non-cropping liveness workflow' do + expect(subject.send(:workflow)).to eq(non_cropping_liveness_flow) + end it_behaves_like 'a successful request' end context 'with unknown image source' do - let(:workflow) { 'test_workflow_liveness_cropping' } let(:image_source) { DocAuth::ImageSources::UNKNOWN } - + it 'use cropping liveness workflow' do + expect(subject.send(:workflow)).to eq(cropping_liveness_flow) + end it_behaves_like 'a successful request' end context 'when hosted env is prod' do let(:selfie_check_allowed) { false } context 'with acuant image source' do - let(:workflow) { 'test_workflow' } let(:image_source) { DocAuth::ImageSources::ACUANT_SDK } + it 'use non-cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(non_cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end context 'with unknown image source' do - let(:workflow) { 'test_workflow_cropping' } let(:image_source) { DocAuth::ImageSources::UNKNOWN } - + it 'use cropping non-liveness workflow' do + expect(subject.send(:workflow)).to eq(cropping_non_liveness_flow) + end it_behaves_like 'a successful request' end end @@ -189,15 +207,14 @@ def include_liveness_expected end context 'with non 200 http status code' do - let(:workflow) { 'test_workflow' } let(:image_source) { DocAuth::ImageSources::ACUANT_SDK } it 'is a network error with 5xx status' do stub_request(:post, full_url).to_return(body: '{}', status: 500) response = subject.fetch expect(response.network_error?).to eq(true) end - it 'is not a network error with 440, 438, 439' do - stub_request(:post, full_url).to_return(body: '{}', status: 443) + it 'is a network error with non 5xx error' do + stub_request(:post, full_url).to_return(body: '{}', status: 401) response = subject.fetch expect(response.network_error?).to eq(true) end diff --git a/spec/services/doc_auth_router_spec.rb b/spec/services/doc_auth_router_spec.rb index 55c39aa814c..c0098bf8873 100644 --- a/spec/services/doc_auth_router_spec.rb +++ b/spec/services/doc_auth_router_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe DocAuthRouter do +RSpec.describe DocAuthRouter, allowed_extra_analytics: [:*] do describe '.client' do before do allow(IdentityConfig.store).to receive(:doc_auth_vendor).and_return(doc_auth_vendor) diff --git a/spec/services/idv/phone_step_spec.rb b/spec/services/idv/phone_step_spec.rb index 337207e25f0..bf1c7495f56 100644 --- a/spec/services/idv/phone_step_spec.rb +++ b/spec/services/idv/phone_step_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::PhoneStep do +RSpec.describe Idv::PhoneStep, allowed_extra_analytics: [:*] do before { stub_attempts_tracker } let(:user) { create(:user) } diff --git a/spec/services/idv/profile_maker_spec.rb b/spec/services/idv/profile_maker_spec.rb index 86d2530b199..ba8fe5e4658 100644 --- a/spec/services/idv/profile_maker_spec.rb +++ b/spec/services/idv/profile_maker_spec.rb @@ -65,15 +65,18 @@ end context 'with fraud review needed' do + let(:gpo_verification_needed) { false } + let(:in_person_verification_needed) { false } let(:profile) do subject.save_profile( fraud_pending_reason: 'threatmetrix_review', - gpo_verification_needed: false, + gpo_verification_needed: gpo_verification_needed, deactivation_reason: nil, - in_person_verification_needed: false, + in_person_verification_needed: in_person_verification_needed, selfie_check_performed: false, ) end + it 'creates a pending profile for fraud review' do expect(profile.activated_at).to be_nil expect(profile.active).to eq(false) @@ -84,9 +87,26 @@ expect(profile.initiating_service_provider).to eq(nil) expect(profile.verified_at).to be_nil end + it 'marks the profile as legacy_unsupervised' do expect(profile.idv_level).to eql('legacy_unsupervised') end + + context 'when GPO verification is needed' do + let(:gpo_verification_needed) { true } + + it 'is not fraud_review_pending?' do + expect(profile.fraud_review_pending?).to eq(false) + end + end + + context 'when IPP is needed' do + let(:in_person_verification_needed) { true } + + it 'is not fraud_review_pending?' do + expect(profile.fraud_review_pending?).to eq(false) + end + end end context 'with gpo_verification_needed' do diff --git a/spec/services/idv/session_spec.rb b/spec/services/idv/session_spec.rb index 9ffb6dde736..59f17f4365d 100644 --- a/spec/services/idv/session_spec.rb +++ b/spec/services/idv/session_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Idv::Session do +RSpec.describe Idv::Session, allowed_extra_analytics: [:*] do let(:user) { create(:user) } let(:user_session) { {} } @@ -56,7 +56,7 @@ Idv::Session::VALID_SESSION_ATTRIBUTES.each do |attr| subject.send attr, 'foo' expect(subject.send(attr)).to eq 'foo' - subject.send "#{attr}=".to_sym, 'foo' + subject.send :"#{attr}=", 'foo' expect(subject.send(attr)).to eq 'foo' end end @@ -70,7 +70,7 @@ it 'allows supported attributes' do Idv::Session::VALID_SESSION_ATTRIBUTES.each do |attr| expect(subject.respond_to?(attr, false)).to eq true - expect(subject.respond_to?("#{attr}=".to_sym, false)).to eq true + expect(subject.respond_to?(:"#{attr}=", false)).to eq true end end end diff --git a/spec/services/outage_status_spec.rb b/spec/services/outage_status_spec.rb index 33300c317bf..99ff222386c 100644 --- a/spec/services/outage_status_spec.rb +++ b/spec/services/outage_status_spec.rb @@ -12,7 +12,7 @@ context 'when all vendors are operational' do before do OutageStatus::ALL_VENDORS.each do |vendor| - allow(IdentityConfig.store).to receive("vendor_status_#{vendor}".to_sym). + allow(IdentityConfig.store).to receive(:"vendor_status_#{vendor}"). and_return(:operational) end end @@ -29,7 +29,7 @@ context 'when any vendor has an outage' do OutageStatus::ALL_VENDORS.each do |vendor| before do - allow(IdentityConfig.store).to receive("vendor_status_#{vendor}".to_sym). + allow(IdentityConfig.store).to receive(:"vendor_status_#{vendor}"). and_return(:full_outage) end diff --git a/spec/services/recaptcha_enterprise_validator_spec.rb b/spec/services/recaptcha_enterprise_validator_spec.rb index 408e27a870f..e7a3a46d80f 100644 --- a/spec/services/recaptcha_enterprise_validator_spec.rb +++ b/spec/services/recaptcha_enterprise_validator_spec.rb @@ -274,7 +274,7 @@ it { expect(valid).to eq(false) } end - context 'with extra analytics properties' do + context 'with extra analytics properties', allowed_extra_analytics: [:extra] do let(:extra_analytics_properties) { { extra: true } } it 'logs analytics of the body' do diff --git a/spec/services/recaptcha_validator_spec.rb b/spec/services/recaptcha_validator_spec.rb index fea2e72d0e0..3b2459269b9 100644 --- a/spec/services/recaptcha_validator_spec.rb +++ b/spec/services/recaptcha_validator_spec.rb @@ -247,7 +247,7 @@ ) end - context 'with extra analytics properties' do + context 'with extra analytics properties', allowed_extra_analytics: [:extra] do let(:extra_analytics_properties) { { extra: true } } it 'logs analytics of the body' do diff --git a/spec/services/user_profiles_encryptor_spec.rb b/spec/services/user_profiles_encryptor_spec.rb index 4602d8fb5d6..337227482c7 100644 --- a/spec/services/user_profiles_encryptor_spec.rb +++ b/spec/services/user_profiles_encryptor_spec.rb @@ -36,25 +36,35 @@ context 'when the user has a pending profile' do let(:profile) { create(:profile, :verify_by_mail_pending, :verified, pii: pii.to_h) } - - it 'encrypts the PII for the pending profile with the password' do - encryptor = UserProfilesEncryptor.new( + let(:encryptor) do + UserProfilesEncryptor.new( user: user, user_session: user_session, password: password, ) - encryptor.encrypt + end + let(:personal_key) { PersonalKeyGenerator.new(user).normalize(encryptor.personal_key) } + let(:decrypted_profile_pii) { profile.decrypt_pii(password) } + let(:decrypted_profile_recovery_pii) { profile.recover_pii(personal_key) } + it 'encrypts the PII for the pending profile with the password' do + encryptor.encrypt profile.reload - personal_key = PersonalKeyGenerator.new(user).normalize(encryptor.personal_key) + expect(decrypted_profile_pii).to eq(pii) + expect(decrypted_profile_recovery_pii).to eq(pii) + expect(user.valid_personal_key?(personal_key)).to eq(true) + end - decrypted_profile_pii = profile.decrypt_pii(password) - decrypted_profile_recovery_pii = profile.recover_pii(personal_key) + context 'but the pending profile has no PII associated with it' do + before { user_session.delete(:encrypted_profiles) } - expect(pii).to eq(decrypted_profile_pii) - expect(pii).to eq(decrypted_profile_recovery_pii) - expect(user.valid_personal_key?(personal_key)).to eq(true) + it 'deactivates the profile with an encryption error' do + encryptor.encrypt + profile.reload + + expect(profile.deactivation_reason).to eq('encryption_error') + end end end diff --git a/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb b/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb index 8869c51013f..07909fb2ce2 100644 --- a/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb +++ b/spec/services/usps_in_person_proofing/enrollment_helper_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe UspsInPersonProofing::EnrollmentHelper do +RSpec.describe UspsInPersonProofing::EnrollmentHelper, allowed_extra_analytics: [:*] do include UspsIppHelper let(:usps_mock_fallback) { false } diff --git a/spec/services/vot/parser_spec.rb b/spec/services/vot/parser_spec.rb new file mode 100644 index 00000000000..662acde156b --- /dev/null +++ b/spec/services/vot/parser_spec.rb @@ -0,0 +1,77 @@ +require 'rails_helper' + +RSpec.describe Vot::Parser do + describe '#parse' do + context 'when a vector is completely expanded' do + it 'returns the vector along with requirements' do + vector_of_trust = 'C1.C2.Cb' + + result = Vot::Parser.new(vector_of_trust:).parse + + expect(result.component_values.map(&:name).join('.')).to eq('C1.C2.Cb') + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(true) + expect(result.identity_proofing?).to eq(false) + expect(result.biometric_comparison?).to eq(false) + expect(result.ialmax?).to eq(false) + end + end + + context 'when a component value has implied components' do + it 'adds the implied components' do + vector_of_trust = 'Pb' + + result = Vot::Parser.new(vector_of_trust:).parse + + expect(result.component_values.map(&:name).join('.')).to eq('C1.C2.P1.Pb') + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(false) + expect(result.identity_proofing?).to eq(true) + expect(result.biometric_comparison?).to eq(true) + expect(result.ialmax?).to eq(false) + end + end + + context 'when a vector includes unrecognized components' do + it 'raises an exception' do + vector_of_trust = 'C1.C2.Xx' + + expect { Vot::Parser.new(vector_of_trust:).parse }.to raise_exception( + Vot::Parser::ParseException, + 'C1.C2.Xx contains unkown component Xx', + ) + end + end + + context 'when a vector include duplicate components' do + it 'raises an exception' do + vector_of_trust = 'C1.C1' + expect { Vot::Parser.new(vector_of_trust:).parse }.to raise_exception( + Vot::Parser::ParseException, + 'C1.C1 contains duplicate components', + ) + end + + context 'when ACR values are provided' do + it 'parses ACR values to component values' do + acr_values = [ + 'http://idmanagement.gov/ns/assurance/aal/2?hspd12=true', + 'http://idmanagement.gov/ns/assurance/ial/2', + ].join(' ') + + result = Vot::Parser.new(acr_values:).parse + + expect(result.component_values.map(&:name).join(' ')).to eq(acr_values) + expect(result.aal2?).to eq(true) + expect(result.phishing_resistant?).to eq(false) + expect(result.hspd12?).to eq(true) + expect(result.identity_proofing?).to eq(true) + expect(result.biometric_comparison?).to eq(false) + expect(result.ialmax?).to eq(false) + end + end + end + end +end diff --git a/spec/support/fake_analytics.rb b/spec/support/fake_analytics.rb index bf1ce740c10..60c18091454 100644 --- a/spec/support/fake_analytics.rb +++ b/spec/support/fake_analytics.rb @@ -69,7 +69,77 @@ def track_event(event, original_attributes = {}) end end + UndocumentedParams = Class.new(StandardError) + + module UndocumentedParamsChecker + mattr_accessor :allowed_extra_analytics + mattr_accessor :asts + mattr_accessor :docstrings + + def track_event(event, original_attributes = {}) + method_name = caller. + grep(/analytics_events\.rb/)&. + first&. + match(/:in `(?[^']+)'/)&.[](:method_name) + + if method_name && !allowed_extra_analytics.include?(:*) + analytics_method = AnalyticsEvents.instance_method(method_name) + + param_names = analytics_method. + parameters. + select { |type, _name| [:keyreq, :key].include?(type) }. + map(&:last) + + extra_keywords = original_attributes.keys \ + - [:pii_like_keypaths, :user_id] \ + - Array(allowed_extra_analytics) \ + - param_names \ + - option_param_names(analytics_method) + + if extra_keywords.present? + raise UndocumentedParams, <<~ERROR + event :#{method_name} called with undocumented params #{extra_keywords.inspect} + (if these params are for specs only, use :allowed_extra_analytics metadata) + ERROR + end + end + + super(event, original_attributes) + end + + # @api private + # Returns the names of @option tags from the source of a method + def option_param_names(instance_method) + self.asts ||= {} + self.docstrings ||= {} + + if !YARD::Tags::Library.instance.has_tag?(:'identity.idp.previous_event_name') + YARD::Tags::Library.define_tag('Previous Event Name', :'identity.idp.previous_event_name') + end + + file = instance_method.source_location.first + + ast = self.asts[file] ||= begin + YARD::Parser::Ruby::RubyParser.new(File.read(file), file). + parse. + ast + end + + docstring = self.docstrings[instance_method.name] ||= begin + node = ast.traverse do |node| + break node if node.type == :def && node.jump(:ident)&.first == instance_method.name.to_s + end + + YARD::DocstringParser.new.parse(node.docstring).to_docstring + end + + docstring.tags.select { |tag| tag.tag_name == 'option' }. + map { |tag| tag.pair.name.tr(%('"), '') } + end + end + prepend PiiAlerter + prepend UndocumentedParamsChecker attr_reader :events attr_accessor :user @@ -97,6 +167,16 @@ def browser_attributes end end +RSpec.configure do |c| + c.around do |ex| + keys = Array(ex.metadata[:allowed_extra_analytics]) + FakeAnalytics::UndocumentedParamsChecker.allowed_extra_analytics = keys + ex.run + ensure + FakeAnalytics::UndocumentedParamsChecker.allowed_extra_analytics = [] + end +end + RSpec::Matchers.define :have_logged_event do |event, attributes_matcher| match do |actual| if event.nil? && attributes_matcher.nil? diff --git a/spec/support/features/idv_step_helper.rb b/spec/support/features/idv_step_helper.rb index 4a1a429ba5a..c126ba5a5ba 100644 --- a/spec/support/features/idv_step_helper.rb +++ b/spec/support/features/idv_step_helper.rb @@ -120,7 +120,7 @@ def complete_idv_steps_before_confirmation_step(address_verification_mechanism = end def complete_idv_steps_before_step(step, user = user_with_2fa) - send("complete_idv_steps_before_#{step}_step", user) + send(:"complete_idv_steps_before_#{step}_step", user) end def expect_step_indicator_current_step(text) diff --git a/spec/support/oidc_auth_helper.rb b/spec/support/oidc_auth_helper.rb index 6613f936174..4e533751983 100644 --- a/spec/support/oidc_auth_helper.rb +++ b/spec/support/oidc_auth_helper.rb @@ -120,8 +120,7 @@ def extract_meta_refresh_url end def extract_redirect_url - content = page.find('a#openid-connect-redirect') - content[:href] + page.find_link(t('forms.buttons.continue'))[:href] end def oidc_redirect_url diff --git a/spec/support/pundit_matcher.rb b/spec/support/pundit_matcher.rb index 346720aaf1e..349829488d5 100644 --- a/spec/support/pundit_matcher.rb +++ b/spec/support/pundit_matcher.rb @@ -1,6 +1,6 @@ RSpec::Matchers.define :permit_action do |action| match do |policy| - policy.public_send("#{action}?") + policy.public_send(:"#{action}?") end failure_message do |policy| diff --git a/spec/support/saml_auth_helper.rb b/spec/support/saml_auth_helper.rb index d3512f222df..c8e16667565 100644 --- a/spec/support/saml_auth_helper.rb +++ b/spec/support/saml_auth_helper.rb @@ -34,7 +34,7 @@ def saml_settings(overrides: {}) settings.idp_cert_fingerprint_algorithm = 'http://www.w3.org/2001/04/xmlenc#sha256' overrides.except(:security).each do |setting, value| - settings.send("#{setting}=", value) + settings.send(:"#{setting}=", value) end settings.security.merge!(overrides[:security]) if overrides[:security] settings diff --git a/spec/support/saml_response_doc.rb b/spec/support/saml_response_doc.rb index c5018586c78..a45ebe25e21 100644 --- a/spec/support/saml_response_doc.rb +++ b/spec/support/saml_response_doc.rb @@ -33,7 +33,7 @@ def input_id def raw_xml_response if @test_type == 'feature' xml_response - elsif @response.body.include?('') + elsif @response.body.include?('