diff --git a/app/components/accordion_component.html.erb b/app/components/accordion_component.html.erb
index faa3d4a2a71..7a60da3f57c 100644
--- a/app/components/accordion_component.html.erb
+++ b/app/components/accordion_component.html.erb
@@ -9,9 +9,7 @@
<%= header %>
-
-
- <%= content %>
-
+
+ <%= content %>
<% end %>
diff --git a/app/controllers/concerns/idv/document_capture_concern.rb b/app/controllers/concerns/idv/document_capture_concern.rb
index 713fd03552b..4054e20a230 100644
--- a/app/controllers/concerns/idv/document_capture_concern.rb
+++ b/app/controllers/concerns/idv/document_capture_concern.rb
@@ -49,7 +49,7 @@ def stored_result
end
def selfie_requirement_met?
- !decorated_sp_session.selfie_required? || stored_result.selfie_check_performed?
+ !decorated_sp_session.biometric_comparison_required? || stored_result.selfie_check_performed?
end
private
diff --git a/app/controllers/concerns/idv_session_concern.rb b/app/controllers/concerns/idv_session_concern.rb
index 9857ee11ae5..d1ceafc3858 100644
--- a/app/controllers/concerns/idv_session_concern.rb
+++ b/app/controllers/concerns/idv_session_concern.rb
@@ -17,7 +17,7 @@ def hybrid_session?
end
def idv_needed?
- user_needs_selfie? ||
+ user_needs_biometric_comparison? ||
idv_session_user.active_profile.blank? ||
decorated_sp_session.requested_more_recent_verification? ||
idv_session_user.reproof_for_irs?(service_provider: current_sp)
@@ -66,7 +66,8 @@ def idv_session_user
current_user
end
- def user_needs_selfie?
- decorated_sp_session.selfie_required? && !current_user.identity_verified_with_selfie?
+ def user_needs_biometric_comparison?
+ decorated_sp_session.biometric_comparison_required? &&
+ !current_user.identity_verified_with_biometric_comparison?
end
end
diff --git a/app/controllers/concerns/idv_step_concern.rb b/app/controllers/concerns/idv_step_concern.rb
index 1344a5c8c3b..396dc73fa25 100644
--- a/app/controllers/concerns/idv_step_concern.rb
+++ b/app/controllers/concerns/idv_step_concern.rb
@@ -111,7 +111,7 @@ def flow_policy
def confirm_step_allowed
# set it everytime, since user may switch SP
- idv_session.selfie_check_required = decorated_sp_session.selfie_required?
+ idv_session.selfie_check_required = decorated_sp_session.biometric_comparison_required?
return if flow_policy.controller_allowed?(controller: self.class)
redirect_to url_for_latest_step
diff --git a/app/controllers/frontend_log_controller.rb b/app/controllers/frontend_log_controller.rb
index fd10cdcf9a6..11efab30328 100644
--- a/app/controllers/frontend_log_controller.rb
+++ b/app/controllers/frontend_log_controller.rb
@@ -35,7 +35,6 @@ class FrontendLogController < ApplicationController
'IdV: personal key acknowledgment toggled' => :idv_personal_key_acknowledgment_toggled,
'IdV: prepare submitted' => :idv_in_person_prepare_submitted,
'IdV: prepare visited' => :idv_in_person_prepare_visited,
- 'IdV: selfie image clicked' => :idv_selfie_image_clicked,
'IdV: switch_back submitted' => :idv_in_person_switch_back_submitted,
'IdV: switch_back visited' => :idv_in_person_switch_back_visited,
'IdV: user clicked sp link on ready to verify page' => :idv_in_person_ready_to_verify_sp_link_clicked,
@@ -55,6 +54,7 @@ class FrontendLogController < ApplicationController
idv_sdk_selfie_image_capture_failed
idv_sdk_selfie_image_capture_opened
idv_selfie_image_added
+ idv_selfie_image_clicked
phone_input_country_changed
].freeze
diff --git a/app/controllers/idv/address_controller.rb b/app/controllers/idv/address_controller.rb
index 0df0196b98f..589b0a78094 100644
--- a/app/controllers/idv/address_controller.rb
+++ b/app/controllers/idv/address_controller.rb
@@ -59,13 +59,6 @@ def address_from_document
def success
idv_session.address_edited = address_edited?
- idv_session.pii_from_doc = idv_session.pii_from_doc.merge(
- address1: @address_form.address1,
- address2: @address_form.address2,
- city: @address_form.city,
- state: @address_form.state,
- zipcode: @address_form.zipcode,
- )
idv_session.updated_user_address = @address_form.updated_user_address
redirect_to idv_verify_info_url
end
diff --git a/app/controllers/idv/document_capture_controller.rb b/app/controllers/idv/document_capture_controller.rb
index 3cca276476b..1801378902e 100644
--- a/app/controllers/idv/document_capture_controller.rb
+++ b/app/controllers/idv/document_capture_controller.rb
@@ -51,7 +51,7 @@ def extra_view_variables
skip_doc_auth: idv_session.skip_doc_auth,
skip_doc_auth_from_handoff: idv_session.skip_doc_auth_from_handoff,
opted_in_to_in_person_proofing: idv_session.opted_in_to_in_person_proofing,
- doc_auth_selfie_capture: decorated_sp_session.selfie_required?,
+ doc_auth_selfie_capture: decorated_sp_session.biometric_comparison_required?,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
@@ -97,7 +97,7 @@ def analytics_arguments
irs_reproofing: irs_reproofing?,
redo_document_capture: idv_session.redo_document_capture,
skip_hybrid_handoff: idv_session.skip_hybrid_handoff,
- liveness_checking_required: decorated_sp_session.selfie_required?,
+ liveness_checking_required: decorated_sp_session.biometric_comparison_required?,
selfie_check_required: idv_session.selfie_check_required,
}.merge(ab_test_analytics_buckets)
end
diff --git a/app/controllers/idv/hybrid_mobile/capture_complete_controller.rb b/app/controllers/idv/hybrid_mobile/capture_complete_controller.rb
index 6dd2cef744e..d40671dddb6 100644
--- a/app/controllers/idv/hybrid_mobile/capture_complete_controller.rb
+++ b/app/controllers/idv/hybrid_mobile/capture_complete_controller.rb
@@ -25,7 +25,7 @@ def analytics_arguments
step: 'capture_complete',
analytics_id: 'Doc Auth',
irs_reproofing: irs_reproofing?,
- liveness_checking_required: decorated_sp_session.selfie_required?,
+ liveness_checking_required: decorated_sp_session.biometric_comparison_required?,
}.merge(ab_test_analytics_buckets)
end
end
diff --git a/app/controllers/idv/hybrid_mobile/document_capture_controller.rb b/app/controllers/idv/hybrid_mobile/document_capture_controller.rb
index df483aa7e8a..ae138d92096 100644
--- a/app/controllers/idv/hybrid_mobile/document_capture_controller.rb
+++ b/app/controllers/idv/hybrid_mobile/document_capture_controller.rb
@@ -43,7 +43,7 @@ def extra_view_variables
flow_path: 'hybrid',
document_capture_session_uuid: document_capture_session_uuid,
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
- doc_auth_selfie_capture: decorated_sp_session.selfie_required?,
+ doc_auth_selfie_capture: decorated_sp_session.biometric_comparison_required?,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
@@ -57,8 +57,8 @@ def analytics_arguments
step: 'document_capture',
analytics_id: 'Doc Auth',
irs_reproofing: irs_reproofing?,
- liveness_checking_required: decorated_sp_session.selfie_required?,
- selfie_check_required: decorated_sp_session.selfie_required?,
+ liveness_checking_required: decorated_sp_session.biometric_comparison_required?,
+ selfie_check_required: decorated_sp_session.biometric_comparison_required?,
}.merge(
ab_test_analytics_buckets,
)
diff --git a/app/controllers/idv/image_uploads_controller.rb b/app/controllers/idv/image_uploads_controller.rb
index b5d45f192ba..e9a7105e6ad 100644
--- a/app/controllers/idv/image_uploads_controller.rb
+++ b/app/controllers/idv/image_uploads_controller.rb
@@ -25,7 +25,7 @@ def image_upload_form
uuid_prefix: current_sp&.app_id,
irs_attempts_api_tracker: irs_attempts_api_tracker,
store_encrypted_images: store_encrypted_images?,
- liveness_checking_required: decorated_sp_session.selfie_required?,
+ liveness_checking_required: decorated_sp_session.biometric_comparison_required?,
)
end
diff --git a/app/controllers/idv_controller.rb b/app/controllers/idv_controller.rb
index e2d41392326..1f0c366e581 100644
--- a/app/controllers/idv_controller.rb
+++ b/app/controllers/idv_controller.rb
@@ -32,8 +32,8 @@ def activated
private
def already_verified?
- if decorated_sp_session.selfie_required?
- return current_user.identity_verified_with_selfie?
+ if decorated_sp_session.biometric_comparison_required?
+ return current_user.identity_verified_with_biometric_comparison?
end
return current_user.active_profile.present?
diff --git a/app/controllers/openid_connect/authorization_controller.rb b/app/controllers/openid_connect/authorization_controller.rb
index 9c3b3483c15..a40e470c4fd 100644
--- a/app/controllers/openid_connect/authorization_controller.rb
+++ b/app/controllers/openid_connect/authorization_controller.rb
@@ -30,7 +30,7 @@ def index
return redirect_to reactivate_account_url if user_needs_to_reactivate_account?
return redirect_to url_for_pending_profile_reason if user_has_pending_profile?
return redirect_to idv_url if identity_needs_verification?
- return redirect_to idv_url if selfie_needed?
+ return redirect_to idv_url if biometric_comparison_needed?
end
return redirect_to sign_up_completed_url if needs_completion_screen_reason
link_identity_to_service_provider
@@ -127,9 +127,9 @@ def identity_needs_verification?
current_user.reproof_for_irs?(service_provider: current_sp)
end
- def selfie_needed?
- decorated_sp_session.selfie_required? &&
- !current_user.identity_verified_with_selfie?
+ def biometric_comparison_needed?
+ decorated_sp_session.biometric_comparison_required? &&
+ !current_user.identity_verified_with_biometric_comparison?
end
def build_authorize_form_from_params
diff --git a/app/controllers/saml_idp_controller.rb b/app/controllers/saml_idp_controller.rb
index 83fe68307bd..d7f37c7c2fa 100644
--- a/app/controllers/saml_idp_controller.rb
+++ b/app/controllers/saml_idp_controller.rb
@@ -36,7 +36,7 @@ def auth
return redirect_to reactivate_account_url if user_needs_to_reactivate_account?
return redirect_to url_for_pending_profile_reason if user_has_pending_profile?
return redirect_to idv_url if identity_needs_verification?
- return redirect_to idv_url if selfie_needed?
+ return redirect_to idv_url if biometric_comparison_needed?
end
return redirect_to sign_up_completed_url if needs_completion_screen_reason
if auth_count == 1 && first_visit_for_sp?
@@ -112,9 +112,9 @@ def prompt_for_password_if_ial2_request_and_pii_locked
redirect_to capture_password_url
end
- def selfie_needed?
- decorated_sp_session.selfie_required? &&
- !current_user.identity_verified_with_selfie?
+ def biometric_comparison_needed?
+ decorated_sp_session.biometric_comparison_required? &&
+ !current_user.identity_verified_with_biometric_comparison?
end
def set_devise_failure_redirect_for_concurrent_session_logout
diff --git a/app/controllers/sign_up/completions_controller.rb b/app/controllers/sign_up/completions_controller.rb
index 19b4c451bb2..ae83a189aaf 100644
--- a/app/controllers/sign_up/completions_controller.rb
+++ b/app/controllers/sign_up/completions_controller.rb
@@ -6,7 +6,6 @@ class CompletionsController < ApplicationController
before_action :confirm_two_factor_authenticated
before_action :confirm_identity_verified, if: :identity_proofing_required?
- before_action :confirm_selfie_captured, if: :selfie_required?
before_action :apply_secure_headers_override, only: [:show, :update]
before_action :verify_needs_completions_screen
@@ -38,10 +37,6 @@ def confirm_identity_verified
redirect_to idv_url if current_user.identity_not_verified?
end
- def confirm_selfie_captured
- redirect_to idv_url if !current_user.identity_verified_with_selfie?
- end
-
def verify_needs_completions_screen
return_to_account unless needs_completion_screen_reason
end
@@ -65,10 +60,6 @@ def ial2_requested?
resolved_authn_context_result.identity_proofing_or_ialmax? && current_user.identity_verified?
end
- def selfie_required?
- decorated_sp_session.selfie_required?
- end
-
def return_to_account
track_completion_event('account-page')
redirect_to account_url
diff --git a/app/decorators/null_service_provider_session.rb b/app/decorators/null_service_provider_session.rb
index a7024670293..f1c649e76ab 100644
--- a/app/decorators/null_service_provider_session.rb
+++ b/app/decorators/null_service_provider_session.rb
@@ -47,7 +47,7 @@ def request_url_params
{}
end
- def selfie_required?
+ def biometric_comparison_required?
false
end
diff --git a/app/decorators/service_provider_session.rb b/app/decorators/service_provider_session.rb
index 2cd97bb39be..d2e2c41a1ce 100644
--- a/app/decorators/service_provider_session.rb
+++ b/app/decorators/service_provider_session.rb
@@ -72,7 +72,7 @@ def sp_issuer
sp.issuer
end
- def selfie_required?
+ def biometric_comparison_required?
!!(FeatureManagement.idv_allow_selfie_check? &&
sp_session[:biometric_comparison_required])
end
diff --git a/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.spec.ts b/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.spec.ts
index 01e4231ed77..ca980626684 100644
--- a/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.spec.ts
+++ b/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.spec.ts
@@ -136,6 +136,27 @@ describe('CaptchaSubmitButtonElement', () => {
});
});
});
+
+ context('when recaptcha fails to load', () => {
+ beforeEach(() => {
+ delete (global as any).grecaptcha;
+ });
+
+ it('does not prevent default form submission', async () => {
+ const button = screen.getByRole('button', { name: 'Submit' });
+ const form = document.querySelector('form')!;
+
+ let didSubmit = false;
+ form.addEventListener('submit', (event) => {
+ expect(event.defaultPrevented).to.equal(false);
+ event.preventDefault();
+ didSubmit = true;
+ });
+
+ await userEvent.click(button);
+ await waitFor(() => expect(didSubmit).to.be.true());
+ });
+ });
});
});
});
diff --git a/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.ts b/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.ts
index c1dce46dab3..3ec45cbb5b0 100644
--- a/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.ts
+++ b/app/javascript/packages/captcha-submit-button/captcha-submit-button-element.ts
@@ -31,12 +31,12 @@ class CaptchaSubmitButtonElement extends HTMLElement {
return this.getAttribute('recaptcha-enterprise') === 'true';
}
- get recaptchaClient(): ReCaptchaV2.ReCaptcha {
+ get recaptchaClient(): ReCaptchaV2.ReCaptcha | undefined {
if (this.isRecaptchaEnterprise) {
- return grecaptcha.enterprise;
+ return globalThis.grecaptcha?.enterprise;
}
- return grecaptcha;
+ return globalThis.grecaptcha;
}
submit() {
@@ -44,16 +44,16 @@ class CaptchaSubmitButtonElement extends HTMLElement {
}
invokeChallenge() {
- this.recaptchaClient.ready(async () => {
+ this.recaptchaClient!.ready(async () => {
const { recaptchaSiteKey: siteKey, recaptchaAction: action } = this;
- const token = await this.recaptchaClient.execute(siteKey!, { action });
+ const token = await this.recaptchaClient!.execute(siteKey!, { action });
this.tokenInput.value = token;
this.submit();
});
}
shouldInvokeChallenge(): boolean {
- return !!this.recaptchaSiteKey;
+ return !!(this.recaptchaSiteKey && this.recaptchaClient);
}
handleFormSubmit = (event: SubmitEvent) => {
diff --git a/app/javascript/packages/document-capture/components/acuant-capture.tsx b/app/javascript/packages/document-capture/components/acuant-capture.tsx
index 0b71c29398c..5b1b2e12e7d 100644
--- a/app/javascript/packages/document-capture/components/acuant-capture.tsx
+++ b/app/javascript/packages/document-capture/components/acuant-capture.tsx
@@ -437,11 +437,15 @@ function AcuantCapture(
return
any>(fn: T) =>
(...args: Parameters) => {
if (!isSuppressingClickLogging.current) {
- trackEvent(`IdV: ${name} image clicked`, {
- source,
- ...metadata,
- liveness_checking_required: isSelfieCaptureEnabled,
- });
+ trackEvent(
+ name === 'selfie' ? 'idv_selfie_image_clicked' : `IdV: ${name} image clicked`,
+ {
+ source,
+ ...metadata,
+ liveness_checking_required: isSelfieCaptureEnabled,
+ captureAttempts,
+ },
+ );
}
return fn(...args);
diff --git a/app/models/user.rb b/app/models/user.rb
index 75ef943078b..8411ef8a682 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,9 +1,6 @@
# frozen_string_literal: true
class User < ApplicationRecord
- # To be dropped in: https://github.com/18F/identity-idp/pull/10429
- self.ignored_columns = [:remember_created_at]
-
include NonNullUuid
include ::NewRelic::Agent::MethodTracer
@@ -373,7 +370,7 @@ def identity_verified?(service_provider: nil)
active_profile.present? && !reproof_for_irs?(service_provider: service_provider)
end
- def identity_verified_with_selfie?
+ def identity_verified_with_biometric_comparison?
BIOMETRIC_COMPARISON_IDV_LEVELS.include?(active_profile&.idv_level)
end
diff --git a/app/presenters/idv/welcome_presenter.rb b/app/presenters/idv/welcome_presenter.rb
index c9a3c2c57b2..fbb2a65cbd9 100644
--- a/app/presenters/idv/welcome_presenter.rb
+++ b/app/presenters/idv/welcome_presenter.rb
@@ -22,6 +22,10 @@ def title
t('doc_auth.headings.welcome', sp_name: sp_name)
end
+ def selfie_required?
+ decorated_sp_session.biometric_comparison_required?
+ end
+
def explanation_text(help_link)
if first_time_idv?
t(
diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb
index 8e98b531e89..f7b56a7af0e 100644
--- a/app/services/analytics_events.rb
+++ b/app/services/analytics_events.rb
@@ -763,6 +763,7 @@ def idv_back_image_added(
# @param [Boolean] isDrop
# @param [Boolean] source
# @param [Boolean] use_alternate_sdk
+ # @param [Number] captureAttempts count of image capturing attempts
# @param [String] liveness_checking_required Whether or not the selfie is required
def idv_back_image_clicked(
acuant_sdk_upgrade_a_b_testing_enabled:,
@@ -771,6 +772,7 @@ def idv_back_image_clicked(
isDrop:,
source:,
use_alternate_sdk:,
+ captureAttempts:,
liveness_checking_required:,
**extra
)
@@ -783,6 +785,7 @@ def idv_back_image_clicked(
source: source,
use_alternate_sdk: use_alternate_sdk,
liveness_checking_required: liveness_checking_required,
+ captureAttempts: captureAttempts,
**extra,
)
end
@@ -1529,6 +1532,7 @@ def idv_front_image_added(
# @param [Boolean] isDrop
# @param [String] source
# @param [String] use_alternate_sdk
+ # @param [Number] captureAttempts count of image capturing attempts
# @param [Boolean] liveness_checking_required
def idv_front_image_clicked(
acuant_sdk_upgrade_a_b_testing_enabled:,
@@ -1537,6 +1541,7 @@ def idv_front_image_clicked(
isDrop:,
source:,
use_alternate_sdk:,
+ captureAttempts:,
liveness_checking_required: nil,
**extra
)
@@ -1549,6 +1554,7 @@ def idv_front_image_clicked(
source: source,
use_alternate_sdk: use_alternate_sdk,
liveness_checking_required: liveness_checking_required,
+ captureAttempts: captureAttempts,
**extra,
)
end
@@ -3321,6 +3327,7 @@ def idv_selfie_image_added(
# @param [Boolean] isDrop
# @param [String] source
# @param [String] use_alternate_sdk
+ # @param [Number] captureAttempts
# @param [Boolean] liveness_checking_required
# @param [Hash,nil] proofing_components User's proofing components.
# @param [String,nil] active_profile_idv_level ID verification level of user's active profile.
@@ -3332,6 +3339,7 @@ def idv_selfie_image_clicked(
isDrop:,
source:,
use_alternate_sdk:,
+ captureAttempts:,
liveness_checking_required: nil,
proofing_components: nil,
active_profile_idv_level: nil,
@@ -3346,6 +3354,7 @@ def idv_selfie_image_clicked(
isDrop: isDrop,
source: source,
use_alternate_sdk: use_alternate_sdk,
+ captureAttempts: captureAttempts,
liveness_checking_required: liveness_checking_required,
proofing_components: proofing_components,
active_profile_idv_level: active_profile_idv_level,
diff --git a/app/services/doc_auth/selfie_concern.rb b/app/services/doc_auth/selfie_concern.rb
index 0c518e0118c..7db7f82f29a 100644
--- a/app/services/doc_auth/selfie_concern.rb
+++ b/app/services/doc_auth/selfie_concern.rb
@@ -4,15 +4,15 @@ module DocAuth
module SelfieConcern
extend ActiveSupport::Concern
def selfie_live?
- portait_error = get_portrait_error(portrait_match_results)
- return true if portait_error.nil? || portait_error.blank?
- return !error_is_not_live(portait_error)
+ portrait_error = get_portrait_error(portrait_match_results)
+ return true if portrait_error.nil? || portrait_error.blank?
+ !error_is_not_live(portrait_error)
end
def selfie_quality_good?
- portait_error = get_portrait_error(portrait_match_results)
- return true if portait_error.nil? || portait_error.blank?
- return !error_is_poor_quality(portait_error)
+ portrait_error = get_portrait_error(portrait_match_results)
+ return true if portrait_error.nil? || portrait_error.blank?
+ !error_is_poor_quality(portrait_error)
end
def error_is_success(error_message)
@@ -20,7 +20,7 @@ def error_is_success(error_message)
end
def error_is_not_live(error_message)
- return error_message == ERROR_TEXTS[:not_live]
+ error_message == ERROR_TEXTS[:not_live]
end
def error_is_poor_quality(error_message)
@@ -41,7 +41,7 @@ def selfie_check_performed?
poor_quality: 'Liveness: PoorQuality',
}.freeze
- # @param [Object] portrait_match_results trueid portait match info
+ # @param [Object] portrait_match_results trueid portrait match info
def get_portrait_error(portrait_match_results)
portrait_match_results&.with_indifferent_access&.dig(:FaceErrorMessage)
end
diff --git a/app/services/idv/steps/doc_auth_base_step.rb b/app/services/idv/steps/doc_auth_base_step.rb
index a59b560c99c..3f8ee103544 100644
--- a/app/services/idv/steps/doc_auth_base_step.rb
+++ b/app/services/idv/steps/doc_auth_base_step.rb
@@ -58,17 +58,6 @@ def user_id
current_user ? current_user.id : user_id_from_token
end
- def add_cost(token, transaction_id: nil)
- Db::SpCost::AddSpCost.call(current_sp, 2, token, transaction_id: transaction_id)
- end
-
- def add_costs(result)
- Db::AddDocumentVerificationAndSelfieCosts.
- new(user_id: user_id,
- service_provider: current_sp).
- call(result)
- end
-
def sp_session
session.fetch(:sp, {})
end
diff --git a/config/locales/user_mailer/es.yml b/config/locales/user_mailer/es.yml
index a44ed1340c0..bdd8cc52499 100644
--- a/config/locales/user_mailer/es.yml
+++ b/config/locales/user_mailer/es.yml
@@ -167,12 +167,12 @@ es:
retrasado
in_person_please_call:
body:
- contact_message_html: Llame al %{contact_number} y facilíteles
+ contact_message_html: Llame al %{contact_number} y proporcione
el código de error %{support_code}.
- intro_html: Llame a nuestro centro de atención antes del
+ intro_html: Llame a nuestro centro de contacto antes del
%{date} para seguir verificando su identidad.
header: Llámenos
- subject: Llame a %{app_name} para proseguir con la verificación de su identidad
+ subject: Llame a %{app_name} para continuar con la verificación de identidad
in_person_ready_to_verify:
subject: Está listo para verificar su identidad con %{app_name} en persona
in_person_ready_to_verify_reminder:
diff --git a/config/locales/user_mailer/fr.yml b/config/locales/user_mailer/fr.yml
index 308db563801..d672155b857 100644
--- a/config/locales/user_mailer/fr.yml
+++ b/config/locales/user_mailer/fr.yml
@@ -173,7 +173,7 @@ fr:
intro_html: Appelez notre centre de contact avant le %{date}
pour continuer à vérifier votre identité.
header: S’il vous plaît, appelez-nous
- subject: Appelez %{app_name} pour poursuivre la vérification de votre identité
+ subject: Appeler %{app_name} afin de poursuivre la vérification de votre identité
in_person_ready_to_verify:
subject: Vous êtes prêt à vérifier votre identité avec %{app_name} en personne
in_person_ready_to_verify_reminder:
diff --git a/db/primary_migrate/20240415125124_drop_remember_created_at_from_users.rb b/db/primary_migrate/20240415125124_drop_remember_created_at_from_users.rb
new file mode 100644
index 00000000000..18ba3e912ef
--- /dev/null
+++ b/db/primary_migrate/20240415125124_drop_remember_created_at_from_users.rb
@@ -0,0 +1,7 @@
+class DropRememberCreatedAtFromUsers < ActiveRecord::Migration[7.1]
+ def change
+ safety_assured do
+ remove_column :users, :remember_created_at, :datetime
+ end
+ end
+end
diff --git a/db/primary_migrate/20240416165602_add_password_compromised_checked_at_to_users.rb b/db/primary_migrate/20240416165602_add_password_compromised_checked_at_to_users.rb
new file mode 100644
index 00000000000..0397c23147e
--- /dev/null
+++ b/db/primary_migrate/20240416165602_add_password_compromised_checked_at_to_users.rb
@@ -0,0 +1,5 @@
+class AddPasswordCompromisedCheckedAtToUsers < ActiveRecord::Migration[7.1]
+ def change
+ add_column :users, :password_compromised_checked_at, :datetime, default: nil
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ca81df3b182..68cb83a886b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.1].define(version: 2024_04_11_163520) do
+ActiveRecord::Schema[7.1].define(version: 2024_04_16_165602) do
# These are extensions that must be enabled in order to support this database
enable_extension "citext"
enable_extension "pg_stat_statements"
@@ -588,7 +588,6 @@
create_table "users", id: :serial, force: :cascade do |t|
t.string "reset_password_token", limit: 255
t.datetime "reset_password_sent_at", precision: nil
- t.datetime "remember_created_at", precision: nil
t.datetime "created_at", precision: nil
t.datetime "updated_at", precision: nil
t.datetime "confirmed_at", precision: nil
@@ -613,6 +612,7 @@
t.datetime "second_mfa_reminder_dismissed_at"
t.datetime "piv_cac_recommended_dismissed_at"
t.datetime "sign_in_new_device_at"
+ t.datetime "password_compromised_checked_at"
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
t.index ["sign_in_new_device_at"], name: "index_users_on_sign_in_new_device_at"
t.index ["uuid"], name: "index_users_on_uuid", unique: true
diff --git a/spec/components/accordion_component_spec.rb b/spec/components/accordion_component_spec.rb
index df1bec0e45e..9c9d515817f 100644
--- a/spec/components/accordion_component_spec.rb
+++ b/spec/components/accordion_component_spec.rb
@@ -21,8 +21,8 @@
it 'assigns a unique id' do
second_rendered = render_inline(described_class.new)
- rendered_id = rendered.css('.usa-accordion__container').first['id']
- second_rendered_id = second_rendered.css('.usa-accordion__container').first['id']
+ rendered_id = rendered.css('.usa-accordion__content').first['id']
+ second_rendered_id = second_rendered.css('.usa-accordion__content').first['id']
expect(rendered_id).to be_present
expect(second_rendered_id).to be_present
diff --git a/spec/controllers/concerns/idv/document_capture_concern_spec.rb b/spec/controllers/concerns/idv/document_capture_concern_spec.rb
index c77665906c4..5b2375acfc8 100644
--- a/spec/controllers/concerns/idv/document_capture_concern_spec.rb
+++ b/spec/controllers/concerns/idv/document_capture_concern_spec.rb
@@ -20,7 +20,8 @@ def show
context 'selfie checks enabled' do
before do
decorated_sp_session = instance_double(ServiceProviderSession)
- allow(decorated_sp_session).to receive(:selfie_required?).and_return(selfie_required)
+ allow(decorated_sp_session).to receive(:biometric_comparison_required?).
+ and_return(biometric_comparison_required)
allow(controller).to receive(:decorated_sp_session).and_return(decorated_sp_session)
stored_result = instance_double(DocumentCaptureSessionResult)
allow(stored_result).to receive(:selfie_check_performed?).and_return(selfie_check_performed)
@@ -28,7 +29,7 @@ def show
end
context 'SP requires biometric_comparison' do
- let(:selfie_required) { true }
+ let(:biometric_comparison_required) { true }
context 'selfie check performed' do
let(:selfie_check_performed) { true }
@@ -46,7 +47,7 @@ def show
end
context 'SP does not require biometric_comparison' do
- let(:selfie_required) { false }
+ let(:biometric_comparison_required) { false }
context 'selfie check performed' do
let(:selfie_check_performed) { true }
diff --git a/spec/controllers/idv/address_controller_spec.rb b/spec/controllers/idv/address_controller_spec.rb
index 2e908237adc..fcfe4edb492 100644
--- a/spec/controllers/idv/address_controller_spec.rb
+++ b/spec/controllers/idv/address_controller_spec.rb
@@ -63,24 +63,6 @@
end.to change { subject.idv_session.address_edited }.from(nil).to eql(true)
end
- it 'updates pii_from_doc in idv_session' do
- expect do
- put :update, params: params
- end.to change { subject.idv_session.pii_from_doc }
-
- expect(subject.idv_session.pii_from_doc).to eql(
- pii_from_doc.merge(
- {
- 'address1' => '1234 Main St',
- 'address2' => 'Apt B',
- 'city' => 'Beverly Hills',
- 'state' => 'CA',
- 'zipcode' => '90210',
- },
- ),
- )
- end
-
it 'adds updated_user_data to idv_session' do
expect do
put :update, params: params
@@ -127,7 +109,7 @@
end
end
- xit 'has the correct `address_edited` value when submitted twice with the same data' do
+ it 'has the correct `address_edited` value when submitted twice with the same data' do
put :update, params: params
expect(subject.idv_session.address_edited).to eq(true)
put :update, params: params
diff --git a/spec/controllers/idv/document_capture_controller_spec.rb b/spec/controllers/idv/document_capture_controller_spec.rb
index 6ef47db3842..57e58874208 100644
--- a/spec/controllers/idv/document_capture_controller_spec.rb
+++ b/spec/controllers/idv/document_capture_controller_spec.rb
@@ -30,7 +30,7 @@
stub_up_to(:hybrid_handoff, idv_session: subject.idv_session)
stub_analytics
subject.idv_session.document_capture_session_uuid = document_capture_session_uuid
- allow(controller.decorated_sp_session).to receive(:selfie_required?).
+ allow(controller.decorated_sp_session).to receive(:biometric_comparison_required?).
and_return(doc_auth_selfie_capture_enabled && sp_selfie_enabled)
subject.idv_session.flow_path = flow_path
allow(subject).to receive(:ab_test_analytics_buckets).and_return(ab_test_args)
@@ -265,7 +265,8 @@
before do
allow(IdentityConfig.store).to receive(:doc_auth_selfie_desktop_test_mode).and_return(false)
allow(Idv::InPersonConfig).to receive(:enabled_for_issuer?).with(anything).and_return(false)
- allow(subject.decorated_sp_session).to receive(:selfie_required?).and_return(true)
+ allow(subject.decorated_sp_session).to receive(:biometric_comparison_required?).
+ and_return(true)
end
it 'redirect back when accessed from handoff' do
subject.idv_session.skip_hybrid_handoff = nil
diff --git a/spec/controllers/idv/hybrid_handoff_controller_spec.rb b/spec/controllers/idv/hybrid_handoff_controller_spec.rb
index 41a2c3549a7..35c86c9fa4c 100644
--- a/spec/controllers/idv/hybrid_handoff_controller_spec.rb
+++ b/spec/controllers/idv/hybrid_handoff_controller_spec.rb
@@ -25,7 +25,7 @@
stub_attempts_tracker
allow(subject).to receive(:ab_test_analytics_buckets).and_return(ab_test_args)
allow(subject.idv_session).to receive(:service_provider).and_return(service_provider)
- allow(subject.decorated_sp_session).to receive(:selfie_required?).
+ allow(subject.decorated_sp_session).to receive(:biometric_comparison_required?).
and_return(sp_selfie_enabled && doc_auth_selfie_capture_enabled)
allow(IdentityConfig.store).to receive(:in_person_proofing_enabled) { in_person_proofing }
allow(IdentityConfig.store).to receive(:in_person_proofing_opt_in_enabled) {
diff --git a/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb b/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb
index de0d01b980d..4a260d4ff14 100644
--- a/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb
+++ b/spec/controllers/idv/hybrid_mobile/document_capture_controller_spec.rb
@@ -79,7 +79,12 @@
context 'when a selfie is requested' do
before do
allow(subject).to receive(:decorated_sp_session).
- and_return(double('decorated_session', { selfie_required?: true, sp_name: 'sp' }))
+ and_return(
+ double(
+ 'decorated_session',
+ { biometric_comparison_required?: true, sp_name: 'sp' },
+ ),
+ )
end
context 'when selfie is required by sp session' do
it 'requests FE to display selfie' do
diff --git a/spec/controllers/idv/image_uploads_controller_spec.rb b/spec/controllers/idv/image_uploads_controller_spec.rb
index 91e3ed90794..7e48898ad57 100644
--- a/spec/controllers/idv/image_uploads_controller_spec.rb
+++ b/spec/controllers/idv/image_uploads_controller_spec.rb
@@ -334,7 +334,8 @@
let(:selfie_img) { DocAuthImageFixtures.selfie_image_multipart }
before do
- allow(controller.decorated_sp_session).to receive(:selfie_required?).and_return(true)
+ allow(controller.decorated_sp_session).to receive(:biometric_comparison_required?).
+ and_return(true)
end
it 'returns a successful response and modifies the session' do
@@ -1225,7 +1226,7 @@
context 'the frontend requests a selfie' do
before do
allow(controller).to receive(:decorated_sp_session).
- and_return(double('decorated_session', { selfie_required?: true }))
+ and_return(double('decorated_session', { biometric_comparison_required?: true }))
end
let(:back_image) { DocAuthImageFixtures.portrait_match_success_yaml }
diff --git a/spec/controllers/sign_up/completions_controller_spec.rb b/spec/controllers/sign_up/completions_controller_spec.rb
index 17d953e9c5b..6f0b9990838 100644
--- a/spec/controllers/sign_up/completions_controller_spec.rb
+++ b/spec/controllers/sign_up/completions_controller_spec.rb
@@ -103,33 +103,6 @@
expect(response).to redirect_to(idv_url)
end
end
-
- context 'sp requires selfie' do
- let(:selfie_capture_enabled) { true }
- before do
- expect(FeatureManagement).to receive(:idv_allow_selfie_check?).
- and_return(selfie_capture_enabled)
- subject.session[:sp][:biometric_comparison_required] = 'true'
- end
-
- context 'user does not have a selfie' do
- it 'redirects to idv_url' do
- get :show
-
- expect(response).to redirect_to(idv_url)
- end
- end
-
- context 'selfie capture not enabled' do
- let(:selfie_capture_enabled) { false }
-
- it 'does not redirect' do
- get :show
-
- expect(response).to render_template :show
- end
- end
- end
end
context 'IALMax' do
diff --git a/spec/decorators/service_provider_session_spec.rb b/spec/decorators/service_provider_session_spec.rb
index 49de2b5c8dc..489c90fb87c 100644
--- a/spec/decorators/service_provider_session_spec.rb
+++ b/spec/decorators/service_provider_session_spec.rb
@@ -190,22 +190,22 @@
it 'returns true when sp biometric_comparison_required is true' do
sp_session[:biometric_comparison_required] = true
- expect(subject.selfie_required?).to eq(true)
+ expect(subject.biometric_comparison_required?).to eq(true)
end
it 'returns true when sp biometric_comparison_required is truthy' do
sp_session[:biometric_comparison_required] = 1
- expect(subject.selfie_required?).to eq(true)
+ expect(subject.biometric_comparison_required?).to eq(true)
end
it 'returns false when sp biometric_comparison_required is false' do
sp_session[:biometric_comparison_required] = false
- expect(subject.selfie_required?).to eq(false)
+ expect(subject.biometric_comparison_required?).to eq(false)
end
it 'returns false when sp biometric_comparison_required is nil' do
sp_session[:biometric_comparison_required] = nil
- expect(subject.selfie_required?).to eq(false)
+ expect(subject.biometric_comparison_required?).to eq(false)
end
end
@@ -214,7 +214,7 @@
it 'returns false' do
sp_session[:biometric_comparison_required] = true
- expect(subject.selfie_required?).to eq(false)
+ expect(subject.biometric_comparison_required?).to eq(false)
end
end
end
diff --git a/spec/features/idv/doc_auth/redo_document_capture_spec.rb b/spec/features/idv/doc_auth/redo_document_capture_spec.rb
index 1d9444bf60d..dd765980c00 100644
--- a/spec/features/idv/doc_auth/redo_document_capture_spec.rb
+++ b/spec/features/idv/doc_auth/redo_document_capture_spec.rb
@@ -265,7 +265,7 @@
end
end
- context 'when doc auth is success and portait match fails', allow_browser_log: true do
+ context 'when doc auth is success and portrait match fails', allow_browser_log: true do
before do
expect(FeatureManagement).to receive(:idv_allow_selfie_check?).at_least(:once).
and_return(true)
diff --git a/spec/fixtures/ial2_test_credential_classification_info_no_name.yml b/spec/fixtures/ial2_test_credential_classification_info_no_name.yml
index 1452f12ee24..f3bbd617ef9 100644
--- a/spec/fixtures/ial2_test_credential_classification_info_no_name.yml
+++ b/spec/fixtures/ial2_test_credential_classification_info_no_name.yml
@@ -8,7 +8,7 @@ document:
phone: +1 314-555-1212
state_id_jurisdiction: 'ND'
doc_auth_result: Passed
-failed_alert: []
+failed_alerts: []
classification_info:
Front:
ClassName: Drivers License
diff --git a/spec/fixtures/ial2_test_portrait_match_success.yml b/spec/fixtures/ial2_test_portrait_match_success.yml
index 6641f442865..decfc65999d 100644
--- a/spec/fixtures/ial2_test_portrait_match_success.yml
+++ b/spec/fixtures/ial2_test_portrait_match_success.yml
@@ -12,6 +12,6 @@ document:
state_id_type: 'drivers_license'
zipcode: '59010'
doc_auth_result: Passed
-failed_alert: []
+failed_alerts: []
portrait_match_results:
FaceMatchResult: Pass
diff --git a/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx b/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx
index da4a369ab84..931b49bf775 100644
--- a/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx
+++ b/spec/javascript/packages/document-capture/components/acuant-capture-spec.jsx
@@ -1176,7 +1176,7 @@ describe('document-capture/components/acuant-capture', () => {
}),
});
- expect(trackEvent).to.be.calledWith('IdV: selfie image clicked');
+ expect(trackEvent).to.be.calledWith('idv_selfie_image_clicked');
expect(trackEvent).to.be.calledWith('IdV: Acuant SDK loaded');
expect(trackEvent).to.have.been.calledWith('idv_sdk_selfie_image_capture_opened');
@@ -1193,7 +1193,7 @@ describe('document-capture/components/acuant-capture', () => {
}),
});
- expect(trackEvent).to.be.calledWith('IdV: selfie image clicked');
+ expect(trackEvent).to.be.calledWith('idv_selfie_image_clicked');
expect(trackEvent).to.be.calledWith('IdV: Acuant SDK loaded');
expect(trackEvent).to.have.been.calledWith(
@@ -1212,7 +1212,7 @@ describe('document-capture/components/acuant-capture', () => {
}),
});
- expect(trackEvent).to.be.calledWith('IdV: selfie image clicked');
+ expect(trackEvent).to.be.calledWith('idv_selfie_image_clicked');
expect(trackEvent).to.be.calledWith('IdV: Acuant SDK loaded');
expect(trackEvent).to.have.been.calledWith(
@@ -1236,7 +1236,7 @@ describe('document-capture/components/acuant-capture', () => {
}),
});
- expect(trackEvent).to.be.calledWith('IdV: selfie image clicked');
+ expect(trackEvent).to.be.calledWith('idv_selfie_image_clicked');
expect(trackEvent).to.be.calledWith('IdV: Acuant SDK loaded');
expect(trackEvent).to.have.been.calledWith(
@@ -1402,16 +1402,19 @@ describe('document-capture/components/acuant-capture', () => {
source: 'placeholder',
isDrop: false,
liveness_checking_required: false,
+ captureAttempts: 1,
});
expect(trackEvent).to.have.been.calledWith('IdV: test image clicked', {
source: 'button',
isDrop: false,
liveness_checking_required: false,
+ captureAttempts: 1,
});
expect(trackEvent).to.have.been.calledWith('IdV: test image clicked', {
source: 'upload',
isDrop: false,
liveness_checking_required: false,
+ captureAttempts: 1,
});
});
@@ -1432,6 +1435,7 @@ describe('document-capture/components/acuant-capture', () => {
source: 'placeholder',
isDrop: true,
liveness_checking_required: false,
+ captureAttempts: 1,
});
});
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 38abe57012f..48515dbeb8f 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1415,7 +1415,7 @@ def it_should_not_send_survey
end
end
- describe '#identity_verified_with_selfie?' do
+ describe '#identity_verified_with_biometric_comparison?' do
let(:user) { create(:user) }
let(:active_profile) do
create(
@@ -1428,23 +1428,23 @@ def it_should_not_send_survey
it 'returns true if user has an active profile with selfie' do
active_profile.idv_level = :unsupervised_with_selfie
active_profile.save
- expect(user.identity_verified_with_selfie?).to eq true
+ expect(user.identity_verified_with_biometric_comparison?).to eq true
end
it 'returns false if user has an active profile without selfie' do
- expect(user.identity_verified_with_selfie?).to eq false
+ expect(user.identity_verified_with_biometric_comparison?).to eq false
end
it 'return true if user has an active in-person profile' do
active_profile.idv_level = :in_person
active_profile.save
- expect(user.identity_verified_with_selfie?).to eq true
+ expect(user.identity_verified_with_biometric_comparison?).to eq true
end
context 'user does not have active profile' do
let(:active_profile) { nil }
it 'returns false' do
- expect(user.identity_verified_with_selfie?).to eq false
+ expect(user.identity_verified_with_biometric_comparison?).to eq false
end
end
end
diff --git a/spec/services/doc_auth/selfie_concern_spec.rb b/spec/services/doc_auth/selfie_concern_spec.rb
index 8516c2e9587..36900af849e 100644
--- a/spec/services/doc_auth/selfie_concern_spec.rb
+++ b/spec/services/doc_auth/selfie_concern_spec.rb
@@ -2,7 +2,7 @@
RSpec.describe DocAuth::SelfieConcern do
let(:face_error_message) { '' }
- let(:portait_info) do
+ let(:portrait_info) do
{
FaceErrorMessage: face_error_message,
}
@@ -15,7 +15,7 @@
def initialize(portrait_match_results)
@portrait_match_results = portrait_match_results
end
- end.new(portait_info)
+ end.new(portrait_info)
end
describe '#selfie_live?' do