diff --git a/app/controllers/idv/in_person/usps_locations_controller.rb b/app/controllers/idv/in_person/usps_locations_controller.rb index 4367b795ba3..a6d2278cacf 100644 --- a/app/controllers/idv/in_person/usps_locations_controller.rb +++ b/app/controllers/idv/in_person/usps_locations_controller.rb @@ -46,7 +46,9 @@ def update enrollment.update!( selected_location_details: update_params.as_json, issuer: current_sp&.issuer, + doc_auth_result: document_capture_session&.last_doc_auth_result, ) + add_proofing_component render json: { success: true }, status: :ok @@ -54,6 +56,24 @@ def update private + def idv_session + if user_session && current_user + @idv_session ||= Idv::Session.new( + user_session: user_session, + current_user: current_user, + service_provider: current_sp, + ) + end + end + + def document_capture_session + if idv_session&.document_capture_session_uuid # standard flow + DocumentCaptureSession.find_by(uuid: idv_session.document_capture_session_uuid) + else # hybrid flow + super + end + end + def proofer @proofer ||= EnrollmentHelper.usps_proofer end diff --git a/app/controllers/sign_up/completions_controller.rb b/app/controllers/sign_up/completions_controller.rb index f665f0d85fc..1107fa56309 100644 --- a/app/controllers/sign_up/completions_controller.rb +++ b/app/controllers/sign_up/completions_controller.rb @@ -89,6 +89,11 @@ def analytics_attributes(page_occurence) needs_completion_screen_reason: needs_completion_screen_reason, } + if (last_enrollment = current_user.in_person_enrollments.last) + attributes[:in_person_proofing_status] = last_enrollment.status + attributes[:doc_auth_result] = last_enrollment.doc_auth_result + end + if page_occurence.present? && DisposableEmailDomain.disposable?(email_domain) attributes[:disposable_email_domain] = email_domain end diff --git a/app/forms/idv/api_image_upload_form.rb b/app/forms/idv/api_image_upload_form.rb index 5e53082199d..51dedff8923 100644 --- a/app/forms/idv/api_image_upload_form.rb +++ b/app/forms/idv/api_image_upload_form.rb @@ -38,6 +38,10 @@ def submit if form_response.success? client_response = post_images_to_client + document_capture_session.update!( + last_doc_auth_result: client_response.extra[:doc_auth_result], + ) + if client_response.success? doc_pii_response = validate_pii_from_doc(client_response) end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index caecbcde27d..e03e7e03d5d 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -5776,6 +5776,8 @@ def user_registration_cancellation(request_came_from:, **extra) # @param [Array] sp_session_requested_attributes Attributes requested by the service provider # @param [Boolean] in_account_creation_flow Whether user is going through account creation flow # @param [String, nil] disposable_email_domain Disposable email domain used for registration + # @param [String, nil] in_person_proofing_status In person proofing status + # @param [String, nil] doc_auth_result The doc auth result def user_registration_complete( ial2:, service_provider_name:, @@ -5785,6 +5787,8 @@ def user_registration_complete( sp_session_requested_attributes:, ialmax: nil, disposable_email_domain: nil, + in_person_proofing_status: nil, + doc_auth_result: nil, **extra ) track_event( @@ -5797,6 +5801,8 @@ def user_registration_complete( needs_completion_screen_reason:, sp_session_requested_attributes:, disposable_email_domain:, + in_person_proofing_status:, + doc_auth_result:, **extra, ) end diff --git a/db/primary_migrate/20240708183211_add_doc_auth_result_to_in_person_enrollments.rb b/db/primary_migrate/20240708183211_add_doc_auth_result_to_in_person_enrollments.rb new file mode 100644 index 00000000000..7cc64052e54 --- /dev/null +++ b/db/primary_migrate/20240708183211_add_doc_auth_result_to_in_person_enrollments.rb @@ -0,0 +1,6 @@ +class AddDocAuthResultToInPersonEnrollments < ActiveRecord::Migration[7.1] + def change + add_column :in_person_enrollments, :doc_auth_result, :string + add_column :document_capture_sessions, :last_doc_auth_result, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c99936d6691..06cfd26c3f8 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_06_04_173515) do +ActiveRecord::Schema[7.1].define(version: 2024_07_08_183211) do # These are extensions that must be enabled in order to support this database enable_extension "citext" enable_extension "pg_stat_statements" @@ -191,6 +191,7 @@ t.string "issuer" t.datetime "cancelled_at", precision: nil t.boolean "ocr_confirmation_pending", default: false + t.string "last_doc_auth_result" t.index ["result_id"], name: "index_document_capture_sessions_on_result_id" t.index ["user_id"], name: "index_document_capture_sessions_on_user_id" t.index ["uuid"], name: "index_document_capture_sessions_on_uuid" @@ -318,6 +319,7 @@ t.datetime "notification_sent_at", comment: "The time a notification was sent" t.datetime "last_batch_claimed_at" t.string "sponsor_id" + t.string "doc_auth_result" t.index ["profile_id"], name: "index_in_person_enrollments_on_profile_id" t.index ["ready_for_status_check"], name: "index_in_person_enrollments_on_ready_for_status_check", where: "(ready_for_status_check = true)" t.index ["status_check_attempted_at"], name: "index_in_person_enrollments_on_status_check_attempted_at", where: "(status = 1)" diff --git a/spec/controllers/idv/image_uploads_controller_spec.rb b/spec/controllers/idv/image_uploads_controller_spec.rb index f029a085d88..fc2357d2993 100644 --- a/spec/controllers/idv/image_uploads_controller_spec.rb +++ b/spec/controllers/idv/image_uploads_controller_spec.rb @@ -8,13 +8,17 @@ let(:back_image) { DocAuthImageFixtures.document_back_image_multipart } let(:selfie_img) { nil } let(:state_id_number) { 'S59397998' } + let(:user) { create(:user) } + + before do + stub_sign_in(user) if user + end describe '#create' do subject(:action) do post :create, params: params end - let(:user) { create(:user) } let!(:document_capture_session) { user.document_capture_sessions.create!(user: user) } let(:flow_path) { 'standard' } let(:params) do diff --git a/spec/controllers/idv/in_person/usps_locations_controller_spec.rb b/spec/controllers/idv/in_person/usps_locations_controller_spec.rb index 402ae40efa4..130b8bfe6f5 100644 --- a/spec/controllers/idv/in_person/usps_locations_controller_spec.rb +++ b/spec/controllers/idv/in_person/usps_locations_controller_spec.rb @@ -326,6 +326,23 @@ end end + context 'with failed doc_auth_result' do + before do + allow(controller).to receive(:document_capture_session).and_return( + OpenStruct.new({ last_doc_auth_result: 'Failed' }), + ) + end + + it 'updates the doc_auth_result in the enrollment' do + response + + enrollment = user.reload.establishing_in_person_enrollment + + expect(enrollment.selected_location_details).to_not be_nil + expect(enrollment.doc_auth_result).to eq('Failed') + end + end + context 'with feature disabled' do let(:in_person_proofing_enabled) { false } diff --git a/spec/controllers/sign_up/completions_controller_spec.rb b/spec/controllers/sign_up/completions_controller_spec.rb index 41a4ea46018..985c64c241b 100644 --- a/spec/controllers/sign_up/completions_controller_spec.rb +++ b/spec/controllers/sign_up/completions_controller_spec.rb @@ -236,6 +236,8 @@ sp_session_requested_attributes: nil, in_account_creation_flow: true, disposable_email_domain: nil, + in_person_proofing_status: nil, + doc_auth_result: nil, ) end @@ -296,6 +298,8 @@ sp_session_requested_attributes: nil, in_account_creation_flow: true, disposable_email_domain: 'temporary.com', + doc_auth_result: nil, + in_person_proofing_status: nil, ) end end @@ -312,6 +316,7 @@ ) stub_sign_in(user) sp = create(:service_provider, issuer: 'https://awesome') + create(:in_person_enrollment, status: 'passed', doc_auth_result: 'Passed', user: user) subject.session[:sp] = { issuer: sp.issuer, acr_values: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, @@ -332,6 +337,8 @@ sp_session_requested_attributes: ['email'], in_account_creation_flow: true, disposable_email_domain: 'temporary.com', + in_person_proofing_status: 'passed', + doc_auth_result: 'Passed', ) end diff --git a/spec/forms/idv/api_image_upload_form_spec.rb b/spec/forms/idv/api_image_upload_form_spec.rb index f1b69b835e5..68cac14c6e1 100644 --- a/spec/forms/idv/api_image_upload_form_spec.rb +++ b/spec/forms/idv/api_image_upload_form_spec.rb @@ -452,7 +452,10 @@ DocAuth::Response.new( success: false, errors: errors, - extra: { remaining_submit_attempts: IdentityConfig.store.doc_auth_max_attempts - 1 }, + extra: { + remaining_submit_attempts: IdentityConfig.store.doc_auth_max_attempts - 1, + doc_auth_result: 'Failed', + }, ) end let(:doc_auth_client) { double(DocAuth::LexisNexis::LexisNexisClient) } @@ -470,7 +473,16 @@ expect(response.selfie_status).to eq(:not_processed) expect(response.attention_with_barcode?).to eq(false) expect(response.pii_from_doc).to eq(nil) + end + + it 'saves the doc_auth_result to document_capture_session' do + response = form.submit + session = DocumentCaptureSession.find_by(uuid: document_capture_session_uuid) + + expect(response).to be_a_kind_of DocAuth::Response + expect(response.success?).to eq(false) expect(response.doc_auth_success?).to eq(false) + expect(session.last_doc_auth_result).to eq('Failed') end it 'includes remaining_submit_attempts' do @@ -498,7 +510,7 @@ expect(fake_analytics).to have_logged_event( 'IdV: doc auth image upload vendor submitted', hash_including( - doc_auth_result: nil, + doc_auth_result: 'Failed', errors: { front: 'glare' }, success: false, doc_type_supported: boolean, diff --git a/spec/models/document_capture_session_spec.rb b/spec/models/document_capture_session_spec.rb index 5e67837cfa5..b1056460a49 100644 --- a/spec/models/document_capture_session_spec.rb +++ b/spec/models/document_capture_session_spec.rb @@ -21,6 +21,9 @@ zipcode: '12345', issuing_country_code: 'USA', ), + extra: { + doc_auth_result: 'Passed', + }, ) end