diff --git a/app/assets/images/info-pin-map.svg b/app/assets/images/info-pin-map.svg new file mode 100644 index 00000000000..5f31cbcfaca --- /dev/null +++ b/app/assets/images/info-pin-map.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/assets/stylesheets/components/_footer.scss b/app/assets/stylesheets/components/_footer.scss index fe1bb21e5f0..e00be9a86db 100644 --- a/app/assets/stylesheets/components/_footer.scss +++ b/app/assets/stylesheets/components/_footer.scss @@ -24,9 +24,11 @@ body { } a { + @include u-padding-y(1); text-decoration: none; @include at-media('tablet') { + @include u-padding-y(0); &, &:visited { color: color($theme-link-reverse-color); @@ -59,6 +61,12 @@ body { } .footer__links { - @include u-padding-y(1); + @include u-padding-x(1); display: flex; + flex-wrap: wrap; + + @include at-media('tablet') { + @include u-padding-y(1); + @include u-padding-x(0); + } } diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index c93d411c23d..f9ec08ed644 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -28,4 +28,10 @@ def reauthentication redirect_to login_two_factor_options_path end + + private + + def confirm_user_is_not_suspended + redirect_to user_please_call_url if current_user.suspended? + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ee85bbe5536..acbb0d18a13 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -184,18 +184,7 @@ def service_provider_request @service_provider_request ||= ServiceProviderRequestProxy.from_uuid(params[:request_id]) end - def add_piv_cac_setup_url - session[:needs_to_setup_piv_cac_after_sign_in] ? login_add_piv_cac_prompt_url : nil - end - - def service_provider_mfa_setup_url - service_provider_mfa_policy.user_needs_sp_auth_method_setup? ? - authentication_methods_setup_url : nil - end - def fix_broken_personal_key_url - return if !current_user.broken_personal_key? - flash[:info] = t('account.personal_key.needs_new') pii_unlocked = Pii::Cacher.new(current_user, user_session).exists_in_session? @@ -217,26 +206,21 @@ def fix_broken_personal_key_url end def after_sign_in_path_for(_user) - accept_rules_of_use_url || - service_provider_mfa_setup_url || - add_piv_cac_setup_url || - fix_broken_personal_key_url || - user_session.delete(:stored_location) || - sp_session_request_url_with_updated_params || - signed_in_url + return rules_of_use_path if !current_user.accepted_rules_of_use_still_valid? + return user_please_call_url if current_user.suspended? + return authentication_methods_setup_url if user_needs_sp_auth_method_setup? + return login_add_piv_cac_prompt_url if session[:needs_to_setup_piv_cac_after_sign_in].present? + return fix_broken_personal_key_url if current_user.broken_personal_key? + return user_session.delete(:stored_location) if user_session.key?(:stored_location) + return reactivate_account_url if user_needs_to_reactivate_account? + return sp_session_request_url_with_updated_params if sp_session.key?(:request_url) + signed_in_url end def signed_in_url - return user_two_factor_authentication_url unless user_fully_authenticated? - return user_please_call_url if current_user.suspended? - return reactivate_account_url if user_needs_to_reactivate_account? return url_for_pending_profile_reason if user_has_pending_profile? return backup_code_reminder_url if user_needs_backup_code_reminder? - account_url - end - - def accept_rules_of_use_url - rules_of_use_path unless current_user.accepted_rules_of_use_still_valid? + account_path end def after_mfa_setup_path @@ -291,10 +275,6 @@ def user_fully_authenticated? two_factor_enabled? end - def confirm_user_is_not_suspended - redirect_to user_please_call_url if current_user.suspended? - end - def confirm_two_factor_authenticated authenticate_user!(force: true) @@ -404,6 +384,7 @@ def service_provider_mfa_policy phishing_resistant_requested: sp_session[:phishing_resistant_requested], ) end + delegate :user_needs_sp_auth_method_setup?, to: :service_provider_mfa_policy def sp_session session.fetch(:sp, {}) diff --git a/app/controllers/concerns/idv/threat_metrix_concern.rb b/app/controllers/concerns/idv/threat_metrix_concern.rb index 5ff95b6b9b7..2f44d13a30a 100644 --- a/app/controllers/concerns/idv/threat_metrix_concern.rb +++ b/app/controllers/concerns/idv/threat_metrix_concern.rb @@ -8,16 +8,6 @@ module ThreatMetrixConcern def override_csp_for_threat_metrix return unless FeatureManagement.proofing_device_profiling_collecting_enabled? - return if params[:step] != 'ssn' - - threat_metrix_csp_overrides - end - - # Remove this duplication once in_person_controller is no longer in use - # for their SSN step - def override_csp_for_threat_metrix_no_fsm - return unless FeatureManagement.proofing_device_profiling_collecting_enabled? - threat_metrix_csp_overrides end diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index 752eb89c0fa..a4172f60aab 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -69,8 +69,9 @@ def resolution_rate_limiter end def ssn_rate_limiter + ssn = idv_session.ssn || pii[:ssn] @ssn_rate_limiter ||= RateLimiter.new( - target: Pii::Fingerprinter.fingerprint(pii[:ssn]), + target: Pii::Fingerprinter.fingerprint(ssn), rate_limit_type: :proof_ssn, ) end @@ -223,7 +224,7 @@ def async_state_done(current_async_state) end def next_step_url - return idv_gpo_url if FeatureManagement.idv_by_mail_only? + return idv_request_letter_url if FeatureManagement.idv_by_mail_only? idv_phone_url end @@ -300,17 +301,19 @@ def log_idv_verification_submitted_event(success: false, failure_reason: nil) last_name: pii_from_doc[:last_name], date_of_birth: pii_from_doc[:dob], address: pii_from_doc[:address1], - ssn: pii_from_doc[:ssn], + ssn: idv_session.ssn || pii_from_doc[:ssn], failure_reason: failure_reason, ) end def check_ssn - Idv::SsnForm.new(current_user).submit(ssn: pii[:ssn]) + ssn = idv_session.ssn || pii[:ssn] + Idv::SsnForm.new(current_user).submit(ssn: ssn) end def move_applicant_to_idv_session idv_session.applicant = pii + idv_session.applicant[:ssn] ||= idv_session.ssn idv_session.applicant['uuid'] = current_user.uuid delete_pii end diff --git a/app/controllers/concerns/idv_step_concern.rb b/app/controllers/concerns/idv_step_concern.rb index 86b62f3f840..44ce2834e9d 100644 --- a/app/controllers/concerns/idv_step_concern.rb +++ b/app/controllers/concerns/idv_step_concern.rb @@ -17,7 +17,7 @@ module IdvStepConcern end def confirm_no_pending_gpo_profile - redirect_to idv_gpo_verify_url if current_user&.gpo_verification_pending_profile? + redirect_to idv_verify_by_mail_enter_code_url if current_user&.gpo_verification_pending_profile? end def confirm_no_pending_in_person_enrollment @@ -52,7 +52,7 @@ def flow_path private def confirm_ssn_step_complete - return if pii.present? && pii[:ssn].present? + return if pii.present? && (idv_session.ssn.present? || pii[:ssn].present?) redirect_to prev_url end diff --git a/app/controllers/concerns/rate_limit_concern.rb b/app/controllers/concerns/rate_limit_concern.rb index 2d5bb2bc916..d5b3a9ae4e7 100644 --- a/app/controllers/concerns/rate_limit_concern.rb +++ b/app/controllers/concerns/rate_limit_concern.rb @@ -64,8 +64,8 @@ def idv_attempter_rate_limited?(rate_limit_type) end def pii_ssn - return unless defined?(flow_session) && user_session - pii_from_doc_ssn = flow_session[:pii_from_doc]&.[](:ssn) + return unless defined?(flow_session) && defined?(idv_session) && user_session + pii_from_doc_ssn = idv_session&.ssn || flow_session[:pii_from_doc]&.[](:ssn) return pii_from_doc_ssn if pii_from_doc_ssn flow_session[:pii_from_user]&.[](:ssn) end diff --git a/app/controllers/concerns/verify_profile_concern.rb b/app/controllers/concerns/verify_profile_concern.rb index 740723a2bd5..45e8a8bca38 100644 --- a/app/controllers/concerns/verify_profile_concern.rb +++ b/app/controllers/concerns/verify_profile_concern.rb @@ -2,7 +2,7 @@ module VerifyProfileConcern private def url_for_pending_profile_reason - return idv_gpo_verify_url if current_user.gpo_verification_pending_profile? + return idv_verify_by_mail_enter_code_url if current_user.gpo_verification_pending_profile? return idv_in_person_ready_to_verify_url if current_user.in_person_pending_profile? return idv_please_call_url if current_user.fraud_review_pending? idv_not_verified_url if current_user.fraud_rejection? diff --git a/app/controllers/idv/gpo_verify_controller.rb b/app/controllers/idv/by_mail/enter_code_controller.rb similarity index 91% rename from app/controllers/idv/gpo_verify_controller.rb rename to app/controllers/idv/by_mail/enter_code_controller.rb index 082c5e96dc1..d7782d08a55 100644 --- a/app/controllers/idv/gpo_verify_controller.rb +++ b/app/controllers/idv/by_mail/enter_code_controller.rb @@ -1,7 +1,7 @@ -module Idv - class GpoVerifyController < ApplicationController +module Idv::ByMail + class EnterCodeController < ApplicationController include IdvSession - include StepIndicatorConcern + include Idv::StepIndicatorConcern include FraudReviewConcern prepend_before_action :note_if_user_did_not_receive_letter @@ -13,7 +13,7 @@ def index # slightly different copy on this screen. @user_did_not_receive_letter = !!params[:did_not_receive_letter] - analytics.idv_gpo_verification_visited( + analytics.idv_verify_by_mail_enter_code_visited( source: if @user_did_not_receive_letter then 'gpo_reminder_email' end, ) @@ -52,7 +52,7 @@ def create @gpo_verify_form = build_gpo_verify_form result = @gpo_verify_form.submit - analytics.idv_gpo_verification_submitted(**result.to_h) + analytics.idv_verify_by_mail_enter_code_submitted(**result.to_h) irs_attempts_api_tracker.idv_gpo_verification_submitted( success: result.success?, failure_reason: irs_attempts_api_tracker.parse_failure_reason(result), @@ -60,7 +60,7 @@ def create if !result.success? flash[:error] = @gpo_verify_form.errors.first.message - redirect_to idv_gpo_verify_url + redirect_to idv_verify_by_mail_enter_code_url return end @@ -90,7 +90,7 @@ def note_if_user_did_not_receive_letter if current_user && session.delete(:gpo_user_did_not_receive_letter) # ...and we can pick things up here. - redirect_to idv_gpo_verify_path(did_not_receive_letter: 1) + redirect_to idv_verify_by_mail_enter_code_path(did_not_receive_letter: 1) end end diff --git a/app/controllers/idv/come_back_later_controller.rb b/app/controllers/idv/by_mail/letter_enqueued_controller.rb similarity index 66% rename from app/controllers/idv/come_back_later_controller.rb rename to app/controllers/idv/by_mail/letter_enqueued_controller.rb index 55b0415505e..2a9bf4fb720 100644 --- a/app/controllers/idv/come_back_later_controller.rb +++ b/app/controllers/idv/by_mail/letter_enqueued_controller.rb @@ -1,13 +1,13 @@ -module Idv - class ComeBackLaterController < ApplicationController +module Idv::ByMail + class LetterEnqueuedController < ApplicationController include IdvSession - include StepIndicatorConcern + include Idv::StepIndicatorConcern before_action :confirm_two_factor_authenticated before_action :confirm_user_needs_gpo_confirmation def show - analytics.idv_come_back_later_visit + analytics.idv_letter_enqueued_visit end private diff --git a/app/controllers/idv/gpo_controller.rb b/app/controllers/idv/by_mail/request_letter_controller.rb similarity index 93% rename from app/controllers/idv/gpo_controller.rb rename to app/controllers/idv/by_mail/request_letter_controller.rb index 32fa3fd8204..6871c080375 100644 --- a/app/controllers/idv/gpo_controller.rb +++ b/app/controllers/idv/by_mail/request_letter_controller.rb @@ -1,7 +1,7 @@ -module Idv - class GpoController < ApplicationController +module Idv::ByMail + class RequestLetterController < ApplicationController include IdvSession - include StepIndicatorConcern + include Idv::StepIndicatorConcern include Idv::AbTestAnalyticsConcern before_action :confirm_two_factor_authenticated @@ -11,11 +11,11 @@ class GpoController < ApplicationController before_action :confirm_profile_not_too_old def index - @presenter = GpoPresenter.new(current_user, url_options) + @presenter = RequestLetterPresenter.new(current_user, url_options) @step_indicator_current_step = step_indicator_current_step Funnel::DocAuth::RegisterStep.new(current_user.id, current_sp&.issuer). call(:usps_address, :view, true) - analytics.idv_gpo_address_visited( + analytics.idv_request_letter_visited( letter_already_sent: @presenter.resend_requested?, ) end @@ -29,7 +29,7 @@ def create elsif resend_requested? resend_letter flash[:success] = t('idv.messages.gpo.another_letter_on_the_way') - redirect_to idv_come_back_later_url + redirect_to idv_letter_enqueued_url else redirect_to idv_review_url end diff --git a/app/controllers/idv/in_person/address_search_controller.rb b/app/controllers/idv/in_person/address_search_controller.rb deleted file mode 100644 index 256940c760c..00000000000 --- a/app/controllers/idv/in_person/address_search_controller.rb +++ /dev/null @@ -1,68 +0,0 @@ -module Idv - module InPerson - class AddressSearchController < ApplicationController - rescue_from ActionController::InvalidAuthenticityToken, - Faraday::Error, - StandardError, - with: :report_errors - - def index - response = addresses(params[:address]) - - render(**response) - end - - protected - - def addresses(search_term) - addresses = geocoder.find_address_candidates(SingleLine: search_term).slice(0, 1) - if addresses.empty? - analytics.idv_in_person_locations_searched( - success: false, errors: 'No address candidates found by ArcGIS', - ) - end - - { json: addresses, status: :ok } - end - - def geocoder - @geocoder ||= ArcgisApi::GeocoderFactory.new.create - end - - def report_errors(error) - remapped_error = case error - when Faraday::Error, - ActionController::InvalidAuthenticityToken - :unprocessable_entity - else - :internal_server_error - end - - errors = if error.respond_to?(:response_body) - error.response_body.is_a?(Hash) && error.response_body[:details] - end - - errors ||= 'ArcGIS error performing operation' - - analytics.idv_in_person_locations_searched( - success: false, - errors: errors, - api_status_code: Rack::Utils.status_code(remapped_error), - exception_class: error.class, - exception_message: error.message, - response_status_code: error.try(:response_status), - ) - - analytics.idv_arcgis_request_failure( - api_status_code: Rack::Utils.status_code(remapped_error), - exception_class: error.class, - exception_message: error.message, - response_body_present: error.respond_to?(:response_body) && error.response_body.present?, - response_body: error.respond_to?(:response_body) && error.response_body, - response_status_code: error.try(:response_status), - ) - render json: [], status: remapped_error - end - end - end -end diff --git a/app/controllers/idv/in_person/public/address_search_controller.rb b/app/controllers/idv/in_person/public/address_search_controller.rb deleted file mode 100644 index d05efe033ef..00000000000 --- a/app/controllers/idv/in_person/public/address_search_controller.rb +++ /dev/null @@ -1,33 +0,0 @@ -module Idv - module InPerson - module Public - class AddressSearchController < ApplicationController - include RenderConditionConcern - - check_or_render_not_found -> { enabled? } - - skip_forgery_protection - - def index - addresses = geocoder.find_address_candidates(SingleLine: params[:address]).slice(0, 1) - - render json: addresses.to_json - end - - def options - head :ok - end - - protected - - def geocoder - ArcgisApi::Mock::Geocoder.new - end - - def enabled? - IdentityConfig.store.in_person_public_address_search_enabled - end - end - end - end -end diff --git a/app/controllers/idv/in_person/ssn_controller.rb b/app/controllers/idv/in_person/ssn_controller.rb index b3414c49628..8a717ba6968 100644 --- a/app/controllers/idv/in_person/ssn_controller.rb +++ b/app/controllers/idv/in_person/ssn_controller.rb @@ -9,12 +9,13 @@ class SsnController < ApplicationController before_action :confirm_verify_info_step_needed before_action :confirm_in_person_address_step_complete before_action :confirm_repeat_ssn, only: :show - before_action :override_csp_for_threat_metrix_no_fsm + before_action :override_csp_for_threat_metrix attr_accessor :error_message def show - @ssn_form = Idv::SsnFormatForm.new(current_user, flow_session) + incoming_ssn = idv_session.ssn || flow_session.dig(:pii_from_user, :ssn) + @ssn_form = Idv::SsnFormatForm.new(current_user, incoming_ssn) analytics.idv_doc_auth_redo_ssn_submitted(**analytics_arguments) if updating_ssn? analytics.idv_doc_auth_ssn_visited(**analytics_arguments) @@ -27,8 +28,8 @@ def show def update @error_message = nil - - @ssn_form = Idv::SsnFormatForm.new(current_user, flow_session) + incoming_ssn = idv_session.ssn || flow_session.dig(:pii_from_user, :ssn) + @ssn_form = Idv::SsnFormatForm.new(current_user, incoming_ssn) ssn = params.require(:doc_auth).permit(:ssn) form_response = @ssn_form.submit(ssn) @@ -42,6 +43,7 @@ def update if form_response.success? flow_session[:pii_from_user][:ssn] = params[:doc_auth][:ssn] + idv_session.ssn = params[:doc_auth][:ssn] idv_session.invalidate_steps_after_ssn! redirect_to idv_in_person_verify_info_url else @@ -68,7 +70,7 @@ def flow_path end def confirm_repeat_ssn - return if !pii_from_user[:ssn] + return if !idv_session.ssn && !pii_from_user[:ssn] return if request.referer == idv_in_person_verify_info_url redirect_to idv_in_person_verify_info_url end @@ -84,7 +86,7 @@ def analytics_arguments end def updating_ssn? - flow_session.dig(:pii_from_user, :ssn).present? + idv_session.ssn.present? || flow_session.dig(:pii_from_user, :ssn).present? end def confirm_in_person_address_step_complete diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb index 37f3fb6be1d..e2853047e3c 100644 --- a/app/controllers/idv/in_person/verify_info_controller.rb +++ b/app/controllers/idv/in_person/verify_info_controller.rb @@ -12,6 +12,7 @@ class VerifyInfoController < ApplicationController def show @step_indicator_steps = step_indicator_steps + @ssn = idv_session.ssn || flow_session[:pii_from_user][:ssn] @capture_secondary_id_enabled = capture_secondary_id_enabled analytics.idv_doc_auth_verify_visited(**analytics_arguments) diff --git a/app/controllers/idv/in_person_controller.rb b/app/controllers/idv/in_person_controller.rb index 21c191c1855..b35a3de87f5 100644 --- a/app/controllers/idv/in_person_controller.rb +++ b/app/controllers/idv/in_person_controller.rb @@ -12,7 +12,6 @@ class InPersonController < ApplicationController include Idv::ThreatMetrixConcern before_action :redirect_if_flow_completed - before_action :override_csp_for_threat_metrix FLOW_STATE_MACHINE_SETTINGS = { step_url: :idv_in_person_step_url, diff --git a/app/controllers/idv/review_controller.rb b/app/controllers/idv/review_controller.rb index 4e94f554b01..1fc52488b2a 100644 --- a/app/controllers/idv/review_controller.rb +++ b/app/controllers/idv/review_controller.rb @@ -157,7 +157,7 @@ def need_personal_key_confirmation? def next_step if gpo_user_flow? - idv_come_back_later_url + idv_letter_enqueued_url else idv_personal_key_url end diff --git a/app/controllers/idv/session_errors_controller.rb b/app/controllers/idv/session_errors_controller.rb index 12bbf1b65f2..4dd98df5847 100644 --- a/app/controllers/idv/session_errors_controller.rb +++ b/app/controllers/idv/session_errors_controller.rb @@ -60,7 +60,7 @@ def rate_limited private def ssn_from_doc - user_session&.dig('idv/doc_auth', :pii_from_doc, 'ssn') + idv_session&.ssn || user_session&.dig('idv/doc_auth', :pii_from_doc, :ssn) end def confirm_two_factor_authenticated_or_user_id_in_session diff --git a/app/controllers/idv/ssn_controller.rb b/app/controllers/idv/ssn_controller.rb index ca517ce946d..ab41a5b0df5 100644 --- a/app/controllers/idv/ssn_controller.rb +++ b/app/controllers/idv/ssn_controller.rb @@ -8,12 +8,13 @@ class SsnController < ApplicationController before_action :confirm_verify_info_step_needed before_action :confirm_document_capture_complete before_action :confirm_repeat_ssn, only: :show - before_action :override_csp_for_threat_metrix_no_fsm + before_action :override_csp_for_threat_metrix attr_accessor :error_message def show - @ssn_form = Idv::SsnFormatForm.new(current_user, flow_session) + incoming_ssn = idv_session.ssn || flow_session.dig(:pii_from_doc, :ssn) + @ssn_form = Idv::SsnFormatForm.new(current_user, incoming_ssn) analytics.idv_doc_auth_redo_ssn_submitted(**analytics_arguments) if @ssn_form.updating_ssn? analytics.idv_doc_auth_ssn_visited(**analytics_arguments) @@ -27,7 +28,8 @@ def show def update @error_message = nil - @ssn_form = Idv::SsnFormatForm.new(current_user, flow_session) + incoming_ssn = idv_session.ssn || flow_session.dig(:pii_from_doc, :ssn) + @ssn_form = Idv::SsnFormatForm.new(current_user, incoming_ssn) form_response = @ssn_form.submit(params.require(:doc_auth).permit(:ssn)) analytics.idv_doc_auth_ssn_submitted( @@ -39,6 +41,7 @@ def update if form_response.success? flow_session[:pii_from_doc][:ssn] = params[:doc_auth][:ssn] + idv_session.ssn = params[:doc_auth][:ssn] idv_session.invalidate_steps_after_ssn! redirect_to next_url else @@ -50,7 +53,7 @@ def update private def confirm_repeat_ssn - return if !pii_from_doc[:ssn] + return if !idv_session.ssn && !pii_from_doc[:ssn] return if request.referer == idv_verify_info_url redirect_to idv_verify_info_url diff --git a/app/controllers/idv/verify_info_controller.rb b/app/controllers/idv/verify_info_controller.rb index 6bad7dbec80..833143b4cb7 100644 --- a/app/controllers/idv/verify_info_controller.rb +++ b/app/controllers/idv/verify_info_controller.rb @@ -11,6 +11,7 @@ class VerifyInfoController < ApplicationController def show @step_indicator_steps = step_indicator_steps + @ssn = idv_session.ssn || pii_from_doc[:ssn] analytics.idv_doc_auth_verify_visited(**analytics_arguments) Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]). @@ -54,7 +55,6 @@ def analytics_arguments }.merge(ab_test_analytics_buckets) end - # copied from verify_step def pii @pii = pii_from_doc end diff --git a/app/controllers/openid_connect/authorization_controller.rb b/app/controllers/openid_connect/authorization_controller.rb index e34174ef6ff..b0e4014c6d4 100644 --- a/app/controllers/openid_connect/authorization_controller.rb +++ b/app/controllers/openid_connect/authorization_controller.rb @@ -132,12 +132,13 @@ def sign_out_if_prompt_param_is_login_and_user_is_signed_in is_forced_reauthentication: false, ) end - return unless user_signed_in? && @authorize_form.prompt == 'login' + return unless @authorize_form.prompt == 'login' return if session[:oidc_state_for_login_prompt] == @authorize_form.state + session[:oidc_state_for_login_prompt] = @authorize_form.state + return unless user_signed_in? return if check_sp_handoff_bounced unless sp_session[:request_url] == request.original_url sign_out - session[:oidc_state_for_login_prompt] = @authorize_form.state set_issuer_forced_reauthentication( issuer: @authorize_form.service_provider.issuer, is_forced_reauthentication: true, diff --git a/app/controllers/users/piv_cac_login_controller.rb b/app/controllers/users/piv_cac_login_controller.rb index 98e88fe6a87..3344cead017 100644 --- a/app/controllers/users/piv_cac_login_controller.rb +++ b/app/controllers/users/piv_cac_login_controller.rb @@ -66,8 +66,6 @@ def process_valid_submission user = piv_cac_login_form.user sign_in(:user, user) - mark_user_session_authenticated(:piv_cac) - save_piv_cac_information( subject: piv_cac_login_form.x509_dn, issuer: piv_cac_login_form.x509_issuer, diff --git a/app/controllers/users/webauthn_setup_controller.rb b/app/controllers/users/webauthn_setup_controller.rb index 9c2510f76b5..eb4503648dd 100644 --- a/app/controllers/users/webauthn_setup_controller.rb +++ b/app/controllers/users/webauthn_setup_controller.rb @@ -27,6 +27,7 @@ def new user_opted_remember_device_cookie: user_opted_remember_device_cookie, remember_device_default: remember_device_default, platform_authenticator: @platform_authenticator, + url_options:, ) properties = result.to_h.merge(analytics_properties) analytics.webauthn_setup_visit(**properties) @@ -54,6 +55,7 @@ def confirm user_opted_remember_device_cookie: user_opted_remember_device_cookie, remember_device_default: remember_device_default, platform_authenticator: @platform_authenticator, + url_options:, ) properties = result.to_h.merge(analytics_properties) analytics.multi_factor_auth_setup(**properties) diff --git a/app/forms/idv/ssn_format_form.rb b/app/forms/idv/ssn_format_form.rb index bdd78be1e39..f5588991318 100644 --- a/app/forms/idv/ssn_format_form.rb +++ b/app/forms/idv/ssn_format_form.rb @@ -11,9 +11,9 @@ def self.model_name ActiveModel::Name.new(self, nil, 'doc_auth') end - def initialize(user, flow_session = {}) + def initialize(user, incoming_ssn) @user = user - @ssn = flow_session.dig(:pii_from_doc, :ssn) + @ssn = incoming_ssn @updating_ssn = ssn.present? end diff --git a/app/forms/user_piv_cac_verification_form.rb b/app/forms/user_piv_cac_verification_form.rb index 1192dae8274..66131e32a6a 100644 --- a/app/forms/user_piv_cac_verification_form.rb +++ b/app/forms/user_piv_cac_verification_form.rb @@ -21,6 +21,7 @@ def submit end def piv_cac_configuration + return nil if x509_dn_uuid.blank? @piv_cac_configuration ||= ::PivCacConfiguration.find_by(x509_dn_uuid: x509_dn_uuid) end diff --git a/app/javascript/packages/address-search/README.md b/app/javascript/packages/address-search/README.md index b3c3fb5c4fb..39213a0f503 100644 --- a/app/javascript/packages/address-search/README.md +++ b/app/javascript/packages/address-search/README.md @@ -1,6 +1,6 @@ # `@18f/identity-address-search` -This is a npm module that provides a React UI component to search for USPS (United States Postal Service) locations using the ArcGIS API. It allows you to retrieve USPS location information based on a full address. +This is a npm module that provides a React UI component to search for USPS (United States Postal Service) locations. It allows you to retrieve USPS location information based on a full address. Additionally, this module depends on existing backend services from the Login.gov project. Make sure to have the required backend services or mock services set up and running before using this module. @@ -26,12 +26,13 @@ import AddressSearch from '@18f/identity-address-search'; return( <> ); diff --git a/app/javascript/packages/address-search/components/address-search.tsx b/app/javascript/packages/address-search/components/address-search.tsx index ac6d82fce1e..4d116f48705 100644 --- a/app/javascript/packages/address-search/components/address-search.tsx +++ b/app/javascript/packages/address-search/components/address-search.tsx @@ -3,16 +3,17 @@ import { Alert, PageHeading } from '@18f/identity-components'; import { t } from '@18f/identity-i18n'; import InPersonLocations from './in-person-locations'; import AddressInput from './address-input'; -import type { LocationQuery, FormattedLocation } from '../types'; +import type { AddressSearchProps, LocationQuery, FormattedLocation } from '../types'; function AddressSearch({ - registerField, - locationsURL, addressSearchURL, - handleLocationSelect, disabled, + handleLocationSelect, + locationsURL, onFoundLocations, -}) { + registerField, + resultsHeaderComponent, +}: AddressSearchProps) { const [apiError, setApiError] = useState(null); const [foundAddress, setFoundAddress] = useState(null); const [locationResults, setLocationResults] = useState( @@ -47,6 +48,7 @@ function AddressSearch({ locations={locationResults} onSelect={handleLocationSelect} address={foundAddress?.address || ''} + resultsHeaderComponent={resultsHeaderComponent} /> )} diff --git a/app/javascript/packages/address-search/components/in-person-locations.spec.tsx b/app/javascript/packages/address-search/components/in-person-locations.spec.tsx new file mode 100644 index 00000000000..fe95f52ac22 --- /dev/null +++ b/app/javascript/packages/address-search/components/in-person-locations.spec.tsx @@ -0,0 +1,70 @@ +import { render } from '@testing-library/react'; +import { Alert } from '@18f/identity-components'; +import type { FormattedLocation } from './in-person-locations'; +import InPersonLocations from './in-person-locations'; + +describe('InPersonLocations', () => { + const locations: FormattedLocation[] = [ + { + formattedCityStateZip: 'one', + distance: 'one', + id: 1, + name: 'one', + saturdayHours: 'one', + streetAddress: 'one', + sundayHours: 'one', + weekdayHours: 'one', + isPilot: false, + }, + { + formattedCityStateZip: 'two', + distance: 'two', + id: 2, + name: 'two', + saturdayHours: 'two', + streetAddress: 'two', + sundayHours: 'two', + weekdayHours: 'two', + isPilot: false, + }, + ]; + + const onSelect = () => {}; + + const address = '123 Fake St, Hollywood, CA 90210'; + + it('renders a component at the top of results when passed', () => { + const alertText = 'hello world'; + const alertComponent = () => {alertText}; + + const { getByText } = render( + , + ); + + // the alert text + expect(getByText(alertText)).to.exist(); + }); + + it('renders results instructions when onSelect is passed', () => { + const { getByText } = render( + , + ); + + expect(getByText('in_person_proofing.body.location.po_search.results_instructions')).to.exist(); + }); + + it('does not render results instructions when onSelect is not passed', () => { + const { queryByText } = render( + , + ); + + expect( + queryByText('in_person_proofing.body.location.po_search.results_instructions'), + ).to.not.exist(); + }); +}); diff --git a/app/javascript/packages/address-search/components/in-person-locations.tsx b/app/javascript/packages/address-search/components/in-person-locations.tsx index fe258755a69..737f1d79adc 100644 --- a/app/javascript/packages/address-search/components/in-person-locations.tsx +++ b/app/javascript/packages/address-search/components/in-person-locations.tsx @@ -1,6 +1,8 @@ +import { ComponentType } from 'react'; import { t } from '@18f/identity-i18n'; import LocationCollection from './location-collection'; import LocationCollectionItem from './location-collection-item'; +import NoInPersonLocationsDisplay from './no-in-person-locations-display'; export interface FormattedLocation { formattedCityStateZip: string; @@ -18,20 +20,19 @@ interface InPersonLocationsProps { locations: FormattedLocation[] | null | undefined; onSelect; address: string; + resultsHeaderComponent?: ComponentType; } -function InPersonLocations({ locations, onSelect, address }: InPersonLocationsProps) { +function InPersonLocations({ + locations, + onSelect, + address, + resultsHeaderComponent: HeaderComponent, +}: InPersonLocationsProps) { const isPilot = locations?.some((l) => l.isPilot); if (locations?.length === 0) { - return ( - <> -

- {t('in_person_proofing.body.location.po_search.none_found', { address })} -

-

{t('in_person_proofing.body.location.po_search.none_found_tip')}

- - ); + return ; } return ( @@ -43,7 +44,8 @@ function InPersonLocations({ locations, onSelect, address }: InPersonLocationsPr count: locations?.length, })} -

{t('in_person_proofing.body.location.po_search.results_instructions')}

+ {HeaderComponent && } + {onSelect &&

{t('in_person_proofing.body.location.po_search.results_instructions')}

} {(locations || []).map((item, index) => ( { + it('renders the component with expected image and text', async () => { + const { findAllByText, getByAltText } = render( + , + ); + + const image = getByAltText(t('image_description.info_pin_map')); + const noneFoundMessage = await findAllByText( + 'in_person_proofing.body.location.po_search.none_found', + ); + const noneFoundTipMessage = await findAllByText( + 'in_person_proofing.body.location.po_search.none_found_tip', + ); + + expect(image).to.exist(); + expect(noneFoundMessage).to.exist(); + expect(noneFoundTipMessage).to.exist(); + }); +}); diff --git a/app/javascript/packages/address-search/components/no-in-person-locations-display.tsx b/app/javascript/packages/address-search/components/no-in-person-locations-display.tsx new file mode 100644 index 00000000000..82c3ce8b1b7 --- /dev/null +++ b/app/javascript/packages/address-search/components/no-in-person-locations-display.tsx @@ -0,0 +1,24 @@ +import { getAssetPath } from '@18f/identity-assets'; +import { t } from '@18f/identity-i18n'; + +function NoInPersonLocationsDisplay({ address }) { + return ( +
+ {t('image_description.info_pin_map')} +
+

+ {t('in_person_proofing.body.location.po_search.none_found', { address })} +

+

{t('in_person_proofing.body.location.po_search.none_found_tip')}

+
+
+ ); +} + +export default NoInPersonLocationsDisplay; diff --git a/app/javascript/packages/address-search/hooks/use-usps-locations.ts b/app/javascript/packages/address-search/hooks/use-usps-locations.ts index af022401d3c..c5365101680 100644 --- a/app/javascript/packages/address-search/hooks/use-usps-locations.ts +++ b/app/javascript/packages/address-search/hooks/use-usps-locations.ts @@ -5,20 +5,20 @@ import useSWR from 'swr/immutable'; import type { Location, FormattedLocation, LocationQuery, PostOffice } from '../types'; import { formatLocations, snakeCase, transformKeys } from '../utils'; -const requestUspsLocations = async ({ +export async function requestUspsLocations({ locationsURL, address, }: { locationsURL: string; address: LocationQuery; -}): Promise => { +}): Promise { const response = await request(locationsURL, { method: 'post', json: { address: transformKeys(address, snakeCase) }, }); return formatLocations(response); -}; +} function requestAddressCandidates({ unvalidatedAddressInput, @@ -56,7 +56,7 @@ export default function useUspsLocations({ setAddressQuery(unvalidatedAddressInput); }, []); - // sends the raw text query to arcgis + // sends the raw text query for geocoding const { data: addressCandidates, isLoading: isLoadingCandidates, diff --git a/app/javascript/packages/address-search/index.tsx b/app/javascript/packages/address-search/index.tsx index f5d9054738a..4be29bd8694 100644 --- a/app/javascript/packages/address-search/index.tsx +++ b/app/javascript/packages/address-search/index.tsx @@ -1,8 +1,18 @@ import { snakeCase, formatLocations, transformKeys } from './utils'; -import InPersonLocations from './components/in-person-locations'; import AddressInput from './components/address-input'; import AddressSearch from './components/address-search'; +import InPersonLocations from './components/in-person-locations'; +import NoInPersonLocationsDisplay from './components/no-in-person-locations-display'; +import { requestUspsLocations } from './hooks/use-usps-locations'; -export { snakeCase, formatLocations, transformKeys, InPersonLocations, AddressInput }; +export { + AddressInput, + InPersonLocations, + NoInPersonLocationsDisplay, + formatLocations, + snakeCase, + transformKeys, + requestUspsLocations, +}; export default AddressSearch; diff --git a/app/javascript/packages/address-search/package.json b/app/javascript/packages/address-search/package.json index f68b6a85b7b..585cbf93bfb 100644 --- a/app/javascript/packages/address-search/package.json +++ b/app/javascript/packages/address-search/package.json @@ -1,6 +1,6 @@ { "name": "@18f/identity-address-search", - "version": "2.0.0", + "version": "2.2.0", "type": "module", "private": false, "files": [ diff --git a/app/javascript/packages/address-search/types.d.ts b/app/javascript/packages/address-search/types.d.ts index 587b78e4203..66e4b583aa7 100644 --- a/app/javascript/packages/address-search/types.d.ts +++ b/app/javascript/packages/address-search/types.d.ts @@ -1,5 +1,5 @@ import type { RegisterFieldCallback } from '@18f/identity-form-steps'; -import type { ReactNode } from 'react'; +import type { ComponentType, Dispatch, SetStateAction, ReactNode } from 'react'; interface FormattedLocation { formattedCityStateZip: string; @@ -54,6 +54,16 @@ interface AddressInputProps { locationsURL: string; } +interface AddressSearchProps { + addressSearchURL: string; + disabled: boolean; + handleLocationSelect: ((e: any, id: number) => Promise) | null | undefined; + resultsHeaderComponent?: ComponentType; + locationsURL: string; + onFoundLocations: Dispatch>; + registerField: RegisterFieldCallback; +} + interface InPersonLocationsProps { locations: FormattedLocation[] | null | undefined; onSelect; diff --git a/app/javascript/packages/document-capture/components/acuant-camera.tsx b/app/javascript/packages/document-capture/components/acuant-camera.tsx index afa4ec638f2..6b857187b11 100644 --- a/app/javascript/packages/document-capture/components/acuant-camera.tsx +++ b/app/javascript/packages/document-capture/components/acuant-camera.tsx @@ -129,7 +129,7 @@ interface AcuantCameraUICallbacks { /** * Callback that occurs when there is a failure. */ - onFailure: (error?: AcuantCaptureFailureError, code?: string) => void; + onError: (error?: AcuantCaptureFailureError, code?: string) => void; } type AcuantCameraUIStart = ( @@ -330,7 +330,7 @@ function AcuantCamera({ { onCaptured: onCropStart, onCropped, - onFailure: onImageCaptureFailure, + onError: onImageCaptureFailure, }, onFailureCallbackWithOptions, textOptions, diff --git a/app/javascript/packages/document-capture/components/in-person-full-address-search.tsx b/app/javascript/packages/document-capture/components/in-person-full-address-search.tsx index 83c91d7c93b..0f3d3639feb 100644 --- a/app/javascript/packages/document-capture/components/in-person-full-address-search.tsx +++ b/app/javascript/packages/document-capture/components/in-person-full-address-search.tsx @@ -1,139 +1,13 @@ import { TextInput, SelectInput } from '@18f/identity-components'; import { useState, useRef, useEffect, useCallback, useContext } from 'react'; import { t } from '@18f/identity-i18n'; -import { request } from '@18f/identity-request'; import ValidatedField from '@18f/identity-validated-field/validated-field'; import SpinnerButton, { SpinnerButtonRefHandle } from '@18f/identity-spinner-button/spinner-button'; import type { RegisterFieldCallback } from '@18f/identity-form-steps'; -import useSWR from 'swr/immutable'; import { useDidUpdateEffect } from '@18f/identity-react-hooks'; -import { transformKeys, snakeCase } from '@18f/identity-address-search'; -import type { - LocationQuery, - PostOffice, - FormattedLocation, -} from '@18f/identity-address-search/types'; +import type { LocationQuery, FormattedLocation } from '@18f/identity-address-search/types'; import { InPersonContext } from '../context'; - -const formatLocations = (postOffices: PostOffice[]): FormattedLocation[] => - postOffices.map((po: PostOffice, index) => ({ - formattedCityStateZip: `${po.city}, ${po.state}, ${po.zip_code_5}-${po.zip_code_4}`, - id: index, - distance: po.distance, - name: po.name, - saturdayHours: po.saturday_hours, - streetAddress: po.address, - sundayHours: po.sunday_hours, - weekdayHours: po.weekday_hours, - isPilot: !!po.is_pilot, - })); - -const requestUspsLocations = async ({ - address, - locationsURL, -}: { - locationsURL: string; - address: LocationQuery; -}): Promise => { - const response = await request(locationsURL, { - method: 'post', - json: { address: transformKeys(address, snakeCase) }, - }); - - return formatLocations(response); -}; - -function useUspsLocations(locationsURL: string) { - const [locationQuery, setLocationQuery] = useState(null); - const validatedAddressFieldRef = useRef(null); - const validatedCityFieldRef = useRef(null); - const validatedStateFieldRef = useRef(null); - const validatedZipCodeFieldRef = useRef(null); - - const checkValidityAndDisplayErrors = (address, city, state, zipCode) => { - let formIsValid = true; - const zipCodeIsValid = zipCode.length === 5 && !!zipCode.match(/\d{5}/); - - if (address.length === 0) { - validatedAddressFieldRef.current?.setCustomValidity(t('simple_form.required.text')); - formIsValid = false; - } else { - validatedAddressFieldRef.current?.setCustomValidity(''); - } - - if (city.length === 0) { - formIsValid = false; - validatedCityFieldRef.current?.setCustomValidity(t('simple_form.required.text')); - } else { - validatedCityFieldRef.current?.setCustomValidity(''); - } - - if (state.length === 0) { - formIsValid = false; - validatedStateFieldRef.current?.setCustomValidity(t('simple_form.required.text')); - } else { - validatedStateFieldRef.current?.setCustomValidity(''); - } - - if (zipCode.length === 0) { - formIsValid = false; - validatedZipCodeFieldRef.current?.setCustomValidity(t('simple_form.required.text')); - } else { - validatedZipCodeFieldRef.current?.setCustomValidity(''); - } - - validatedAddressFieldRef.current?.reportValidity(); - validatedCityFieldRef.current?.reportValidity(); - validatedStateFieldRef.current?.reportValidity(); - validatedZipCodeFieldRef.current?.reportValidity(); - - return formIsValid && zipCodeIsValid; - }; - - const handleLocationSearch = useCallback( - (event, addressValue, cityValue, stateValue, zipCodeValue) => { - event.preventDefault(); - const address = addressValue.trim(); - const city = cityValue.trim(); - const zipCode = zipCodeValue.trim(); - - const formIsValid = checkValidityAndDisplayErrors(address, city, stateValue, zipCode); - - if (!formIsValid) { - return; - } - - setLocationQuery({ - address: `${address}, ${city}, ${stateValue} ${zipCode}`, - streetAddress: address, - city, - state: stateValue, - zipCode, - }); - }, - [], - ); - - const { - data: locationResults, - isLoading: isLoadingLocations, - error: uspsError, - } = useSWR([locationQuery], ([address]) => - address ? requestUspsLocations({ address, locationsURL }) : null, - ); - - return { - locationQuery, - locationResults, - uspsError, - isLoading: isLoadingLocations, - handleLocationSearch, - validatedAddressFieldRef, - validatedCityFieldRef, - validatedStateFieldRef, - validatedZipCodeFieldRef, - }; -} +import useValidatedUspsLocations from '../hooks/use-validated-usps-locations'; interface FullAddressSearchProps { registerField?: RegisterFieldCallback; @@ -170,7 +44,7 @@ function FullAddressSearch({ validatedCityFieldRef, validatedStateFieldRef, validatedZipCodeFieldRef, - } = useUspsLocations(locationsURL); + } = useValidatedUspsLocations(locationsURL); const inputChangeHandler = (input) => diff --git a/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx b/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx index c256eb18f25..237003d2dac 100644 --- a/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx +++ b/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx @@ -94,12 +94,12 @@ function InPersonLocationPostOfficeSearchStep({ onChange, toPreviousStep, regist return ( <> diff --git a/app/javascript/packages/document-capture/hooks/use-validated-usps-locations.spec.ts b/app/javascript/packages/document-capture/hooks/use-validated-usps-locations.spec.ts new file mode 100644 index 00000000000..a711f27b229 --- /dev/null +++ b/app/javascript/packages/document-capture/hooks/use-validated-usps-locations.spec.ts @@ -0,0 +1,62 @@ +import { renderHook } from '@testing-library/react-hooks'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import type { SetupServer } from 'msw/node'; +import useValidatedUspsLocations from './use-validated-usps-locations'; +import { LOCATIONS_URL } from '../components/in-person-location-post-office-search-step'; + +const USPS_RESPONSE = [ + { + address: '100 Main St E, Bronwood, Georgia, 39826', + location: { + latitude: 31.831686000000005, + longitude: -84.363768, + }, + street_address: '100 Main St E', + city: 'Bronwood', + state: 'GA', + zip_code: '39826', + }, + { + address: '200 Main St E, Bronwood, Georgia, 39826', + location: { + latitude: 32.831686000000005, + longitude: -83.363768, + }, + street_address: '200 Main St E', + city: 'Bronwood', + state: 'GA', + zip_code: '39826', + }, +]; + +describe('useValidatedUspsLocations', () => { + let server: SetupServer; + + before(() => { + server = setupServer(); + server.listen(); + }); + + after(() => { + server.close(); + }); + + beforeEach(() => { + server.resetHandlers(); + server.use(rest.post(LOCATIONS_URL, (_req, res, ctx) => res(ctx.json(USPS_RESPONSE)))); + }); + + it('returns location results', async () => { + const { result, waitForNextUpdate } = renderHook(() => + useValidatedUspsLocations(LOCATIONS_URL), + ); + + const { handleLocationSearch } = result.current; + handleLocationSearch(new Event('submit'), '200 main', 'Endeavor', 'DE', '12345'); + + await waitForNextUpdate(); + + expect(result.current.locationResults?.length).to.equal(USPS_RESPONSE.length); + }); +}); diff --git a/app/javascript/packages/document-capture/hooks/use-validated-usps-locations.ts b/app/javascript/packages/document-capture/hooks/use-validated-usps-locations.ts new file mode 100644 index 00000000000..829e4a77041 --- /dev/null +++ b/app/javascript/packages/document-capture/hooks/use-validated-usps-locations.ts @@ -0,0 +1,97 @@ +import { useState, useRef, useCallback } from 'react'; +import { requestUspsLocations } from '@18f/identity-address-search'; +import useSWR from 'swr/immutable'; +import type { LocationQuery } from '@18f/identity-address-search/types'; +import { t } from '@18f/identity-i18n'; + +export default function useValidatedUspsLocations(locationsURL: string) { + const [locationQuery, setLocationQuery] = useState(null); + const validatedAddressFieldRef = useRef(null); + const validatedCityFieldRef = useRef(null); + const validatedStateFieldRef = useRef(null); + const validatedZipCodeFieldRef = useRef(null); + + const checkValidityAndDisplayErrors = (address, city, state, zipCode) => { + let formIsValid = true; + const zipCodeIsValid = zipCode.length === 5 && !!zipCode.match(/\d{5}/); + + if (address.length === 0) { + validatedAddressFieldRef.current?.setCustomValidity(t('simple_form.required.text')); + formIsValid = false; + } else { + validatedAddressFieldRef.current?.setCustomValidity(''); + } + + if (city.length === 0) { + formIsValid = false; + validatedCityFieldRef.current?.setCustomValidity(t('simple_form.required.text')); + } else { + validatedCityFieldRef.current?.setCustomValidity(''); + } + + if (state.length === 0) { + formIsValid = false; + validatedStateFieldRef.current?.setCustomValidity(t('simple_form.required.text')); + } else { + validatedStateFieldRef.current?.setCustomValidity(''); + } + + if (zipCode.length === 0) { + formIsValid = false; + validatedZipCodeFieldRef.current?.setCustomValidity(t('simple_form.required.text')); + } else { + validatedZipCodeFieldRef.current?.setCustomValidity(''); + } + + validatedAddressFieldRef.current?.reportValidity(); + validatedCityFieldRef.current?.reportValidity(); + validatedStateFieldRef.current?.reportValidity(); + validatedZipCodeFieldRef.current?.reportValidity(); + + return formIsValid && zipCodeIsValid; + }; + + const handleLocationSearch = useCallback( + (event, addressValue, cityValue, stateValue, zipCodeValue) => { + event.preventDefault(); + const address = addressValue.trim(); + const city = cityValue.trim(); + const zipCode = zipCodeValue.trim(); + + const formIsValid = checkValidityAndDisplayErrors(address, city, stateValue, zipCode); + + if (!formIsValid) { + return; + } + + setLocationQuery({ + address: `${address}, ${city}, ${stateValue} ${zipCode}`, + streetAddress: address, + city, + state: stateValue, + zipCode, + }); + }, + [], + ); + + const { + data: locationResults, + isLoading: isLoadingLocations, + error: uspsError, + } = useSWR([locationQuery], ([address]) => + address ? requestUspsLocations({ address, locationsURL }) : null, + ); + + return { + locationQuery, + locationResults, + uspsError, + isLoading: isLoadingLocations, + handleLocationSearch, + validatedAddressFieldRef, + validatedCityFieldRef, + validatedStateFieldRef, + validatedZipCodeFieldRef, + }; +} diff --git a/app/jobs/arcgis_token_job.rb b/app/jobs/arcgis_token_job.rb deleted file mode 100644 index e7dd979618f..00000000000 --- a/app/jobs/arcgis_token_job.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Refresh the ArcGIS API token -# -# Keeping this behavior in a job reduces the latency and probability -# of user-facing errors related to the post office search for in-person -# proofing. -class ArcgisTokenJob < ApplicationJob - queue_as :default - - def perform - analytics.idv_arcgis_token_job_started - geocoder.retrieve_token! - return true - ensure - analytics.idv_arcgis_token_job_completed - end - - private - - def geocoder - @geocoder ||= ArcgisApi::GeocoderFactory.new.create - end - - def analytics - @analytics ||= Analytics.new( - user: AnonymousUser.new, - request: nil, - session: {}, - sp: nil, - ) - end -end diff --git a/app/jobs/in_person/send_proofing_notification_job.rb b/app/jobs/in_person/send_proofing_notification_job.rb index c3d84a404d5..d8d30952fc0 100644 --- a/app/jobs/in_person/send_proofing_notification_job.rb +++ b/app/jobs/in_person/send_proofing_notification_job.rb @@ -80,6 +80,7 @@ def notification_message(enrollment:) 'telephony.confirmation_ipp_enrollment_result.sms', app_name: APP_NAME, proof_date: proof_date, + contact_number: IdentityConfig.store.idv_contact_phone_number, ) end end diff --git a/app/jobs/multi_region_kms_migration/user_migration_job.rb b/app/jobs/multi_region_kms_migration/user_migration_job.rb new file mode 100644 index 00000000000..8314e43dc3e --- /dev/null +++ b/app/jobs/multi_region_kms_migration/user_migration_job.rb @@ -0,0 +1,73 @@ +module MultiRegionKmsMigration + class UserMigrationJob < ApplicationJob + MAXIMUM_ERROR_TOLERANCE = 10 + + include ::NewRelic::Agent::MethodTracer + + def perform(statement_timeout: 120, user_count: 1000) + return unless IdentityConfig.store.multi_region_kms_migration_jobs_enabled + + error_count = 0 + success_count = 0 + + users = find_users_to_migrate(statement_timeout:, user_count:) + users.each do |user| + return if error_count >= MAXIMUM_ERROR_TOLERANCE # rubocop:disable Lint/NonLocalExitFromIterator + + Encryption::MultiRegionKmsMigration::UserMigrator.new(user).migrate! + success_count += 1 + analytics.multi_region_kms_migration_user_migrated( + success: true, + user_id: user.id, + exception: nil, + ) + rescue => err + error_count += 1 + analytics.multi_region_kms_migration_user_migrated( + success: false, + user_id: user.id, + exception: err.inspect, + ) + end + analytics.multi_region_kms_migration_user_migration_summary( + user_count: users.size, + success_count: success_count, + error_count: error_count, + ) + end + + def find_users_to_migrate(statement_timeout:, user_count:) + User.transaction do + quoted_timeout = User.connection.quote(statement_timeout * 1000) + User.connection.execute("SET LOCAL statement_timeout = #{quoted_timeout}") + + password_scope = User.where.not( + encrypted_password_digest: '', + ).where( + 'encrypted_password_digest IS NOT NULL', + ).where( + encrypted_password_digest_multi_region: nil, + ).where( + 'encrypted_password_digest NOT LIKE ?', '%encryption_key%' + ) + personal_key_scope = User.where.not( + encrypted_recovery_code_digest: '', + ).where( + 'encrypted_recovery_code_digest IS NOT NULL', + ).where( + encrypted_recovery_code_digest_multi_region: nil, + ).where( + 'encrypted_recovery_code_digest NOT LIKE ?', '%encryption_key%' + ) + + password_scope.or(personal_key_scope).limit(user_count) + end + end + + def analytics + @analytics ||= Analytics.new(user: AnonymousUser.new, request: nil, session: {}, sp: nil) + end + + add_method_tracer :find_users_to_migrate, "Custom/#{name}/find_users_to_migrate" + end +end diff --git a/app/jobs/reports/identity_verification_report.rb b/app/jobs/reports/identity_verification_report.rb index 8943374b7c8..2903770f8ca 100644 --- a/app/jobs/reports/identity_verification_report.rb +++ b/app/jobs/reports/identity_verification_report.rb @@ -7,6 +7,7 @@ class IdentityVerificationReport < BaseReport attr_accessor :report_date def perform(report_date) + return unless IdentityConfig.store.s3_reports_enabled self.report_date = report_date csv = report_maker.to_csv @@ -16,7 +17,7 @@ def perform(report_date) def report_maker Reporting::IdentityVerificationReport.new( - issuer: nil, + issuers: [], time_range: report_date.all_day, slice: 4.hours, ) diff --git a/app/presenters/idv/gpo_presenter.rb b/app/presenters/idv/by_mail/request_letter_presenter.rb similarity index 88% rename from app/presenters/idv/gpo_presenter.rb rename to app/presenters/idv/by_mail/request_letter_presenter.rb index 2cb2021f79d..ee96ad76d7a 100644 --- a/app/presenters/idv/gpo_presenter.rb +++ b/app/presenters/idv/by_mail/request_letter_presenter.rb @@ -1,5 +1,5 @@ -module Idv - class GpoPresenter +module Idv::ByMail + class RequestLetterPresenter include Rails.application.routes.url_helpers attr_reader :current_user, :url_options @@ -19,7 +19,7 @@ def button def fallback_back_path return idv_verify_info_path if OutageStatus.new.any_phone_vendor_outage? - user_needs_address_otp_verification? ? idv_gpo_verify_path : idv_phone_path + user_needs_address_otp_verification? ? idv_verify_by_mail_enter_code_path : idv_phone_path end def resend_requested? diff --git a/app/presenters/two_factor_login_options_presenter.rb b/app/presenters/two_factor_login_options_presenter.rb index 355e06fc5ad..c9ddcdd710e 100644 --- a/app/presenters/two_factor_login_options_presenter.rb +++ b/app/presenters/two_factor_login_options_presenter.rb @@ -43,6 +43,7 @@ def restricted_options_warning_text end def options + return @options if defined?(@options) mfa = MfaContext.new(user) if @piv_cac_required @@ -63,7 +64,9 @@ def options # webauthn keys and phones. However, we only want to show one of each option # during login, except for phones, where we want to allow the user to choose # which MFA-enabled phone they want to use. - configurations.group_by(&:class).flat_map { |klass, set| klass.selection_presenters(set) } + @options = configurations.group_by(&:class).flat_map do |klass, set| + klass.selection_presenters(set) + end end def account_reset_or_cancel_link diff --git a/app/presenters/webauthn_setup_presenter.rb b/app/presenters/webauthn_setup_presenter.rb index d931f55cab9..c7b44ca9bb8 100644 --- a/app/presenters/webauthn_setup_presenter.rb +++ b/app/presenters/webauthn_setup_presenter.rb @@ -1,13 +1,17 @@ class WebauthnSetupPresenter < SetupPresenter + include Rails.application.routes.url_helpers include ActionView::Helpers::UrlHelper include ActionView::Helpers::TranslationHelper + attr_reader :url_options + def initialize( current_user:, user_fully_authenticated:, user_opted_remember_device_cookie:, remember_device_default:, - platform_authenticator: + platform_authenticator:, + url_options: ) super( current_user: current_user, @@ -17,6 +21,7 @@ def initialize( ) @platform_authenticator = platform_authenticator + @url_options = url_options end def image_path @@ -54,23 +59,21 @@ def intro_html t( 'forms.webauthn_platform_setup.intro_html', app_name: APP_NAME, - link: intro_link, + link: link_to( + t('forms.webauthn_platform_setup.intro_link_text'), + help_center_redirect_path( + category: 'trouble-signing-in', + article: 'face-or-touch-unlock', + flow: :two_factor_authentication, + step: :webauthn_setup, + ), + ), ) else t('forms.webauthn_setup.intro_html') end end - def intro_link - link_to( - t('forms.webauthn_platform_setup.intro_link_text'), - MarketingSite.help_center_article_url( - category: 'get-started', - article: 'authentication-options', - ), - ) - end - def nickname_label if @platform_authenticator t('forms.webauthn_platform_setup.nickname') diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 2ec58e24479..efd3dc1df3f 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -559,47 +559,6 @@ def idv_address_visit track_event('IdV: address visited') end - # Tracks if request to get address candidates from ArcGIS fails - # @param [String] exception_class - # @param [String] exception_message - # @param [Boolean] response_body_present - # @param [Hash] response_body - # @param [Integer] response_status_code - def idv_arcgis_request_failure( - exception_class:, - exception_message:, - response_body_present:, - response_body:, - response_status_code:, - **extra - ) - track_event( - 'Request ArcGIS Address Candidates: request failed', - exception_class: exception_class, - exception_message: exception_message, - response_body_present: response_body_present, - response_body: response_body, - response_status_code: response_status_code, - **extra, - ) - end - - # Track when ArcGIS auth token refresh job completed - def idv_arcgis_token_job_completed(**extra) - track_event( - 'ArcgisTokenJob: Completed', - **extra, - ) - end - - # Track when ArcGIS auth token refresh job started - def idv_arcgis_token_job_started(**extra) - track_event( - 'ArcgisTokenJob: Started', - **extra, - ) - end - # @param [String] step the step that the user was on when they clicked cancel # @param [Idv::ProofingComponentsLogging] proofing_components User's current proofing components # The user confirmed their choice to cancel going through IDV @@ -644,16 +603,6 @@ def idv_cancellation_visited( ) end - # The user visited the "come back later" page shown during the GPO mailing flow - # @param [Idv::ProofingComponentsLogging] proofing_components User's current proofing components - def idv_come_back_later_visit(proofing_components: nil, **extra) - track_event( - 'IdV: come back later visited', - proofing_components: proofing_components, - **extra, - ) - end - # The user checked or unchecked the "By checking this box..." checkbox on the idv agreement step. # (This is a frontend event.) # @param [Boolean] checked Whether the user checked the checkbox @@ -1034,19 +983,6 @@ def idv_gpo_address_letter_requested( ) end - # @param [Boolean] letter_already_sent - # GPO address visited - def idv_gpo_address_visited( - letter_already_sent:, - **extra - ) - track_event( - 'IdV: USPS address visited', - letter_already_sent: letter_already_sent, - **extra, - ) - end - # The user visited the gpo confirm cancellation screen def idv_gpo_confirm_start_over_visited track_event('IdV: gpo confirm start over visited') @@ -1058,60 +994,6 @@ def idv_gpo_reminder_email_sent(user_id:, **extra) track_event('IdV: gpo reminder email sent', user_id: user_id, **extra) end - # @identity.idp.previous_event_name Account verification submitted - # @param [Boolean] success - # @param [Hash] errors - # @param [Hash] pii_like_keypaths - # @param [DateTime] enqueued_at When was this letter enqueued - # @param [Integer] which_letter Sorted by enqueue time, which letter had this code - # @param [Integer] letter_count How many letters did the user enqueue for this profile - # @param [Integer] attempts Number of attempts to enter a correct code - # @param [Boolean] pending_in_person_enrollment - # @param [Boolean] fraud_check_failed - # @see Reporting::IdentityVerificationReport#query This event is used by the identity verification - # report. Changes here should be reflected there. - # GPO verification submitted - def idv_gpo_verification_submitted( - success:, - errors:, - pii_like_keypaths:, - enqueued_at:, - which_letter:, - letter_count:, - attempts:, - pending_in_person_enrollment:, - fraud_check_failed:, - **extra - ) - track_event( - 'IdV: GPO verification submitted', - success: success, - errors: errors, - pii_like_keypaths: pii_like_keypaths, - enqueued_at: enqueued_at, - which_letter: which_letter, - letter_count: letter_count, - attempts: attempts, - pending_in_person_enrollment: pending_in_person_enrollment, - fraud_check_failed: fraud_check_failed, - **extra, - ) - end - - # @identity.idp.previous_event_name Account verification visited - # GPO verification visited - # @param [String,nil] source The source for the visit (i.e., "gpo_reminder_email"). - def idv_gpo_verification_visited( - source: nil, - **extra - ) - track_event( - 'IdV: GPO verification visited', - source: source, - **extra, - ) - end - # Tracks emails that are initiated during InPerson::EmailReminderJob # @param [String] email_type early or late # @param [String] enrollment_id @@ -1944,6 +1826,17 @@ def idv_intro_visit track_event('IdV: intro visited') end + # The user visited the "letter enqueued" page shown during the verify by mail flow + # @param [Idv::ProofingComponentsLogging] proofing_components User's current proofing components + # @identity.idp.previous_event_name IdV: come back later visited + def idv_letter_enqueued_visit(proofing_components: nil, **extra) + track_event( + 'IdV: letter enqueued visited', + proofing_components: proofing_components, + **extra, + ) + end + # Tracks when the user visits Mail only warning when vendor_status_sms is set to full_outage def idv_mail_only_warning_visited(**extra) track_event( @@ -2352,6 +2245,20 @@ def idv_proofing_resolution_result_missing(proofing_components: nil, **extra) ) end + # @param [Boolean] letter_already_sent + # GPO "request letter" page visited + # @identity.idp.previous_event_name IdV: USPS address visited + def idv_request_letter_visited( + letter_already_sent:, + **extra + ) + track_event( + 'IdV: request letter visited', + letter_already_sent: letter_already_sent, + **extra, + ) + end + # User submitted IDV password confirm page # @param [Boolean] success # @param [Boolean] fraud_review_pending @@ -2462,6 +2369,62 @@ def idv_usps_auth_token_refresh_job_started(**extra) ) end + # @identity.idp.previous_event_name Account verification submitted + # @identity.idp.previous_event_name IdV: GPO verification submitted + # @param [Boolean] success + # @param [Hash] errors + # @param [Hash] pii_like_keypaths + # @param [DateTime] enqueued_at When was this letter enqueued + # @param [Integer] which_letter Sorted by enqueue time, which letter had this code + # @param [Integer] letter_count How many letters did the user enqueue for this profile + # @param [Integer] attempts Number of attempts to enter a correct code + # @param [Boolean] pending_in_person_enrollment + # @param [Boolean] fraud_check_failed + # @see Reporting::IdentityVerificationReport#query This event is used by the identity verification + # report. Changes here should be reflected there. + # GPO verification submitted + def idv_verify_by_mail_enter_code_submitted( + success:, + errors:, + pii_like_keypaths:, + enqueued_at:, + which_letter:, + letter_count:, + attempts:, + pending_in_person_enrollment:, + fraud_check_failed:, + **extra + ) + track_event( + 'IdV: enter verify by mail code submitted', + success: success, + errors: errors, + pii_like_keypaths: pii_like_keypaths, + enqueued_at: enqueued_at, + which_letter: which_letter, + letter_count: letter_count, + attempts: attempts, + pending_in_person_enrollment: pending_in_person_enrollment, + fraud_check_failed: fraud_check_failed, + **extra, + ) + end + + # @identity.idp.previous_event_name Account verification visited + # @identity.idp.previous_event_name IdV: GPO verification visited + # Visited page used to enter address verification code received via US mail. + # @param [String,nil] source The source for the visit (i.e., "gpo_reminder_email"). + def idv_verify_by_mail_enter_code_visited( + source: nil, + **extra + ) + track_event( + 'IdV: enter verify by mail code visited', + source: source, + **extra, + ) + end + # @param [String] flow_path Document capture path ("hybrid" or "standard") # The user clicked the troubleshooting option to start in-person proofing def idv_verify_in_person_troubleshooting_option_clicked(flow_path:, @@ -2903,6 +2866,44 @@ def multi_region_kms_migration_profile_migration_summary( ) end + # @param [Boolean] success + # @param [String] exception + # @param [Integer] user_id + # A user was migrated from a single-region key to a multi-region key + def multi_region_kms_migration_user_migrated( + success:, + exception:, + user_id:, + **extra + ) + track_event( + 'Multi-region KMS migration: User migrated', + success: success, + exception: exception, + user_id: user_id, + **extra, + ) + end + + # @param [Integer] user_count + # @param [Integer] success_count + # @param [Integer] error_count + # The user migration job finished running + def multi_region_kms_migration_user_migration_summary( + user_count:, + success_count:, + error_count:, + **extra + ) + track_event( + 'Multi-region KMS migration: User migration summary', + user_count: user_count, + success_count: success_count, + error_count: error_count, + **extra, + ) + end + # @param [Boolean] success # @param [String] client_id # @param [Boolean] client_id_parameter_present diff --git a/app/services/arcgis_api/geocoder.rb b/app/services/arcgis_api/geocoder.rb deleted file mode 100644 index 7345c58fb09..00000000000 --- a/app/services/arcgis_api/geocoder.rb +++ /dev/null @@ -1,189 +0,0 @@ -module ArcgisApi - class Geocoder - AddressCandidate = Struct.new( - :address, :location, :street_address, :city, :state, :zip_code, - keyword_init: true - ) - Location = Struct.new(:latitude, :longitude, keyword_init: true) - API_TOKEN_HOST = URI(IdentityConfig.store.arcgis_api_generate_token_url).host - API_TOKEN_CACHE_KEY = "arcgis_api_token:#{API_TOKEN_HOST}" - - # These are option URL params that tend to apply to multiple endpoints - # https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find-address-candidates.htm#ESRI_SECTION2_38613C3FCB12462CAADD55B2905140BF - COMMON_DEFAULT_PARAMETERS = { - f: 'json', - countryCode: 'USA', - # See https://developers.arcgis.com/rest/geocode/api-reference/geocoding-category-filtering.htm#ESRI_SECTION1_502B3FE2028145D7B189C25B1A00E17B - # and https://developers.arcgis.com/rest/geocode/api-reference/geocoding-service-output.htm#GUID-D5C1A6E8-82DE-4900-8F8D-B390C2714A1F - category: [ - # A subset of a PointAddress that represents a house or building subaddress location, - # such as an apartment unit, floor, or individual building within a complex. - # E.g. 3836 Emerald Ave, Suite C, La Verne, CA, 91750 - 'Subaddress', - - # A street address based on points that represent house and building locations. - # E.g. 380 New York St, Redlands, CA, 92373 - 'Point Address', - - # A street address that differs from PointAddress because the house number is interpolated - # from a range of numbers. E.g. 647 Haight St, San Francisco, CA, 94117 - 'Street Address', - - # Similar to a street address but without the house number. - # E.g. Olive Ave, Redlands, CA, 92373. - 'Street Name', - ].join(','), - }.freeze - - KNOWN_FIND_ADDRESS_CANDIDATES_PARAMETERS = [ - :magicKey, # Generated from /suggest; identifier used to retrieve full address record - :SingleLine, # Unvalidated address-like text string used to search for geocoded addresses - ] - - # Makes HTTP request to find a full address record using a magic key or single text line - # @param options [Hash] one of 'magicKey', which is an ID returned from /suggest, - # or 'SingleLine', which should be a single string address that includes at least city - # and state. - # @return [Array] AddressCandidates - def find_address_candidates(**options) - supported_params = options.slice(*KNOWN_FIND_ADDRESS_CANDIDATES_PARAMETERS) - - if supported_params.empty? - raise ArgumentError, <<~MSG - Unknown parameters: #{options.except(*KNOWN_FIND_ADDRESS_CANDIDATES_PARAMETERS)}. - See https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find-address-candidates.htm - MSG - end - - params = { - outFields: 'StAddr,City,RegionAbbr,Postal', - **COMMON_DEFAULT_PARAMETERS, - **supported_params, - } - - parse_address_candidates( - faraday.get( - IdentityConfig.store.arcgis_api_find_address_candidates_url, params, - dynamic_headers - ) do |req| - req.options.context = { service_name: 'arcgis_geocoder_find_address_candidates' } - end.body, - ) - end - - # Makes a request to retrieve a new token - # it expires after 1 hour - # @return [String] Auth token - def retrieve_token! - token, expires = request_token.fetch_values('token', 'expires') - expires_at = Time.zone.at(expires / 1000) - Rails.cache.write(API_TOKEN_CACHE_KEY, token, expires_at: expires_at) - token - end - - # Checks the cache for an unexpired token and returns that. - # If the cache has expired, retrieves a new token and returns it - # @return [String] Auth token - def token - Rails.cache.read(API_TOKEN_CACHE_KEY) || retrieve_token! - end - - private - - def faraday - Faraday.new do |conn| - # Log request metrics - conn.request :instrumentation, name: 'request_metric.faraday' - - conn.options.timeout = IdentityConfig.store.arcgis_api_request_timeout_seconds - - # Raise an error subclassing Faraday::Error on 4xx, 5xx, and malformed responses - # Note: The order of this matters for parsing the error response body. - conn.response :raise_error - - # Parse JSON responses - conn.response :json, content_type: 'application/json' - - yield conn if block_given? - end - end - - def parse_address_candidates(response_body) - handle_api_errors(response_body) - - response_body['candidates'].map do |candidate| - AddressCandidate.new( - address: candidate['address'], - location: Location.new( - longitude: candidate.dig('location', 'x'), - latitude: candidate.dig('location', 'y'), - ), - street_address: candidate.dig('attributes', 'StAddr'), - city: candidate.dig('attributes', 'City'), - state: candidate.dig('attributes', 'RegionAbbr'), - zip_code: candidate.dig('attributes', 'Postal'), - ) - end - end - - # handles API error state when returned as a status of 200 - # @param response_body [Hash] - def handle_api_errors(response_body) - if response_body['error'] - # response_body is in this format: - # {"error"=>{"code"=>400, "message"=>"", "details"=>[""]}} - error_code = response_body.dig('error', 'code') - error_message = response_body.dig('error', 'message') || "Received error code #{error_code}" - # log an error - analytics.idv_arcgis_request_failure( - exception_class: 'ArcGIS', - exception_message: error_message, - response_body_present: false, - response_body: '', - response_status_code: error_code, - api_status_code: error_code, - ) - Rails.cache.delete(API_TOKEN_CACHE_KEY) # this might only be needed for local testing - raise Faraday::ClientError.new( - RuntimeError.new(error_message), - { - status: error_code, - body: { details: response_body.dig('error', 'details')&.join(', ') }, - }, - ) - end - end - - # Retrieve the short-lived API token (if needed) and then pass - # the headers to an arbitrary block of code as a Hash. - # - # Returns the same value returned by that block of code. - def dynamic_headers - { 'Authorization' => "Bearer #{token}" } - end - - # Makes HTTP request to authentication endpoint and - # returns the token and when it expires (1 hour). - # @return [Hash] API response - def request_token - body = { - username: IdentityConfig.store.arcgis_api_username, - password: IdentityConfig.store.arcgis_api_password, - referer: IdentityConfig.store.domain_name, - f: 'json', - } - - faraday.post( - IdentityConfig.store.arcgis_api_generate_token_url, URI.encode_www_form(body) - ) do |req| - req.options.context = { service_name: 'arcgis_token' } - end.body.tap do |body| - handle_api_errors(body) - end - end - - def analytics(user: AnonymousUser.new) - Analytics.new(user: user, request: nil, session: {}, sp: nil) - end - end -end diff --git a/app/services/arcgis_api/geocoder_factory.rb b/app/services/arcgis_api/geocoder_factory.rb deleted file mode 100644 index 0bd6d041cb3..00000000000 --- a/app/services/arcgis_api/geocoder_factory.rb +++ /dev/null @@ -1,11 +0,0 @@ -module ArcgisApi - class GeocoderFactory - def create - if IdentityConfig.store.arcgis_mock_fallback - ArcgisApi::Mock::Geocoder.new - else - ArcgisApi::Geocoder.new - end - end - end -end diff --git a/app/services/arcgis_api/mock/fixtures.rb b/app/services/arcgis_api/mock/fixtures.rb deleted file mode 100644 index 34bb5cb6d2b..00000000000 --- a/app/services/arcgis_api/mock/fixtures.rb +++ /dev/null @@ -1,50 +0,0 @@ -module ArcgisApi - module Mock - class Fixtures - def self.request_candidates_response - generate_address_candidates.to_json - end - - def self.request_candidates_empty_response - load_response_fixture('request_candidates_response_empty.json') - end - - def self.request_candidates_error - load_response_fixture('request_candidates_error.json') - end - - def self.load_response_fixture(filename) - Rails.root.join('spec', 'fixtures', 'arcgis_responses', filename).read - end - - def self.generate_address_candidates(count = 5) - { - candidates: Array.new(count) do - { - address: Faker::Address.full_address, - location: { - x: Faker::Address.latitude, - y: Faker::Address.longitude, - }, - attributes: { - StAddr: Faker::Address.street_address, - City: Faker::Address.city, - RegionAbbr: Faker::Address.state_abbr, - Postal: Faker::Address.zip, - }, - } - end, - } - end - - def self.request_token_service_error - load_response_fixture('request_token_service_error.json') - end - - def self.invalid_gis_token_credentials_response - load_response_fixture('invalid_gis_token_credentials_response.json') - end - private_class_method :generate_address_candidates - end - end -end diff --git a/app/services/arcgis_api/mock/geocoder.rb b/app/services/arcgis_api/mock/geocoder.rb deleted file mode 100644 index 8c800f7ad0c..00000000000 --- a/app/services/arcgis_api/mock/geocoder.rb +++ /dev/null @@ -1,40 +0,0 @@ -module ArcgisApi - module Mock - class Geocoder < ArcgisApi::Geocoder - def faraday - super do |conn| - conn.adapter :test do |stub| - stub_generate_token(stub) - stub_address_candidates(stub) - end - end - end - - private - - def stub_generate_token(stub) - stub.post(IdentityConfig.store.arcgis_api_generate_token_url) do |env| - [ - 200, - { 'Content-Type': 'application/json' }, - { - token: '1234', - expires: 1234, - ssl: true, - }.to_json, - ] - end - end - - def stub_address_candidates(stub) - stub.get(IdentityConfig.store.arcgis_api_find_address_candidates_url) do |env| - [ - 200, - { 'Content-Type': 'application/json' }, - ArcgisApi::Mock::Fixtures.request_candidates_response, - ] - end - end - end - end -end diff --git a/app/services/encryption/encryptors/background_proofing_arg_encryptor.rb b/app/services/encryption/encryptors/background_proofing_arg_encryptor.rb index d7364cf0ddf..eb012994157 100644 --- a/app/services/encryption/encryptors/background_proofing_arg_encryptor.rb +++ b/app/services/encryption/encryptors/background_proofing_arg_encryptor.rb @@ -6,12 +6,12 @@ class BackgroundProofingArgEncryptor def encrypt(plaintext) aes_ciphertext = AesEncryptor.new.encrypt(plaintext, aes_encryption_key) - kms_ciphertext = KmsClient.new.encrypt(aes_ciphertext, 'context' => 'session-encryption') + kms_ciphertext = kms_client.encrypt(aes_ciphertext, 'context' => 'session-encryption') encode(kms_ciphertext) end def decrypt(ciphertext) - aes_ciphertext = KmsClient.new.decrypt( + aes_ciphertext = kms_client.decrypt( decode(ciphertext), 'context' => 'session-encryption' ) aes_encryptor.decrypt(aes_ciphertext, aes_encryption_key) @@ -27,6 +27,10 @@ def aes_encryption_key IdentityConfig.store.session_encryption_key[0...32] end + def kms_client + @kms_client ||= KmsClient.new(kms_key_id: IdentityConfig.store.aws_kms_session_key_id) + end + add_method_tracer :encrypt, "Custom/#{name}/encrypt" add_method_tracer :decrypt, "Custom/#{name}/decrypt" end diff --git a/app/services/encryption/encryptors/session_encryptor.rb b/app/services/encryption/encryptors/session_encryptor.rb index 34b226d1067..42002bb2352 100644 --- a/app/services/encryption/encryptors/session_encryptor.rb +++ b/app/services/encryption/encryptors/session_encryptor.rb @@ -6,12 +6,12 @@ class SessionEncryptor def encrypt(plaintext) aes_ciphertext = AesEncryptor.new.encrypt(plaintext, aes_encryption_key) - kms_ciphertext = KmsClient.new.encrypt(aes_ciphertext, 'context' => 'session-encryption') + kms_ciphertext = kms_client.encrypt(aes_ciphertext, 'context' => 'session-encryption') encode(kms_ciphertext) end def decrypt(ciphertext) - aes_ciphertext = KmsClient.new.decrypt( + aes_ciphertext = kms_client.decrypt( decode(ciphertext), 'context' => 'session-encryption' ) aes_encryptor.decrypt(aes_ciphertext, aes_encryption_key) @@ -27,6 +27,10 @@ def aes_encryption_key IdentityConfig.store.session_encryption_key[0...32] end + def kms_client + @kms_client ||= KmsClient.new(kms_key_id: IdentityConfig.store.aws_kms_session_key_id) + end + add_method_tracer :encrypt, "Custom/#{name}/encrypt" add_method_tracer :decrypt, "Custom/#{name}/decrypt" end diff --git a/app/services/encryption/multi_region_kms_migration/user_migrator.rb b/app/services/encryption/multi_region_kms_migration/user_migrator.rb new file mode 100644 index 00000000000..75f59054056 --- /dev/null +++ b/app/services/encryption/multi_region_kms_migration/user_migrator.rb @@ -0,0 +1,91 @@ +module Encryption + module MultiRegionKmsMigration + class UserMigrator + include ::NewRelic::Agent::MethodTracer + + attr_reader :user + + def initialize(user) + @user = user + end + + def migrate! + user.with_lock do + if needs_password_migration? + multi_region_digest = migrate_ciphertext(user.encrypted_password_digest) + user.update!( + encrypted_password_digest: user.encrypted_password_digest, + encrypted_password_digest_multi_region: multi_region_digest, + ) + end + + if needs_recovery_code_migration? + multi_region_digest = migrate_ciphertext(user.encrypted_recovery_code_digest) + user.update!( + encrypted_recovery_code_digest: user.encrypted_recovery_code_digest, + encrypted_recovery_code_digest_multi_region: multi_region_digest, + ) + end + end + end + + private + + def migrate_ciphertext(ciphertext_string) + ciphertext = Encryption::PasswordVerifier::PasswordDigest.parse_from_string( + ciphertext_string, + ) + kms_decrypted_password_digest = multi_region_kms_client.decrypt( + ciphertext.encrypted_password, kms_encryption_context + ) + multi_region_kms_encrypted_password = multi_region_kms_client.encrypt( + kms_decrypted_password_digest, kms_encryption_context + ) + Encryption::PasswordVerifier::PasswordDigest.new( + encrypted_password: multi_region_kms_encrypted_password, + password_salt: ciphertext.password_salt, + password_cost: ciphertext.password_cost, + ).to_s + end + + def needs_password_migration? + return false if user.encrypted_password_digest_multi_region.present? + return false if user.encrypted_password_digest.blank? + + ciphertext = Encryption::PasswordVerifier::PasswordDigest.parse_from_string( + user.encrypted_password_digest, + ) + + return false if ciphertext.uak_password_digest? + true + end + + def needs_recovery_code_migration? + return false if user.encrypted_recovery_code_digest_multi_region.present? + return false if user.encrypted_recovery_code_digest.blank? + + ciphertext = Encryption::PasswordVerifier::PasswordDigest.parse_from_string( + user.encrypted_recovery_code_digest, + ) + + return false if ciphertext.uak_password_digest? + true + end + + def kms_encryption_context + { + 'context' => 'password-digest', + 'user_uuid' => user.uuid, + } + end + + def multi_region_kms_client + @multi_region_kms_client ||= KmsClient.new( + kms_key_id: IdentityConfig.store.aws_kms_multi_region_key_id, + ) + end + + add_method_tracer :migrate!, "Custom/#{name}/migrate!" + end + end +end diff --git a/app/services/idv/analytics_events_enhancer.rb b/app/services/idv/analytics_events_enhancer.rb index a4ea664f4e2..759a3b2d7f5 100644 --- a/app/services/idv/analytics_events_enhancer.rb +++ b/app/services/idv/analytics_events_enhancer.rb @@ -4,13 +4,13 @@ module AnalyticsEventsEnhancer idv_cancellation_confirmed idv_cancellation_go_back idv_cancellation_visited - idv_come_back_later_visit idv_forgot_password idv_forgot_password_confirmed idv_final idv_gpo_address_letter_enqueued idv_gpo_address_letter_requested idv_in_person_ready_to_verify_visit + idv_letter_enqueued_visit idv_personal_key_acknowledgment_toggled idv_personal_key_downloaded idv_personal_key_submitted diff --git a/app/services/idv/session.rb b/app/services/idv/session.rb index bb57f9e1e31..e952e9da614 100644 --- a/app/services/idv/session.rb +++ b/app/services/idv/session.rb @@ -17,12 +17,11 @@ class Session phone_for_mobile_flow pii previous_phone_step_params - profile_confirmation profile_id - profile_step_params redo_document_capture resolution_successful skip_hybrid_handoff + ssn threatmetrix_review_status threatmetrix_session_id user_phone_confirmation @@ -185,16 +184,10 @@ def clear_applicant! def mark_verify_info_step_complete! session[:resolution_successful] = true - # This is here to maintain backwards compadibility with old code. - # Once the code that checks `profile_confirmation` is removed from prod - # this setter and eventually the value in the Idv::Session struct itself - # can be removed. - session[:profile_confirmation] = true end def invalidate_verify_info_step! session[:resolution_successful] = nil - session[:profile_confirmation] = nil end def invalidate_steps_after_verify_info! diff --git a/app/views/accounts/_pending_profile_gpo.html.erb b/app/views/accounts/_pending_profile_gpo.html.erb index cbc20037104..f613180fda4 100644 --- a/app/views/accounts/_pending_profile_gpo.html.erb +++ b/app/views/accounts/_pending_profile_gpo.html.erb @@ -3,6 +3,6 @@ <%= t('account.index.verification.instructions') %>

- <%= link_to t('account.index.verification.reactivate_button'), idv_gpo_verify_path %> + <%= link_to t('account.index.verification.reactivate_button'), idv_verify_by_mail_enter_code_path %>

<% end %> diff --git a/app/views/idv/gpo_verify/index.html.erb b/app/views/idv/by_mail/enter_code/index.html.erb similarity index 93% rename from app/views/idv/gpo_verify/index.html.erb rename to app/views/idv/by_mail/enter_code/index.html.erb index 034392ef5a5..22c000e0976 100644 --- a/app/views/idv/gpo_verify/index.html.erb +++ b/app/views/idv/by_mail/enter_code/index.html.erb @@ -39,7 +39,7 @@ 'idv.gpo.did_not_receive_letter.intro.request_new_letter_prompt_html', request_new_letter_link: link_to( t('idv.gpo.did_not_receive_letter.intro.request_new_letter_link'), - idv_gpo_path, + idv_request_letter_path, ), ) %> <% end %> @@ -60,7 +60,7 @@ <%= simple_form_for( @gpo_verify_form, - url: idv_gpo_verify_path, + url: idv_verify_by_mail_enter_code_path, html: { autocomplete: 'off', method: :post }, ) do |f| %>
@@ -83,7 +83,7 @@ <% if @should_prompt_user_to_request_another_letter %> <% unless @user_did_not_receive_letter %> - <%= link_to t('idv.messages.gpo.resend'), idv_gpo_path, class: 'display-block margin-bottom-2' %> + <%= link_to t('idv.messages.gpo.resend'), idv_request_letter_path, class: 'display-block margin-bottom-2' %> <% end %> <% end %> diff --git a/app/views/idv/gpo_verify/rate_limited.html.erb b/app/views/idv/by_mail/enter_code/rate_limited.html.erb similarity index 100% rename from app/views/idv/gpo_verify/rate_limited.html.erb rename to app/views/idv/by_mail/enter_code/rate_limited.html.erb diff --git a/app/views/idv/come_back_later/show.html.erb b/app/views/idv/by_mail/letter_enqueued/show.html.erb similarity index 100% rename from app/views/idv/come_back_later/show.html.erb rename to app/views/idv/by_mail/letter_enqueued/show.html.erb diff --git a/app/views/idv/gpo/index.html.erb b/app/views/idv/by_mail/request_letter/index.html.erb similarity index 97% rename from app/views/idv/gpo/index.html.erb rename to app/views/idv/by_mail/request_letter/index.html.erb index 58664779d38..7fad784e22f 100644 --- a/app/views/idv/gpo/index.html.erb +++ b/app/views/idv/by_mail/request_letter/index.html.erb @@ -30,7 +30,7 @@
<%= button_to @presenter.button, - idv_gpo_path, + idv_request_letter_path, method: 'put', class: 'usa-button usa-button--big usa-button--wide' %>
diff --git a/app/views/idv/confirm_start_over/index.html.erb b/app/views/idv/confirm_start_over/index.html.erb index f03d9f93520..41724090fd0 100644 --- a/app/views/idv/confirm_start_over/index.html.erb +++ b/app/views/idv/confirm_start_over/index.html.erb @@ -25,4 +25,4 @@ ).with_content(t('idv.buttons.continue_plain')) %>
<% end %> -<%= render('idv/shared/back', step: 'gpo_verify', fallback_path: idv_gpo_verify_path) %> +<%= render('idv/shared/back', step: 'gpo_verify', fallback_path: idv_verify_by_mail_enter_code_path) %> diff --git a/app/views/idv/in_person/ssn/show.html.erb b/app/views/idv/in_person/ssn/show.html.erb index e8512c995bd..3a25d815d2f 100644 --- a/app/views/idv/in_person/ssn/show.html.erb +++ b/app/views/idv/in_person/ssn/show.html.erb @@ -60,7 +60,7 @@ locals: <% end %> <%= simple_form_for( - Idv::SsnFormatForm.new(current_user), + Idv::SsnFormatForm.new(current_user, nil), url: url_for, method: :put, html: { autocomplete: 'off' }, diff --git a/app/views/idv/in_person/verify_info/show.html.erb b/app/views/idv/in_person/verify_info/show.html.erb index 6aff91ed815..25ea23ca778 100644 --- a/app/views/idv/in_person/verify_info/show.html.erb +++ b/app/views/idv/in_person/verify_info/show.html.erb @@ -2,6 +2,7 @@ locals: @step_indicator_steps - the correct Idv::Flows variable for this flow @pii - user's information + @ssn - user's ssn @had_barcode_read_failure - show warning if there's a barcode read error %> @@ -132,12 +133,12 @@ locals: <%= t('idv.form.ssn') %>: <%= render( 'shared/masked_text', - text: SsnFormatter.format(@pii[:ssn]), - masked_text: SsnFormatter.format_masked(@pii[:ssn]), + text: SsnFormatter.format(@ssn), + masked_text: SsnFormatter.format_masked(@ssn), accessible_masked_text: t( 'idv.accessible_labels.masked_ssn', - first_number: @pii[:ssn][0], - last_number: @pii[:ssn][-1], + first_number: @ssn[0], + last_number: @ssn[-1], ), toggle_label: t('forms.ssn.show'), ) %> diff --git a/app/views/idv/phone/new.html.erb b/app/views/idv/phone/new.html.erb index ad97b710ce5..9eccdb60444 100644 --- a/app/views/idv/phone/new.html.erb +++ b/app/views/idv/phone/new.html.erb @@ -80,7 +80,7 @@ 'idv.messages.phone.failed_number.gpo_alert_html', link_html: link_to( t('idv.messages.phone.failed_number.gpo_verify_link'), - idv_gpo_path, + idv_request_letter_path, ), ) %> <% else %> @@ -129,7 +129,7 @@ heading: t('components.troubleshooting_options.default_heading'), options: [ gpo_letter_available && { - url: idv_gpo_path, + url: idv_request_letter_path, text: t('idv.troubleshooting.options.verify_by_mail'), }, ].select(&:present?), diff --git a/app/views/idv/phone_errors/_warning.html.erb b/app/views/idv/phone_errors/_warning.html.erb index 13ff634a3c5..3c993d86915 100644 --- a/app/views/idv/phone_errors/_warning.html.erb +++ b/app/views/idv/phone_errors/_warning.html.erb @@ -34,7 +34,7 @@ locals: }, @gpo_letter_available && { text: t('idv.troubleshooting.options.verify_by_mail'), - url: idv_gpo_path, + url: idv_request_letter_path, }, decorated_session.sp_name && { url: return_to_sp_failure_to_proof_path( diff --git a/app/views/idv/phone_errors/failure.html.erb b/app/views/idv/phone_errors/failure.html.erb index 594d7837e8f..526da33f467 100644 --- a/app/views/idv/phone_errors/failure.html.erb +++ b/app/views/idv/phone_errors/failure.html.erb @@ -34,7 +34,7 @@ <% if @gpo_letter_available %>
<%= render ButtonComponent.new( - action: ->(**tag_options, &block) { link_to idv_gpo_path, **tag_options, &block }, + action: ->(**tag_options, &block) { link_to idv_request_letter_path, **tag_options, &block }, big: true, wide: true, ).with_content(t('idv.failure.phone.rate_limited.gpo.button')) %> diff --git a/app/views/idv/phone_errors/warning.html.erb b/app/views/idv/phone_errors/warning.html.erb index d962b925021..e53d56d6980 100644 --- a/app/views/idv/phone_errors/warning.html.erb +++ b/app/views/idv/phone_errors/warning.html.erb @@ -51,7 +51,7 @@
<%= render ButtonComponent.new( - action: ->(**tag_options, &block) { link_to idv_gpo_path, **tag_options, &block }, + action: ->(**tag_options, &block) { link_to idv_request_letter_path, **tag_options, &block }, big: true, wide: true, outline: true, diff --git a/app/views/idv/verify_info/show.html.erb b/app/views/idv/verify_info/show.html.erb index 8ef047236c8..8244ca499c2 100644 --- a/app/views/idv/verify_info/show.html.erb +++ b/app/views/idv/verify_info/show.html.erb @@ -2,6 +2,7 @@ locals: @step_indicator_steps - the correct Idv::Flows variable for this flow @pii - user's information + @ssn - user's ssn @had_barcode_read_failure - show warning if there's a barcode read error %> @@ -97,12 +98,12 @@ locals: <%= t('idv.form.ssn') %>: <%= render( 'shared/masked_text', - text: SsnFormatter.format(@pii[:ssn]), - masked_text: SsnFormatter.format_masked(@pii[:ssn]), + text: SsnFormatter.format(@ssn), + masked_text: SsnFormatter.format_masked(@ssn), accessible_masked_text: t( 'idv.accessible_labels.masked_ssn', - first_number: @pii[:ssn][0], - last_number: @pii[:ssn][-1], + first_number: @ssn[0], + last_number: @ssn[-1], ), toggle_label: t('forms.ssn.show'), ) %> diff --git a/app/views/user_mailer/gpo_reminder.html.erb b/app/views/user_mailer/gpo_reminder.html.erb index ef04ff809b6..5c4da0812e4 100644 --- a/app/views/user_mailer/gpo_reminder.html.erb +++ b/app/views/user_mailer/gpo_reminder.html.erb @@ -27,7 +27,7 @@ <%= link_to t('idv.messages.gpo_reminder.finish'), - idv_gpo_verify_url, + idv_verify_by_mail_enter_code_url, target: '_blank', class: 'float-center', align: 'center', @@ -47,7 +47,7 @@ 'idv.messages.gpo_reminder.did_not_get_a_letter_html', another_letter_link_html: link_to( t('idv.messages.gpo_reminder.sign_in_and_request_another_letter'), - idv_gpo_verify_url(did_not_receive_letter: 1), + idv_verify_by_mail_enter_code_url(did_not_receive_letter: 1), { style: "text-decoration: 'underline'" }, ), ) %> diff --git a/app/views/users/piv_cac_setup_from_sign_in/prompt.html.erb b/app/views/users/piv_cac_setup_from_sign_in/prompt.html.erb index 348b068e81f..cbcd456be03 100644 --- a/app/views/users/piv_cac_setup_from_sign_in/prompt.html.erb +++ b/app/views/users/piv_cac_setup_from_sign_in/prompt.html.erb @@ -25,11 +25,16 @@
<%= f.submit t('forms.piv_cac_setup.submit') %>
-
- <%= link_to t('forms.piv_cac_setup.no_thanks'), - new_user_session_url, - class: 'usa-button usa-button--wide usa-button--big usa-button--outline' %> -
<% end %> +<%= render ButtonComponent.new( + action: ->(**tag_options, &block) do + button_to(login_add_piv_cac_prompt_path, **tag_options, method: :post, &block) + end, + big: true, + wide: true, + outline: true, + class: 'margin-top-2', + ).with_content(t('forms.piv_cac_setup.no_thanks')) %> + <%= render 'shared/cancel', link: new_user_session_url %> diff --git a/app/views/vendor_outage/show.html.erb b/app/views/vendor_outage/show.html.erb index f204a6f3a56..281d4715d4d 100644 --- a/app/views/vendor_outage/show.html.erb +++ b/app/views/vendor_outage/show.html.erb @@ -4,7 +4,7 @@ options: [ @show_gpo_option && { text: t('idv.troubleshooting.options.verify_by_mail'), - url: idv_gpo_path, + url: idv_request_letter_path, }, { text: t('vendor_outage.get_updates_on_status_page'), diff --git a/config/application.rb b/config/application.rb index 971180f4b23..455645f0517 100644 --- a/config/application.rb +++ b/config/application.rb @@ -130,7 +130,6 @@ class Application < Rails::Application resource '/api/analytics-events', headers: :any, methods: [:get] resource '/api/country-support', headers: :any, methods: [:get] if IdentityConfig.store.in_person_public_address_search_enabled - resource '/api/address_search', headers: :any, methods: %i[post options] resource '/api/usps_locations', headers: :any, methods: %i[post options] end end diff --git a/config/application.yml.default b/config/application.yml.default index 4a1c07eb8aa..d95b9ab29a1 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -41,14 +41,6 @@ acuant_get_results_timeout: 1.0 acuant_create_document_timeout: 1.0 add_email_link_valid_for_hours: 24 address_identity_proofing_supported_country_codes: '["AS", "GU", "MP", "PR", "US", "VI"]' -arcgis_api_username: '' -arcgis_api_password: '' -arcgis_mock_fallback: true -arcgis_api_generate_token_url: 'https://gis.gsa.gov/portal/sharing/rest/generateToken' -arcgis_api_find_address_candidates_url: 'https://gis.gsa.gov/servernh/rest/services/GSA/USA/GeocodeServer/findAddressCandidates' -arcgis_api_refresh_token_job_cron: '0/55 * * * *' -arcgis_api_refresh_token_job_enabled: false -arcgis_api_request_timeout_seconds: 5 asset_host: '' async_wait_timeout_seconds: 60 async_stale_job_timeout_seconds: 300 @@ -60,6 +52,7 @@ aws_kms_client_contextless_pool_size: 5 aws_kms_client_multi_pool_size: 5 aws_kms_multi_region_key_id: alias/login-dot-gov-keymaker-multi-region aws_kms_multi_region_read_enabled: false +aws_kms_session_key_id: alias/login-dot-gov-test-keymaker aws_logo_bucket: '' aws_region: 'us-west-2' backup_code_cost: '2000$8$1$' @@ -146,7 +139,7 @@ in_person_enrollments_ready_job_visibility_timeout_seconds: 30 in_person_enrollments_ready_job_wait_time_seconds: 20 in_person_results_delay_in_hours: 1 in_person_completion_survey_url: 'https://login.gov' -in_person_full_address_entry_enabled: false +in_person_full_address_entry_enabled: true in_person_outage_message_enabled: false # in_person_outage_expected_update_date and in_person_outage_emailed_by_date below # are strings in the format 'Month day, year' @@ -419,7 +412,6 @@ production: aamva_private_key: '' aamva_public_key: '' aamva_verification_url: 'https://verificationservices-cert.aamva.org:18449/dldv/2.1/online' - arcgis_api_refresh_token_job_enabled: true attribute_encryption_key: attribute_encryption_key_queue: '[]' aws_logo_bucket: '' diff --git a/config/application.yml.default.docker b/config/application.yml.default.docker index 196f6af58cb..5cb51cd09bd 100644 --- a/config/application.yml.default.docker +++ b/config/application.yml.default.docker @@ -31,5 +31,4 @@ production: telephony_adapter: test doc_auth_vendor: 'mock' usps_auth_token_refresh_job_enabled: false - arcgis_api_refresh_token_job_enabled: false lexisnexis_threatmetrix_mock_enabled: true diff --git a/config/initializers/job_configurations.rb b/config/initializers/job_configurations.rb index f027a9ee2d9..78edbc75ad3 100644 --- a/config/initializers/job_configurations.rb +++ b/config/initializers/job_configurations.rb @@ -177,12 +177,6 @@ cron: cron_12m, } end), - arcgis_token: (if IdentityConfig.store.arcgis_api_refresh_token_job_enabled - { - class: 'ArcgisTokenJob', - cron: IdentityConfig.store.arcgis_api_refresh_token_job_cron, - } - end), # Account creation/deletion stats for OKRs quarterly_account_stats: { class: 'Reports::QuarterlyAccountStats', @@ -195,11 +189,17 @@ cron: cron_24h, args: -> { [14.days.ago] }, }, + # Weekly report describing account reuse monthly_account_reuse_report: { class: 'Reports::MonthlyAccountReuseReport', cron: cron_1st_of_mo, args: -> { [Time.zone.today] }, }, + # Job to backfill encrypted_pii_recovery_multi_region on profiles + multi_region_kms_migration_profile_migraiton: { + class: 'MultiRegionKmsMigration::ProfileMigrationJob', + cron: cron_12m, + }, }.compact end # rubocop:enable Metrics/BlockLength diff --git a/config/locales/forms/es.yml b/config/locales/forms/es.yml index 152b10de671..f3c449b72e5 100644 --- a/config/locales/forms/es.yml +++ b/config/locales/forms/es.yml @@ -148,7 +148,7 @@ es: intro_html: '

Guarde la cara o la huella digital como credencial en su dispositivo. De esta forma, accederá a su cuenta con una de ellas. %{app_name} no almacena la cara ni la huella digital.

Es posible - que necesite usar el mismo dispositivo para ingresar en cada ocasión + que necesite usar el mismo dispositivo para ingresar en cada ocasión. %{link}

' intro_link_text: Obtenga más información sobre el desbloqueo con la cara o con la huella digital. diff --git a/config/locales/forms/fr.yml b/config/locales/forms/fr.yml index 85512d11b15..ce5005634e1 100644 --- a/config/locales/forms/fr.yml +++ b/config/locales/forms/fr.yml @@ -153,7 +153,7 @@ fr: qu’identifiant sur votre appareil, afin de pouvoir les utiliser pour accéder à votre compte. %{app_name} ne stocke pas votre visage ni votre empreinte digitale

Il se peut que vous ayez besoin d’utiliser le - même appareil pour vous connecter chaque fois.%{link}

' + même appareil pour vous connecter chaque fois. %{link}

' intro_link_text: En savoir plus sur le déverrouillage facial ou sur le déverrouillage tactile. nickname: Pseudo dispositivo diff --git a/config/locales/image_description/en.yml b/config/locales/image_description/en.yml index 0ad51b973e4..3433e8be26e 100644 --- a/config/locales/image_description/en.yml +++ b/config/locales/image_description/en.yml @@ -5,6 +5,7 @@ en: delete: Red trash can error: Red error x error_lock: Red error lock + info_pin_map: Image of a map pin info_question: Blue question mark laptop: Laptop computer personal_key: Personal key diff --git a/config/locales/image_description/es.yml b/config/locales/image_description/es.yml index 16f5ec5b245..1003287e15f 100644 --- a/config/locales/image_description/es.yml +++ b/config/locales/image_description/es.yml @@ -5,6 +5,7 @@ es: delete: Bote de basura rojo error: x roja de error error_lock: candado rojo de error + info_pin_map: Imagen de un marcador de mapa info_question: signo de interrogación azul laptop: Computadora portátil personal_key: Clave personal diff --git a/config/locales/image_description/fr.yml b/config/locales/image_description/fr.yml index 2acde6571d7..6e5de75bfc2 100644 --- a/config/locales/image_description/fr.yml +++ b/config/locales/image_description/fr.yml @@ -5,6 +5,7 @@ fr: delete: Poubelle rouge error: erreur rouge x error_lock: verrouillage rouge des erreurs + info_pin_map: Image d’une épingle à carte info_question: point d’interrogation bleu laptop: Ordinateur portable personal_key: Clé personnelle diff --git a/config/locales/telephony/en.yml b/config/locales/telephony/en.yml index 9e02a0167f4..eb0b8cdd769 100644 --- a/config/locales/telephony/en.yml +++ b/config/locales/telephony/en.yml @@ -15,7 +15,7 @@ en: code expires in %{expiration} minutes. confirmation_ipp_enrollment_result: sms: |- - %{app_name}: You attempted to verify your identity at a Post Office on %{proof_date}. Check your email for your result. + %{app_name}: You visited the Post Office on %{proof_date}. Check email for your result. Not you? Report this right away: %{contact_number} confirmation_otp: sms: |- %{app_name}: Your one-time code is %{code}. It expires in %{expiration} minutes. Don't share this code with anyone. diff --git a/config/locales/telephony/es.yml b/config/locales/telephony/es.yml index 682909ff6ec..8be4d787dad 100644 --- a/config/locales/telephony/es.yml +++ b/config/locales/telephony/es.yml @@ -15,7 +15,7 @@ es: Este código expira en %{expiration} minutos. confirmation_ipp_enrollment_result: sms: |- - %{app_name}: Intentó verificar su identidad en una oficina postal en %{proof_date}. Revise su correo electrónico para ver su resultado. + %{app_name}: Visitó la oficina de correos el %{proof_date}. Revise su correo electrónico para ver su resultado. ¿No fue usted? Informe ahora mismo: %{contact_number} confirmation_otp: sms: |- %{app_name}: La contraseña es %{code}. Esta contraseña puede usarse una vez y se vence en %{expiration} minutos. No la comparta con nadie. diff --git a/config/locales/telephony/fr.yml b/config/locales/telephony/fr.yml index 41a35bbf284..b1428880d30 100644 --- a/config/locales/telephony/fr.yml +++ b/config/locales/telephony/fr.yml @@ -16,7 +16,7 @@ fr: minutes. confirmation_ipp_enrollment_result: sms: |- - %{app_name}: Vous avez tenté de vérifier votre identité dans un bureau de poste le %{proof_date}. Vérifiez votre e-mail pour votre résultat. + %{app_name}: Vous avez visité le bureau de poste le %{proof_date}. Vérifiez votre e-mail pour votre résultat. Ce n'est pas vous? Signalez-le immédiatement: %{contact_number} confirmation_otp: sms: |- %{app_name}: Votre code à usage unique est %{code}. Il est valable pendant %{expiration} minutes. Vous ne devez pas partager ce code avec personne. diff --git a/config/routes.rb b/config/routes.rb index 3ba43611fb6..a0f8f899ecf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,8 +12,6 @@ get '/api/openid_connect/userinfo' => 'openid_connect/user_info#show' post '/api/risc/security_events' => 'risc/security_events#create' - post '/api/address_search' => 'idv/in_person/public/address_search#index' - match '/api/address_search' => 'idv/in_person/public/address_search#options', via: :options post '/api/usps_locations' => 'idv/in_person/public/usps_locations#index' match '/api/usps_locations' => 'idv/in_person/public/usps_locations#options', via: :options @@ -44,7 +42,6 @@ post '/api/service_provider' => 'service_provider#update' post '/api/verify/images' => 'idv/image_uploads#create' post '/api/logger' => 'frontend_log#create' - post '/api/addresses' => 'idv/in_person/address_search#index' get '/openid_connect/authorize' => 'openid_connect/authorization#index' get '/openid_connect/logout' => 'openid_connect/logout#index' @@ -315,7 +312,6 @@ end get '/mail_only_warning' => 'mail_only_warning#show' - get '/come_back_later' => 'come_back_later#show' get '/personal_key' => 'personal_key#show' post '/personal_key' => 'personal_key#update' get '/forgot_password' => 'forgot_password#new' @@ -387,7 +383,6 @@ as: :in_person_ready_to_verify post '/in_person/usps_locations' => 'in_person/usps_locations#index' put '/in_person/usps_locations' => 'in_person/usps_locations#update' - post '/in_person/addresses' => 'in_person/address_search#index' get '/in_person/ssn' => 'in_person/ssn#show' put '/in_person/ssn' => 'in_person/ssn#update' get '/in_person/verify_info' => 'in_person/verify_info#show' @@ -395,15 +390,29 @@ get '/in_person/:step' => 'in_person#show', as: :in_person_step put '/in_person/:step' => 'in_person#update' - get '/by_mail' => 'gpo_verify#index', as: :gpo_verify - post '/by_mail' => 'gpo_verify#create' + get '/by_mail' => 'by_mail/enter_code#index', as: :verify_by_mail_enter_code + post '/by_mail' => 'by_mail/enter_code#create' get '/by_mail/confirm_start_over' => 'confirm_start_over#index', as: :confirm_start_over if FeatureManagement.gpo_verification_enabled? - get '/usps' => 'gpo#index', as: :gpo - put '/usps' => 'gpo#create' + get '/usps' => 'by_mail/request_letter#index', as: :request_letter + put '/usps' => 'by_mail/request_letter#create' + + # These will be made the new "official" routes in a future commit + get '/by_mail/request_letter' => 'by_mail/request_letter#index' + put '/by_mail/request_letter' => 'by_mail/request_letter#create' end + + get '/come_back_later' => 'by_mail/letter_enqueued#show', as: :letter_enqueued + + # BEGIN temporary routes in preparation for renaming the GPO routes + # These will allow old instances to serve requests for new routes during the 50/50 + # state when new routes are deployed. + get '/by_mail/letter_enqueued' => 'by_mail/letter_enqueued#show' + get '/by_mail/enter_code' => 'by_mail/enter_code#index' + post '/by_mail/enter_code' => 'by_mail/enter_code#create' + # END temporary routes end root to: 'users/sessions#new' diff --git a/docs/mobile.md b/docs/mobile.md index 5ea1fe53db2..1404711f0e9 100644 --- a/docs/mobile.md +++ b/docs/mobile.md @@ -64,7 +64,7 @@ If you don't see any tabs under the "Remote Target" heading, you may need to try inspect-androd-chrome-tab -### iPhone / Safari +### iPhone / Safari or Chrome These instructions work only if your development computer is an Apple product. You will need a USB cable with the appropriate "lightning" connector to plug into an iPhone. @@ -74,7 +74,9 @@ These instructions work only if your development computer is an Apple product. Y 2. Take a glance at the newly-revealed **Develop** menu item in Safari. Seeing how the menu looks now may help you find your iPhone when it later appears in the menu. -3. On your iPhone, go to **Settings → Safari → Advanced** and turn on Web Inspector. Make sure JavaScript is also on. +3. Turn on Web Inspector for your phone browser + - Safari: On your iPhone, go to **Settings → Safari → Advanced** and turn on Web Inspector. Make sure JavaScript is also on. + - Chrome: On your iPhone, go to **Chrome App → ... → Settings → Content Settings** and turn on Web Inspector. 4. Plug your iPhone into your development computer with a USB cable. (A USB hub may or may not work.) If you see a message on your phone asking you to **Trust This Computer?** click to trust it. diff --git a/knapsack_rspec_report.json b/knapsack_rspec_report.json index c7564bddb54..6f9efe20355 100644 --- a/knapsack_rspec_report.json +++ b/knapsack_rspec_report.json @@ -1,916 +1,922 @@ { - "spec/bin/oncall/email-deliveries_spec.rb": 0.016029498, - "spec/bin/query-cloudwatch_spec.rb": 0.11443181, - "spec/browsers_json_spec.rb": 0.00403294, - "spec/components/accordion_component_spec.rb": 0.021929535, - "spec/components/alert_component_spec.rb": 0.039371790000000004, - "spec/components/alert_icon_component_spec.rb": 0.018874768, - "spec/components/badge_component_spec.rb": 0.013681295999999999, - "spec/components/barcode_component_spec.rb": 0.06315646, - "spec/components/base_component_spec.rb": 0.048200353, - "spec/components/block_link_component_spec.rb": 0.015960888, - "spec/components/button_component_spec.rb": 0.042670017, - "spec/components/captcha_submit_button_component_spec.rb": 0.055777369, - "spec/components/click_observer_component_spec.rb": 0.011688411999999999, - "spec/components/clipboard_button_component_spec.rb": 0.019295595, - "spec/components/countdown_alert_component_spec.rb": 0.025977046, - "spec/components/countdown_component_spec.rb": 0.028313503, - "spec/components/download_button_component_spec.rb": 0.014437744, - "spec/components/flash_component_spec.rb": 0.045745931999999996, - "spec/components/form_link_component_spec.rb": 0.011954956, - "spec/components/icon_component_spec.rb": 0.025169294000000002, - "spec/components/javascript_required_component_spec.rb": 0.035737663, - "spec/components/language_picker_component_spec.rb": 0.06554908799999999, - "spec/components/memorable_date_component_spec.rb": 0.115841776, - "spec/components/modal_component_spec.rb": 0.017940805, - "spec/components/one_time_code_input_component_spec.rb": 0.103618665, - "spec/components/page_footer_component_spec.rb": 0.013076154, - "spec/components/page_heading_component_spec.rb": 0.010842735, - "spec/components/password_confirmation_component_spec.rb": 0.021583312, - "spec/components/password_toggle_component_spec.rb": 0.033281253, - "spec/components/phone_input_component_spec.rb": 0.479912697, - "spec/components/print_button_component_spec.rb": 0.012890986, - "spec/components/process_list_component_spec.rb": 0.030706864, - "spec/components/spinner_button_component_spec.rb": 0.021058603, - "spec/components/status_page_component_spec.rb": 0.03744955, - "spec/components/step_indicator_component_spec.rb": 0.044376354, - "spec/components/step_indicator_step_component_spec.rb": 0.02384773, - "spec/components/submit_button_component_spec.rb": 0.015670774000000002, - "spec/components/tab_navigation_component_spec.rb": 0.599260453, - "spec/components/time_component_spec.rb": 0.012970068000000001, - "spec/components/troubleshooting_options_component_spec.rb": 0.024936777, - "spec/components/validated_field_component_spec.rb": 0.044629393999999996, - "spec/components/vendor_outage_alert_component_spec.rb": 0.022095568, - "spec/components/webauthn_input_component_spec.rb": 0.040618443, - "spec/components/webauthn_verify_button_component_spec.rb": 0.018525789, - "spec/config/initializers/ab_tests_spec.rb": 0.003185286, - "spec/config/initializers/ahoy_spec.rb": 0.015264737, - "spec/config/initializers/ext_digest_spec.rb": 0.002716886, - "spec/config/initializers/job_configurations_spec.rb": 0.054526002, - "spec/config/initializers/phonelib_spec.rb": 0.003695375, - "spec/config/initializers/secure_headers_spec.rb": 0.003783135, - "spec/controllers/account_reset/cancel_controller_spec.rb": 0.644431397, - "spec/controllers/account_reset/confirm_delete_account_controller_spec.rb": 0.014952030000000002, - "spec/controllers/account_reset/confirm_request_controller_spec.rb": 0.015272001, - "spec/controllers/account_reset/delete_account_controller_spec.rb": 0.5485947800000001, - "spec/controllers/account_reset/pending_controller_spec.rb": 0.293989887, - "spec/controllers/account_reset/recovery_options_controller_spec.rb": 0.09731969700000001, - "spec/controllers/account_reset/request_controller_spec.rb": 1.29395448, - "spec/controllers/accounts/personal_keys_controller_spec.rb": 0.474896688, - "spec/controllers/accounts_controller_spec.rb": 0.386755554, - "spec/controllers/analytics_events_controller_spec.rb": 0.011811402, - "spec/controllers/api/internal/sessions_controller_spec.rb": 0.711887727, - "spec/controllers/application_controller_spec.rb": 1.197846373, - "spec/controllers/concerns/api/csrf_token_concern_spec.rb": 0.012881304, - "spec/controllers/concerns/effective_user_spec.rb": 0.067127, - "spec/controllers/concerns/idv/ab_test_analytics_concern_spec.rb": 0.046839160000000005, - "spec/controllers/concerns/idv/acuant_concern_spec.rb": 0.032227052, - "spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb": 0.19871330399999998, - "spec/controllers/concerns/idv/phone_otp_rate_limitable_spec.rb": 0.016687026, - "spec/controllers/concerns/idv/step_indicator_concern_spec.rb": 0.263845389, - "spec/controllers/concerns/idv/threat_metrix_concern_spec.rb": 0.038026687999999996, - "spec/controllers/concerns/idv_step_concern_spec.rb": 0.501916241, - "spec/controllers/concerns/mfa_setup_concern_spec.rb": 0.049723394, - "spec/controllers/concerns/rate_limit_concern_spec.rb": 0.106417175, - "spec/controllers/concerns/reauthentication_required_concern_spec.rb": 0.107135434, - "spec/controllers/concerns/recaptcha_concern_spec.rb": 0.053792851, - "spec/controllers/concerns/render_condition_concern_spec.rb": 0.061273178, - "spec/controllers/concerns/verify_sp_attributes_concern_spec.rb": 0.339501192, - "spec/controllers/country_support_controller_spec.rb": 0.035494995, - "spec/controllers/event_disavowal_controller_spec.rb": 0.266770625, - "spec/controllers/fake_s3_controller_spec.rb": 0.017341684, - "spec/controllers/forgot_password_controller_spec.rb": 0.013267148, - "spec/controllers/frontend_log_controller_spec.rb": 0.216992566, - "spec/controllers/health/database_controller_spec.rb": 0.027351936, - "spec/controllers/health/health_controller_spec.rb": 0.024173067, - "spec/controllers/health/outbound_controller_spec.rb": 0.049121868, - "spec/controllers/idv/agreement_controller_spec.rb": 0.274759449, - "spec/controllers/idv/cancellations_controller_spec.rb": 0.460948923, - "spec/controllers/idv/capture_doc_status_controller_spec.rb": 0.387922111, - "spec/controllers/idv/come_back_later_controller_spec.rb": 0.04431445, - "spec/controllers/idv/document_capture_controller_spec.rb": 0.358413446, - "spec/controllers/idv/forgot_password_controller_spec.rb": 0.296915728, - "spec/controllers/idv/getting_started_controller_spec.rb": 0.40922300699999997, - "spec/controllers/idv/gpo_controller_spec.rb": 1.451111489, - "spec/controllers/idv/gpo_only_warning_controller_spec.rb": 0.172325562, - "spec/controllers/idv/gpo_verify_controller_spec.rb": 1.46865419, - "spec/controllers/idv/hybrid_handoff_controller_spec.rb": 0.54156289, - "spec/controllers/idv/hybrid_mobile/capture_complete_controller_spec.rb": 0.179117442, - "spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb": 0.270306834, - "spec/controllers/idv/hybrid_mobile/entry_controller_spec.rb": 0.432816698, - "spec/controllers/idv/image_uploads_controller_spec.rb": 1.235049496, - "spec/controllers/idv/in_person/address_search_controller_spec.rb": 0.262545847, - "spec/controllers/idv/in_person/public/address_search_controller_spec.rb": 0.055419974, - "spec/controllers/idv/in_person/public/usps_locations_controller_spec.rb": 0.01539855, - "spec/controllers/idv/in_person/ready_to_verify_controller_spec.rb": 0.151524404, - "spec/controllers/idv/in_person/ssn_controller_spec.rb": 0.442049107, - "spec/controllers/idv/in_person/usps_locations_controller_spec.rb": 0.250745724, - "spec/controllers/idv/in_person/verify_info_controller_spec.rb": 0.6786473199999999, - "spec/controllers/idv/in_person_controller_spec.rb": 0.151641501, - "spec/controllers/idv/link_sent_controller_spec.rb": 0.372120715, - "spec/controllers/idv/not_verified_controller_spec.rb": 0.0305031, - "spec/controllers/idv/otp_verification_controller_spec.rb": 0.276954292, - "spec/controllers/idv/personal_key_controller_spec.rb": 1.251379822, - "spec/controllers/idv/phone_controller_spec.rb": 1.298165313, - "spec/controllers/idv/phone_errors_controller_spec.rb": 0.732257493, - "spec/controllers/idv/please_call_controller_spec.rb": 0.123074087, - "spec/controllers/idv/resend_otp_controller_spec.rb": 0.080586851, - "spec/controllers/idv/review_controller_spec.rb": 11.447201596, - "spec/controllers/idv/session_errors_controller_spec.rb": 1.910555484, - "spec/controllers/idv/sessions_controller_spec.rb": 0.271090021, - "spec/controllers/idv/ssn_controller_spec.rb": 0.715428995, - "spec/controllers/idv/unavailable_controller_spec.rb": 0.057567601999999995, - "spec/controllers/idv/verify_info_controller_spec.rb": 1.727100134, - "spec/controllers/idv/welcome_controller_spec.rb": 0.518981182, - "spec/controllers/idv_controller_spec.rb": 0.402118385, - "spec/controllers/mfa_confirmation_controller_spec.rb": 0.024088044, - "spec/controllers/no_js_controller_spec.rb": 0.015443068, - "spec/controllers/openid_connect/authorization_controller_spec.rb": 1.257397793, - "spec/controllers/openid_connect/certs_controller_spec.rb": 0.012502876, - "spec/controllers/openid_connect/configuration_controller_spec.rb": 0.014025018, - "spec/controllers/openid_connect/logout_controller_spec.rb": 1.058289311, - "spec/controllers/openid_connect/token_controller_spec.rb": 0.187052349, - "spec/controllers/openid_connect/user_info_controller_spec.rb": 0.114519797, - "spec/controllers/pages_controller_spec.rb": 0.040046856, - "spec/controllers/password_capture_controller_spec.rb": 0.105781734, - "spec/controllers/reactivate_account_controller_spec.rb": 0.156927868, - "spec/controllers/redirect/contact_controller_spec.rb": 0.008324502, - "spec/controllers/redirect/help_center_controller_spec.rb": 0.037317177, - "spec/controllers/redirect/policy_controller_spec.rb": 0.009606344, - "spec/controllers/redirect/return_to_sp_controller_spec.rb": 0.046473474, - "spec/controllers/risc/configuration_controller_spec.rb": 0.007048622, - "spec/controllers/risc/security_events_controller_spec.rb": 0.553805812, - "spec/controllers/saml_completion_controller_spec.rb": 0.023114381, - "spec/controllers/saml_idp_controller_spec.rb": 10.427402423, - "spec/controllers/saml_post_controller_spec.rb": 0.0173086, - "spec/controllers/saml_signed_message_spec.rb": 0.369522323, - "spec/controllers/service_provider_controller_spec.rb": 0.079090357, - "spec/controllers/sign_out_controller_spec.rb": 0.134153349, - "spec/controllers/sign_up/cancellations_controller_spec.rb": 0.38024873800000003, - "spec/controllers/sign_up/completions_controller_spec.rb": 0.825167963, - "spec/controllers/sign_up/email_confirmations_controller_spec.rb": 0.184444821, - "spec/controllers/sign_up/emails_controller_spec.rb": 0.016880889, - "spec/controllers/sign_up/passwords_controller_spec.rb": 0.176964396, - "spec/controllers/sign_up/registrations_controller_spec.rb": 0.9349881809999999, - "spec/controllers/test/device_profiling_controller_spec.rb": 0.017992696000000002, - "spec/controllers/test/piv_cac_authentication_test_subject_controller_spec.rb": 0.034246558, - "spec/controllers/test/push_notification_controller_spec.rb": 0.020892189, - "spec/controllers/test/telephony_controller_spec.rb": 0.025101480000000002, - "spec/controllers/two_factor_authentication/backup_code_verification_controller_spec.rb": 0.8386131490000001, - "spec/controllers/two_factor_authentication/options_controller_spec.rb": 0.362142912, - "spec/controllers/two_factor_authentication/otp_verification_controller_spec.rb": 3.227179948, - "spec/controllers/two_factor_authentication/personal_key_verification_controller_spec.rb": 0.899425807, - "spec/controllers/two_factor_authentication/piv_cac_verification_controller_spec.rb": 1.007163137, - "spec/controllers/two_factor_authentication/sms_opt_in_controller_spec.rb": 0.434314913, - "spec/controllers/two_factor_authentication/totp_verification_controller_spec.rb": 0.7118313589999999, - "spec/controllers/two_factor_authentication/webauthn_verification_controller_spec.rb": 0.321169567, - "spec/controllers/users/authorization_confirmation_controller_spec.rb": 0.12795864699999998, - "spec/controllers/users/backup_code_setup_controller_spec.rb": 2.044818806, - "spec/controllers/users/delete_controller_spec.rb": 0.461463098, - "spec/controllers/users/edit_phone_controller_spec.rb": 0.15847371, - "spec/controllers/users/email_confirmations_controller_spec.rb": 1.1747965249999999, - "spec/controllers/users/email_language_controller_spec.rb": 0.170308849, - "spec/controllers/users/emails_controller_spec.rb": 0.504522221, - "spec/controllers/users/forget_all_browsers_controller_spec.rb": 0.161967116, - "spec/controllers/users/mfa_selection_controller_spec.rb": 0.208947573, - "spec/controllers/users/passwords_controller_spec.rb": 0.9977754129999999, - "spec/controllers/users/personal_keys_controller_spec.rb": 0.22366553, - "spec/controllers/users/phone_setup_controller_spec.rb": 0.223177211, - "spec/controllers/users/phones_controller_spec.rb": 0.399725803, - "spec/controllers/users/piv_cac_authentication_setup_controller_spec.rb": 0.841456191, - "spec/controllers/users/piv_cac_login_controller_spec.rb": 0.596468877, - "spec/controllers/users/please_call_controller_spec.rb": 0.024082175, - "spec/controllers/users/reset_passwords_controller_spec.rb": 2.066956614, - "spec/controllers/users/rules_of_use_controller_spec.rb": 0.337019643, - "spec/controllers/users/service_provider_revoke_controller_spec.rb": 0.404839203, - "spec/controllers/users/sessions_controller_spec.rb": 1.377879359, - "spec/controllers/users/totp_setup_controller_spec.rb": 3.81778188, - "spec/controllers/users/two_factor_authentication_controller_spec.rb": 1.614555972, - "spec/controllers/users/two_factor_authentication_setup_controller_spec.rb": 0.295617439, - "spec/controllers/users/verify_password_controller_spec.rb": 0.362259492, - "spec/controllers/users/verify_personal_key_controller_spec.rb": 0.698139564, - "spec/controllers/users/webauthn_setup_controller_spec.rb": 0.664785856, - "spec/controllers/vendor_outage_controller_spec.rb": 0.026793964, - "spec/decorators/device_decorator_spec.rb": 0.045672367, - "spec/decorators/email_context_spec.rb": 0.053522931, - "spec/decorators/event_decorator_spec.rb": 0.063504567, - "spec/decorators/mfa_context_spec.rb": 0.833185477, - "spec/decorators/service_provider_session_decorator_spec.rb": 0.168684744, - "spec/decorators/session_decorator_spec.rb": 0.017834157, - "spec/features/accessibility/idv_pages_spec.rb": 311.30431135, - "spec/features/accessibility/static_pages_spec.rb": 111.20816859199999, - "spec/features/accessibility/user_pages_spec.rb": 284.783216708, - "spec/features/accessibility/visitor_pages_spec.rb": 62.898459596, - "spec/features/account/backup_codes_spec.rb": 17.461253658, - "spec/features/account/device_spec.rb": 3.18660527, - "spec/features/account/unphishable_badge_spec.rb": 6.277008018, - "spec/features/account_connected_apps_spec.rb": 7.259324101000001, - "spec/features/account_creation/multiple_browsers_spec.rb": 14.778924625, - "spec/features/account_creation/sp_return_log_spec.rb": 4.418131184, - "spec/features/account_email_language_spec.rb": 10.105295949, - "spec/features/account_history_spec.rb": 3.290347017, - "spec/features/account_reset/cancel_request_spec.rb": 4.453041557, - "spec/features/account_reset/delete_account_spec.rb": 12.332110101, - "spec/features/account_reset/pending_request_spec.rb": 4.356147192, - "spec/features/device_tracking_spec.rb": 6.4033184, - "spec/features/event_disavowal_spec.rb": 41.732833108, - "spec/features/ialmax/saml_sign_in_spec.rb": 26.381675771, - "spec/features/idv/account_creation_spec.rb": 47.515435174000004, - "spec/features/idv/analytics_spec.rb": 47.541242773, - "spec/features/idv/cancel_spec.rb": 23.631593405, - "spec/features/idv/clearing_and_restarting_spec.rb": 69.331402404, - "spec/features/idv/confirm_start_over_spec.rb": 8.615027499, - "spec/features/idv/doc_auth/address_step_spec.rb": 40.021022115, - "spec/features/idv/doc_auth/agreement_spec.rb": 12.340974046, - "spec/features/idv/doc_auth/document_capture_spec.rb": 50.200625711, - "spec/features/idv/doc_auth/getting_started_spec.rb": 20.93810615, - "spec/features/idv/doc_auth/hybrid_handoff_spec.rb": 35.007203119, - "spec/features/idv/doc_auth/link_sent_spec.rb": 3.641936074, - "spec/features/idv/doc_auth/redo_document_capture_spec.rb": 27.270896345, - "spec/features/idv/doc_auth/ssn_step_spec.rb": 5.923736021, - "spec/features/idv/doc_auth/test_credentials_spec.rb": 9.533464259999999, - "spec/features/idv/doc_auth/verify_info_step_spec.rb": 119.300631601, - "spec/features/idv/doc_auth/welcome_spec.rb": 13.33034557, - "spec/features/idv/end_to_end_idv_spec.rb": 37.209372394, - "spec/features/idv/gpo_disabled_spec.rb": 10.046501798, - "spec/features/idv/hybrid_mobile/entry_spec.rb": 13.684451717, - "spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb": 40.814266004, - "spec/features/idv/in_person_spec.rb": 256.036439207, - "spec/features/idv/outage_spec.rb": 103.274384175, - "spec/features/idv/pending_profile_password_reset_spec.rb": 12.95651217, - "spec/features/idv/phone_errors_spec.rb": 26.06410248, - "spec/features/idv/phone_input_spec.rb": 13.087435521, - "spec/features/idv/phone_otp_rate_limiting_spec.rb": 28.028343194999998, - "spec/features/idv/proofing_components_spec.rb": 19.702021988, - "spec/features/idv/puerto_rican_address_spec.rb": 12.651740440000001, - "spec/features/idv/sp_handoff_spec.rb": 123.087861688, - "spec/features/idv/sp_requested_attributes_spec.rb": 62.861611579, - "spec/features/idv/steps/confirmation_step_spec.rb": 41.79072466, - "spec/features/idv/steps/forgot_password_step_spec.rb": 22.571051587, - "spec/features/idv/steps/gpo_otp_verification_step_spec.rb": 81.05347071999999, - "spec/features/idv/steps/gpo_step_spec.rb": 71.260392288, - "spec/features/idv/steps/in_person/ssn_spec.rb": 67.311191344, - "spec/features/idv/steps/in_person/state_id_step_spec.rb": 8.431870908, - "spec/features/idv/steps/in_person/verify_info_spec.rb": 35.633852467, - "spec/features/idv/steps/phone_otp_verification_step_spec.rb": 30.056020119, - "spec/features/idv/steps/phone_step_spec.rb": 212.701576452, - "spec/features/idv/steps/review_step_spec.rb": 26.905211112, - "spec/features/idv/threat_metrix_pending_spec.rb": 47.626580084, - "spec/features/idv/uak_password_spec.rb": 9.662862442, - "spec/features/legacy_passwords_spec.rb": 13.410819622, - "spec/features/load_testing/email_sign_up_spec.rb": 3.701921156, - "spec/features/multi_factor_authentication/mfa_cta_spec.rb": 16.491231593, - "spec/features/multiple_emails/add_email_spec.rb": 56.919889209, - "spec/features/multiple_emails/email_management_spec.rb": 24.254934721, - "spec/features/multiple_emails/reset_password_spec.rb": 7.428991173, - "spec/features/multiple_emails/sign_in_spec.rb": 11.099086243, - "spec/features/multiple_emails/sp_sign_in_spec.rb": 17.197742485, - "spec/features/new_device_tracking_spec.rb": 11.73324324, - "spec/features/openid_connect/authorization_confirmation_spec.rb": 24.948406334999998, - "spec/features/openid_connect/openid_connect_spec.rb": 175.398915327, - "spec/features/openid_connect/phishing_resistant_required_spec.rb": 53.147626076, - "spec/features/openid_connect/redirect_uri_validation_spec.rb": 33.118007607, - "spec/features/phone/add_phone_spec.rb": 39.708864666, - "spec/features/phone/confirmation_spec.rb": 110.361660798, - "spec/features/phone/default_phone_selection_spec.rb": 18.3316374, - "spec/features/phone/edit_phone_spec.rb": 9.496032134, - "spec/features/phone/rate_limitting_spec.rb": 51.907103627, - "spec/features/phone/remove_phone_spec.rb": 6.633094141, - "spec/features/remember_device/cookie_expiration_spec.rb": 7.037207915, - "spec/features/remember_device/phone_spec.rb": 33.585307313, - "spec/features/remember_device/revocation_spec.rb": 10.127280886000001, - "spec/features/remember_device/session_expiration_spec.rb": 3.964416338, - "spec/features/remember_device/sp_expiration_spec.rb": 210.965194528, - "spec/features/remember_device/totp_spec.rb": 50.517232160999995, - "spec/features/remember_device/user_opted_preference_spec.rb": 26.611881225, - "spec/features/remember_device/webauthn_spec.rb": 95.36310379, - "spec/features/reports/authorization_count_spec.rb": 85.459731246, - "spec/features/reports/monthly_gpo_letter_requests_report_spec.rb": 12.129190382, - "spec/features/reports/sp_active_users_report_spec.rb": 7.050487992000001, - "spec/features/saml/authorization_confirmation_spec.rb": 28.267998161999998, - "spec/features/saml/ial1/account_creation_spec.rb": 10.519696046, - "spec/features/saml/ial1_sso_spec.rb": 52.744601399000004, - "spec/features/saml/ial2_sso_spec.rb": 28.336969198000002, - "spec/features/saml/multiple_endpoints_spec.rb": 25.167846058, - "spec/features/saml/phishing_resistant_required_spec.rb": 43.824324236, - "spec/features/saml/redirect_uri_validation_spec.rb": 3.730775138, - "spec/features/saml/saml_logout_spec.rb": 23.405326642, - "spec/features/saml/saml_relay_state_spec.rb": 14.884182249, - "spec/features/saml/saml_spec.rb": 109.623368674, - "spec/features/session/decryption_spec.rb": 3.268707305, - "spec/features/session/timeout_spec.rb": 9.4113291, - "spec/features/sign_in/banned_users_spec.rb": 11.974359472, - "spec/features/sign_in/remember_device_default_spec.rb": 9.872865305, - "spec/features/sign_in/sp_return_log_spec.rb": 3.62995022, - "spec/features/sign_in/two_factor_options_spec.rb": 47.090297334, - "spec/features/sp_cost_tracking_spec.rb": 49.147899992999996, - "spec/features/two_factor_authentication/backup_code_sign_up_spec.rb": 23.266210852, - "spec/features/two_factor_authentication/change_factor_spec.rb": 16.740917582, - "spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb": 31.293558315, - "spec/features/two_factor_authentication/multiple_tabs_spec.rb": 10.362617987, - "spec/features/two_factor_authentication/sign_in_spec.rb": 112.221805175, - "spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb": 7.546569657, - "spec/features/users/password_recovery_via_recovery_code_spec.rb": 46.938266229, - "spec/features/users/password_reset_with_pending_profile_spec.rb": 6.9592271310000005, - "spec/features/users/piv_cac_management_spec.rb": 30.547620959, - "spec/features/users/regenerate_personal_key_spec.rb": 7.823530437, - "spec/features/users/sign_in_spec.rb": 365.684857889, - "spec/features/users/sign_out_spec.rb": 3.17907558, - "spec/features/users/sign_up_spec.rb": 147.282360199, - "spec/features/users/totp_management_spec.rb": 19.18292553, - "spec/features/users/user_edit_spec.rb": 3.259098979, - "spec/features/users/user_profile_spec.rb": 52.106702784, - "spec/features/users/verify_profile_spec.rb": 14.280162159, - "spec/features/visitors/bad_password_spec.rb": 3.535405508, - "spec/features/visitors/email_confirmation_spec.rb": 22.003049609, - "spec/features/visitors/email_language_preference_spec.rb": 6.4911326670000005, - "spec/features/visitors/i18n_spec.rb": 38.635086049, - "spec/features/visitors/js_disabled_spec.rb": 6.332076986000001, - "spec/features/visitors/navigation_spec.rb": 3.069709129, - "spec/features/visitors/password_recovery_spec.rb": 70.344225227, - "spec/features/visitors/resend_email_confirmation_spec.rb": 17.025253237, - "spec/features/visitors/set_password_spec.rb": 31.257997095, - "spec/features/visitors/sign_up_with_email_spec.rb": 29.178854434, - "spec/features/webauthn/hidden_spec.rb": 32.862081489, - "spec/features/webauthn/management_spec.rb": 53.298207404, - "spec/features/webauthn/sign_in_spec.rb": 21.850217707, - "spec/features/webauthn/sign_up_spec.rb": 14.150749127000001, - "spec/forms/add_user_email_form_spec.rb": 0.42580276100000003, - "spec/forms/backup_code_verification_form_spec.rb": 0.623128424, - "spec/forms/delete_user_email_form_spec.rb": 0.210262501, - "spec/forms/edit_phone_form_spec.rb": 0.222738532, - "spec/forms/event_disavowal/password_reset_from_disavowal_form_spec.rb": 0.8395951269999999, - "spec/forms/gpo_verify_form_spec.rb": 1.206826233, - "spec/forms/idv/api_image_upload_form_spec.rb": 1.0033632160000001, - "spec/forms/idv/doc_pii_form_spec.rb": 0.02771845, - "spec/forms/idv/in_person/address_form_spec.rb": 0.039573396, - "spec/forms/idv/phone_confirmation_otp_verification_form_spec.rb": 0.152126398, - "spec/forms/idv/phone_form_spec.rb": 1.0207794, - "spec/forms/idv/ssn_form_spec.rb": 0.11784415300000001, - "spec/forms/idv/ssn_format_form_spec.rb": 0.085384782, - "spec/forms/idv/state_id_form_spec.rb": 0.02166426, - "spec/forms/new_phone_form_spec.rb": 1.433822616, - "spec/forms/openid_connect_authorize_form_spec.rb": 0.281390302, - "spec/forms/openid_connect_logout_form_spec.rb": 0.447136335, - "spec/forms/openid_connect_token_form_spec.rb": 1.333544496, - "spec/forms/otp_delivery_selection_form_spec.rb": 0.15327406600000001, - "spec/forms/otp_verification_form_spec.rb": 0.330770143, - "spec/forms/password_form_spec.rb": 0.301609862, - "spec/forms/password_reset_email_form_spec.rb": 0.041808583, - "spec/forms/personal_key_form_spec.rb": 0.06260586800000001, - "spec/forms/register_user_email_form_spec.rb": 3.380474414, - "spec/forms/reset_password_form_spec.rb": 0.602732424, - "spec/forms/security_event_form_spec.rb": 2.51993092, - "spec/forms/totp_setup_form_spec.rb": 0.21515911299999999, - "spec/forms/totp_verification_form_spec.rb": 0.039981997, - "spec/forms/two_factor_authentication/phone_deletion_form_spec.rb": 0.471530551, - "spec/forms/two_factor_login_options_form_spec.rb": 0.017587342, - "spec/forms/two_factor_options_form_spec.rb": 0.31509855, - "spec/forms/update_email_language_form_spec.rb": 0.041982276, - "spec/forms/update_user_password_form_spec.rb": 0.34402706, - "spec/forms/user_piv_cac_login_form_spec.rb": 0.028470341, - "spec/forms/user_piv_cac_setup_form_spec.rb": 0.1321422, - "spec/forms/user_piv_cac_verification_form_spec.rb": 0.11411471200000001, - "spec/forms/verify_password_form_spec.rb": 0.143661832, - "spec/forms/verify_personal_key_form_spec.rb": 0.191811697, - "spec/forms/webauthn_setup_form_spec.rb": 0.277566684, - "spec/forms/webauthn_verification_form_spec.rb": 0.168862438, - "spec/forms/webauthn_visit_form_spec.rb": 0.130093268, - "spec/helpers/application_helper_spec.rb": 0.009548288, - "spec/helpers/go_back_helper_spec.rb": 0.020314744, - "spec/helpers/link_helper_spec.rb": 0.039760137, - "spec/helpers/locale_helper_spec.rb": 0.050905891, - "spec/helpers/script_helper_spec.rb": 0.035459462, - "spec/helpers/session_timeout_warning_helper_spec.rb": 0.017068177, - "spec/helpers/stylesheet_helper_spec.rb": 0.022812415, - "spec/i18n_spec.rb": 54.898213782, - "spec/jobs/address_proofing_job_spec.rb": 0.14946554, - "spec/jobs/application_job_spec.rb": 0.00212879, - "spec/jobs/arcgis_token_job_spec.rb": 0.00826398, - "spec/jobs/fraud_rejection_daily_job_spec.rb": 0.054524676, - "spec/jobs/get_usps_proofing_results_job_spec.rb": 8.725798706, - "spec/jobs/get_usps_ready_proofing_results_job_spec.rb": 1.099346811, - "spec/jobs/get_usps_waiting_proofing_results_job_spec.rb": 0.893019351, - "spec/jobs/gpo_daily_job_spec.rb": 0.057020859, - "spec/jobs/heartbeat_job_spec.rb": 0.007068972, - "spec/jobs/in_person/email_reminder_job_spec.rb": 0.873619004, - "spec/jobs/in_person/enrollments_ready_for_status_check/batch_processor_spec.rb": 0.027846448, - "spec/jobs/in_person/enrollments_ready_for_status_check/enrollment_pipeline_spec.rb": 0.134803985, - "spec/jobs/in_person/enrollments_ready_for_status_check/error_reporter_spec.rb": 0.026628640000000002, - "spec/jobs/in_person/enrollments_ready_for_status_check/sqs_batch_wrapper_spec.rb": 0.011806554, - "spec/jobs/in_person/enrollments_ready_for_status_check_job_spec.rb": 0.037152356, - "spec/jobs/in_person/send_proofing_notification_job_spec.rb": 0.501296203, - "spec/jobs/job_helpers/encryption_helper_spec.rb": 0.002909699, - "spec/jobs/job_helpers/s3_helper_spec.rb": 0.09047566200000001, - "spec/jobs/job_helpers/stale_job_helper_spec.rb": 0.012549832, - "spec/jobs/job_helpers/timer_spec.rb": 0.007969234, - "spec/jobs/phone_number_opt_out_sync_job_spec.rb": 0.062211133, - "spec/jobs/reports/agreement_summary_report_spec.rb": 0.084890255, - "spec/jobs/reports/base_report_spec.rb": 0.00380639, - "spec/jobs/reports/combined_invoice_supplement_report_spec.rb": 0.268783926, - "spec/jobs/reports/daily_auths_report_spec.rb": 0.210602125, - "spec/jobs/reports/daily_dropoffs_report_spec.rb": 0.22743522900000002, - "spec/jobs/reports/daily_registration_report_spec.rb": 0.161134769, - "spec/jobs/reports/deleted_user_accounts_report_spec.rb": 0.070425241, - "spec/jobs/reports/duplicate_ssn_report_spec.rb": 0.10374475500000001, - "spec/jobs/reports/irs_weekly_summary_report_spec.rb": 0.265210009, - "spec/jobs/reports/month_helper_spec.rb": 0.005062879, - "spec/jobs/reports/quarterly_account_stats_spec.rb": 0.32825381, - "spec/jobs/reports/query_helpers_spec.rb": 0.005812005, - "spec/jobs/reports/sp_active_users_report_spec.rb": 0.053793039, - "spec/jobs/reports/sp_issuer_user_counts_report_spec.rb": 0.035920965, - "spec/jobs/reports/sp_user_counts_report_spec.rb": 0.037685203, - "spec/jobs/reports/total_ial2_costs_report_spec.rb": 0.029817397, - "spec/jobs/reports/total_monthly_auths_report_spec.rb": 0.029754119, - "spec/jobs/reports/verification_failures_report_spec.rb": 0.458672768, - "spec/jobs/resolution_proofing_job_spec.rb": 1.08310779, - "spec/jobs/risc_delivery_job_spec.rb": 0.138099803, - "spec/jobs/threat_metrix_js_verification_job_spec.rb": 0.388718485, - "spec/jobs/usps_auth_token_refresh_job_spec.rb": 0.052430252, - "spec/lib/ab_test_bucket_spec.rb": 0.02630679, - "spec/lib/action_account_spec.rb": 0.64945279, - "spec/lib/analytics_events_documenter_spec.rb": 0.131911687, - "spec/lib/app_artifacts_spec.rb": 0.019064595, - "spec/lib/asset_sources_spec.rb": 0.042079723, - "spec/lib/aws/ses_spec.rb": 0.036781668000000003, - "spec/lib/base16_spec.rb": 0.008944698, - "spec/lib/data_pull_spec.rb": 0.467799439, - "spec/lib/data_requests/deployed/create_email_addresses_report_spec.rb": 0.019527341, - "spec/lib/data_requests/deployed/create_mfa_configurations_report_spec.rb": 0.156383077, - "spec/lib/data_requests/deployed/create_user_events_report_spec.rb": 0.052316581, - "spec/lib/data_requests/deployed/create_user_report_spec.rb": 0.079853579, - "spec/lib/data_requests/deployed/lookup_shared_device_users_spec.rb": 0.041058329, - "spec/lib/data_requests/deployed/lookup_user_by_uuid_spec.rb": 0.029085166, - "spec/lib/data_requests/local/fetch_cloudwatch_logs_spec.rb": 0.030412213, - "spec/lib/data_requests/local/write_cloudwatch_logs_spec.rb": 0.012975602, - "spec/lib/data_requests/local/write_user_events_spec.rb": 0.00589135, - "spec/lib/data_requests/local/write_user_info_spec.rb": 0.003899474, - "spec/lib/deploy/activate_spec.rb": 0.035560401, - "spec/lib/feature_management_spec.rb": 0.16935324, - "spec/lib/fingerprinter_spec.rb": 0.006360417, - "spec/lib/good_job_connection_pool_size_spec.rb": 0.008305107, - "spec/lib/headers_filter_spec.rb": 0.003686154, - "spec/lib/identity_config_spec.rb": 0.009103066, - "spec/lib/identity_cors_spec.rb": 0.022770119, - "spec/lib/identity_job_log_subscriber_spec.rb": 0.10132005599999999, - "spec/lib/linters/errors_add_linter_spec.rb": 0.17795768899999997, - "spec/lib/linters/image_size_linter_spec.rb": 0.04137473, - "spec/lib/linters/localized_validation_message_linter_spec.rb": 0.191137897, - "spec/lib/linters/mail_later_linter_spec.rb": 0.178001444, - "spec/lib/linters/redirect_back_linter_spec.rb": 0.18346305100000002, - "spec/lib/linters/url_options_linter_spec.rb": 0.19965920699999998, - "spec/lib/makefile_help_parser_spec.rb": 0.051550536, - "spec/lib/otp_code_generator_spec.rb": 0.016005775, - "spec/lib/pinpoint_supported_countries_spec.rb": 0.138713739, - "spec/lib/query_tracker_spec.rb": 0.011222914, - "spec/lib/reporting/authentication_report_spec.rb": 0.01950074, - "spec/lib/reporting/cloudwatch_client_spec.rb": 0.7635089070000001, - "spec/lib/reporting/cloudwatch_query_quoting_spec.rb": 0.0057256089999999996, - "spec/lib/reporting/cloudwatch_query_time_slice_spec.rb": 0.015159796, - "spec/lib/reporting/command_line_options_spec.rb": 0.077932021, - "spec/lib/reporting/identity_verification_report_spec.rb": 0.023723435, - "spec/lib/reporting/monthly_proofing_report_spec.rb": 0.008048655, - "spec/lib/session_encryptor_spec.rb": 0.027618164, - "spec/lib/tasks/dev_rake_spec.rb": 10.824365406, - "spec/lib/tasks/partners_rake_spec.rb": 0.769115526, - "spec/lib/tasks/review_profile_spec.rb": 0.875547714, - "spec/lib/tasks/rotate_rake_spec.rb": 0.273677931, - "spec/lib/telephony/alert_sender_spec.rb": 0.02412074, - "spec/lib/telephony/otp_sender_spec.rb": 0.072009463, - "spec/lib/telephony/pinpoint/aws_credential_builder_spec.rb": 0.014156001999999999, - "spec/lib/telephony/pinpoint/opt_out_manager_spec.rb": 0.067296089, - "spec/lib/telephony/pinpoint/sms_sender_spec.rb": 0.08879621, - "spec/lib/telephony/pinpoint/voice_sender_spec.rb": 0.046662381, - "spec/lib/telephony/pinpoint_configuration_spec.rb": 0.002015575, - "spec/lib/telephony/response_spec.rb": 0.030793108, - "spec/lib/telephony/telephony_spec.rb": 0.057784886, - "spec/lib/telephony/test/call_spec.rb": 0.017388538, - "spec/lib/telephony/test/message_spec.rb": 0.013050307, - "spec/lib/telephony/test/sms_sender_spec.rb": 0.016910006, - "spec/lib/telephony/test/voice_sender_spec.rb": 0.008776909999999999, - "spec/lib/telephony/util_spec.rb": 0.002168732, - "spec/lib/utf8_sanitizer_spec.rb": 0.030747785, - "spec/mailers/previews/report_mailer_preview_spec.rb": 0.003660543, - "spec/mailers/previews/user_mailer_preview_spec.rb": 0.161742787, - "spec/mailers/report_mailer_spec.rb": 0.091746431, - "spec/mailers/user_mailer_spec.rb": 3.842360828, - "spec/models/account_reset_request_spec.rb": 0.027082884, - "spec/models/agency_identity_spec.rb": 0.012213993999999999, - "spec/models/agency_spec.rb": 0.024545928, - "spec/models/agreements/iaa_gtc_spec.rb": 0.244737842, - "spec/models/agreements/iaa_order_spec.rb": 0.321724, - "spec/models/agreements/iaa_spec.rb": 0.174676324, - "spec/models/agreements/integration_spec.rb": 0.277707449, - "spec/models/agreements/integration_status_spec.rb": 0.038866911000000004, - "spec/models/agreements/integration_usage_spec.rb": 0.261801988, - "spec/models/agreements/partner_account_spec.rb": 0.149483012, - "spec/models/agreements/partner_account_status_spec.rb": 0.045561853, - "spec/models/anonymous_user_spec.rb": 0.0131436, - "spec/models/backup_code_configuration_spec.rb": 1.063496608, - "spec/models/concerns/user_otp_methods_spec.rb": 0.003014794, - "spec/models/deleted_user_spec.rb": 0.06806198100000001, - "spec/models/device_spec.rb": 0.060557745, - "spec/models/document_capture_session_spec.rb": 0.039966346, - "spec/models/email_address_spec.rb": 0.15576241700000001, - "spec/models/event_spec.rb": 0.025442565, - "spec/models/gpo_confirmation_code_spec.rb": 0.10772077099999999, - "spec/models/in_person_enrollment_spec.rb": 2.853410852, - "spec/models/notification_phone_configuration_spec.rb": 0.139568254, - "spec/models/null_identity_spec.rb": 0.0021026, - "spec/models/phone_configuration_spec.rb": 0.127054135, - "spec/models/phone_number_opt_out_spec.rb": 0.08150682299999999, - "spec/models/profile_spec.rb": 2.5322332419999998, - "spec/models/service_provider_identity_spec.rb": 0.39048299200000003, - "spec/models/service_provider_spec.rb": 0.047633344, - "spec/models/sp_return_log_spec.rb": 0.012147687, - "spec/models/suspended_email_spec.rb": 0.04176162, - "spec/models/user_spec.rb": 3.059542207, - "spec/models/webauthn_configuration_spec.rb": 0.202991992, - "spec/policies/backup_code_policy_spec.rb": 0.032645065, - "spec/policies/service_provider_mfa_policy_spec.rb": 0.529876993, - "spec/policies/two_factor_authentication/piv_cac_policy_spec.rb": 0.062591718, - "spec/policies/user_mfa_policy_spec.rb": 0.174788115, - "spec/policies/webauthn_login_option_policy_spec.rb": 0.064154187, - "spec/presenters/account_reset/pending_presenter_spec.rb": 0.104902387, - "spec/presenters/account_show_presenter_spec.rb": 0.128882304, - "spec/presenters/cancellation_presenter_spec.rb": 0.013717857, - "spec/presenters/completions_presenter_spec.rb": 0.687868257, - "spec/presenters/confirm_delete_email_presenter_spec.rb": 0.018192274, - "spec/presenters/eastern_time_presenter_spec.rb": 0.002841846, - "spec/presenters/idv/cancellations_presenter_spec.rb": 0.014413642, - "spec/presenters/idv/gpo_presenter_spec.rb": 0.16490828999999999, - "spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb": 0.529994275, - "spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb": 0.574721626, - "spec/presenters/image_upload_response_presenter_spec.rb": 0.039190325, - "spec/presenters/max_attempts_reached_presenter_spec.rb": 0.010618643, - "spec/presenters/mfa_confirmation_presenter_spec.rb": 0.011522072, - "spec/presenters/navigation_presenter_spec.rb": 0.099298787, - "spec/presenters/openid_connect_certs_presenter_spec.rb": 0.00278074, - "spec/presenters/openid_connect_configuration_presenter_spec.rb": 0.00477682, - "spec/presenters/openid_connect_user_info_presenter_spec.rb": 0.753319633, - "spec/presenters/piv_cac_authentication_setup_presenter_spec.rb": 0.05366925, - "spec/presenters/piv_cac_error_presenter_spec.rb": 0.011000324, - "spec/presenters/risc_configuration_presenter_spec.rb": 0.008463117, - "spec/presenters/saml_request_presenter_spec.rb": 0.014144068, - "spec/presenters/session_timeout_modal_presenter_spec.rb": 0.007462122999999999, - "spec/presenters/setup_presenter_spec.rb": 0.056136899, - "spec/presenters/two_factor_auth_code/authenticator_delivery_presenter_spec.rb": 0.006582608, - "spec/presenters/two_factor_auth_code/backup_code_presenter_spec.rb": 0.0077926720000000005, - "spec/presenters/two_factor_auth_code/generic_delivery_presenter_spec.rb": 0.016499915, - "spec/presenters/two_factor_auth_code/phone_delivery_presenter_spec.rb": 0.052256445, - "spec/presenters/two_factor_auth_code/piv_cac_authentication_presenter_spec.rb": 0.011009274, - "spec/presenters/two_factor_auth_code/webauthn_authentication_presenter_spec.rb": 0.038593498, - "spec/presenters/two_factor_authentication/auth_app_selection_presenter_spec.rb": 0.047265384, - "spec/presenters/two_factor_authentication/personal_key_selection_presenter_spec.rb": 0.001839484, - "spec/presenters/two_factor_authentication/phone_selection_presenter_spec.rb": 0.12635248799999999, - "spec/presenters/two_factor_authentication/piv_cac_selection_presenter_spec.rb": 0.045298039, - "spec/presenters/two_factor_authentication/selection_presenter_spec.rb": 0.013948381999999999, - "spec/presenters/two_factor_authentication/sms_selection_presenter_spec.rb": 0.06803094700000001, - "spec/presenters/two_factor_authentication/voice_selection_presenter_spec.rb": 0.14647997799999998, - "spec/presenters/two_factor_authentication/webauthn_platform_selection_presenter_spec.rb": 0.242268536, - "spec/presenters/two_factor_authentication/webauthn_selection_presenter_spec.rb": 0.066257998, - "spec/presenters/two_factor_login_options_presenter_spec.rb": 0.10114959800000001, - "spec/presenters/two_factor_options_presenter_spec.rb": 0.032307667, - "spec/presenters/utc_time_presenter_spec.rb": 0.002466402, - "spec/presenters/webauthn_setup_presenter_spec.rb": 0.163405878, - "spec/requests/acuant_sdk_spec.rb": 0.053141394, - "spec/requests/api_cors_spec.rb": 0.407012875, - "spec/requests/csp_spec.rb": 0.09229113200000001, - "spec/requests/headers_spec.rb": 0.197820925, - "spec/requests/i18n_spec.rb": 0.147324537, - "spec/requests/invalid_encoding_spec.rb": 0.191088257, - "spec/requests/invalid_sign_in_params_spec.rb": 0.076806458, - "spec/requests/not_acceptable_spec.rb": 0.062862756, - "spec/requests/openid_connect_authorize_spec.rb": 0.545217798, - "spec/requests/openid_connect_cors_spec.rb": 0.376321012, - "spec/requests/openid_connect_userinfo_spec.rb": 0.054525521, - "spec/requests/page_not_found_spec.rb": 0.098990951, - "spec/requests/rack_attack_spec.rb": 5.767118579, - "spec/requests/redirects_spec.rb": 0.13854102499999998, - "spec/requests/redis_down_spec.rb": 0.028999133, - "spec/requests/saml_requests_spec.rb": 0.25828631, - "spec/requests/secure_cookies_spec.rb": 0.331480271, - "spec/routing/gpo_verification_routing_spec.rb": 0.258306087, - "spec/scripts/changelog_check_spec.rb": 0.029954062, - "spec/services/access_token_verifier_spec.rb": 0.033926155, - "spec/services/account_reset/cancel_request_for_user_spec.rb": 0.404378925, - "spec/services/account_reset/cancel_spec.rb": 1.055362101, - "spec/services/account_reset/create_request_spec.rb": 0.6019008, - "spec/services/account_reset/delete_account_spec.rb": 0.5865679229999999, - "spec/services/account_reset/find_prending_request_for_user_spec.rb": 0.083543877, - "spec/services/account_reset/grant_request_spec.rb": 0.071444097, - "spec/services/account_reset/grant_requests_and_send_emails_spec.rb": 1.113416987, - "spec/services/account_reset/notify_user_of_request_cancellation_spec.rb": 0.605831943, - "spec/services/account_reset/validate_granted_token_spec.rb": 0.044007111, - "spec/services/active_profile_encryptor_spec.rb": 0.045984218, - "spec/services/agency_identity_linker_spec.rb": 0.411155885, - "spec/services/agency_seeder_spec.rb": 0.049166135, - "spec/services/agreements/iaa_gtc_seeder_spec.rb": 0.031874385, - "spec/services/agreements/iaa_order_seeder_spec.rb": 0.07156742299999999, - "spec/services/agreements/integration_seeder_spec.rb": 0.062045605000000004, - "spec/services/agreements/integration_status_seeder_spec.rb": 0.022427974, - "spec/services/agreements/partner_account_seeder_spec.rb": 0.047853344, - "spec/services/agreements/partner_account_status_seeder_spec.rb": 0.033851962, - "spec/services/analytics_spec.rb": 0.119346631, - "spec/services/arcgis_api/geocoder_factory_spec.rb": 0.00645898, - "spec/services/arcgis_api/geocoder_spec.rb": 0.212369798, - "spec/services/attribute_asserter_spec.rb": 1.33627643, - "spec/services/backup_code_generator_spec.rb": 1.390917526, - "spec/services/banned_user_resolver_spec.rb": 0.102483479, - "spec/services/barcode_outputter_spec.rb": 0.014407517, - "spec/services/browser_cache_spec.rb": 0.013072316, - "spec/services/browser_support_spec.rb": 0.028684710000000002, - "spec/services/calendar_service_spec.rb": 0.045940863, - "spec/services/cloud_front_header_parser_spec.rb": 0.015823336, - "spec/services/completions_decider_spec.rb": 0.018516192, - "spec/services/database_health_checker_spec.rb": 0.010625512, - "spec/services/date_parser_spec.rb": 0.014224035, - "spec/services/db/add_document_verification_and_selfie_costs_spec.rb": 0.024644791, - "spec/services/db/identity/sp_active_user_counts_spec.rb": 0.07445273399999999, - "spec/services/db/identity/sp_user_counts_spec.rb": 0.048754673, - "spec/services/db/monthly_auth_count/total_monthly_auth_counts_spec.rb": 0.036134489, - "spec/services/db/monthly_sp_auth_count/total_monthly_auth_counts_within_iaa_window_spec.rb": 0.09658569, - "spec/services/db/monthly_sp_auth_count/unique_monthly_auth_counts_by_iaa_spec.rb": 0.13792246800000002, - "spec/services/db/sp_return_log_spec.rb": 0.00750481, - "spec/services/deleted_accounts_report_spec.rb": 0.125034133, - "spec/services/displayable_pii_formatter_spec.rb": 0.681101073, - "spec/services/doc_auth/acuant/acuant_client_spec.rb": 0.256018007, - "spec/services/doc_auth/acuant/pii_from_doc_spec.rb": 0.013364989, - "spec/services/doc_auth/acuant/request_spec.rb": 0.522011786, - "spec/services/doc_auth/acuant/requests/create_document_request_spec.rb": 0.066697958, - "spec/services/doc_auth/acuant/requests/get_results_request_spec.rb": 0.06252634, - "spec/services/doc_auth/acuant/requests/upload_image_request_spec.rb": 0.074183904, - "spec/services/doc_auth/acuant/responses/create_document_response_spec.rb": 0.024513566, - "spec/services/doc_auth/acuant/responses/get_results_response_spec.rb": 0.062791743, - "spec/services/doc_auth/acuant/result_codes_spec.rb": 0.005929384, - "spec/services/doc_auth/error_generator_spec.rb": 0.061051392, - "spec/services/doc_auth/lexis_nexis/lexis_nexis_client_spec.rb": 0.237417442, - "spec/services/doc_auth/lexis_nexis/request_spec.rb": 0.47949409200000004, - "spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb": 0.125020423, - "spec/services/doc_auth/lexis_nexis/responses/true_id_response_spec.rb": 0.314634467, - "spec/services/doc_auth/mock/doc_auth_mock_client_spec.rb": 0.061074092, - "spec/services/doc_auth/mock/result_response_spec.rb": 0.054072298, - "spec/services/doc_auth/processed_alert_to_log_alert_formatter_spec.rb": 0.006417364, - "spec/services/doc_auth/response_spec.rb": 0.03212755, - "spec/services/doc_auth_router_spec.rb": 0.048156168, - "spec/services/document_capture_session_async_result_spec.rb": 0.02259123, - "spec/services/document_capture_session_result_spec.rb": 0.008096274, - "spec/services/duration_parser_spec.rb": 0.022064844, - "spec/services/email_confirmation_token_validator_spec.rb": 0.163208564, - "spec/services/email_normalizer_spec.rb": 0.010900368, - "spec/services/encrypted_attribute_spec.rb": 0.014740602, - "spec/services/encrypted_document_storage/document_writer_spec.rb": 0.017914814, - "spec/services/encrypted_document_storage/local_storage_spec.rb": 0.002679411, - "spec/services/encrypted_document_storage/s3_storage_spec.rb": 0.006104577, - "spec/services/encrypted_redis_struct_storage_spec.rb": 0.049312725, - "spec/services/encryption/aes_cipher_spec.rb": 0.00949133, - "spec/services/encryption/aes_cipher_v2_spec.rb": 0.010265916, - "spec/services/encryption/contextless_kms_client_spec.rb": 0.131873389, - "spec/services/encryption/encryptors/aes_encryptor_spec.rb": 0.007235676, - "spec/services/encryption/encryptors/aes_encryptor_v2_spec.rb": 0.008307608000000001, - "spec/services/encryption/encryptors/attribute_encryptor_spec.rb": 0.019155578, - "spec/services/encryption/encryptors/background_proofing_arg_encryptor_spec.rb": 0.00814513, - "spec/services/encryption/encryptors/pii_encryptor_spec.rb": 0.058917533, - "spec/services/encryption/encryptors/session_encryptor_spec.rb": 0.012121694999999998, - "spec/services/encryption/kms_client_spec.rb": 0.10111631, - "spec/services/encryption/kms_logger_spec.rb": 0.008259905, - "spec/services/encryption/password_verifier_spec.rb": 0.066257281, - "spec/services/encryption/uak_password_verifier_spec.rb": 0.207996289, - "spec/services/encryption/user_access_key_spec.rb": 0.034706117, - "spec/services/event_disavowal/disavow_event_spec.rb": 0.020224213, - "spec/services/event_disavowal/find_disavowed_event_spec.rb": 0.041671794, - "spec/services/event_disavowal/validate_disavowed_event_spec.rb": 0.062630052, - "spec/services/forget_all_browsers_spec.rb": 0.05425898, - "spec/services/form_response_spec.rb": 0.098185116, - "spec/services/fraud_review_check_spec.rb": 0.515355922, - "spec/services/frontend_logger_spec.rb": 0.0064116929999999996, - "spec/services/funnel/registration/add_mfa_spec.rb": 0.018108663, - "spec/services/funnel/registration/total_registered_count_spec.rb": 0.089785287, - "spec/services/gpo_confirmation_exporter_spec.rb": 0.009930212, - "spec/services/gpo_confirmation_maker_spec.rb": 0.224915894, - "spec/services/gpo_confirmation_spec.rb": 0.024709798999999998, - "spec/services/gpo_confirmation_uploader_spec.rb": 0.04903207, - "spec/services/gpo_daily_test_sender_spec.rb": 0.04056911, - "spec/services/health_check_summary_spec.rb": 0.00448169, - "spec/services/iaa_reporting_helper_spec.rb": 0.161446771, - "spec/services/ial_context_spec.rb": 0.320973344, - "spec/services/id_token_builder_spec.rb": 0.422341748, - "spec/services/identity_linker_spec.rb": 0.257400163, - "spec/services/idv/agent_spec.rb": 0.287036273, - "spec/services/idv/analytics_events_enhancer_spec.rb": 0.033723661, - "spec/services/idv/cancel_verification_attempt_spec.rb": 0.209286501, - "spec/services/idv/data_url_image_spec.rb": 0.012187482999999999, - "spec/services/idv/doc_auth_form_response_spec.rb": 0.02169258, - "spec/services/idv/duplicate_ssn_finder_spec.rb": 0.1913355, - "spec/services/idv/gpo_mail_spec.rb": 0.103400112, - "spec/services/idv/in_person/completion_survey_sender_spec.rb": 0.584241637, - "spec/services/idv/in_person/enrollment_code_formatter_spec.rb": 0.002435467, - "spec/services/idv/in_person_config_spec.rb": 0.052930384999999996, - "spec/services/idv/phone_confirmation_session_spec.rb": 0.024172103, - "spec/services/idv/phone_step_spec.rb": 0.897690304, - "spec/services/idv/profile_maker_spec.rb": 0.311278932, - "spec/services/idv/proofing_components_logging_spec.rb": 0.003691813, - "spec/services/idv/send_phone_confirmation_otp_spec.rb": 0.121514908, - "spec/services/idv/session_spec.rb": 0.842395903, - "spec/services/idv/steps/in_person/address_step_spec.rb": 0.203335856, - "spec/services/idv/steps/in_person/ssn_step_spec.rb": 0.07502012799999999, - "spec/services/idv/steps/in_person/state_id_step_spec.rb": 0.281924758, - "spec/services/key_rotator/attribute_encryption_spec.rb": 0.030795071, - "spec/services/key_rotator/hmac_fingerprinter_spec.rb": 0.124476105, - "spec/services/marketing_site_spec.rb": 0.076663158, - "spec/services/multi_health_checker_spec.rb": 0.026309297, - "spec/services/openid_connect_attribute_scoper_spec.rb": 0.032952309, - "spec/services/otp_preference_updater_spec.rb": 0.046336933999999996, - "spec/services/otp_rate_limiter_spec.rb": 0.107166871, - "spec/services/out_of_band_session_accessor_spec.rb": 0.030188876, - "spec/services/outage_status_spec.rb": 0.051286280000000004, - "spec/services/outbound_health_checker_spec.rb": 0.094332309, - "spec/services/parse_controller_from_referer_spec.rb": 0.004700683, - "spec/services/personal_key_generator_spec.rb": 0.358412635, - "spec/services/phone_formatter_spec.rb": 0.030725701, - "spec/services/phone_number_capabilities_spec.rb": 0.113141917, - "spec/services/phone_recaptcha_validator_spec.rb": 0.042694919, - "spec/services/pii/attributes_spec.rb": 0.017214507, - "spec/services/pii/cacher_spec.rb": 0.341354685, - "spec/services/pii/fingerprinter_spec.rb": 0.037794518, - "spec/services/pii/re_encryptor_spec.rb": 0.130107397, - "spec/services/piv_cac/check_config_spec.rb": 0.007596837, - "spec/services/piv_cac_service_spec.rb": 0.067662373, - "spec/services/profanity_detector_spec.rb": 0.024126593, - "spec/services/proofing/aamva/applicant_spec.rb": 0.007322314, - "spec/services/proofing/aamva/authentication_client_spec.rb": 0.266676399, - "spec/services/proofing/aamva/hmac_secret_spec.rb": 0.00270668, - "spec/services/proofing/aamva/proofer_spec.rb": 0.499805245, - "spec/services/proofing/aamva/request/authentication_token_request_spec.rb": 0.10974771900000001, - "spec/services/proofing/aamva/request/security_token_request_spec.rb": 1.7098030229999999, - "spec/services/proofing/aamva/request/verification_request_spec.rb": 0.303822941, - "spec/services/proofing/aamva/response/authentication_token_response_spec.rb": 0.023444113, - "spec/services/proofing/aamva/response/security_token_response_spec.rb": 0.046981886, - "spec/services/proofing/aamva/response/verification_response_spec.rb": 0.233716753, - "spec/services/proofing/aamva/soap_error_handler_spec.rb": 0.032908554, - "spec/services/proofing/aamva/verification_client_spec.rb": 0.470643727, - "spec/services/proofing/ddp_result_spec.rb": 0.040900607, - "spec/services/proofing/lexis_nexis/date_formatter_spec.rb": 0.00918356, - "spec/services/proofing/lexis_nexis/ddp/proofing_spec.rb": 0.065057957, - "spec/services/proofing/lexis_nexis/ddp/response_redacter_spec.rb": 0.009631958, - "spec/services/proofing/lexis_nexis/ddp/verification_request_spec.rb": 0.01671429, - "spec/services/proofing/lexis_nexis/instant_verify/check_to_attribute_mapper_spec.rb": 0.017768052, - "spec/services/proofing/lexis_nexis/instant_verify/proofing_spec.rb": 0.083792765, - "spec/services/proofing/lexis_nexis/instant_verify/verification_request_spec.rb": 0.082989691, - "spec/services/proofing/lexis_nexis/phone_finder/proofing_spec.rb": 0.126643101, - "spec/services/proofing/lexis_nexis/phone_finder/verification_request_spec.rb": 0.045220841, - "spec/services/proofing/lexis_nexis/request_signer_spec.rb": 0.003552356, - "spec/services/proofing/lexis_nexis/response_spec.rb": 0.037251212, - "spec/services/proofing/lexis_nexis/verification_error_parser_spec.rb": 0.011083184, - "spec/services/proofing/mock/address_mock_client_spec.rb": 0.010728076999999999, - "spec/services/proofing/mock/ddp_mock_client_spec.rb": 0.034380084, - "spec/services/proofing/mock/device_profiling_backend_spec.rb": 0.005178559, - "spec/services/proofing/mock/resolution_mock_client_spec.rb": 0.014000205, - "spec/services/proofing/mock/state_id_mock_client_spec.rb": 0.008144001000000001, - "spec/services/proofing/resolution/progressive_proofer_spec.rb": 0.381898434, - "spec/services/proofing/resolution/result_adjudicator_spec.rb": 0.022390888, - "spec/services/proofing_session_async_result_spec.rb": 0.003767086, - "spec/services/push_notification/account_purged_event_spec.rb": 0.021155201, - "spec/services/push_notification/email_changed_event_spec.rb": 0.02632301, - "spec/services/push_notification/http_push_spec.rb": 0.556917082, - "spec/services/push_notification/identifier_recycled_event_spec.rb": 0.018933802, - "spec/services/push_notification/mfa_limit_account_locked_event_spec.rb": 0.01627792, - "spec/services/push_notification/password_reset_event_spec.rb": 0.019021933, - "spec/services/push_notification/recovery_activated_event_spec.rb": 0.016141500000000003, - "spec/services/push_notification/reproof_completed_event_spec.rb": 0.016535792, - "spec/services/pwned_passwords/lookup_password_spec.rb": 0.007345482, - "spec/services/random_phrase_spec.rb": 0.018809644, - "spec/services/rate_limiter_spec.rb": 0.087675995, - "spec/services/reactivate_account_session_spec.rb": 0.079820947, - "spec/services/recaptcha_enterprise_validator_spec.rb": 0.144221009, - "spec/services/recaptcha_mock_validator_spec.rb": 0.016092804, - "spec/services/recaptcha_validator_spec.rb": 0.13004116, - "spec/services/redis_rate_limiter_spec.rb": 0.028433332000000002, - "spec/services/remember_device_cookie_spec.rb": 0.141542347, - "spec/services/request_password_reset_spec.rb": 3.964429356, - "spec/services/reset_user_password_spec.rb": 1.484456012, - "spec/services/revoke_service_provider_consent_spec.rb": 0.016683625, - "spec/services/saml_endpoint_spec.rb": 0.024109198000000002, - "spec/services/saml_request_validator_spec.rb": 0.060607752, - "spec/services/secure_headers_allow_list_spec.rb": 0.010801352, - "spec/services/send_sign_up_email_confirmation_spec.rb": 1.051587541, - "spec/services/service_provider_request_proxy_spec.rb": 0.024621468, - "spec/services/service_provider_seeder_spec.rb": 1.621671848, - "spec/services/service_provider_updater_spec.rb": 0.358739789, - "spec/services/session_encryptor_spec.rb": 0.008651772, - "spec/services/sp_return_url_resolver_spec.rb": 0.036559204, - "spec/services/ssn_formatter_spec.rb": 0.020678307, - "spec/services/store_sp_metadata_in_session_spec.rb": 0.010824146, - "spec/services/string_redacter_spec.rb": 0.002055621, - "spec/services/time_service_spec.rb": 0.002632507, - "spec/services/update_user_spec.rb": 0.229927053, - "spec/services/uri_service_spec.rb": 0.013365347, - "spec/services/user_alerts/alert_user_about_account_verified_spec.rb": 0.578068412, - "spec/services/user_alerts/alert_user_about_new_device_spec.rb": 0.391921821, - "spec/services/user_alerts/alert_user_about_password_change_spec.rb": 0.405830534, - "spec/services/user_alerts/alert_user_about_personal_key_sign_in_spec.rb": 0.380967464, - "spec/services/user_event_creator_spec.rb": 0.198743487, - "spec/services/user_seeder_spec.rb": 2.416415888, - "spec/services/user_session_context_spec.rb": 0.019922357, - "spec/services/usps_in_person_proofing/enrollment_helper_spec.rb": 3.339497015, - "spec/services/usps_in_person_proofing/proofer_spec.rb": 0.358489619, - "spec/services/usps_in_person_proofing/transliterable_validator_spec.rb": 0.047833046000000004, - "spec/services/usps_in_person_proofing/transliterator_spec.rb": 0.101508431, - "spec/services/uuid_reporter_spec.rb": 0.219325972, - "spec/services/x509/attribute_spec.rb": 0.002169954, - "spec/services/x509/attributes_spec.rb": 0.018183538, - "spec/svg_spec.rb": 0.323569695, - "spec/views/account_reset/cancel/show.html.erb_spec.rb": 0.016055068, - "spec/views/account_reset/confirm_delete_account/show.html.erb_spec.rb": 0.018834034, - "spec/views/account_reset/confirm_request/show.html.erb_spec.rb": 0.008766933, - "spec/views/account_reset/delete_account/show.html.erb_spec.rb": 0.011632963999999999, - "spec/views/account_reset/recovery_options/show.html.erb_spec.rb": 0.032510363, - "spec/views/account_reset/request/show.html.erb_spec.rb": 0.067027367, - "spec/views/account_reset/user_mailer/email_confirmation_instructions.html.erb_spec.rb": 0.083808836, - "spec/views/account_reset/user_mailer/unconfirmed_email_instructions.html.erb_spec.rb": 0.055286033, - "spec/views/accounts/_nav_auth.html.erb_spec.rb": 0.059893999, - "spec/views/accounts/connected_accounts/show.html.erb_spec.rb": 0.069601247, - "spec/views/accounts/history/show.html.erb_spec.rb": 0.037404921, - "spec/views/accounts/show.html.erb_spec.rb": 0.679195136, - "spec/views/accounts/two_factor_authentication/show.html.erb_spec.rb": 0.216540876, - "spec/views/devise/passwords/edit.html.erb_spec.rb": 0.12881257100000001, - "spec/views/devise/passwords/new.html.erb_spec.rb": 0.08288005300000001, - "spec/views/devise/sessions/new.html.erb_spec.rb": 0.25665137, - "spec/views/devise/shared/_password_strength.html.erb_spec.rb": 0.016155856, - "spec/views/forgot_password/show.html.erb_spec.rb": 0.045108888, - "spec/views/idv/activated.html.erb_spec.rb": 0.06130693, - "spec/views/idv/address/new.html.erb_spec.rb": 0.10675225, - "spec/views/idv/agreement/show.html.erb_spec.rb": 0.018584536, - "spec/views/idv/cancellations/destroy.html.erb_spec.rb": 0.011434488999999999, - "spec/views/idv/cancellations/new.html.erb_spec.rb": 0.055448196, - "spec/views/idv/come_back_later/show.html.erb_spec.rb": 0.080626917, - "spec/views/idv/doc_auth/_cancel.html.erb_spec.rb": 0.011565378000000001, - "spec/views/idv/getting_started/show.html.erb_spec.rb": 0.066332563, - "spec/views/idv/gpo/index.html.erb_spec.rb": 0.15427612599999999, - "spec/views/idv/gpo_verify/index.html.erb_spec.rb": 0.14563474399999998, - "spec/views/idv/in_person/ready_to_verify/show.html.erb_spec.rb": 0.490113443, - "spec/views/idv/in_person/ssn.html.erb_spec.rb": 0.055345338, - "spec/views/idv/phone/new.html.erb_spec.rb": 0.104702249, - "spec/views/idv/phone_errors/_warning.html.erb_spec.rb": 0.080359519, - "spec/views/idv/phone_errors/failure.html.erb_spec.rb": 0.077472512, - "spec/views/idv/phone_errors/jobfail.html.erb_spec.rb": 0.046031727, - "spec/views/idv/phone_errors/timeout.html.erb_spec.rb": 0.047166996, - "spec/views/idv/phone_errors/warning.html.erb_spec.rb": 0.089877908, - "spec/views/idv/please_call/show.html.erb_spec.rb": 0.015269477, - "spec/views/idv/review/new.html.erb_spec.rb": 0.060098816, - "spec/views/idv/session_errors/exception.html.erb_spec.rb": 0.025743264000000002, - "spec/views/idv/session_errors/failure.html.erb_spec.rb": 0.032194266, - "spec/views/idv/session_errors/rate_limited.html.erb_spec.rb": 0.034073959, - "spec/views/idv/session_errors/state_id_warning.html.erb_spec.rb": 0.028498002, - "spec/views/idv/session_errors/warning.html.erb_spec.rb": 0.040000974, - "spec/views/idv/shared/_back.html.erb_spec.rb": 0.057338999, - "spec/views/idv/shared/_document_capture.html.erb_spec.rb": 0.028159316, - "spec/views/idv/shared/_error.html.erb_spec.rb": 0.105720585, - "spec/views/idv/unavailable/show.html.erb_spec.rb": 0.039529703, - "spec/views/idv/welcome/show.html.erb_spec.rb": 0.075006768, - "spec/views/layouts/application.html.erb_spec.rb": 0.221632823, - "spec/views/layouts/user_mailer.html.erb_spec.rb": 0.184484126, - "spec/views/mfa_confirmation/show.html.erb_spec.rb": 0.150758942, - "spec/views/partials/multi_factor_authentication/_mfa_selection.html.erb_spec.rb": 0.082973188, - "spec/views/partials/personal_key/_key.html.erb_spec.rb": 0.040870411, - "spec/views/phone_setup/index.html.erb_spec.rb": 0.369102776, - "spec/views/phone_setup/spam_protection.html.erb_spec.rb": 0.140642145, - "spec/views/reactivate_account/index.html.erb_spec.rb": 0.023798051, - "spec/views/shared/_address.html.erb_spec.rb": 0.013456504000000001, - "spec/views/shared/_banner.html.erb_spec.rb": 0.008378619, - "spec/views/shared/_email_languages.html.erb_spec.rb": 0.032764001, - "spec/views/shared/_footer_lite.html.erb_spec.rb": 0.028653046, - "spec/views/shared/_masked_text.html.erb_spec.rb": 0.024444485999999998, - "spec/views/shared/_nav_branded.html.erb_spec.rb": 0.040645654, - "spec/views/shared/_nav_lite.html.erb_spec.rb": 0.007438458, - "spec/views/shared/_personal_key.html.erb_spec.rb": 0.028869733, - "spec/views/shared/_troubleshooting_options.html.erb_spec.rb": 0.035898935, - "spec/views/sign_up/completions/show.html.erb_spec.rb": 0.275366376, - "spec/views/sign_up/email_resend/new.html.erb_spec.rb": 0.017631446000000002, - "spec/views/sign_up/emails/show.html.erb_spec.rb": 0.090247052, - "spec/views/sign_up/passwords/new.html.erb_spec.rb": 0.123872801, - "spec/views/sign_up/registrations/new.html.erb_spec.rb": 0.19341228700000002, - "spec/views/two_factor_authentication/options/index.html.erb_spec.rb": 0.086384579, - "spec/views/two_factor_authentication/otp_verification/show.html.erb_spec.rb": 0.60061919, - "spec/views/two_factor_authentication/personal_key_verification/show.html.erb_spec.rb": 0.141005088, - "spec/views/two_factor_authentication/sms_opt_in/error.html.erb_spec.rb": 0.060716856, - "spec/views/two_factor_authentication/sms_opt_in/new.html.erb_spec.rb": 0.056423563999999995, - "spec/views/two_factor_authentication/totp_verification/show.html.erb_spec.rb": 0.255010299, - "spec/views/two_factor_authentication/webauthn_verification/show.html.erb_spec.rb": 0.11872779700000001, - "spec/views/users/backup_code_setup/create.html.erb_spec.rb": 1.402158054, - "spec/views/users/backup_code_setup/index.html.erb_spec.rb": 0.066799209, - "spec/views/users/backup_code_setup/reminder.html.erb_spec.rb": 0.038427540999999996, - "spec/views/users/delete/show.html.erb_spec.rb": 0.163661911, - "spec/views/users/edit_phone/remove_phone.html.erb_spec.rb": 0.081398467, - "spec/views/users/emails/verify.html.erb_spec.rb": 0.050732558999999997, - "spec/views/users/mfa_selection/index.html.erb_spec.rb": 0.135954981, - "spec/views/users/passwords/edit.html.erb_spec.rb": 0.064206208, - "spec/views/users/phones/add.html.erb_spec.rb": 0.089398265, - "spec/views/users/piv_cac_authentication_setup/new.html.erb_spec.rb": 0.061688584, - "spec/views/users/please_call/show.html.erb_spec.rb": 0.019461451999999997, - "spec/views/users/shared/_otp_delivery_preference_selection.html.erb_spec.rb": 0.052436179, - "spec/views/users/totp_setup/new.html.erb_spec.rb": 0.138152677, - "spec/views/users/two_factor_authentication_setup/index.html.erb_spec.rb": 0.113567281, - "spec/views/users/webauthn_setup/new.html.erb_spec.rb": 0.10796064999999999, - "spec/views/vendor_outage/show.html.erb_spec.rb": 0.019171182000000002 + "spec/bin/oncall/download-piv-certs_spec.rb": 0.106682471, + "spec/bin/oncall/email-deliveries_spec.rb": 0.012327779, + "spec/bin/oncall/otp-deliveries_spec.rb": 0.021846031, + "spec/bin/query-cloudwatch_spec.rb": 0.076234818, + "spec/browsers_json_spec.rb": 0.004108529, + "spec/components/accordion_component_spec.rb": 0.021702784, + "spec/components/alert_component_spec.rb": 0.03629131, + "spec/components/alert_icon_component_spec.rb": 0.015110143, + "spec/components/badge_component_spec.rb": 0.024898291, + "spec/components/barcode_component_spec.rb": 0.070166372, + "spec/components/base_component_spec.rb": 0.04242291, + "spec/components/block_link_component_spec.rb": 0.016438273, + "spec/components/button_component_spec.rb": 0.061774694, + "spec/components/captcha_submit_button_component_spec.rb": 0.078115245, + "spec/components/click_observer_component_spec.rb": 0.00930169, + "spec/components/clipboard_button_component_spec.rb": 0.017570665, + "spec/components/countdown_alert_component_spec.rb": 0.033197465, + "spec/components/countdown_component_spec.rb": 0.019987192, + "spec/components/download_button_component_spec.rb": 0.016131435, + "spec/components/flash_component_spec.rb": 0.013532344, + "spec/components/form_link_component_spec.rb": 0.006824967, + "spec/components/icon_component_spec.rb": 0.016488359, + "spec/components/javascript_required_component_spec.rb": 0.042062842, + "spec/components/language_picker_component_spec.rb": 0.025928054, + "spec/components/memorable_date_component_spec.rb": 0.144546954, + "spec/components/modal_component_spec.rb": 0.025129645, + "spec/components/one_time_code_input_component_spec.rb": 0.088850091, + "spec/components/page_footer_component_spec.rb": 0.01469027, + "spec/components/page_heading_component_spec.rb": 0.013641759, + "spec/components/password_confirmation_component_spec.rb": 0.033782466, + "spec/components/password_toggle_component_spec.rb": 0.042867724, + "spec/components/phone_input_component_spec.rb": 0.603454506, + "spec/components/print_button_component_spec.rb": 0.017488752, + "spec/components/process_list_component_spec.rb": 0.036370694, + "spec/components/spinner_button_component_spec.rb": 0.025637396, + "spec/components/status_page_component_spec.rb": 0.029493657, + "spec/components/step_indicator_component_spec.rb": 0.04951706, + "spec/components/step_indicator_step_component_spec.rb": 0.029385179, + "spec/components/submit_button_component_spec.rb": 0.01633493, + "spec/components/tab_navigation_component_spec.rb": 0.619678144, + "spec/components/time_component_spec.rb": 0.041720905, + "spec/components/troubleshooting_options_component_spec.rb": 0.036284618, + "spec/components/validated_field_component_spec.rb": 0.039247156, + "spec/components/vendor_outage_alert_component_spec.rb": 0.029885146, + "spec/components/webauthn_input_component_spec.rb": 0.028751618, + "spec/components/webauthn_verify_button_component_spec.rb": 0.018149498, + "spec/config/initializers/ab_tests_spec.rb": 0.003378054, + "spec/config/initializers/ahoy_spec.rb": 0.020168789, + "spec/config/initializers/ext_digest_spec.rb": 0.002168022, + "spec/config/initializers/job_configurations_spec.rb": 0.074738308, + "spec/config/initializers/phonelib_spec.rb": 0.003205203, + "spec/config/initializers/secure_headers_spec.rb": 0.00319277, + "spec/controllers/account_reset/cancel_controller_spec.rb": 0.660926357, + "spec/controllers/account_reset/confirm_delete_account_controller_spec.rb": 0.036922166, + "spec/controllers/account_reset/confirm_request_controller_spec.rb": 0.014651191000000001, + "spec/controllers/account_reset/delete_account_controller_spec.rb": 0.582295321, + "spec/controllers/account_reset/pending_controller_spec.rb": 0.285145641, + "spec/controllers/account_reset/recovery_options_controller_spec.rb": 0.121976163, + "spec/controllers/account_reset/request_controller_spec.rb": 1.449789885, + "spec/controllers/accounts/personal_keys_controller_spec.rb": 0.500781321, + "spec/controllers/accounts_controller_spec.rb": 0.349651305, + "spec/controllers/analytics_events_controller_spec.rb": 0.017045767, + "spec/controllers/api/internal/sessions_controller_spec.rb": 0.725091884, + "spec/controllers/application_controller_spec.rb": 1.327077847, + "spec/controllers/concerns/api/csrf_token_concern_spec.rb": 0.011080072, + "spec/controllers/concerns/effective_user_spec.rb": 0.059383954999999995, + "spec/controllers/concerns/forced_reauthentication_concern_spec.rb": 0.021330248, + "spec/controllers/concerns/idv/ab_test_analytics_concern_spec.rb": 0.08539967500000001, + "spec/controllers/concerns/idv/acuant_concern_spec.rb": 0.027034086, + "spec/controllers/concerns/idv/getting_started_ab_test_concern_spec.rb": 0.203948813, + "spec/controllers/concerns/idv/phone_otp_rate_limitable_spec.rb": 0.011887227, + "spec/controllers/concerns/idv/step_indicator_concern_spec.rb": 0.221094806, + "spec/controllers/concerns/idv/threat_metrix_concern_spec.rb": 0.038295173, + "spec/controllers/concerns/idv_step_concern_spec.rb": 0.450385977, + "spec/controllers/concerns/mfa_setup_concern_spec.rb": 0.079901897, + "spec/controllers/concerns/rate_limit_concern_spec.rb": 0.153628388, + "spec/controllers/concerns/reauthentication_required_concern_spec.rb": 0.107920039, + "spec/controllers/concerns/recaptcha_concern_spec.rb": 0.070476041, + "spec/controllers/concerns/render_condition_concern_spec.rb": 0.058838864, + "spec/controllers/concerns/verify_sp_attributes_concern_spec.rb": 0.339756288, + "spec/controllers/country_support_controller_spec.rb": 0.036077245, + "spec/controllers/event_disavowal_controller_spec.rb": 0.312000122, + "spec/controllers/fake_s3_controller_spec.rb": 0.026079192, + "spec/controllers/forgot_password_controller_spec.rb": 0.016576595, + "spec/controllers/frontend_log_controller_spec.rb": 0.274382444, + "spec/controllers/health/database_controller_spec.rb": 0.023440268, + "spec/controllers/health/health_controller_spec.rb": 0.017119684, + "spec/controllers/health/outbound_controller_spec.rb": 0.040136636, + "spec/controllers/idv/address_controller_spec.rb": 0.136801294, + "spec/controllers/idv/agreement_controller_spec.rb": 0.359170772, + "spec/controllers/idv/cancellations_controller_spec.rb": 0.612795356, + "spec/controllers/idv/capture_doc_status_controller_spec.rb": 0.310287775, + "spec/controllers/idv/come_back_later_controller_spec.rb": 0.057619458, + "spec/controllers/idv/document_capture_controller_spec.rb": 0.426081635, + "spec/controllers/idv/forgot_password_controller_spec.rb": 0.30012744999999996, + "spec/controllers/idv/getting_started_controller_spec.rb": 0.461602304, + "spec/controllers/idv/gpo_controller_spec.rb": 1.364664544, + "spec/controllers/idv/gpo_verify_controller_spec.rb": 1.789055364, + "spec/controllers/idv/hybrid_handoff_controller_spec.rb": 0.508717929, + "spec/controllers/idv/hybrid_mobile/capture_complete_controller_spec.rb": 0.105156342, + "spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb": 0.215253766, + "spec/controllers/idv/hybrid_mobile/entry_controller_spec.rb": 0.304502927, + "spec/controllers/idv/image_uploads_controller_spec.rb": 1.10676586, + "spec/controllers/idv/in_person/public/usps_locations_controller_spec.rb": 0.017465976, + "spec/controllers/idv/in_person/ready_to_verify_controller_spec.rb": 0.150824395, + "spec/controllers/idv/in_person/ssn_controller_spec.rb": 0.586151492, + "spec/controllers/idv/in_person/usps_locations_controller_spec.rb": 0.407136139, + "spec/controllers/idv/in_person/verify_info_controller_spec.rb": 0.592762645, + "spec/controllers/idv/in_person_controller_spec.rb": 0.178254408, + "spec/controllers/idv/link_sent_controller_spec.rb": 0.46018104, + "spec/controllers/idv/mail_only_warning_controller_spec.rb": 0.166252643, + "spec/controllers/idv/not_verified_controller_spec.rb": 0.02559913, + "spec/controllers/idv/otp_verification_controller_spec.rb": 0.408394286, + "spec/controllers/idv/personal_key_controller_spec.rb": 1.792270601, + "spec/controllers/idv/phone_controller_spec.rb": 1.288699172, + "spec/controllers/idv/phone_errors_controller_spec.rb": 0.85062278, + "spec/controllers/idv/please_call_controller_spec.rb": 0.165412597, + "spec/controllers/idv/resend_otp_controller_spec.rb": 0.19723875200000002, + "spec/controllers/idv/review_controller_spec.rb": 11.250024544, + "spec/controllers/idv/session_errors_controller_spec.rb": 1.742782538, + "spec/controllers/idv/sessions_controller_spec.rb": 0.336330752, + "spec/controllers/idv/ssn_controller_spec.rb": 0.594575855, + "spec/controllers/idv/unavailable_controller_spec.rb": 0.044124125, + "spec/controllers/idv/verify_info_controller_spec.rb": 1.46748914, + "spec/controllers/idv/welcome_controller_spec.rb": 0.488611254, + "spec/controllers/idv_controller_spec.rb": 0.44277257, + "spec/controllers/mfa_confirmation_controller_spec.rb": 0.022729528, + "spec/controllers/no_js_controller_spec.rb": 0.014010254, + "spec/controllers/openid_connect/authorization_controller_spec.rb": 1.631792298, + "spec/controllers/openid_connect/certs_controller_spec.rb": 0.014930894, + "spec/controllers/openid_connect/configuration_controller_spec.rb": 0.015591976, + "spec/controllers/openid_connect/logout_controller_spec.rb": 0.994101017, + "spec/controllers/openid_connect/token_controller_spec.rb": 0.177990686, + "spec/controllers/openid_connect/user_info_controller_spec.rb": 0.229356213, + "spec/controllers/pages_controller_spec.rb": 0.039617611999999996, + "spec/controllers/password_capture_controller_spec.rb": 0.095857316, + "spec/controllers/reactivate_account_controller_spec.rb": 0.172713839, + "spec/controllers/redirect/contact_controller_spec.rb": 0.006789866, + "spec/controllers/redirect/help_center_controller_spec.rb": 0.035217479, + "spec/controllers/redirect/policy_controller_spec.rb": 0.006797472, + "spec/controllers/redirect/return_to_sp_controller_spec.rb": 0.068611461, + "spec/controllers/risc/configuration_controller_spec.rb": 0.0139805, + "spec/controllers/risc/security_events_controller_spec.rb": 0.59114672, + "spec/controllers/saml_completion_controller_spec.rb": 0.061597171000000006, + "spec/controllers/saml_idp_controller_spec.rb": 9.539217857, + "spec/controllers/saml_post_controller_spec.rb": 0.019799756, + "spec/controllers/saml_signed_message_spec.rb": 0.382224806, + "spec/controllers/service_provider_controller_spec.rb": 0.161155864, + "spec/controllers/sign_out_controller_spec.rb": 0.032107764999999996, + "spec/controllers/sign_up/cancellations_controller_spec.rb": 0.342522842, + "spec/controllers/sign_up/completions_controller_spec.rb": 0.906443451, + "spec/controllers/sign_up/email_confirmations_controller_spec.rb": 0.258627753, + "spec/controllers/sign_up/emails_controller_spec.rb": 0.011725590000000001, + "spec/controllers/sign_up/passwords_controller_spec.rb": 0.211951164, + "spec/controllers/sign_up/registrations_controller_spec.rb": 0.895594407, + "spec/controllers/test/device_profiling_controller_spec.rb": 0.012469105000000001, + "spec/controllers/test/piv_cac_authentication_test_subject_controller_spec.rb": 0.066384627, + "spec/controllers/test/push_notification_controller_spec.rb": 0.023906147, + "spec/controllers/test/telephony_controller_spec.rb": 0.025305293, + "spec/controllers/two_factor_authentication/backup_code_verification_controller_spec.rb": 1.002921213, + "spec/controllers/two_factor_authentication/options_controller_spec.rb": 0.378362882, + "spec/controllers/two_factor_authentication/otp_verification_controller_spec.rb": 3.129257289, + "spec/controllers/two_factor_authentication/personal_key_verification_controller_spec.rb": 0.893364871, + "spec/controllers/two_factor_authentication/piv_cac_verification_controller_spec.rb": 0.9135700680000001, + "spec/controllers/two_factor_authentication/sms_opt_in_controller_spec.rb": 0.529445614, + "spec/controllers/two_factor_authentication/totp_verification_controller_spec.rb": 0.802855888, + "spec/controllers/two_factor_authentication/webauthn_verification_controller_spec.rb": 0.322562539, + "spec/controllers/users/authorization_confirmation_controller_spec.rb": 0.14813248, + "spec/controllers/users/backup_code_setup_controller_spec.rb": 2.052194197, + "spec/controllers/users/delete_controller_spec.rb": 0.662968182, + "spec/controllers/users/edit_phone_controller_spec.rb": 0.209512198, + "spec/controllers/users/email_confirmations_controller_spec.rb": 1.1524911340000001, + "spec/controllers/users/email_language_controller_spec.rb": 0.208246414, + "spec/controllers/users/emails_controller_spec.rb": 0.520868568, + "spec/controllers/users/forget_all_browsers_controller_spec.rb": 0.160310469, + "spec/controllers/users/passwords_controller_spec.rb": 1.237611707, + "spec/controllers/users/personal_keys_controller_spec.rb": 0.353623395, + "spec/controllers/users/phone_setup_controller_spec.rb": 0.240144514, + "spec/controllers/users/phones_controller_spec.rb": 0.49203463199999997, + "spec/controllers/users/piv_cac_authentication_setup_controller_spec.rb": 0.712669146, + "spec/controllers/users/piv_cac_login_controller_spec.rb": 0.573131764, + "spec/controllers/users/please_call_controller_spec.rb": 0.023554788, + "spec/controllers/users/reset_passwords_controller_spec.rb": 2.20146453, + "spec/controllers/users/rules_of_use_controller_spec.rb": 0.331999831, + "spec/controllers/users/service_provider_revoke_controller_spec.rb": 0.351202827, + "spec/controllers/users/sessions_controller_spec.rb": 1.3008381390000001, + "spec/controllers/users/totp_setup_controller_spec.rb": 4.069980828, + "spec/controllers/users/two_factor_authentication_controller_spec.rb": 1.560669477, + "spec/controllers/users/two_factor_authentication_setup_controller_spec.rb": 0.249827848, + "spec/controllers/users/verify_password_controller_spec.rb": 0.368433856, + "spec/controllers/users/verify_personal_key_controller_spec.rb": 0.771071465, + "spec/controllers/users/webauthn_setup_controller_spec.rb": 0.906013792, + "spec/controllers/vendor_outage_controller_spec.rb": 0.027951384, + "spec/decorators/device_decorator_spec.rb": 0.035177185, + "spec/decorators/email_context_spec.rb": 0.050031986, + "spec/decorators/event_decorator_spec.rb": 0.065760027, + "spec/decorators/mfa_context_spec.rb": 0.786879907, + "spec/decorators/service_provider_session_decorator_spec.rb": 0.157021163, + "spec/decorators/session_decorator_spec.rb": 0.020510855, + "spec/features/accessibility/idv_pages_spec.rb": 312.706216429, + "spec/features/accessibility/static_pages_spec.rb": 111.01600643, + "spec/features/accessibility/user_pages_spec.rb": 284.243189689, + "spec/features/accessibility/visitor_pages_spec.rb": 62.605596543000004, + "spec/features/account/backup_codes_spec.rb": 17.964285624, + "spec/features/account/device_spec.rb": 3.181092467, + "spec/features/account/unphishable_badge_spec.rb": 6.245601282, + "spec/features/account_connected_apps_spec.rb": 6.7784582239999995, + "spec/features/account_creation/multiple_browsers_spec.rb": 16.298428026000003, + "spec/features/account_creation/sp_return_log_spec.rb": 4.426285835, + "spec/features/account_email_language_spec.rb": 10.159887498, + "spec/features/account_history_spec.rb": 3.553860391, + "spec/features/account_reset/cancel_request_spec.rb": 4.46722074, + "spec/features/account_reset/delete_account_spec.rb": 12.83159394, + "spec/features/account_reset/pending_request_spec.rb": 4.765274101, + "spec/features/device_tracking_spec.rb": 6.4204759110000005, + "spec/features/event_disavowal_spec.rb": 41.571273107, + "spec/features/ialmax/saml_sign_in_spec.rb": 27.046222935, + "spec/features/idv/account_creation_spec.rb": 49.340442959, + "spec/features/idv/analytics_spec.rb": 47.206773027, + "spec/features/idv/cancel_spec.rb": 23.666285000000002, + "spec/features/idv/clearing_and_restarting_spec.rb": 71.399621135, + "spec/features/idv/confirm_start_over_spec.rb": 8.525807797999999, + "spec/features/idv/doc_auth/address_step_spec.rb": 41.440274784, + "spec/features/idv/doc_auth/agreement_spec.rb": 3.949206118, + "spec/features/idv/doc_auth/document_capture_spec.rb": 49.353517944000004, + "spec/features/idv/doc_auth/getting_started_spec.rb": 13.036240668, + "spec/features/idv/doc_auth/hybrid_handoff_spec.rb": 34.570606448999996, + "spec/features/idv/doc_auth/link_sent_spec.rb": 3.672220204, + "spec/features/idv/doc_auth/redo_document_capture_spec.rb": 29.247669477, + "spec/features/idv/doc_auth/ssn_step_spec.rb": 6.807138952, + "spec/features/idv/doc_auth/test_credentials_spec.rb": 19.354323438999998, + "spec/features/idv/doc_auth/verify_info_step_spec.rb": 113.127964733, + "spec/features/idv/doc_auth/welcome_spec.rb": 13.56225574, + "spec/features/idv/end_to_end_idv_spec.rb": 42.04841694700001, + "spec/features/idv/gpo_disabled_spec.rb": 9.958308303, + "spec/features/idv/hybrid_mobile/entry_spec.rb": 13.514930663, + "spec/features/idv/hybrid_mobile/hybrid_mobile_spec.rb": 40.311939392, + "spec/features/idv/in_person_spec.rb": 261.776077151, + "spec/features/idv/outage_spec.rb": 100.850982055, + "spec/features/idv/pending_profile_password_reset_spec.rb": 12.512042782999998, + "spec/features/idv/phone_errors_spec.rb": 22.815664065, + "spec/features/idv/phone_input_spec.rb": 12.362709226, + "spec/features/idv/phone_otp_rate_limiting_spec.rb": 25.45060412, + "spec/features/idv/proofing_components_spec.rb": 20.196063698, + "spec/features/idv/puerto_rican_address_spec.rb": 12.634334853999999, + "spec/features/idv/sp_handoff_spec.rb": 124.539828887, + "spec/features/idv/sp_requested_attributes_spec.rb": 64.599183075, + "spec/features/idv/steps/confirmation_step_spec.rb": 41.987294835, + "spec/features/idv/steps/forgot_password_step_spec.rb": 20.708952619, + "spec/features/idv/steps/gpo_otp_verification_step_spec.rb": 85.243368798, + "spec/features/idv/steps/gpo_step_spec.rb": 65.662185263, + "spec/features/idv/steps/in_person/ssn_spec.rb": 67.339800721, + "spec/features/idv/steps/in_person/state_id_step_spec.rb": 7.323571947, + "spec/features/idv/steps/in_person/verify_info_spec.rb": 37.721488504999996, + "spec/features/idv/steps/phone_otp_verification_step_spec.rb": 29.096864069, + "spec/features/idv/steps/phone_step_spec.rb": 222.847636951, + "spec/features/idv/steps/review_step_spec.rb": 40.965021873, + "spec/features/idv/threat_metrix_pending_spec.rb": 45.477877873, + "spec/features/idv/uak_password_spec.rb": 8.103272761, + "spec/features/legacy_passwords_spec.rb": 13.501430565, + "spec/features/load_testing/email_sign_up_spec.rb": 3.721553019, + "spec/features/multi_factor_authentication/mfa_cta_spec.rb": 15.913442093, + "spec/features/multiple_emails/add_email_spec.rb": 55.994173371, + "spec/features/multiple_emails/email_management_spec.rb": 24.35126123, + "spec/features/multiple_emails/reset_password_spec.rb": 7.2696582450000005, + "spec/features/multiple_emails/sign_in_spec.rb": 11.025990923, + "spec/features/multiple_emails/sp_sign_in_spec.rb": 17.038355825, + "spec/features/new_device_tracking_spec.rb": 11.958377565000001, + "spec/features/openid_connect/authorization_confirmation_spec.rb": 25.422907915, + "spec/features/openid_connect/openid_connect_spec.rb": 184.621484096, + "spec/features/openid_connect/phishing_resistant_required_spec.rb": 54.181345012, + "spec/features/openid_connect/redirect_uri_validation_spec.rb": 32.762728752, + "spec/features/phone/add_phone_spec.rb": 40.562091766, + "spec/features/phone/confirmation_spec.rb": 111.516925996, + "spec/features/phone/default_phone_selection_spec.rb": 18.691410425, + "spec/features/phone/edit_phone_spec.rb": 9.534897559000001, + "spec/features/phone/rate_limitting_spec.rb": 54.860108437, + "spec/features/phone/remove_phone_spec.rb": 6.732094185999999, + "spec/features/remember_device/cookie_expiration_spec.rb": 7.172119835, + "spec/features/remember_device/phone_spec.rb": 32.939784489, + "spec/features/remember_device/revocation_spec.rb": 9.690912416, + "spec/features/remember_device/session_expiration_spec.rb": 3.838383708, + "spec/features/remember_device/sp_expiration_spec.rb": 222.593915647, + "spec/features/remember_device/totp_spec.rb": 51.099380694, + "spec/features/remember_device/user_opted_preference_spec.rb": 27.509273367000002, + "spec/features/remember_device/webauthn_spec.rb": 96.893856713, + "spec/features/reports/authorization_count_spec.rb": 86.83905732, + "spec/features/reports/monthly_gpo_letter_requests_report_spec.rb": 12.116176325, + "spec/features/reports/sp_active_users_report_spec.rb": 7.352414689, + "spec/features/saml/authorization_confirmation_spec.rb": 28.294976478, + "spec/features/saml/ial1/account_creation_spec.rb": 11.006729055, + "spec/features/saml/ial1_sso_spec.rb": 53.050855719, + "spec/features/saml/ial2_sso_spec.rb": 27.454566569, + "spec/features/saml/multiple_endpoints_spec.rb": 25.177820115, + "spec/features/saml/phishing_resistant_required_spec.rb": 44.021806286, + "spec/features/saml/redirect_uri_validation_spec.rb": 3.858197517, + "spec/features/saml/saml_logout_spec.rb": 23.627735869, + "spec/features/saml/saml_relay_state_spec.rb": 14.877922152, + "spec/features/saml/saml_spec.rb": 112.824453267, + "spec/features/session/decryption_spec.rb": 3.216834036, + "spec/features/session/timeout_spec.rb": 9.539040564, + "spec/features/sign_in/banned_users_spec.rb": 12.829438009, + "spec/features/sign_in/remember_device_default_spec.rb": 9.922692245, + "spec/features/sign_in/sp_return_log_spec.rb": 3.778259286, + "spec/features/sign_in/two_factor_options_spec.rb": 47.095407473, + "spec/features/sp_cost_tracking_spec.rb": 50.730036903, + "spec/features/two_factor_authentication/backup_code_sign_up_spec.rb": 23.168434964, + "spec/features/two_factor_authentication/change_factor_spec.rb": 16.218428652, + "spec/features/two_factor_authentication/multiple_mfa_sign_up_spec.rb": 35.291820978, + "spec/features/two_factor_authentication/multiple_tabs_spec.rb": 10.783208542, + "spec/features/two_factor_authentication/sign_in_spec.rb": 110.53489652100001, + "spec/features/two_factor_authentication/sign_in_via_personal_key_spec.rb": 7.153002084000001, + "spec/features/users/password_recovery_via_recovery_code_spec.rb": 43.95579787, + "spec/features/users/password_reset_with_pending_profile_spec.rb": 6.850623744, + "spec/features/users/piv_cac_management_spec.rb": 30.545730781, + "spec/features/users/regenerate_personal_key_spec.rb": 7.812219931, + "spec/features/users/sign_in_spec.rb": 326.898692958, + "spec/features/users/sign_out_spec.rb": 3.198928971, + "spec/features/users/sign_up_spec.rb": 160.389000702, + "spec/features/users/totp_management_spec.rb": 19.072460997, + "spec/features/users/user_edit_spec.rb": 3.227050507, + "spec/features/users/user_profile_spec.rb": 54.875588972, + "spec/features/users/verify_profile_spec.rb": 14.46948876, + "spec/features/visitors/bad_password_spec.rb": 3.531694154, + "spec/features/visitors/email_confirmation_spec.rb": 22.377857367, + "spec/features/visitors/email_language_preference_spec.rb": 6.5975330240000005, + "spec/features/visitors/i18n_spec.rb": 40.038599626999996, + "spec/features/visitors/js_disabled_spec.rb": 6.348578203000001, + "spec/features/visitors/navigation_spec.rb": 3.116054085, + "spec/features/visitors/password_recovery_spec.rb": 73.481015699, + "spec/features/visitors/resend_email_confirmation_spec.rb": 16.854222368, + "spec/features/visitors/set_password_spec.rb": 30.999538143, + "spec/features/visitors/sign_up_with_email_spec.rb": 27.895392229, + "spec/features/webauthn/hidden_spec.rb": 32.655933077, + "spec/features/webauthn/management_spec.rb": 53.716660797, + "spec/features/webauthn/sign_in_spec.rb": 21.739840251, + "spec/features/webauthn/sign_up_spec.rb": 14.484833086, + "spec/forms/add_user_email_form_spec.rb": 0.366541016, + "spec/forms/backup_code_verification_form_spec.rb": 0.582923939, + "spec/forms/delete_user_email_form_spec.rb": 0.25282485, + "spec/forms/edit_phone_form_spec.rb": 0.204878755, + "spec/forms/event_disavowal/password_reset_from_disavowal_form_spec.rb": 0.7377633, + "spec/forms/gpo_verify_form_spec.rb": 1.593093596, + "spec/forms/idv/api_image_upload_form_spec.rb": 1.052662178, + "spec/forms/idv/doc_pii_form_spec.rb": 0.026188422, + "spec/forms/idv/in_person/address_form_spec.rb": 0.032275723, + "spec/forms/idv/phone_confirmation_otp_verification_form_spec.rb": 0.144590163, + "spec/forms/idv/phone_form_spec.rb": 1.07679105, + "spec/forms/idv/ssn_form_spec.rb": 0.109430818, + "spec/forms/idv/ssn_format_form_spec.rb": 0.08662983199999999, + "spec/forms/idv/state_id_form_spec.rb": 0.027810541, + "spec/forms/new_phone_form_spec.rb": 1.5338864620000001, + "spec/forms/openid_connect_authorize_form_spec.rb": 0.312212695, + "spec/forms/openid_connect_logout_form_spec.rb": 0.516275654, + "spec/forms/openid_connect_token_form_spec.rb": 1.565577595, + "spec/forms/otp_delivery_selection_form_spec.rb": 0.119364501, + "spec/forms/otp_verification_form_spec.rb": 0.350938732, + "spec/forms/password_form_spec.rb": 0.32559821299999997, + "spec/forms/password_reset_email_form_spec.rb": 0.044723973, + "spec/forms/personal_key_form_spec.rb": 0.058616217, + "spec/forms/register_user_email_form_spec.rb": 3.322593618, + "spec/forms/reset_password_form_spec.rb": 0.636852756, + "spec/forms/security_event_form_spec.rb": 2.59512553, + "spec/forms/totp_setup_form_spec.rb": 0.143478317, + "spec/forms/totp_verification_form_spec.rb": 0.060074768, + "spec/forms/two_factor_authentication/phone_deletion_form_spec.rb": 0.373749172, + "spec/forms/two_factor_login_options_form_spec.rb": 0.021907384000000002, + "spec/forms/two_factor_options_form_spec.rb": 0.211669106, + "spec/forms/update_email_language_form_spec.rb": 0.048419731, + "spec/forms/update_user_password_form_spec.rb": 0.264876433, + "spec/forms/user_piv_cac_login_form_spec.rb": 0.027177803, + "spec/forms/user_piv_cac_setup_form_spec.rb": 0.163593496, + "spec/forms/user_piv_cac_verification_form_spec.rb": 0.108672394, + "spec/forms/verify_password_form_spec.rb": 0.132214306, + "spec/forms/verify_personal_key_form_spec.rb": 0.27340376099999997, + "spec/forms/webauthn_setup_form_spec.rb": 0.465814539, + "spec/forms/webauthn_verification_form_spec.rb": 0.226480063, + "spec/forms/webauthn_visit_form_spec.rb": 0.174715691, + "spec/helpers/application_helper_spec.rb": 0.014860068, + "spec/helpers/go_back_helper_spec.rb": 0.02083718, + "spec/helpers/link_helper_spec.rb": 0.037100242, + "spec/helpers/locale_helper_spec.rb": 0.066327901, + "spec/helpers/script_helper_spec.rb": 0.060938172, + "spec/helpers/session_timeout_warning_helper_spec.rb": 0.023598091, + "spec/helpers/stylesheet_helper_spec.rb": 0.02318469, + "spec/i18n_spec.rb": 53.174239955, + "spec/jobs/address_proofing_job_spec.rb": 0.15995336300000002, + "spec/jobs/application_job_spec.rb": 0.004290818, + "spec/jobs/fraud_rejection_daily_job_spec.rb": 0.05256447, + "spec/jobs/get_usps_proofing_results_job_spec.rb": 24.299568393, + "spec/jobs/get_usps_ready_proofing_results_job_spec.rb": 0.533867349, + "spec/jobs/get_usps_waiting_proofing_results_job_spec.rb": 0.391731914, + "spec/jobs/gpo_daily_job_spec.rb": 0.093121878, + "spec/jobs/gpo_reminder_job_spec.rb": 0.538474703, + "spec/jobs/heartbeat_job_spec.rb": 0.004522984, + "spec/jobs/in_person/email_reminder_job_spec.rb": 0.968637741, + "spec/jobs/in_person/enrollments_ready_for_status_check/batch_processor_spec.rb": 0.02568907, + "spec/jobs/in_person/enrollments_ready_for_status_check/enrollment_pipeline_spec.rb": 0.182931328, + "spec/jobs/in_person/enrollments_ready_for_status_check/error_reporter_spec.rb": 0.021881621, + "spec/jobs/in_person/enrollments_ready_for_status_check/sqs_batch_wrapper_spec.rb": 0.00942552, + "spec/jobs/in_person/enrollments_ready_for_status_check_job_spec.rb": 0.043540706, + "spec/jobs/in_person/send_proofing_notification_job_spec.rb": 0.657961252, + "spec/jobs/job_helpers/encryption_helper_spec.rb": 0.002612607, + "spec/jobs/job_helpers/s3_helper_spec.rb": 0.076404986, + "spec/jobs/job_helpers/stale_job_helper_spec.rb": 0.012228236, + "spec/jobs/job_helpers/timer_spec.rb": 0.007063797, + "spec/jobs/multi_region_kms_migration/profile_migration_job_spec.rb": 1.387738774, + "spec/jobs/phone_number_opt_out_sync_job_spec.rb": 0.058790965, + "spec/jobs/reports/agreement_summary_report_spec.rb": 0.083628985, + "spec/jobs/reports/base_report_spec.rb": 0.00389943, + "spec/jobs/reports/combined_invoice_supplement_report_spec.rb": 0.288315611, + "spec/jobs/reports/daily_auths_report_spec.rb": 0.12788185700000002, + "spec/jobs/reports/daily_dropoffs_report_spec.rb": 0.24691489800000002, + "spec/jobs/reports/daily_registration_report_spec.rb": 0.16625987199999998, + "spec/jobs/reports/deleted_user_accounts_report_spec.rb": 0.12638216600000002, + "spec/jobs/reports/duplicate_ssn_report_spec.rb": 0.093047075, + "spec/jobs/reports/identity_verification_report_spec.rb": 0.0048478819999999995, + "spec/jobs/reports/irs_weekly_summary_report_spec.rb": 0.24289666399999998, + "spec/jobs/reports/month_helper_spec.rb": 0.005092787, + "spec/jobs/reports/monthly_account_reuse_report_spec.rb": 0.38658185600000006, + "spec/jobs/reports/quarterly_account_stats_spec.rb": 0.295870659, + "spec/jobs/reports/query_helpers_spec.rb": 0.0075033470000000005, + "spec/jobs/reports/sp_active_users_report_spec.rb": 0.056523575, + "spec/jobs/reports/sp_issuer_user_counts_report_spec.rb": 0.073038061, + "spec/jobs/reports/sp_user_counts_report_spec.rb": 0.031889135, + "spec/jobs/reports/total_ial2_costs_report_spec.rb": 0.025872067, + "spec/jobs/reports/total_monthly_auths_report_spec.rb": 0.049705927, + "spec/jobs/reports/verification_failures_report_spec.rb": 0.378594607, + "spec/jobs/resolution_proofing_job_spec.rb": 0.899992773, + "spec/jobs/risc_delivery_job_spec.rb": 0.126778647, + "spec/jobs/threat_metrix_js_verification_job_spec.rb": 0.503099794, + "spec/jobs/usps_auth_token_refresh_job_spec.rb": 0.098585374, + "spec/lib/ab_test_bucket_spec.rb": 0.024145344, + "spec/lib/action_account_spec.rb": 0.782183052, + "spec/lib/analytics_events_documenter_spec.rb": 0.116298802, + "spec/lib/app_artifacts_spec.rb": 0.015370622, + "spec/lib/asset_sources_spec.rb": 0.037521689, + "spec/lib/aws/ses_spec.rb": 0.018118009, + "spec/lib/base16_spec.rb": 0.013284832, + "spec/lib/cleanup/destroy_unused_providers_spec.rb": 0.096469197, + "spec/lib/cleanup/destroyable_records_spec.rb": 0.775007445, + "spec/lib/data_pull_spec.rb": 0.567496971, + "spec/lib/data_requests/deployed/create_email_addresses_report_spec.rb": 0.015413951, + "spec/lib/data_requests/deployed/create_mfa_configurations_report_spec.rb": 0.220289807, + "spec/lib/data_requests/deployed/create_user_events_report_spec.rb": 0.04774091, + "spec/lib/data_requests/deployed/create_user_report_spec.rb": 0.086462863, + "spec/lib/data_requests/deployed/lookup_shared_device_users_spec.rb": 0.05410461, + "spec/lib/data_requests/deployed/lookup_user_by_uuid_spec.rb": 0.055166484999999994, + "spec/lib/data_requests/local/fetch_cloudwatch_logs_spec.rb": 0.016098778, + "spec/lib/data_requests/local/write_cloudwatch_logs_spec.rb": 0.01337228, + "spec/lib/data_requests/local/write_user_events_spec.rb": 0.004784065, + "spec/lib/data_requests/local/write_user_info_spec.rb": 0.005360066, + "spec/lib/deploy/activate_spec.rb": 0.068100593, + "spec/lib/feature_management_spec.rb": 0.173540281, + "spec/lib/fingerprinter_spec.rb": 0.005050665, + "spec/lib/good_job_connection_pool_size_spec.rb": 0.007865273, + "spec/lib/headers_filter_spec.rb": 0.00270594, + "spec/lib/identity_config_spec.rb": 0.012199027, + "spec/lib/identity_cors_spec.rb": 0.016022345, + "spec/lib/identity_job_log_subscriber_spec.rb": 0.135331486, + "spec/lib/linters/errors_add_linter_spec.rb": 0.19585207400000001, + "spec/lib/linters/image_size_linter_spec.rb": 0.18751934599999998, + "spec/lib/linters/localized_validation_message_linter_spec.rb": 0.185622533, + "spec/lib/linters/mail_later_linter_spec.rb": 0.180537584, + "spec/lib/linters/redirect_back_linter_spec.rb": 0.170209057, + "spec/lib/linters/url_options_linter_spec.rb": 0.205685538, + "spec/lib/makefile_help_parser_spec.rb": 0.063305975, + "spec/lib/otp_code_generator_spec.rb": 0.01205979, + "spec/lib/pinpoint_supported_countries_spec.rb": 0.059020415, + "spec/lib/query_tracker_spec.rb": 0.018049385, + "spec/lib/reporting/authentication_report_spec.rb": 0.017565692, + "spec/lib/reporting/cloudwatch_client_spec.rb": 0.924579689, + "spec/lib/reporting/cloudwatch_query_quoting_spec.rb": 0.004945555, + "spec/lib/reporting/cloudwatch_query_time_slice_spec.rb": 0.015285003, + "spec/lib/reporting/command_line_options_spec.rb": 0.073130619, + "spec/lib/reporting/identity_verification_report_spec.rb": 0.035833948, + "spec/lib/reporting/monthly_proofing_report_spec.rb": 0.016048153, + "spec/lib/reporting/unknown_progress_bar_spec.rb": 0.114921313, + "spec/lib/session_encryptor_spec.rb": 0.036636869, + "spec/lib/tasks/dev_rake_spec.rb": 11.459567969, + "spec/lib/tasks/partners_rake_spec.rb": 0.853642103, + "spec/lib/tasks/review_profile_spec.rb": 0.9999740610000001, + "spec/lib/tasks/rotate_rake_spec.rb": 0.292745902, + "spec/lib/telephony/alert_sender_spec.rb": 0.022804831, + "spec/lib/telephony/otp_sender_spec.rb": 0.07868096, + "spec/lib/telephony/pinpoint/aws_credential_builder_spec.rb": 0.015833485, + "spec/lib/telephony/pinpoint/opt_out_manager_spec.rb": 0.038834163, + "spec/lib/telephony/pinpoint/sms_sender_spec.rb": 0.110123107, + "spec/lib/telephony/pinpoint/voice_sender_spec.rb": 0.058191564, + "spec/lib/telephony/pinpoint_configuration_spec.rb": 0.002288855, + "spec/lib/telephony/response_spec.rb": 0.013338701, + "spec/lib/telephony/telephony_spec.rb": 0.0273591, + "spec/lib/telephony/test/call_spec.rb": 0.024258547, + "spec/lib/telephony/test/message_spec.rb": 0.013564817, + "spec/lib/telephony/test/sms_sender_spec.rb": 0.022731438, + "spec/lib/telephony/test/voice_sender_spec.rb": 0.0078397, + "spec/lib/telephony/util_spec.rb": 0.006217463, + "spec/lib/utf8_sanitizer_spec.rb": 0.026568295999999998, + "spec/mailers/previews/report_mailer_preview_spec.rb": 0.004336597, + "spec/mailers/previews/user_mailer_preview_spec.rb": 0.139542386, + "spec/mailers/report_mailer_spec.rb": 0.097829737, + "spec/mailers/user_mailer_spec.rb": 4.903760608, + "spec/models/account_reset_request_spec.rb": 0.025667639, + "spec/models/agency_identity_spec.rb": 0.01247941, + "spec/models/agency_spec.rb": 0.021040706, + "spec/models/agreements/iaa_gtc_spec.rb": 0.22739842899999999, + "spec/models/agreements/iaa_order_spec.rb": 0.356875205, + "spec/models/agreements/iaa_spec.rb": 0.173175527, + "spec/models/agreements/integration_spec.rb": 0.283424074, + "spec/models/agreements/integration_status_spec.rb": 0.048712751, + "spec/models/agreements/integration_usage_spec.rb": 0.255684598, + "spec/models/agreements/partner_account_spec.rb": 0.168169339, + "spec/models/agreements/partner_account_status_spec.rb": 0.04185945, + "spec/models/anonymous_user_spec.rb": 0.020698199, + "spec/models/backup_code_configuration_spec.rb": 1.125044828, + "spec/models/concerns/user_otp_methods_spec.rb": 0.002827497, + "spec/models/deleted_user_spec.rb": 0.065960724, + "spec/models/device_spec.rb": 0.052514192, + "spec/models/document_capture_session_spec.rb": 0.043053105, + "spec/models/email_address_spec.rb": 0.147875095, + "spec/models/event_spec.rb": 0.025822649, + "spec/models/gpo_confirmation_code_spec.rb": 0.117443281, + "spec/models/in_person_enrollment_spec.rb": 2.633024327, + "spec/models/notification_phone_configuration_spec.rb": 0.142779661, + "spec/models/null_identity_spec.rb": 0.002909283, + "spec/models/phone_configuration_spec.rb": 0.094129769, + "spec/models/phone_number_opt_out_spec.rb": 0.088100451, + "spec/models/profile_spec.rb": 2.971656051, + "spec/models/service_provider_identity_spec.rb": 0.333874602, + "spec/models/service_provider_spec.rb": 0.035812911, + "spec/models/sp_return_log_spec.rb": 0.00373755, + "spec/models/suspended_email_spec.rb": 0.122754336, + "spec/models/user_spec.rb": 3.93750681, + "spec/models/webauthn_configuration_spec.rb": 0.244282458, + "spec/policies/backup_code_policy_spec.rb": 0.020193306, + "spec/policies/service_provider_mfa_policy_spec.rb": 0.622013701, + "spec/policies/two_factor_authentication/piv_cac_policy_spec.rb": 0.057421650000000005, + "spec/policies/user_mfa_policy_spec.rb": 0.167963602, + "spec/policies/webauthn_login_option_policy_spec.rb": 0.074905819, + "spec/presenters/account_reset/pending_presenter_spec.rb": 0.088717961, + "spec/presenters/account_show_presenter_spec.rb": 0.179208179, + "spec/presenters/cancellation_presenter_spec.rb": 0.010612439000000001, + "spec/presenters/completions_presenter_spec.rb": 0.71867844, + "spec/presenters/confirm_delete_email_presenter_spec.rb": 0.019386052, + "spec/presenters/eastern_time_presenter_spec.rb": 0.002287595, + "spec/presenters/idv/cancellations_presenter_spec.rb": 0.031458982, + "spec/presenters/idv/gpo_presenter_spec.rb": 0.172737372, + "spec/presenters/idv/in_person/ready_to_verify_presenter_spec.rb": 0.5086508359999999, + "spec/presenters/idv/in_person/verification_results_email_presenter_spec.rb": 0.62312128, + "spec/presenters/image_upload_response_presenter_spec.rb": 0.052504845, + "spec/presenters/max_attempts_reached_presenter_spec.rb": 0.009224431, + "spec/presenters/mfa_confirmation_presenter_spec.rb": 0.012113281, + "spec/presenters/navigation_presenter_spec.rb": 0.09638060799999999, + "spec/presenters/openid_connect_certs_presenter_spec.rb": 0.003882543, + "spec/presenters/openid_connect_configuration_presenter_spec.rb": 0.003964811, + "spec/presenters/openid_connect_user_info_presenter_spec.rb": 0.629763042, + "spec/presenters/piv_cac_authentication_setup_presenter_spec.rb": 0.038746804, + "spec/presenters/piv_cac_error_presenter_spec.rb": 0.009657171, + "spec/presenters/risc_configuration_presenter_spec.rb": 0.003787687, + "spec/presenters/saml_request_presenter_spec.rb": 0.020839022, + "spec/presenters/session_timeout_modal_presenter_spec.rb": 0.006341627, + "spec/presenters/setup_presenter_spec.rb": 0.064449188, + "spec/presenters/two_factor_auth_code/authenticator_delivery_presenter_spec.rb": 0.006623709, + "spec/presenters/two_factor_auth_code/backup_code_presenter_spec.rb": 0.004680367, + "spec/presenters/two_factor_auth_code/generic_delivery_presenter_spec.rb": 0.031171834, + "spec/presenters/two_factor_auth_code/phone_delivery_presenter_spec.rb": 0.028520557000000002, + "spec/presenters/two_factor_auth_code/piv_cac_authentication_presenter_spec.rb": 0.011861636, + "spec/presenters/two_factor_auth_code/webauthn_authentication_presenter_spec.rb": 0.061794574, + "spec/presenters/two_factor_authentication/auth_app_selection_presenter_spec.rb": 0.049306093, + "spec/presenters/two_factor_authentication/personal_key_selection_presenter_spec.rb": 0.013391519, + "spec/presenters/two_factor_authentication/phone_selection_presenter_spec.rb": 0.138879578, + "spec/presenters/two_factor_authentication/piv_cac_selection_presenter_spec.rb": 0.091495325, + "spec/presenters/two_factor_authentication/selection_presenter_spec.rb": 0.12007853, + "spec/presenters/two_factor_authentication/sms_selection_presenter_spec.rb": 0.08666894, + "spec/presenters/two_factor_authentication/voice_selection_presenter_spec.rb": 0.100102596, + "spec/presenters/two_factor_authentication/webauthn_platform_selection_presenter_spec.rb": 0.112377123, + "spec/presenters/two_factor_authentication/webauthn_selection_presenter_spec.rb": 0.059715596999999995, + "spec/presenters/two_factor_login_options_presenter_spec.rb": 0.099787484, + "spec/presenters/two_factor_options_presenter_spec.rb": 0.108481161, + "spec/presenters/utc_time_presenter_spec.rb": 0.002424084, + "spec/presenters/webauthn_setup_presenter_spec.rb": 0.123082188, + "spec/requests/acuant_sdk_spec.rb": 0.058827727999999996, + "spec/requests/api_cors_spec.rb": 0.411416802, + "spec/requests/bimi_logo_spec.rb": 0.020925564, + "spec/requests/csp_spec.rb": 0.091510021, + "spec/requests/headers_spec.rb": 0.231085353, + "spec/requests/i18n_spec.rb": 0.091102271, + "spec/requests/invalid_encoding_spec.rb": 0.212196911, + "spec/requests/invalid_sign_in_params_spec.rb": 0.085552086, + "spec/requests/not_acceptable_spec.rb": 0.069316832, + "spec/requests/openid_connect_authorize_spec.rb": 0.693808623, + "spec/requests/openid_connect_cors_spec.rb": 0.400301987, + "spec/requests/openid_connect_userinfo_spec.rb": 0.062619999, + "spec/requests/page_not_found_spec.rb": 0.098349297, + "spec/requests/rack_attack_spec.rb": 5.706272716, + "spec/requests/redis_down_spec.rb": 0.026517473, + "spec/requests/saml_requests_spec.rb": 0.251828248, + "spec/requests/secure_cookies_spec.rb": 0.115911398, + "spec/routing/gpo_verification_routing_spec.rb": 0.239072943, + "spec/scripts/changelog_check_spec.rb": 0.02639691, + "spec/services/access_token_verifier_spec.rb": 0.051659580999999996, + "spec/services/account_reset/cancel_request_for_user_spec.rb": 0.38754839599999996, + "spec/services/account_reset/cancel_spec.rb": 1.281365367, + "spec/services/account_reset/create_request_spec.rb": 0.555224407, + "spec/services/account_reset/delete_account_spec.rb": 0.593583868, + "spec/services/account_reset/find_prending_request_for_user_spec.rb": 0.10105803099999999, + "spec/services/account_reset/grant_request_spec.rb": 0.054776651999999995, + "spec/services/account_reset/grant_requests_and_send_emails_spec.rb": 0.941665388, + "spec/services/account_reset/notify_user_of_request_cancellation_spec.rb": 0.523438633, + "spec/services/account_reset/validate_granted_token_spec.rb": 0.045224197, + "spec/services/active_profile_encryptor_spec.rb": 0.057672288, + "spec/services/agency_identity_linker_spec.rb": 0.344112651, + "spec/services/agency_seeder_spec.rb": 0.046743617, + "spec/services/agreements/iaa_gtc_seeder_spec.rb": 0.028591456, + "spec/services/agreements/iaa_order_seeder_spec.rb": 0.074432856, + "spec/services/agreements/integration_seeder_spec.rb": 0.057194575, + "spec/services/agreements/integration_status_seeder_spec.rb": 0.028043191000000002, + "spec/services/agreements/partner_account_seeder_spec.rb": 0.041262599999999997, + "spec/services/agreements/partner_account_status_seeder_spec.rb": 0.043031457, + "spec/services/analytics_spec.rb": 0.115084797, + "spec/services/attribute_asserter_spec.rb": 1.064169597, + "spec/services/backup_code_generator_spec.rb": 1.398218477, + "spec/services/banned_user_resolver_spec.rb": 0.126945433, + "spec/services/barcode_outputter_spec.rb": 0.014177648, + "spec/services/browser_cache_spec.rb": 0.007922452, + "spec/services/browser_support_spec.rb": 0.027945455, + "spec/services/calendar_service_spec.rb": 0.053805879, + "spec/services/cloud_front_header_parser_spec.rb": 0.010802931, + "spec/services/completions_decider_spec.rb": 0.018477566, + "spec/services/database_health_checker_spec.rb": 0.008138685, + "spec/services/date_parser_spec.rb": 0.013899662, + "spec/services/db/add_document_verification_and_selfie_costs_spec.rb": 0.025553410999999998, + "spec/services/db/identity/sp_active_user_counts_spec.rb": 0.094682397, + "spec/services/db/identity/sp_user_counts_spec.rb": 0.051818892, + "spec/services/db/monthly_auth_count/total_monthly_auth_counts_spec.rb": 0.037683803, + "spec/services/db/monthly_sp_auth_count/total_monthly_auth_counts_within_iaa_window_spec.rb": 0.093815373, + "spec/services/db/monthly_sp_auth_count/unique_monthly_auth_counts_by_iaa_spec.rb": 0.13920667, + "spec/services/db/sp_return_log_spec.rb": 0.036098091, + "spec/services/deleted_accounts_report_spec.rb": 0.13873707000000002, + "spec/services/displayable_pii_formatter_spec.rb": 0.699058893, + "spec/services/doc_auth/acuant/acuant_client_spec.rb": 0.29341190300000003, + "spec/services/doc_auth/acuant/pii_from_doc_spec.rb": 0.014881184, + "spec/services/doc_auth/acuant/request_spec.rb": 0.566821514, + "spec/services/doc_auth/acuant/requests/create_document_request_spec.rb": 0.036986530000000004, + "spec/services/doc_auth/acuant/requests/get_results_request_spec.rb": 0.065222897, + "spec/services/doc_auth/acuant/requests/upload_image_request_spec.rb": 0.10025046600000001, + "spec/services/doc_auth/acuant/responses/create_document_response_spec.rb": 0.003991661, + "spec/services/doc_auth/acuant/responses/get_results_response_spec.rb": 0.080210484, + "spec/services/doc_auth/acuant/result_codes_spec.rb": 0.004983233, + "spec/services/doc_auth/error_generator_spec.rb": 0.073544903, + "spec/services/doc_auth/lexis_nexis/lexis_nexis_client_spec.rb": 0.278956172, + "spec/services/doc_auth/lexis_nexis/request_spec.rb": 0.504964585, + "spec/services/doc_auth/lexis_nexis/requests/true_id_request_spec.rb": 0.134159603, + "spec/services/doc_auth/lexis_nexis/responses/true_id_response_spec.rb": 0.388976116, + "spec/services/doc_auth/mock/doc_auth_mock_client_spec.rb": 0.066188606, + "spec/services/doc_auth/mock/result_response_spec.rb": 0.054269502, + "spec/services/doc_auth/processed_alert_to_log_alert_formatter_spec.rb": 0.006953002999999999, + "spec/services/doc_auth/response_spec.rb": 0.036033169, + "spec/services/doc_auth_router_spec.rb": 0.061641064, + "spec/services/document_capture_session_async_result_spec.rb": 0.029609502, + "spec/services/document_capture_session_result_spec.rb": 0.005166748, + "spec/services/duration_parser_spec.rb": 0.022013184, + "spec/services/email_confirmation_token_validator_spec.rb": 0.134612832, + "spec/services/email_normalizer_spec.rb": 0.013432528, + "spec/services/encrypted_attribute_spec.rb": 0.017268501999999998, + "spec/services/encrypted_document_storage/document_writer_spec.rb": 0.016887165, + "spec/services/encrypted_document_storage/local_storage_spec.rb": 0.003351698, + "spec/services/encrypted_document_storage/s3_storage_spec.rb": 0.08256681, + "spec/services/encrypted_redis_struct_storage_spec.rb": 0.050693256, + "spec/services/encryption/aes_cipher_spec.rb": 0.009491825, + "spec/services/encryption/aes_cipher_v2_spec.rb": 0.009329377, + "spec/services/encryption/contextless_kms_client_spec.rb": 0.076801319, + "spec/services/encryption/encryptors/aes_encryptor_spec.rb": 0.010632828, + "spec/services/encryption/encryptors/aes_encryptor_v2_spec.rb": 0.00877251, + "spec/services/encryption/encryptors/attribute_encryptor_spec.rb": 0.020480389999999998, + "spec/services/encryption/encryptors/background_proofing_arg_encryptor_spec.rb": 0.009621303, + "spec/services/encryption/encryptors/pii_encryptor_spec.rb": 0.101555144, + "spec/services/encryption/encryptors/session_encryptor_spec.rb": 0.010661563, + "spec/services/encryption/kms_client_spec.rb": 0.11086546100000001, + "spec/services/encryption/kms_logger_spec.rb": 0.007052196, + "spec/services/encryption/multi_region_kms_migration/profile_migrator_spec.rb": 0.181228685, + "spec/services/encryption/password_verifier_spec.rb": 0.133859629, + "spec/services/encryption/uak_password_verifier_spec.rb": 0.213904981, + "spec/services/encryption/user_access_key_spec.rb": 0.039995851, + "spec/services/event_disavowal/disavow_event_spec.rb": 0.025420214, + "spec/services/event_disavowal/find_disavowed_event_spec.rb": 0.095074535, + "spec/services/event_disavowal/validate_disavowed_event_spec.rb": 0.057300127, + "spec/services/forget_all_browsers_spec.rb": 0.016661017, + "spec/services/form_response_spec.rb": 0.114119641, + "spec/services/fraud_review_check_spec.rb": 0.488372239, + "spec/services/frontend_logger_spec.rb": 0.005133043, + "spec/services/funnel/registration/add_mfa_spec.rb": 0.030001041, + "spec/services/funnel/registration/total_registered_count_spec.rb": 0.07665209099999999, + "spec/services/gpo_confirmation_exporter_spec.rb": 0.015237819, + "spec/services/gpo_confirmation_maker_spec.rb": 0.164512584, + "spec/services/gpo_confirmation_spec.rb": 0.015768996, + "spec/services/gpo_confirmation_uploader_spec.rb": 0.043565981, + "spec/services/gpo_daily_test_sender_spec.rb": 0.023738464, + "spec/services/gpo_reminder_sender_spec.rb": 4.746882273, + "spec/services/health_check_summary_spec.rb": 0.005796202, + "spec/services/iaa_reporting_helper_spec.rb": 0.19996967100000002, + "spec/services/ial_context_spec.rb": 0.38625708999999997, + "spec/services/id_token_builder_spec.rb": 0.326061063, + "spec/services/identity_linker_spec.rb": 0.299051287, + "spec/services/idv/agent_spec.rb": 0.331506763, + "spec/services/idv/analytics_events_enhancer_spec.rb": 0.037015448, + "spec/services/idv/cancel_verification_attempt_spec.rb": 0.251062781, + "spec/services/idv/data_url_image_spec.rb": 0.010149339, + "spec/services/idv/doc_auth_form_response_spec.rb": 0.016595744, + "spec/services/idv/duplicate_ssn_finder_spec.rb": 0.210852818, + "spec/services/idv/gpo_mail_spec.rb": 0.098945174, + "spec/services/idv/in_person/completion_survey_sender_spec.rb": 0.640610067, + "spec/services/idv/in_person/enrollment_code_formatter_spec.rb": 0.003501469, + "spec/services/idv/in_person_config_spec.rb": 0.03940473, + "spec/services/idv/phone_confirmation_session_spec.rb": 0.025309808, + "spec/services/idv/phone_step_spec.rb": 0.867603628, + "spec/services/idv/profile_maker_spec.rb": 0.291196728, + "spec/services/idv/proofing_components_logging_spec.rb": 0.002292929, + "spec/services/idv/send_phone_confirmation_otp_spec.rb": 0.16278936100000002, + "spec/services/idv/session_spec.rb": 0.763527445, + "spec/services/idv/steps/in_person/address_step_spec.rb": 0.232334855, + "spec/services/idv/steps/in_person/state_id_step_spec.rb": 0.281044495, + "spec/services/key_rotator/attribute_encryption_spec.rb": 0.036704899, + "spec/services/key_rotator/hmac_fingerprinter_spec.rb": 0.17661306300000001, + "spec/services/marketing_site_spec.rb": 0.068416352, + "spec/services/multi_health_checker_spec.rb": 0.007467177, + "spec/services/openid_connect_attribute_scoper_spec.rb": 0.034905028, + "spec/services/otp_preference_updater_spec.rb": 0.045215478999999996, + "spec/services/otp_rate_limiter_spec.rb": 0.18773779499999999, + "spec/services/out_of_band_session_accessor_spec.rb": 0.023971222, + "spec/services/outage_status_spec.rb": 0.056214563, + "spec/services/outbound_health_checker_spec.rb": 0.092318175, + "spec/services/parse_controller_from_referer_spec.rb": 0.004462692, + "spec/services/personal_key_generator_spec.rb": 0.311820656, + "spec/services/phone_formatter_spec.rb": 0.087994348, + "spec/services/phone_number_capabilities_spec.rb": 0.091675114, + "spec/services/phone_recaptcha_validator_spec.rb": 0.052747774, + "spec/services/pii/attributes_spec.rb": 0.021582513, + "spec/services/pii/cacher_spec.rb": 0.423980442, + "spec/services/pii/fingerprinter_spec.rb": 0.026146503, + "spec/services/pii/re_encryptor_spec.rb": 0.125766178, + "spec/services/piv_cac/check_config_spec.rb": 0.010556799, + "spec/services/piv_cac_service_spec.rb": 0.059652417, + "spec/services/profanity_detector_spec.rb": 0.026497848, + "spec/services/proofing/aamva/applicant_spec.rb": 0.007014124, + "spec/services/proofing/aamva/authentication_client_spec.rb": 0.150244447, + "spec/services/proofing/aamva/hmac_secret_spec.rb": 0.003893154, + "spec/services/proofing/aamva/proofer_spec.rb": 0.6517063120000001, + "spec/services/proofing/aamva/request/authentication_token_request_spec.rb": 0.13554570900000001, + "spec/services/proofing/aamva/request/security_token_request_spec.rb": 1.716375688, + "spec/services/proofing/aamva/request/verification_request_spec.rb": 0.425805135, + "spec/services/proofing/aamva/response/authentication_token_response_spec.rb": 0.038744099000000004, + "spec/services/proofing/aamva/response/security_token_response_spec.rb": 0.046389236, + "spec/services/proofing/aamva/response/verification_response_spec.rb": 0.191560949, + "spec/services/proofing/aamva/soap_error_handler_spec.rb": 0.0544985, + "spec/services/proofing/aamva/verification_client_spec.rb": 0.40287876, + "spec/services/proofing/ddp_result_spec.rb": 0.040096024, + "spec/services/proofing/lexis_nexis/date_formatter_spec.rb": 0.007165006, + "spec/services/proofing/lexis_nexis/ddp/proofing_spec.rb": 0.046680449, + "spec/services/proofing/lexis_nexis/ddp/response_redacter_spec.rb": 0.008995162, + "spec/services/proofing/lexis_nexis/ddp/verification_request_spec.rb": 0.011583693, + "spec/services/proofing/lexis_nexis/instant_verify/check_to_attribute_mapper_spec.rb": 0.022947279, + "spec/services/proofing/lexis_nexis/instant_verify/proofing_spec.rb": 0.049779657, + "spec/services/proofing/lexis_nexis/instant_verify/verification_request_spec.rb": 0.034377369, + "spec/services/proofing/lexis_nexis/phone_finder/proofing_spec.rb": 0.084039418, + "spec/services/proofing/lexis_nexis/phone_finder/verification_request_spec.rb": 0.037631678, + "spec/services/proofing/lexis_nexis/request_signer_spec.rb": 0.003053672, + "spec/services/proofing/lexis_nexis/response_spec.rb": 0.035251369, + "spec/services/proofing/lexis_nexis/verification_error_parser_spec.rb": 0.014488079, + "spec/services/proofing/mock/address_mock_client_spec.rb": 0.012002392, + "spec/services/proofing/mock/ddp_mock_client_spec.rb": 0.032158448, + "spec/services/proofing/mock/device_profiling_backend_spec.rb": 0.007847348, + "spec/services/proofing/mock/resolution_mock_client_spec.rb": 0.018443127, + "spec/services/proofing/mock/state_id_mock_client_spec.rb": 0.015560624, + "spec/services/proofing/resolution/progressive_proofer_spec.rb": 0.354360286, + "spec/services/proofing/resolution/result_adjudicator_spec.rb": 0.022095727, + "spec/services/proofing_session_async_result_spec.rb": 0.003937377, + "spec/services/push_notification/account_purged_event_spec.rb": 0.020991113, + "spec/services/push_notification/email_changed_event_spec.rb": 0.022074703, + "spec/services/push_notification/http_push_spec.rb": 0.596549542, + "spec/services/push_notification/identifier_recycled_event_spec.rb": 0.040976205, + "spec/services/push_notification/mfa_limit_account_locked_event_spec.rb": 0.023643663000000002, + "spec/services/push_notification/password_reset_event_spec.rb": 0.019431432, + "spec/services/push_notification/recovery_activated_event_spec.rb": 0.019480282, + "spec/services/push_notification/reproof_completed_event_spec.rb": 0.018149514, + "spec/services/pwned_passwords/lookup_password_spec.rb": 0.006263852, + "spec/services/random_phrase_spec.rb": 0.07127613699999999, + "spec/services/rate_limiter_spec.rb": 0.065951519, + "spec/services/reactivate_account_session_spec.rb": 0.094381044, + "spec/services/recaptcha_enterprise_validator_spec.rb": 0.132004602, + "spec/services/recaptcha_mock_validator_spec.rb": 0.012447827, + "spec/services/recaptcha_validator_spec.rb": 0.119948609, + "spec/services/redis_rate_limiter_spec.rb": 0.024088341, + "spec/services/remember_device_cookie_spec.rb": 0.15363532800000002, + "spec/services/request_password_reset_spec.rb": 3.879671035, + "spec/services/reset_user_password_spec.rb": 1.809230628, + "spec/services/revoke_service_provider_consent_spec.rb": 0.021176188, + "spec/services/saml_endpoint_spec.rb": 0.026093374, + "spec/services/saml_request_validator_spec.rb": 0.070049736, + "spec/services/secure_headers_allow_list_spec.rb": 0.010906825, + "spec/services/send_sign_up_email_confirmation_spec.rb": 0.950526415, + "spec/services/service_provider_request_proxy_spec.rb": 0.018222111, + "spec/services/service_provider_seeder_spec.rb": 1.256766919, + "spec/services/service_provider_updater_spec.rb": 0.458280581, + "spec/services/session_encryptor_spec.rb": 0.007635058, + "spec/services/sp_return_url_resolver_spec.rb": 0.035308351, + "spec/services/ssn_formatter_spec.rb": 0.020145367, + "spec/services/store_sp_metadata_in_session_spec.rb": 0.012174037, + "spec/services/string_redacter_spec.rb": 0.002447241, + "spec/services/time_service_spec.rb": 0.002371261, + "spec/services/update_user_spec.rb": 0.252475456, + "spec/services/uri_service_spec.rb": 0.012564572, + "spec/services/user_alerts/alert_user_about_account_verified_spec.rb": 0.593480688, + "spec/services/user_alerts/alert_user_about_new_device_spec.rb": 0.368468876, + "spec/services/user_alerts/alert_user_about_password_change_spec.rb": 0.368299808, + "spec/services/user_alerts/alert_user_about_personal_key_sign_in_spec.rb": 0.472850259, + "spec/services/user_event_creator_spec.rb": 0.253950005, + "spec/services/user_seeder_spec.rb": 2.7063205850000003, + "spec/services/user_session_context_spec.rb": 0.025046204, + "spec/services/usps_in_person_proofing/enrollment_helper_spec.rb": 4.03215247, + "spec/services/usps_in_person_proofing/proofer_spec.rb": 0.34354361099999997, + "spec/services/usps_in_person_proofing/transliterable_validator_spec.rb": 0.043670886, + "spec/services/usps_in_person_proofing/transliterator_spec.rb": 0.10674436, + "spec/services/uuid_reporter_spec.rb": 0.226906565, + "spec/services/x509/attribute_spec.rb": 0.002275788, + "spec/services/x509/attributes_spec.rb": 0.02190224, + "spec/svg_spec.rb": 0.318740858, + "spec/views/account_reset/cancel/show.html.erb_spec.rb": 0.016139819, + "spec/views/account_reset/confirm_delete_account/show.html.erb_spec.rb": 0.042938398, + "spec/views/account_reset/confirm_request/show.html.erb_spec.rb": 0.006873193, + "spec/views/account_reset/delete_account/show.html.erb_spec.rb": 0.01464609, + "spec/views/account_reset/recovery_options/show.html.erb_spec.rb": 0.017849426, + "spec/views/account_reset/request/show.html.erb_spec.rb": 0.060496201, + "spec/views/account_reset/user_mailer/email_confirmation_instructions.html.erb_spec.rb": 0.12376949599999999, + "spec/views/account_reset/user_mailer/unconfirmed_email_instructions.html.erb_spec.rb": 0.06123269, + "spec/views/accounts/_nav_auth.html.erb_spec.rb": 0.065759186, + "spec/views/accounts/connected_accounts/show.html.erb_spec.rb": 0.061582544, + "spec/views/accounts/history/show.html.erb_spec.rb": 0.033875595, + "spec/views/accounts/show.html.erb_spec.rb": 0.741568079, + "spec/views/accounts/two_factor_authentication/show.html.erb_spec.rb": 0.215294232, + "spec/views/devise/passwords/edit.html.erb_spec.rb": 0.14550944, + "spec/views/devise/passwords/new.html.erb_spec.rb": 0.07746093600000001, + "spec/views/devise/sessions/new.html.erb_spec.rb": 0.317551978, + "spec/views/devise/shared/_password_strength.html.erb_spec.rb": 0.016301421, + "spec/views/forgot_password/show.html.erb_spec.rb": 0.076041431, + "spec/views/idv/activated.html.erb_spec.rb": 0.025995651, + "spec/views/idv/address/new.html.erb_spec.rb": 0.12634022, + "spec/views/idv/agreement/show.html.erb_spec.rb": 0.022761506, + "spec/views/idv/cancellations/destroy.html.erb_spec.rb": 0.033767066, + "spec/views/idv/cancellations/new.html.erb_spec.rb": 0.072067207, + "spec/views/idv/come_back_later/show.html.erb_spec.rb": 0.040369175, + "spec/views/idv/doc_auth/_cancel.html.erb_spec.rb": 0.025085548, + "spec/views/idv/getting_started/show.html.erb_spec.rb": 0.098918009, + "spec/views/idv/gpo/index.html.erb_spec.rb": 0.162694065, + "spec/views/idv/gpo_verify/index.html.erb_spec.rb": 0.18076298200000002, + "spec/views/idv/in_person/ready_to_verify/show.html.erb_spec.rb": 0.45821712800000003, + "spec/views/idv/in_person/ssn/show.html.erb_spec.rb": 0.09840162899999999, + "spec/views/idv/phone/new.html.erb_spec.rb": 0.094671674, + "spec/views/idv/phone_errors/_warning.html.erb_spec.rb": 0.059338031, + "spec/views/idv/phone_errors/failure.html.erb_spec.rb": 0.06633931, + "spec/views/idv/phone_errors/jobfail.html.erb_spec.rb": 0.055434024, + "spec/views/idv/phone_errors/timeout.html.erb_spec.rb": 0.039597196, + "spec/views/idv/phone_errors/warning.html.erb_spec.rb": 0.13265237600000002, + "spec/views/idv/please_call/show.html.erb_spec.rb": 0.016844854, + "spec/views/idv/review/new.html.erb_spec.rb": 0.06459221700000001, + "spec/views/idv/session_errors/exception.html.erb_spec.rb": 0.036492746, + "spec/views/idv/session_errors/failure.html.erb_spec.rb": 0.035772016, + "spec/views/idv/session_errors/rate_limited.html.erb_spec.rb": 0.046142485999999996, + "spec/views/idv/session_errors/state_id_warning.html.erb_spec.rb": 0.037498486, + "spec/views/idv/session_errors/warning.html.erb_spec.rb": 0.02844333, + "spec/views/idv/shared/_back.html.erb_spec.rb": 0.054472032999999996, + "spec/views/idv/shared/_document_capture.html.erb_spec.rb": 0.028872121, + "spec/views/idv/shared/_error.html.erb_spec.rb": 0.170328333, + "spec/views/idv/unavailable/show.html.erb_spec.rb": 0.045682456999999996, + "spec/views/idv/welcome/show.html.erb_spec.rb": 0.102285163, + "spec/views/layouts/application.html.erb_spec.rb": 0.174248445, + "spec/views/layouts/user_mailer.html.erb_spec.rb": 0.19682555100000002, + "spec/views/mfa_confirmation/show.html.erb_spec.rb": 0.193284213, + "spec/views/partials/multi_factor_authentication/_mfa_selection.html.erb_spec.rb": 0.924356506, + "spec/views/partials/personal_key/_key.html.erb_spec.rb": 0.02895075, + "spec/views/phone_setup/index.html.erb_spec.rb": 0.409925364, + "spec/views/phone_setup/spam_protection.html.erb_spec.rb": 0.134181532, + "spec/views/reactivate_account/index.html.erb_spec.rb": 0.024034147999999998, + "spec/views/shared/_address.html.erb_spec.rb": 0.009128134999999999, + "spec/views/shared/_banner.html.erb_spec.rb": 0.007680919, + "spec/views/shared/_cancel_or_back_to_options.html.erb_spec.rb": 0.055230439, + "spec/views/shared/_email_languages.html.erb_spec.rb": 0.034761263, + "spec/views/shared/_footer_lite.html.erb_spec.rb": 0.028440994, + "spec/views/shared/_masked_text.html.erb_spec.rb": 0.018684603, + "spec/views/shared/_nav_branded.html.erb_spec.rb": 0.033830714, + "spec/views/shared/_nav_lite.html.erb_spec.rb": 0.008691643, + "spec/views/shared/_personal_key.html.erb_spec.rb": 0.008725215, + "spec/views/shared/_troubleshooting_options.html.erb_spec.rb": 0.048389627000000004, + "spec/views/sign_up/completions/show.html.erb_spec.rb": 0.247847635, + "spec/views/sign_up/email_resend/new.html.erb_spec.rb": 0.018955642, + "spec/views/sign_up/emails/show.html.erb_spec.rb": 0.05768305, + "spec/views/sign_up/passwords/new.html.erb_spec.rb": 0.089344473, + "spec/views/sign_up/registrations/new.html.erb_spec.rb": 0.16937989, + "spec/views/two_factor_authentication/options/index.html.erb_spec.rb": 0.11397581700000001, + "spec/views/two_factor_authentication/otp_verification/show.html.erb_spec.rb": 0.309014525, + "spec/views/two_factor_authentication/personal_key_verification/show.html.erb_spec.rb": 0.14518335100000002, + "spec/views/two_factor_authentication/sms_opt_in/error.html.erb_spec.rb": 0.103829894, + "spec/views/two_factor_authentication/sms_opt_in/new.html.erb_spec.rb": 0.078400848, + "spec/views/two_factor_authentication/totp_verification/show.html.erb_spec.rb": 0.30985782100000003, + "spec/views/two_factor_authentication/webauthn_verification/show.html.erb_spec.rb": 0.103494117, + "spec/views/users/backup_code_setup/create.html.erb_spec.rb": 1.5299489640000001, + "spec/views/users/backup_code_setup/index.html.erb_spec.rb": 0.039656144, + "spec/views/users/backup_code_setup/reminder.html.erb_spec.rb": 0.041007073, + "spec/views/users/delete/show.html.erb_spec.rb": 0.183402587, + "spec/views/users/edit_phone/remove_phone.html.erb_spec.rb": 0.082034128, + "spec/views/users/emails/verify.html.erb_spec.rb": 0.077436051, + "spec/views/users/passwords/edit.html.erb_spec.rb": 0.043665011000000004, + "spec/views/users/phones/add.html.erb_spec.rb": 0.051736206, + "spec/views/users/piv_cac_authentication_setup/new.html.erb_spec.rb": 0.057931651, + "spec/views/users/please_call/show.html.erb_spec.rb": 0.014484036, + "spec/views/users/shared/_otp_delivery_preference_selection.html.erb_spec.rb": 0.060821631, + "spec/views/users/totp_setup/new.html.erb_spec.rb": 0.149845209, + "spec/views/users/two_factor_authentication_setup/index.html.erb_spec.rb": 0.310852565, + "spec/views/users/webauthn_setup/new.html.erb_spec.rb": 0.102320111, + "spec/views/vendor_outage/show.html.erb_spec.rb": 0.013359681000000002 } diff --git a/lib/identity_config.rb b/lib/identity_config.rb index fbd3fb1e8ed..79645c6d376 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -126,14 +126,6 @@ def self.build_store(config_map) config.add(:address_identity_proofing_supported_country_codes, type: :json) config.add(:all_redirect_uris_cache_duration_minutes, type: :integer) config.add(:allowed_ialmax_providers, type: :json) - config.add(:arcgis_api_find_address_candidates_url, type: :string) - config.add(:arcgis_api_generate_token_url, type: :string) - config.add(:arcgis_api_password, type: :string) - config.add(:arcgis_api_refresh_token_job_cron, type: :string) - config.add(:arcgis_api_refresh_token_job_enabled, type: :boolean) - config.add(:arcgis_api_request_timeout_seconds, type: :integer) - config.add(:arcgis_api_username, type: :string) - config.add(:arcgis_mock_fallback, type: :boolean) config.add(:asset_host, type: :string) config.add(:async_stale_job_timeout_seconds, type: :integer) config.add(:async_wait_timeout_seconds, type: :integer) @@ -147,6 +139,7 @@ def self.build_store(config_map) config.add(:aws_kms_key_id, type: :string) config.add(:aws_kms_multi_region_key_id, type: :string) config.add(:aws_kms_multi_region_read_enabled, type: :boolean) + config.add(:aws_kms_session_key_id, type: :string) config.add(:aws_logo_bucket, type: :string) config.add(:aws_region, type: :string) config.add(:backup_code_cost, type: :string) diff --git a/lib/reporting/authentication_report.rb b/lib/reporting/authentication_report.rb index 8924c0f9c5e..f13bfc14f0c 100644 --- a/lib/reporting/authentication_report.rb +++ b/lib/reporting/authentication_report.rb @@ -14,7 +14,7 @@ module Reporting class AuthenticationReport include Reporting::CloudwatchQueryQuoting - attr_reader :issuer, :time_range + attr_reader :issuers, :time_range module Events OIDC_AUTH_REQUEST = 'OpenID Connect: authorization request' @@ -28,17 +28,17 @@ def self.all_events end end - # @param [String] isssuer + # @param [Array] issuers # @param [Range