Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ module VerifyInfoConcern

STEP_NAME = 'verify_info'

class_methods do
def threatmetrix_session_id_present_or_not_required?(idv_session:)
return true unless FeatureManagement.proofing_device_profiling_decisioning_enabled?
idv_session.threatmetrix_session_id.present?
end
end

def shared_update
return if idv_session.verify_info_step_document_capture_session_uuid
analytics.idv_doc_auth_verify_submitted(**analytics_arguments)
Expand Down Expand Up @@ -36,6 +43,11 @@ def shared_update
return true
end

def log_event_for_missing_threatmetrix_session_id
return if self.class.threatmetrix_session_id_present_or_not_required?(idv_session:)
analytics.idv_verify_info_missing_threatmetrix_session_id if idv_session.ssn_step_complete?
end

private

def ipp_enrollment_in_progress?
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/idv/verify_info_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class VerifyInfoController < ApplicationController
include Steps::ThreatMetrixStepHelper

before_action :confirm_not_rate_limited_after_doc_auth, except: [:show]
before_action :log_event_for_missing_threatmetrix_session_id
before_action :confirm_step_allowed

def show
Expand Down Expand Up @@ -45,7 +46,9 @@ def self.step_info
controller: self,
next_steps: [:phone, :request_letter],
preconditions: ->(idv_session:, user:) do
idv_session.ssn && idv_session.remote_document_capture_complete?
idv_session.remote_document_capture_complete? &&
idv_session.ssn_step_complete? &&
threatmetrix_session_id_present_or_not_required?(idv_session:)
end,
undo_step: ->(idv_session:, user:) do
idv_session.resolution_successful = nil
Expand Down
5 changes: 5 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4758,6 +4758,11 @@ def idv_verify_in_person_troubleshooting_option_clicked(
)
end

# The user ended up at the "Verify info" screen without a Threatmetrix session id.
def idv_verify_info_missing_threatmetrix_session_id(**extra)
track_event(:idv_verify_info_missing_threatmetrix_session_id, **extra)
end

# @param [Boolean] acuant_sdk_upgrade_a_b_testing_enabled
# @param [String] acuant_version
# @param ["hybrid","standard"] flow_path Document capture user flow
Expand Down
4 changes: 4 additions & 0 deletions app/services/idv/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ def ipp_state_id_complete?
user_session['idv/in_person'][:pii_from_user].has_key?(:identity_doc_address1)
end

def ssn_step_complete?
ssn.present?
end

def verify_info_step_complete?
resolution_successful
end
Expand Down
13 changes: 12 additions & 1 deletion app/services/idv/steps/threat_metrix_step_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ def threatmetrix_view_variables(updating_ssn)
end

def generate_threatmetrix_session_id(updating_ssn)
idv_session.threatmetrix_session_id = SecureRandom.uuid if !updating_ssn
if should_generate_new_threatmetrix_session_id?(updating_ssn)
idv_session.threatmetrix_session_id = SecureRandom.uuid
end

idv_session.threatmetrix_session_id
end

def should_generate_new_threatmetrix_session_id?(updating_ssn)
if updating_ssn
idv_session.threatmetrix_session_id.blank?
else
true
end
end

# @return [Array<String>]
def threatmetrix_javascript_urls(session_id)
sources = if IdentityConfig.store.lexisnexis_threatmetrix_mock_enabled
Expand Down
1 change: 1 addition & 0 deletions spec/controllers/idv/enter_password_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
subject.idv_session.flow_path = 'standard'
subject.idv_session.pii_from_doc = Pii::StateId.new(**Idp::Constants::MOCK_IDV_APPLICANT)
subject.idv_session.ssn = Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE[:ssn]
subject.idv_session.threatmetrix_session_id = 'random-session-id'
subject.idv_session.resolution_successful = true
subject.idv_session.applicant = Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE
subject.idv_session.resolution_successful = true
Expand Down
1 change: 1 addition & 0 deletions spec/controllers/idv/otp_verification_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
subject.idv_session.idv_consent_given_at = Time.zone.now
subject.idv_session.flow_path = 'standard'
subject.idv_session.pii_from_doc = Pii::StateId.new(**Idp::Constants::MOCK_IDV_APPLICANT)
subject.idv_session.threatmetrix_session_id = 'random-session-id'
subject.idv_session.ssn = Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE[:ssn]
subject.idv_session.resolution_successful = true
subject.idv_session.applicant[:phone] = phone
Expand Down
1 change: 1 addition & 0 deletions spec/controllers/idv/phone_errors_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
subject.idv_session.idv_consent_given_at = Time.zone.now
subject.idv_session.flow_path = 'standard'
subject.idv_session.pii_from_doc = Pii::StateId.new(**Idp::Constants::MOCK_IDV_APPLICANT)
subject.idv_session.threatmetrix_session_id = 'random-session-id'
subject.idv_session.ssn = '123-45-6789'
subject.idv_session.applicant = Idp::Constants::MOCK_IDV_APPLICANT_WITH_PHONE
subject.idv_session.resolution_successful = true
Expand Down
40 changes: 37 additions & 3 deletions spec/controllers/idv/ssn_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,43 @@
expect { get :show }.to change { subject.idv_session.threatmetrix_session_id }.from(nil)
end

it 'does not change threatmetrix_session_id when updating ssn' do
subject.idv_session.ssn = ssn
expect { get :show }.not_to change { subject.idv_session.threatmetrix_session_id }
context 'when updating ssn' do
let(:threatmetrix_session_id) { 'original-session-id' }

before do
subject.idv_session.ssn = ssn
subject.idv_session.threatmetrix_session_id = threatmetrix_session_id
end
it 'does not change threatmetrix_session_id' do
expect { get :show }.not_to change { subject.idv_session.threatmetrix_session_id }
end
Copy link
Contributor

@gina-yamada gina-yamada Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for including this test. Nice to see if you revisit the ssn page you will not get a new tmx session id.
Code looks good. I don't have time to manually test at the moment but will try to get back to this before end of day


context 'but there is no threatmetrix_session_id in the session' do
let(:threatmetrix_session_id) { nil }

it 'sets a threatmetrix_session_id' do
expect { get :show }.to change { subject.idv_session.threatmetrix_session_id }
end
end
end

context 'proofing_device_profiling disabled' do
before do
allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:disabled)
end

it 'still add a threatmetrix session id to idv_session' do
expect { get :show }.to change { subject.idv_session.threatmetrix_session_id }.from(nil)
end

context 'when idv_session has a threatmetrix_session_id' do
before do
subject.idv_session.threatmetrix_session_id = 'fake-session-id'
end
it 'changes the threatmetrix_session_id' do
expect { get :show }.to change { subject.idv_session.threatmetrix_session_id }
end
end
end

context 'with an ssn in idv_session' do
Expand Down
51 changes: 48 additions & 3 deletions spec/controllers/idv/verify_info_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@

context 'when proofing_device_profiling is enabled' do
let(:threatmetrix_client_id) { 'threatmetrix_client' }

let(:review_status) { 'pass' }
let(:idv_result) do
{
context: {
Expand Down Expand Up @@ -178,9 +178,37 @@
allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:enabled)
end

context 'when threatmetrix response is Pass' do
let(:review_status) { 'pass' }
context 'when idv_session is missing threatmetrix_session_id' do
before do
controller.idv_session.threatmetrix_session_id = nil
end

it 'redirects back to the SSN step' do
get :show
expect(response).to redirect_to(idv_ssn_url)
end

it 'logs an idv_verify_info_missing_threatmetrix_session_id event' do
get :show
expect(@analytics).to have_logged_event(
:idv_verify_info_missing_threatmetrix_session_id,
)
end

context 'when ssn is not present in idv_session' do
before do
controller.idv_session.ssn = nil
end
it 'does not log an idv_verify_info_missing_threatmetrix_session_id event' do
get :show
expect(@analytics).not_to have_logged_event(
:idv_verify_info_missing_threatmetrix_session_id,
)
end
end
end

context 'when threatmetrix response is Pass' do
it 'sets the review status in the idv session' do
get :show
expect(controller.idv_session.threatmetrix_review_status).to eq('pass')
Expand Down Expand Up @@ -238,6 +266,23 @@
end
end

context 'when proofing_device_profiling is disabled' do
before do
allow(IdentityConfig.store).to receive(:proofing_device_profiling).and_return(:disabled)
end

context 'when idv_session is missing threatmetrix_session_id' do
before do
controller.idv_session.threatmetrix_session_id = nil
get :show
end

it 'does not redirect back to the SSN step' do
expect(response).not_to redirect_to(idv_ssn_url)
end
end
end

context 'for an aamva request' do
before do
allow(controller).to receive(:load_async_state).and_return(async_state)
Expand Down
1 change: 1 addition & 0 deletions spec/support/flow_policy_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def stub_step(key:, idv_session:)
idv_session.pii_from_doc = Pii::StateId.new(**Idp::Constants::MOCK_IDV_APPLICANT)
when :ssn
idv_session.ssn = Idp::Constants::MOCK_IDV_APPLICANT_WITH_SSN[:ssn]
idv_session.threatmetrix_session_id = 'a-random-session-id'
when :ipp_ssn
idv_session.send(:user_session)['idv/in_person'] = {
pii_from_user: Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID.dup,
Expand Down