diff --git a/app/jobs/socure_docv_results_job.rb b/app/jobs/socure_docv_results_job.rb index 38c79c0ec05..21a46b73dfc 100644 --- a/app/jobs/socure_docv_results_job.rb +++ b/app/jobs/socure_docv_results_job.rb @@ -15,14 +15,31 @@ def perform(document_capture_session_uuid:, async: true, docv_transaction_token_ document_capture_session timer = JobHelpers::Timer.new - response = timer.time('vendor_request') do + docv_result_response = timer.time('vendor_request') do socure_document_verification_result end log_verification_request( - docv_result_response: response, + docv_result_response:, vendor_request_time_in_ms: timer.results['vendor_request'], ) - document_capture_session.store_result_from_response(response) + + if docv_result_response.success? + doc_pii_response = Idv::DocPiiForm.new(pii: docv_result_response.pii_from_doc.to_h).submit + log_pii_validation(doc_pii_response:) + + unless doc_pii_response&.success? + document_capture_session.store_failed_auth_data( + doc_auth_success: true, + selfie_status: docv_result_response.selfie_status, + errors: { pii_validation: 'failed' }, + front_image_fingerprint: nil, + back_image_fingerprint: nil, + selfie_image_fingerprint: nil, + ) + return + end + end + document_capture_session.store_result_from_response(docv_result_response) end private @@ -50,6 +67,17 @@ def log_verification_request(docv_result_response:, vendor_request_time_in_ms:) ) end + def log_pii_validation(doc_pii_response:) + analytics.idv_doc_auth_submitted_pii_validation( + **doc_pii_response.to_h.merge( + submit_attempts: rate_limiter&.attempts, + remaining_submit_attempts: rate_limiter&.remaining_count, + flow_path: nil, + liveness_checking_required: nil, + ), + ) + end + def socure_document_verification_result DocAuth::Socure::Requests::DocvResultRequest.new( document_capture_session_uuid:, diff --git a/app/models/document_capture_session.rb b/app/models/document_capture_session.rb index 47b618a6bb6..2ce93dea6ca 100644 --- a/app/models/document_capture_session.rb +++ b/app/models/document_capture_session.rb @@ -33,7 +33,8 @@ def store_result_from_response(doc_auth_response) end def store_failed_auth_data(front_image_fingerprint:, back_image_fingerprint:, - selfie_image_fingerprint:, doc_auth_success:, selfie_status:) + selfie_image_fingerprint:, doc_auth_success:, selfie_status:, + errors: nil) session_result = load_result || DocumentCaptureSessionResult.new( id: generate_result_id, ) @@ -46,6 +47,8 @@ def store_failed_auth_data(front_image_fingerprint:, back_image_fingerprint:, session_result.add_failed_back_image!(back_image_fingerprint) session_result.add_failed_selfie_image!(selfie_image_fingerprint) if selfie_status == :fail + session_result.errors = errors + EncryptedRedisStructStorage.store( session_result, expires_in: IdentityConfig.store.doc_capture_request_valid_for_minutes.minutes.in_seconds, diff --git a/app/services/doc_auth/socure/responses/docv_result_response.rb b/app/services/doc_auth/socure/responses/docv_result_response.rb index bc89bab0d22..017b65f0b89 100644 --- a/app/services/doc_auth/socure/responses/docv_result_response.rb +++ b/app/services/doc_auth/socure/responses/docv_result_response.rb @@ -42,7 +42,7 @@ def initialize(http_response:, @pii_from_doc = read_pii super( - success: successful_result? && pii_valid?, + success: successful_result?, errors: error_messages, pii_from_doc:, extra: extra_attributes, @@ -98,8 +98,6 @@ def successful_result? def error_messages if !successful_result? { socure: { reason_codes: get_data(DATA_PATHS[:reason_codes]) } } - elsif !pii_valid? - { pii_validation: 'failed' } else {} end @@ -178,12 +176,6 @@ def parse_date(date_string) Rails.logger.info(message) nil end - - def pii_valid? - return @pii_valid if !@pii_valid.nil? - - @pii_valid = Idv::DocPiiForm.new(pii: pii_from_doc.to_h).submit.success? - end end end end diff --git a/spec/features/idv/doc_auth/socure_document_capture_spec.rb b/spec/features/idv/doc_auth/socure_document_capture_spec.rb index 247b31b3a77..c624fe461d7 100644 --- a/spec/features/idv/doc_auth/socure_document_capture_spec.rb +++ b/spec/features/idv/doc_auth/socure_document_capture_spec.rb @@ -29,6 +29,7 @@ socure_docv_webhook_repeat_endpoints.each { |endpoint| stub_request(:post, endpoint) } allow(IdentityConfig.store).to receive(:ruby_workers_idv_enabled).and_return(false) allow_any_instance_of(ApplicationController).to receive(:analytics).and_return(fake_analytics) + allow_any_instance_of(SocureDocvResultsJob).to receive(:analytics).and_return(fake_analytics) @docv_transaction_token = stub_docv_document_request allow(IdentityConfig.store).to receive(:socure_docv_verification_data_test_mode) .and_return(socure_docv_verification_data_test_mode) @@ -153,6 +154,9 @@ visit idv_socure_document_capture_path expect(page).to have_current_path(idv_session_errors_rate_limited_path) + expect(fake_analytics).to have_logged_event( + :idv_socure_verification_data_requested, + ) end end end @@ -263,6 +267,9 @@ expect(fake_analytics).to have_logged_event( :idv_socure_document_request_submitted, ) + expect(fake_analytics).not_to have_logged_event( + 'IdV: doc auth image upload vendor pii validation', + ) end end @@ -285,6 +292,9 @@ expect(fake_analytics).to have_logged_event( :idv_socure_document_request_submitted, ) + expect(fake_analytics).not_to have_logged_event( + 'IdV: doc auth image upload vendor pii validation', + ) end end end @@ -333,6 +343,9 @@ expect(page).to have_current_path(idv_ssn_url) expect(DocAuthLog.find_by(user_id: @user.id).state).to eq('NY') + expect(fake_analytics).to have_logged_event( + :idv_socure_verification_data_requested, + ) fill_out_ssn_form_ok click_idv_continue @@ -357,6 +370,9 @@ expect(page).to have_current_path(idv_ssn_url) expect(DocAuthLog.find_by(user_id: @user.id).state).to eq('NY') + expect(fake_analytics).to have_logged_event( + :idv_socure_verification_data_requested, + ) fill_out_ssn_form_ok click_idv_continue @@ -394,6 +410,12 @@ expect(fake_analytics).to have_logged_event( :idv_socure_document_request_submitted, ) + expect(fake_analytics).to have_logged_event( + :idv_socure_verification_data_requested, + ) + expect(fake_analytics).to have_logged_event( + 'IdV: doc auth image upload vendor pii validation', + ) fill_out_ssn_form_ok click_idv_continue @@ -427,6 +449,9 @@ expect(fake_analytics).to have_logged_event( :idv_socure_document_request_submitted, ) + expect(fake_analytics).not_to have_logged_event( + :idv_doc_auth_submitted_pii_validation, + ) end end diff --git a/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb b/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb index f5729f69374..866794851cb 100644 --- a/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb +++ b/spec/features/idv/hybrid_mobile/hybrid_socure_mobile_spec.rb @@ -36,6 +36,7 @@ .and_return(socure_docv_verification_data_test_mode) @docv_transaction_token = stub_docv_document_request stub_analytics + allow_any_instance_of(SocureDocvResultsJob).to receive(:analytics).and_return(@analytics) end context 'happy path', allow_browser_log: true do @@ -112,6 +113,10 @@ expect(page).to_not have_content(t('doc_auth.headings.text_message'), wait: 10) expect(page).to have_current_path(idv_ssn_path) expect(@analytics).to have_logged_event(:idv_socure_document_request_submitted) + expect(@analytics).to have_logged_event(:idv_socure_verification_data_requested) + expect(@analytics).to have_logged_event( + 'IdV: doc auth image upload vendor pii validation', + ) fill_out_ssn_form_ok click_idv_continue @@ -549,6 +554,9 @@ expect(page).to have_text(t('doc_auth.headers.general.network_error')) expect(page).to have_text(t('doc_auth.errors.general.new_network_error')) expect(@analytics).to have_logged_event(:idv_socure_document_request_submitted) + expect(@analytics).not_to have_logged_event( + 'IdV: doc auth image upload vendor pii validation', + ) end perform_in_browser(:desktop) do diff --git a/spec/jobs/socure_docv_results_job_spec.rb b/spec/jobs/socure_docv_results_job_spec.rb index 99aadd2ffdc..a50cf8421b8 100644 --- a/spec/jobs/socure_docv_results_job_spec.rb +++ b/spec/jobs/socure_docv_results_job_spec.rb @@ -112,7 +112,34 @@ expect(document_capture_session_result.selfie_status).to eq(:not_processed) end - it 'expect fake analytics to have logged idv_socure_verification_data_requested' do + context 'Pii validation fails' do + before do + allow_any_instance_of(Idv::DocPiiForm).to receive(:zipcode).and_return(:invalid_junk) + end + + it 'stores a failed result' do + perform + + document_capture_session.reload + document_capture_session_result = document_capture_session.load_result + expect(document_capture_session_result.success).to eq(false) + expect(document_capture_session_result.doc_auth_success).to eq(true) + expect(document_capture_session_result.errors).to eq({ pii_validation: 'failed' }) + end + end + + it 'logs an idv_doc_auth_submitted_pii_validation event' do + perform + expect(fake_analytics).to have_logged_event( + 'IdV: doc auth image upload vendor pii validation', + hash_including( + :submit_attempts, + :remaining_submit_attempts, + ), + ) + end + + it 'logs an idv_socure_verification_data_requested event' do perform expect(fake_analytics).to have_logged_event( :idv_socure_verification_data_requested, diff --git a/spec/services/doc_auth/socure/responses/docv_result_response_spec.rb b/spec/services/doc_auth/socure/responses/docv_result_response_spec.rb deleted file mode 100644 index dc8525994d4..00000000000 --- a/spec/services/doc_auth/socure/responses/docv_result_response_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'rails_helper' - -RSpec.describe DocAuth::Socure::Responses::DocvResultResponse do - subject(:docv_response) do - http_response = Struct.new(:body).new(SocureDocvFixtures.pass_json) - described_class.new(http_response:) - end - - context 'Socure says OK and the PII is valid' do - it 'succeeds' do - expect(docv_response.success?).to be(true) - end - end - - context 'Socure says OK but the PII is invalid' do - before do - allow_any_instance_of(Idv::DocPiiForm).to receive(:zipcode).and_return(:invalid_junk) - end - - it 'fails' do - expect(docv_response.success?).to be(false) - end - - it 'with a pii failure error' do - expect(docv_response.errors).to eq({ pii_validation: 'failed' }) - end - end -end