diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb index 24248b2ea94..6da17395cbd 100644 --- a/app/controllers/concerns/idv/verify_info_concern.rb +++ b/app/controllers/concerns/idv/verify_info_concern.rb @@ -173,6 +173,9 @@ def async_state_done(current_async_state) [:proofing_results, :context, :stages, :threatmetrix, :response_body, :first_name], [:same_address_as_id], [:proofing_results, :context, :stages, :state_id, :state_id_jurisdiction], + [:proofing_results, :biographical_info, :identity_doc_address_state], + [:proofing_results, :biographical_info, :state_id_jurisdiction], + [:proofing_results, :biographical_info, :same_address_as_id], ], }, ) diff --git a/app/jobs/socure_shadow_mode_proofing_job.rb b/app/jobs/socure_shadow_mode_proofing_job.rb index 399f8440f22..83b8aa15bf1 100644 --- a/app/jobs/socure_shadow_mode_proofing_job.rb +++ b/app/jobs/socure_shadow_mode_proofing_job.rb @@ -49,6 +49,10 @@ def perform( [:resolution_result, :context, :stages, :residential_address, :errors, :ssn], [:resolution_result, :context, :stages, :threatmetrix, :response_body, :first_name], [:resolution_result, :context, :stages, :state_id, :state_id_jurisdiction], + [:resolution_result, :context, :stages, :state_id, :state_id_jurisdiction], + [:resolution_result, :biographical_info, :identity_doc_address_state], + [:resolution_result, :biographical_info, :state_id_jurisdiction], + [:resolution_result, :biographical_info, :same_address_as_id], ], ) end diff --git a/app/services/proofing/resolution/progressive_proofer.rb b/app/services/proofing/resolution/progressive_proofer.rb index 77b1a4cc1ac..5dc2be668d4 100644 --- a/app/services/proofing/resolution/progressive_proofer.rb +++ b/app/services/proofing/resolution/progressive_proofer.rb @@ -53,6 +53,7 @@ def proof( state_id_result: state_id_result, residential_resolution_result: residential_instant_verify_result, same_address_as_id: applicant_pii[:same_address_as_id], + applicant_pii: applicant_pii, ) end diff --git a/app/services/proofing/resolution/result_adjudicator.rb b/app/services/proofing/resolution/result_adjudicator.rb index 3fc07cb3483..908327ac585 100644 --- a/app/services/proofing/resolution/result_adjudicator.rb +++ b/app/services/proofing/resolution/result_adjudicator.rb @@ -4,7 +4,8 @@ module Proofing module Resolution class ResultAdjudicator attr_reader :resolution_result, :state_id_result, :device_profiling_result, - :ipp_enrollment_in_progress, :residential_resolution_result, :same_address_as_id + :ipp_enrollment_in_progress, :residential_resolution_result, :same_address_as_id, + :applicant_pii def initialize( resolution_result:, # InstantVerify @@ -13,7 +14,8 @@ def initialize( should_proof_state_id:, ipp_enrollment_in_progress:, device_profiling_result:, - same_address_as_id: + same_address_as_id:, + applicant_pii: ) @resolution_result = resolution_result @state_id_result = state_id_result @@ -22,6 +24,7 @@ def initialize( @device_profiling_result = device_profiling_result @residential_resolution_result = residential_resolution_result @same_address_as_id = same_address_as_id # this is a string, "true" or "false" + @applicant_pii = applicant_pii end def adjudicated_result @@ -46,6 +49,7 @@ def adjudicated_result threatmetrix: device_profiling_result.to_h, }, }, + biographical_info: biographical_info, }, ) end @@ -112,6 +116,21 @@ def state_id_attributes_cover_resolution_failures? (failed_resolution_attributes.to_a - passed_state_id_attributes.to_a).empty? end + + def biographical_info + state_id_number = applicant_pii[:state_id_number] + redacted_state_id_number = if state_id_number.present? + StringRedacter.redact_alphanumeric(state_id_number) + end + { + birth_year: applicant_pii[:dob]&.to_date&.year, + state: applicant_pii[:state], + identity_doc_address_state: applicant_pii[:identity_doc_address_state], + state_id_jurisdiction: applicant_pii[:state_id_jurisdiction], + state_id_number: redacted_state_id_number, + same_address_as_id: applicant_pii[:same_address_as_id], + } + end end end end diff --git a/spec/controllers/idv/verify_info_controller_spec.rb b/spec/controllers/idv/verify_info_controller_spec.rb index 1be8cdbe1d0..fbff5d0b88c 100644 --- a/spec/controllers/idv/verify_info_controller_spec.rb +++ b/spec/controllers/idv/verify_info_controller_spec.rb @@ -269,6 +269,7 @@ resolution_result: Proofing::Resolution::Result.new(success: true), same_address_as_id: true, should_proof_state_id: true, + applicant_pii: Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN, ).adjudicated_result.to_h document_capture_session.create_proofing_session diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb index c4f5f26f714..c947cbf14b3 100644 --- a/spec/features/idv/analytics_spec.rb +++ b/spec/features/idv/analytics_spec.rb @@ -107,6 +107,14 @@ threatmetrix: threatmetrix_response, }, }, + biographical_info: { + birth_year: 1938, + identity_doc_address_state: nil, + same_address_as_id: nil, + state: 'MT', + state_id_jurisdiction: 'ND', + state_id_number: '#############', + }, } end @@ -137,6 +145,14 @@ threatmetrix: threatmetrix_response, }, }, + biographical_info: { + birth_year: 1938, + identity_doc_address_state: 'ND', + same_address_as_id: 'false', + state: 'MT', + state_id_jurisdiction: 'ND', + state_id_number: '#############', + }, } end diff --git a/spec/jobs/socure_shadow_mode_proofing_job_spec.rb b/spec/jobs/socure_shadow_mode_proofing_job_spec.rb index 3353e0e427f..a12bcf058d8 100644 --- a/spec/jobs/socure_shadow_mode_proofing_job_spec.rb +++ b/spec/jobs/socure_shadow_mode_proofing_job_spec.rb @@ -105,6 +105,14 @@ }, }, }, + biographical_info: { + birth_year: 1938, + identity_doc_address_state: nil, + same_address_as_id: nil, + state: 'MT', + state_id_jurisdiction: 'ND', + state_id_number: '#############', + }, ssn_is_unique: true, }, ) @@ -250,6 +258,14 @@ ssn_is_unique: true, threatmetrix_review_status: 'pass', timed_out: false, + biographical_info: { + birth_year: 1938, + identity_doc_address_state: nil, + same_address_as_id: nil, + state: 'MT', + state_id_jurisdiction: 'ND', + state_id_number: '#############', + }, }, socure_result: { attributes_requiring_additional_verification: [], diff --git a/spec/services/proofing/resolution/result_adjudicator_spec.rb b/spec/services/proofing/resolution/result_adjudicator_spec.rb index 7da807de820..6e8aba8bbfb 100644 --- a/spec/services/proofing/resolution/result_adjudicator_spec.rb +++ b/spec/services/proofing/resolution/result_adjudicator_spec.rb @@ -44,6 +44,8 @@ ) end + let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN } + subject do described_class.new( resolution_result: resolution_result, @@ -53,6 +55,7 @@ ipp_enrollment_in_progress: ipp_enrollment_in_progress, device_profiling_result: device_profiling_result, same_address_as_id: same_address_as_id, + applicant_pii: applicant_pii, ) end @@ -92,5 +95,39 @@ end end end + + describe 'biographical_info' do + context 'the applicant PII contains one address' do + it 'includes formatted PII' do + result = subject.adjudicated_result + + expect(result.extra[:biographical_info]).to eq( + birth_year: 1938, + state: 'MT', + identity_doc_address_state: nil, + state_id_jurisdiction: 'ND', + state_id_number: '#############', + same_address_as_id: nil, + ) + end + end + + context 'the applicant PII contains a residential address and document address' do + let(:applicant_pii) { Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID } + + it 'includes formatted PII' do + result = subject.adjudicated_result + + expect(result.extra[:biographical_info]).to eq( + birth_year: 1938, + state: 'MT', + identity_doc_address_state: 'MT', + state_id_jurisdiction: 'ND', + state_id_number: '#############', + same_address_as_id: 'true', + ) + end + end + end end end