diff --git a/app/controllers/api/verify/document_capture_controller.rb b/app/controllers/api/verify/document_capture_controller.rb index 7804b299829..cd3b5ad66ac 100644 --- a/app/controllers/api/verify/document_capture_controller.rb +++ b/app/controllers/api/verify/document_capture_controller.rb @@ -7,7 +7,7 @@ class DocumentCaptureController < BaseController def create result = Idv::ApiDocumentVerificationForm.new( verify_params, - liveness_checking_enabled: liveness_checking_enabled?, + liveness_checking_enabled: false, analytics: analytics, irs_attempts_api_tracker: irs_attempts_api_tracker, flow_path: params[:flow_path], @@ -37,7 +37,7 @@ def enqueue_job } Idv::Agent.new(applicant).proof_document( verify_document_capture_session, - liveness_checking_enabled: liveness_checking_enabled?, + liveness_checking_enabled: false, trace_id: amzn_trace_id, image_metadata: image_metadata, analytics_data: { diff --git a/app/controllers/idv/image_uploads_controller.rb b/app/controllers/idv/image_uploads_controller.rb index 81e5b4cbd3f..5f1a9303c3b 100644 --- a/app/controllers/idv/image_uploads_controller.rb +++ b/app/controllers/idv/image_uploads_controller.rb @@ -20,7 +20,7 @@ def create def image_upload_form @image_upload_form ||= Idv::ApiImageUploadForm.new( params, - liveness_checking_enabled: liveness_checking_enabled?, + liveness_checking_enabled: false, service_provider: current_sp, analytics: analytics, uuid_prefix: current_sp&.app_id, diff --git a/app/views/idv/shared/_document_capture.html.erb b/app/views/idv/shared/_document_capture.html.erb index b403cb4bbd6..ee44342cd85 100644 --- a/app/views/idv/shared/_document_capture.html.erb +++ b/app/views/idv/shared/_document_capture.html.erb @@ -12,7 +12,7 @@ %> <%= tag.div id: 'document-capture-form', data: { app_name: APP_NAME, - liveness_required: liveness_checking_enabled?.presence, + liveness_required: nil, mock_client: (DocAuthRouter.doc_auth_vendor(discriminator: session_id) == 'mock').presence, help_center_redirect_url: help_center_redirect_url( flow: :idv, diff --git a/spec/controllers/api/verify/document_capture_controller_spec.rb b/spec/controllers/api/verify/document_capture_controller_spec.rb index 70b41b30026..c764d97359c 100644 --- a/spec/controllers/api/verify/document_capture_controller_spec.rb +++ b/spec/controllers/api/verify/document_capture_controller_spec.rb @@ -23,7 +23,6 @@ let(:password) { 'iambatman' } let(:user) { create(:user, :signed_up) } let(:flow_path) { 'standard' } - let(:liveness_checking_enabled) { false } let(:analytics_data) do { browser_attributes: { browser_bot: false, @@ -92,7 +91,7 @@ expect(agent).to receive(:proof_document).with( document_capture_session, - liveness_checking_enabled: liveness_checking_enabled, + liveness_checking_enabled: false, trace_id: nil, image_metadata: image_metadata, analytics_data: analytics_data, diff --git a/spec/features/idv/doc_auth/document_capture_step_spec.rb b/spec/features/idv/doc_auth/document_capture_step_spec.rb index 5c8a118b052..f8688906770 100644 --- a/spec/features/idv/doc_auth/document_capture_step_spec.rb +++ b/spec/features/idv/doc_auth/document_capture_step_spec.rb @@ -7,25 +7,20 @@ let(:max_attempts) { IdentityConfig.store.doc_auth_max_attempts } let(:user) { user_with_2fa } - let(:liveness_enabled) { false } let(:doc_auth_enable_presigned_s3_urls) { false } let(:fake_analytics) { FakeAnalytics.new } let(:fake_attempts_tracker) { IrsAttemptsApiTrackingHelper::FakeAttemptsTracker.new } let(:sp_name) { 'Test SP' } before do - allow(IdentityConfig.store).to receive(:liveness_checking_enabled). - and_return(liveness_enabled) allow(IdentityConfig.store).to receive(:doc_auth_enable_presigned_s3_urls). and_return(doc_auth_enable_presigned_s3_urls) allow(Identity::Hostdata::EC2).to receive(:load). and_return(OpenStruct.new(region: 'us-west-2', account_id: '123456789')) allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) allow_any_instance_of(ServiceProviderSessionDecorator).to receive(:sp_name).and_return(sp_name) - if liveness_enabled - visit_idp_from_oidc_sp_with_ial2_strict - else - visit_idp_from_oidc_sp_with_ial2 - end + + visit_idp_from_oidc_sp_with_ial2 + sign_in_and_2fa_user(user) complete_doc_auth_steps_before_document_capture_step end @@ -93,127 +88,37 @@ expect(page).to have_content(I18n.t('doc_auth.errors.general.network_error')) end - context 'when liveness checking is enabled' do - let(:liveness_enabled) { true } - - it 'is on the correct page and shows the document upload options' do - expect(current_path).to eq(idv_doc_auth_document_capture_step) - expect(page).to have_content(t('doc_auth.headings.document_capture_front')) - expect(page).to have_content(t('doc_auth.headings.document_capture_back')) - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - # Document capture tips - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) - - # Selfie option, evidenced by "Continue" button instead of "Submit" - expect(page).to have_content(t('forms.buttons.continue')) - end - - it 'proceeds to the next page with valid info and logs analytics info' do - expect_any_instance_of(DocAuth::Mock::DocAuthMockClient). - to receive(:post_images). - with(hash_including(image_source: DocAuth::ImageSources::UNKNOWN)). - and_call_original - - attach_and_submit_images - - expect(page).to have_current_path(next_step) - expect(fake_analytics).to have_logged_event( - 'IdV: ' + "#{Analytics::DOC_AUTH} document_capture submitted".downcase, - step: 'document_capture', - flow_path: 'standard', - ) - expect_costing_for_document - end - - it 'does not proceed to the next page with invalid info', allow_browser_log: true do - mock_general_doc_auth_client_error(:create_document) - - attach_and_submit_images - - expect(page).to have_current_path(idv_doc_auth_document_capture_step) - end - - it 'allows users to retake photos with attention with barcode', allow_browser_log: true do - mock_doc_auth_attention_with_barcode - attach_and_submit_images - - expect(page).to have_content(t('doc_auth.errors.barcode_attention.confirm_info')) - expect(page).to have_content('DAVID') - expect(page).to have_content('SAMPLE') - expect(page).to have_content('1986-10-13') - - click_button t('doc_auth.buttons.add_new_photos') - submit_images - - expect(page).to have_content(t('doc_auth.errors.barcode_attention.confirm_info')) - click_button t('forms.buttons.continue') - - expect(page).to have_current_path(next_step, wait: 10) - end - - it 'does not proceed if doc auth is success but missing information', allow_browser_log: true do - mock_doc_auth_no_name_pii(:post_images) - attach_and_submit_images - - expect(page).to have_current_path(idv_doc_auth_document_capture_step) - - expect(fake_analytics).to have_logged_event( - 'IdV: doc auth image upload vendor pii validation', - flow_path: 'standard', - success: false, - ) - end - - context 'when javascript is enabled', js: true do - it 'proceeds to the next step' do - attach_and_submit_images - - expect(page).to have_current_path(next_step) - end - end + it 'is on the correct page and shows the document upload options' do + expect(current_path).to eq(idv_doc_auth_document_capture_step) + expect(page).to have_content(t('doc_auth.headings.document_capture_front')) + expect(page).to have_content(t('doc_auth.headings.document_capture_back')) + expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) + + # Document capture tips + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) + + # No selfie option, evidenced by "Submit" button instead of "Continue" + expect(page).to have_content(t('forms.buttons.submit.default')) end - context 'when liveness checking is not enabled' do - let(:liveness_enabled) { false } - - it 'is on the correct page and shows the document upload options' do - expect(current_path).to eq(idv_doc_auth_document_capture_step) - expect(page).to have_content(t('doc_auth.headings.document_capture_front')) - expect(page).to have_content(t('doc_auth.headings.document_capture_back')) - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - # Document capture tips - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) - - # No selfie option, evidenced by "Submit" button instead of "Continue" - expect(page).to have_content(t('forms.buttons.submit.default')) - end - - it 'proceeds to the next page with valid info' do - attach_and_submit_images + it 'proceeds to the next page with valid info' do + attach_and_submit_images - expect(page).to have_current_path(next_step) - expect_costing_for_document - expect(DocAuthLog.find_by(user_id: user.id).state).to eq('MT') - end + expect(page).to have_current_path(next_step) + expect_costing_for_document + expect(DocAuthLog.find_by(user_id: user.id).state).to eq('MT') + end - it 'does not track state if state tracking is disabled' do - allow(IdentityConfig.store).to receive(:state_tracking_enabled).and_return(false) - attach_and_submit_images + it 'does not track state if state tracking is disabled' do + allow(IdentityConfig.store).to receive(:state_tracking_enabled).and_return(false) + attach_and_submit_images - expect(DocAuthLog.find_by(user_id: user.id).state).to be_nil - end + expect(DocAuthLog.find_by(user_id: user.id).state).to be_nil end context 'when using async uploads' do diff --git a/spec/features/idv/doc_capture/document_capture_step_spec.rb b/spec/features/idv/doc_capture/document_capture_step_spec.rb index 7f49520b1e7..ca6db7adb82 100644 --- a/spec/features/idv/doc_capture/document_capture_step_spec.rb +++ b/spec/features/idv/doc_capture/document_capture_step_spec.rb @@ -7,14 +7,10 @@ let(:max_attempts) { IdentityConfig.store.doc_auth_max_attempts } let(:user) { user_with_2fa } - let(:liveness_enabled) { true } let(:doc_auth_enable_presigned_s3_urls) { false } - let(:sp_requests_ial2_strict) { true } let(:fake_analytics) { FakeAnalytics.new } let(:sp_name) { 'Test SP' } before do - allow(IdentityConfig.store).to receive(:liveness_checking_enabled). - and_return(liveness_enabled) allow(IdentityConfig.store).to receive(:doc_auth_enable_presigned_s3_urls). and_return(doc_auth_enable_presigned_s3_urls) allow(Identity::Hostdata::EC2).to receive(:load). @@ -23,14 +19,40 @@ allow_any_instance_of(DocumentProofingJob).to receive(:build_analytics). and_return(fake_analytics) allow_any_instance_of(ServiceProviderSessionDecorator).to receive(:sp_name).and_return(sp_name) - if sp_requests_ial2_strict && liveness_enabled - visit_idp_from_oidc_sp_with_ial2_strict - else - visit_idp_from_oidc_sp_with_ial2 - end + + visit_idp_from_oidc_sp_with_ial2 + allow_any_instance_of(Browser).to receive(:mobile?).and_return(true) end + it 'is on the correct page and shows the document upload options' do + complete_doc_capture_steps_before_first_step(user) + + expect(current_path).to eq(idv_capture_doc_document_capture_step) + expect(page).to have_content(t('doc_auth.headings.document_capture_front')) + expect(page).to have_content(t('doc_auth.headings.document_capture_back')) + expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) + + # Document capture tips + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) + expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) + + # No selfie option, evidenced by "Submit" button instead of "Continue" + expect(page).to have_content(t('forms.buttons.submit.default')) + end + + it 'proceeds to the next page with valid info' do + complete_doc_capture_steps_before_first_step(user) + + attach_and_submit_images + + expect(page).to have_current_path(next_step) + end + it 'offers the user the option to cancel and return to desktop' do complete_doc_capture_steps_before_first_step(user) @@ -106,7 +128,7 @@ pii_from_doc: {}, }, ) - click_idv_continue + click_submit_default end click_idv_continue @@ -124,7 +146,7 @@ pii_from_doc: {}, }, ) - click_idv_continue + click_submit_default end click_idv_continue @@ -199,107 +221,23 @@ end end - context 'when liveness checking is enabled' do - let(:liveness_enabled) { true } - - before do - complete_doc_capture_steps_before_first_step(user) - end - - context 'when the SP does not request strict IAL2' do - let(:sp_requests_ial2_strict) { false } - - it 'is on the correct page and shows the document upload options' do - expect(current_path).to eq(idv_capture_doc_document_capture_step) - expect(page).to have_content(t('doc_auth.headings.document_capture_front')) - expect(page).to have_content(t('doc_auth.headings.document_capture_back')) - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - # Doc capture tips - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) - - # No selfie option, evidenced by "Submit" button instead of "Continue" - expect(page).to have_content(t('forms.buttons.submit.default')) - end - end - - it 'is on the correct page and shows the document upload options' do - expect(current_path).to eq(idv_capture_doc_document_capture_step) - expect(page).to have_content(t('doc_auth.headings.document_capture_front')) - expect(page).to have_content(t('doc_auth.headings.document_capture_back')) - - # Doc capture tips - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) - - # Selfie option, evidenced by "Continue" button instead of "Submit" - expect(page).to have_content(t('forms.buttons.continue')) - end - - it 'logs a warning event when there are unknown errors in the response', :allow_browser_log do - Tempfile.create(['ia2_mock', '.yml']) do |yml_file| - yml_file.rewind - yml_file.puts <<~YAML - failed_alerts: - - name: Some Made Up Error - YAML - yml_file.close - - attach_images(yml_file.path) - click_submit_default - end - - expect(page).to have_content(t('errors.doc_auth.throttled_heading'), wait: 5) - expect(fake_analytics).to have_logged_event('Doc Auth Warning', {}) - end - - it 'does not proceed to the next page with invalid info', allow_browser_log: true do - mock_general_doc_auth_client_error(:create_document) - attach_and_submit_images - - expect(page).to have_current_path(idv_capture_doc_document_capture_step) - end - end - - context 'when liveness checking is not enabled' do - let(:liveness_enabled) { false } + it 'logs a warning event when there are unknown errors in the response', :allow_browser_log do + complete_doc_capture_steps_before_first_step(user) - before do - complete_doc_capture_steps_before_first_step(user) - end + Tempfile.create(['ia2_mock', '.yml']) do |yml_file| + yml_file.rewind + yml_file.puts <<~YAML + failed_alerts: + - name: Some Made Up Error + YAML + yml_file.close - it 'is on the correct page and shows the document upload options' do - expect(current_path).to eq(idv_capture_doc_document_capture_step) - expect(page).to have_content(t('doc_auth.headings.document_capture_front')) - expect(page).to have_content(t('doc_auth.headings.document_capture_back')) - expect_step_indicator_current_step(t('step_indicator.flows.idv.verify_id')) - - # Document capture tips - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_header_text')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text1')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text2')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text3')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_id_text4')) - expect(page).to have_content(I18n.t('doc_auth.tips.document_capture_hint')) - - # No selfie option, evidenced by "Submit" button instead of "Continue" - expect(page).to have_content(t('forms.buttons.submit.default')) + attach_images(yml_file.path) + click_submit_default end - it 'proceeds to the next page with valid info' do - attach_and_submit_images - - expect(page).to have_current_path(next_step) - end + expect(page).to have_content(t('errors.doc_auth.throttled_heading'), wait: 5) + expect(fake_analytics).to have_logged_event('Doc Auth Warning', {}) end def next_step diff --git a/spec/features/idv/proofing_components_spec.rb b/spec/features/idv/proofing_components_spec.rb index 60ccdfc1914..efcf8a11f8d 100644 --- a/spec/features/idv/proofing_components_spec.rb +++ b/spec/features/idv/proofing_components_spec.rb @@ -48,33 +48,4 @@ end end end - - it 'clears liveness enabled proofing component when user re-proofs without liveness', js: true do - allow(IdentityConfig.store).to receive(:liveness_checking_enabled).and_return(true) - user = user_with_totp_2fa - sign_in_and_2fa_user(user) - visit_idp_from_oidc_sp_with_ial2_strict - complete_proofing_steps - - expect(user.active_profile.includes_liveness_check?).to be_truthy - - visit account_path - first(:link, t('links.sign_out')).click - - trigger_reset_password_and_click_email_link(user.email) - reset_password_and_sign_back_in(user, user.password) - fill_in_code_with_last_totp(user) - click_submit_default - - expect(user.reload.profiles.where(active: true)).to be_empty - - visit_idp_from_oidc_sp_with_ial2 - click_on t('links.account.reactivate.without_key') - click_on t('forms.buttons.continue') - - complete_proofing_steps - - user = User.find(user.id) - expect(user.active_profile.includes_liveness_check?).to be_falsy - end end diff --git a/spec/features/idv/strict_ial2/upgrade_spec.rb b/spec/features/idv/strict_ial2/upgrade_spec.rb index 9c9c2e46b23..43c10d14c53 100644 --- a/spec/features/idv/strict_ial2/upgrade_spec.rb +++ b/spec/features/idv/strict_ial2/upgrade_spec.rb @@ -8,29 +8,6 @@ before { allow(IdentityConfig.store).to receive(:liveness_checking_enabled).and_return(true) } - scenario 'an IAL2 strict request for a user with no liveness triggers an upgrade' do - user = create( - :profile, :active, :verified, - pii: { first_name: 'John', ssn: '111223333' } - ).user - visit_idp_from_oidc_sp_with_ial2_strict - sign_in_user(user) - fill_in_code_with_last_phone_otp - click_submit_default - click_agree_and_continue_optional - - expect(page.current_path).to eq(idv_doc_auth_welcome_step) - - complete_all_doc_auth_steps_before_password_step - fill_in 'Password', with: user.password - click_continue - acknowledge_and_confirm_personal_key - click_agree_and_continue - - expect(current_url).to start_with('http://localhost:7654/auth/result') - expect(user.active_profile.strict_ial2_proofed?).to be_truthy - end - context 'strict IAL2 does not allow a phone check' do before do allow(IdentityConfig.store).to receive(