diff --git a/app/controllers/concerns/idv/verify_info_concern.rb b/app/controllers/concerns/idv/verify_info_concern.rb
index efceb72bc06..e2608ab854e 100644
--- a/app/controllers/concerns/idv/verify_info_concern.rb
+++ b/app/controllers/concerns/idv/verify_info_concern.rb
@@ -19,8 +19,6 @@ def shared_update
Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).
call('verify', :update, true)
- set_state_id_type
-
ssn_rate_limiter.increment!
document_capture_session = DocumentCaptureSession.create(
diff --git a/app/controllers/idv/in_person/verify_info_controller.rb b/app/controllers/idv/in_person/verify_info_controller.rb
index 5284d5e6881..1eb612bb664 100644
--- a/app/controllers/idv/in_person/verify_info_controller.rb
+++ b/app/controllers/idv/in_person/verify_info_controller.rb
@@ -57,14 +57,6 @@ def flow_param
'in_person'
end
- # state_id_type is hard-coded here because it's required for proofing against
- # AAMVA. We're sticking with driver's license because most states don't discern
- # between various ID types and driver's license is the most common one that will
- # be supported. See also LG-3852 and related findings document.
- def set_state_id_type
- pii_from_user[:state_id_type] = 'drivers_license' unless invalid_state?
- end
-
def invalid_state?
pii_from_user.blank?
end
diff --git a/app/controllers/idv/verify_info_controller.rb b/app/controllers/idv/verify_info_controller.rb
index 9496890cf04..bc11819486b 100644
--- a/app/controllers/idv/verify_info_controller.rb
+++ b/app/controllers/idv/verify_info_controller.rb
@@ -64,9 +64,6 @@ def self.step_info
def flow_param; end
- # state ID type isn't manually set for Idv::VerifyInfoController
- def set_state_id_type; end
-
def prev_url
idv_ssn_url
end
diff --git a/app/services/proofing/aamva/request/verification_request.rb b/app/services/proofing/aamva/request/verification_request.rb
index ecff76af4a4..84e25e75b34 100644
--- a/app/services/proofing/aamva/request/verification_request.rb
+++ b/app/services/proofing/aamva/request/verification_request.rb
@@ -84,9 +84,36 @@ def add_user_provided_data_to_body
inside: '//dldv:verifyDriverLicenseDataRequest',
)
+ if IdentityConfig.store.aamva_send_id_type
+ add_state_id_type(
+ applicant.state_id_data.state_id_type,
+ document,
+ )
+ end
+
@body = document.to_s
end
+ def add_state_id_type(id_type, document)
+ category_code = case id_type
+ when 'drivers_license'
+ 1
+ when 'drivers_permit'
+ 2
+ when 'state_id_card'
+ 3
+ end
+
+ if category_code
+ add_optional_element(
+ 'aa:DocumentCategoryCode',
+ value: category_code,
+ document:,
+ inside: '//dldv:verifyDriverLicenseDataRequest',
+ )
+ end
+ end
+
def add_optional_element(name, value:, document:, inside: nil, after: nil)
return if value.blank?
diff --git a/app/services/proofing/mock/state_id_mock_client.rb b/app/services/proofing/mock/state_id_mock_client.rb
index 7f01945df57..3b86f0bff68 100644
--- a/app/services/proofing/mock/state_id_mock_client.rb
+++ b/app/services/proofing/mock/state_id_mock_client.rb
@@ -72,8 +72,8 @@ def invalid_state_id_number?(state_id_number)
end
def invalid_state_id_type?(state_id_type)
- !SUPPORTED_STATE_ID_TYPES.include?(state_id_type) ||
- state_id_type.nil?
+ !SUPPORTED_STATE_ID_TYPES.include?(state_id_type) &&
+ !state_id_type.nil?
end
end
end
diff --git a/config/application.yml.default b/config/application.yml.default
index 4bdf5c9b6dc..376fe87c200 100644
--- a/config/application.yml.default
+++ b/config/application.yml.default
@@ -19,6 +19,7 @@ aamva_auth_url: 'https://example.org:12345/auth/url'
aamva_cert_enabled: true
aamva_private_key: ''
aamva_public_key: ''
+aamva_send_id_type: true
aamva_supported_jurisdictions: '["AL","AR","AZ","CO","CT","DC","DE","FL","GA","HI","IA","ID","IL","IN","KS","KY","MA","MD","ME","MI","MO","MS","MT","NC","ND","NE","NJ","NM","NV","OH","OR","PA","RI","SC","SD","TN","TX","VA","VT","WA","WI","WV","WY"]'
aamva_verification_request_timeout: 5.0
aamva_verification_url: https://example.org:12345/verification/url
@@ -501,6 +502,7 @@ development:
#
production:
aamva_auth_url: 'https://authentication-cert.aamva.org/Authentication/Authenticate.svc'
+ aamva_send_id_type: false
aamva_verification_url: 'https://verificationservices-cert.aamva.org:18449/dldv/2.1/online'
available_locales: 'en,es,fr'
biometric_ial_enabled: false
diff --git a/lib/identity_config.rb b/lib/identity_config.rb
index 88003036bb8..8eaaf9bd709 100644
--- a/lib/identity_config.rb
+++ b/lib/identity_config.rb
@@ -34,6 +34,7 @@ def self.store
config.add(:aamva_cert_enabled, type: :boolean)
config.add(:aamva_private_key, type: :string)
config.add(:aamva_public_key, type: :string)
+ config.add(:aamva_send_id_type, type: :boolean)
config.add(:aamva_supported_jurisdictions, type: :json)
config.add(:aamva_verification_request_timeout, type: :float)
config.add(:aamva_verification_url)
diff --git a/spec/controllers/idv/in_person/verify_info_controller_spec.rb b/spec/controllers/idv/in_person/verify_info_controller_spec.rb
index 4a6dbda956b..a05953e8b96 100644
--- a/spec/controllers/idv/in_person/verify_info_controller_spec.rb
+++ b/spec/controllers/idv/in_person/verify_info_controller_spec.rb
@@ -234,22 +234,15 @@
allow(user).to receive(:establishing_in_person_enrollment).and_return(enrollment)
end
- it 'sets ssn and state_id_type on pii_from_user' do
+ it 'sets ssn on pii_from_user' do
expect(Idv::Agent).to receive(:new).with(
hash_including(
- state_id_type: 'drivers_license',
ssn: Idp::Constants::MOCK_IDV_APPLICANT_SAME_ADDRESS_AS_ID[:ssn],
consent_given_at: subject.idv_session.idv_consent_given_at,
),
).and_call_original
- # our test data already has the expected value by default
- subject.user_session['idv/in_person'][:pii_from_user].delete(:state_id_type)
-
put :update
-
- expect(subject.user_session['idv/in_person'][:pii_from_user][:state_id_type]).
- to eq 'drivers_license'
end
context 'a user does not have an establishing in person enrollment associated with them' do
diff --git a/spec/features/idv/analytics_spec.rb b/spec/features/idv/analytics_spec.rb
index 7505f8b7717..606eb9373ec 100644
--- a/spec/features/idv/analytics_spec.rb
+++ b/spec/features/idv/analytics_spec.rb
@@ -153,7 +153,7 @@
vendor_name: 'ResolutionMock',
vendor_workflow: nil,
verified_attributes: nil },
- state_id: state_id_resolution_with_id_type,
+ state_id: state_id_resolution,
threatmetrix: threatmetrix_response,
},
},
diff --git a/spec/fixtures/proofing/aamva/requests/verification_request.xml b/spec/fixtures/proofing/aamva/requests/verification_request.xml
index 32d5a25010f..c42882043d4 100644
--- a/spec/fixtures/proofing/aamva/requests/verification_request.xml
+++ b/spec/fixtures/proofing/aamva/requests/verification_request.xml
@@ -31,7 +31,7 @@
VA
20176
-
+ 1
-
\ No newline at end of file
+
diff --git a/spec/services/proofing/aamva/applicant_spec.rb b/spec/services/proofing/aamva/applicant_spec.rb
index bb22b20d376..b2172ce9bd5 100644
--- a/spec/services/proofing/aamva/applicant_spec.rb
+++ b/spec/services/proofing/aamva/applicant_spec.rb
@@ -14,7 +14,7 @@
end
describe '.from_proofer_applicant(applicant)' do
- it 'should create an AAMVA applicant with necessary proofer applcant data' do
+ it 'should create an AAMVA applicant with necessary proofer applicant data' do
aamva_applicant = described_class.from_proofer_applicant(proofer_applicant)
expect(aamva_applicant.uuid).to eq(proofer_applicant[:uuid])
diff --git a/spec/services/proofing/aamva/request/verification_request_spec.rb b/spec/services/proofing/aamva/request/verification_request_spec.rb
index 190d9edf374..68c2a874d83 100644
--- a/spec/services/proofing/aamva/request/verification_request_spec.rb
+++ b/spec/services/proofing/aamva/request/verification_request_spec.rb
@@ -33,7 +33,7 @@
describe '#body' do
it 'should be a request body' do
- expect(subject.body).to eq(AamvaFixtures.verification_request)
+ expect(subject.body + "\n").to eq(AamvaFixtures.verification_request)
end
it 'should escape XML in applicant data' do
@@ -88,6 +88,64 @@
'2030-01-02',
)
end
+
+ context '#state_id_type' do
+ context 'when the feature flag is off' do
+ before do
+ expect(IdentityConfig.store).to receive(:aamva_send_id_type).and_return(false)
+ end
+
+ it 'does not add a DocumentCategoryCode' do
+ applicant.state_id_data.state_id_type = 'drivers_license'
+ expect(subject.body).to_not include('')
+ end
+ end
+
+ context 'when the feature flag is on' do
+ before do
+ expect(IdentityConfig.store).to receive(:aamva_send_id_type).and_return(true)
+ end
+
+ context 'when the type is a Drivers License' do
+ it 'includes DocumentCategoryCode=1' do
+ applicant.state_id_data.state_id_type = 'drivers_license'
+ expect(subject.body).to include(
+ '1',
+ )
+ end
+ end
+
+ context 'when the type is a learners permit' do
+ it 'includes DocumentCategoryCode=2' do
+ applicant.state_id_data.state_id_type = 'drivers_permit'
+ expect(subject.body).to include(
+ '2',
+ )
+ end
+ end
+
+ context 'when the type is an ID Card' do
+ it 'includes DocumentCategoryCode=3' do
+ applicant.state_id_data.state_id_type = 'state_id_card'
+ expect(subject.body).to include(
+ '3',
+ )
+ end
+ end
+
+ context 'when the type is something invalid' do
+ it 'does not add a DocumentCategoryCode for nil ID type' do
+ applicant.state_id_data.state_id_type = nil
+ expect(subject.body).to_not include('')
+ end
+
+ it 'does not add a DocumentCategoryCode for invalid ID types' do
+ applicant.state_id_data.state_id_type = 'License to Keep an Alpaca'
+ expect(subject.body).to_not include('')
+ end
+ end
+ end
+ end
end
describe '#headers' do