From b6d2df6ad48aa456d6a2bd2179ede72856b3a7a9 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Fri, 13 Sep 2024 12:49:07 -0400 Subject: [PATCH 01/12] changelog: Internal, Account Management, Include identity-verified status in account reset delete event --- app/services/account_reset/delete_account.rb | 18 ++- app/services/analytics_events.rb | 6 + .../delete_account_controller_spec.rb | 134 ++++++++++++++++++ 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index 1fa187682aa..f297e11b0b9 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -16,6 +16,8 @@ def call track_account_age track_mfa_method_counts + track_identity_verified_status + track_identity_verification_pending extra = extra_analytics_attributes @@ -26,7 +28,8 @@ def call private - attr_reader :success, :account_age, :mfa_method_counts, :request, :analytics + attr_reader :success, :account_age, :mfa_method_counts, :request, :analytics, :verified_status, + :verification_method # @return [Integer, nil] number of days since the account was confirmed (rounded) or nil if # the account was not confirmed @@ -39,6 +42,17 @@ def track_mfa_method_counts @mfa_method_counts = MfaContext.new(user).enabled_two_factor_configuration_counts_hash end + def track_identity_verified_status + @verified_status = user.identity_verified? + end + + def track_identity_verification_pending + return false unless success + @verification_method = user.pending_in_person_enrollment.present? && 'IPP' || + user.gpo_verification_pending_profile.present? && 'GPO' || + user.identity_verified_with_biometric_comparison? && 'Biometric' || nil + end + def handle_successful_submission notify_user_via_email_of_deletion send_push_notifications @@ -73,6 +87,8 @@ def extra_analytics_attributes account_age_in_days: account_age, account_confirmed_at: user.confirmed_at, mfa_method_counts: mfa_method_counts, + identity_verified: verified_status, + identity_verification_method: verification_method, pii_like_keypaths: [[:mfa_method_counts, :phone]], } end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index f01ca2b86a9..29a296b79fb 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -87,6 +87,8 @@ def account_reset_cancel_token_validation( # @param [Time] account_confirmed_at date that account creation was confirmed # (rounded) or nil if the account was not confirmed # @param [Hash] mfa_method_counts Hash of MFA method with the number of that method on the account + # @param [Boolean] identity_verified if the deletion occurs on a verified account + # @param [String, nil] identity_verification_method verification method used if applicable # @param [Hash] errors Errors resulting from form validation # @param [Hash] error_details Details for errors that occurred in unsuccessful submission # An account has been deleted through the account reset flow @@ -96,6 +98,8 @@ def account_reset_delete( account_age_in_days:, account_confirmed_at:, mfa_method_counts:, + identity_verified:, + identity_verification_method:, errors:, error_details: nil, **extra @@ -107,6 +111,8 @@ def account_reset_delete( account_age_in_days:, account_confirmed_at:, mfa_method_counts:, + identity_verified:, + identity_verification_method:, errors:, error_details:, **extra, diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index e838933b9ce..8b8118374f8 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -30,6 +30,7 @@ webauthn: 2, phone: 2, }, + identity_verified: false, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) @@ -48,6 +49,7 @@ errors: invalid_token_error, error_details: { token: { granted_token_invalid: true } }, mfa_method_counts: {}, + identity_verified: false, account_age_in_days: 0, account_confirmed_at: kind_of(Time), ) @@ -65,6 +67,7 @@ errors: { token: [t('errors.account_reset.granted_token_missing', app_name: APP_NAME)] }, error_details: { token: { blank: true } }, mfa_method_counts: {}, + identity_verified: false, account_age_in_days: 0, account_confirmed_at: kind_of(Time), ) @@ -92,6 +95,7 @@ errors: { token: [t('errors.account_reset.granted_token_expired', app_name: APP_NAME)] }, error_details: { token: { granted_token_expired: true } }, mfa_method_counts: {}, + identity_verified: false, account_age_in_days: 2, account_confirmed_at: kind_of(Time), ) @@ -100,6 +104,136 @@ t('errors.account_reset.granted_token_expired', app_name: APP_NAME), ) end + + it 'logs info about user verified account' do + user = create( + :user, + :fully_registered, + confirmed_at: Time.zone.now.round, + profiles: [build(:profile, :active, :verified, pii: { first_name: 'Jane' })], + ) + + create_list(:webauthn_configuration, 2, user: user) + create_account_reset_request_for(user) + grant_request(user) + session[:granted_token] = AccountResetRequest.first.granted_token + + delete :delete + + expect(@analytics).to have_logged_event( + 'Account Reset: delete', + user_id: user.uuid, + success: true, + errors: {}, + mfa_method_counts: { + phone: 1, + webauthn: 2, + }, + identity_verified: true, + account_age_in_days: 0, + account_confirmed_at: user.confirmed_at, + ) + expect(response).to redirect_to account_reset_confirm_delete_account_url + end + + it 'logs info about user biometrically verified account' do + user = create( + :user, + :fully_registered, + confirmed_at: Time.zone.now.round, + profiles: [build( + :profile, :active, :verified, pii: { first_name: 'Jane' }, + idv_level: :unsupervised_with_selfie + )], + ) + + create_list(:webauthn_configuration, 2, user: user) + create_account_reset_request_for(user) + grant_request(user) + session[:granted_token] = AccountResetRequest.first.granted_token + + delete :delete + + expect(@analytics).to have_logged_event( + 'Account Reset: delete', + user_id: user.uuid, + success: true, + errors: {}, + mfa_method_counts: { + phone: 1, + webauthn: 2, + }, + identity_verified: true, + identity_verification_method: 'Biometric', + account_age_in_days: 0, + account_confirmed_at: user.confirmed_at, + ) + expect(response).to redirect_to account_reset_confirm_delete_account_url + end + + it 'logs info about user pending verify by mail account' do + user = create( + :user, + :fully_registered, + confirmed_at: Time.zone.now.round, + profiles: [build(:profile, :verify_by_mail_pending, pii: { first_name: 'Jane' })], + ) + + create_list(:webauthn_configuration, 2, user: user) + create_account_reset_request_for(user) + grant_request(user) + session[:granted_token] = AccountResetRequest.first.granted_token + + delete :delete + + expect(@analytics).to have_logged_event( + 'Account Reset: delete', + user_id: user.uuid, + success: true, + errors: {}, + mfa_method_counts: { + phone: 1, + webauthn: 2, + }, + identity_verified: false, + identity_verification_method: 'GPO', + account_age_in_days: 0, + account_confirmed_at: user.confirmed_at, + ) + expect(response).to redirect_to account_reset_confirm_delete_account_url + end + + it 'logs info about user pending in person verification account' do + user = create( + :user, + :fully_registered, + :with_pending_in_person_enrollment, + confirmed_at: Time.zone.now.round, + ) + + create_list(:webauthn_configuration, 2, user: user) + create_account_reset_request_for(user) + grant_request(user) + session[:granted_token] = AccountResetRequest.first.granted_token + + delete :delete + + expect(@analytics).to have_logged_event( + 'Account Reset: delete', + user_id: user.uuid, + success: true, + errors: {}, + mfa_method_counts: { + phone: 1, + webauthn: 2, + }, + identity_verified: false, + identity_verification_method: 'IPP', + account_age_in_days: 0, + account_confirmed_at: user.confirmed_at, + ) + expect(response).to redirect_to account_reset_confirm_delete_account_url + end end describe '#show' do From 2e84b3542c16c51e9a3c4ea072805b348e393da0 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Mon, 16 Sep 2024 10:01:19 -0400 Subject: [PATCH 02/12] make identity assignment more succinct and no longer side effect --- app/services/account_reset/delete_account.rb | 25 ++++++++----------- .../delete_account_controller_spec.rb | 6 ++--- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index f297e11b0b9..26012bbae3a 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -16,8 +16,6 @@ def call track_account_age track_mfa_method_counts - track_identity_verified_status - track_identity_verification_pending extra = extra_analytics_attributes @@ -28,8 +26,7 @@ def call private - attr_reader :success, :account_age, :mfa_method_counts, :request, :analytics, :verified_status, - :verification_method + attr_reader :success, :account_age, :mfa_method_counts, :request, :analytics # @return [Integer, nil] number of days since the account was confirmed (rounded) or nil if # the account was not confirmed @@ -42,15 +39,15 @@ def track_mfa_method_counts @mfa_method_counts = MfaContext.new(user).enabled_two_factor_configuration_counts_hash end - def track_identity_verified_status - @verified_status = user.identity_verified? - end - - def track_identity_verification_pending - return false unless success - @verification_method = user.pending_in_person_enrollment.present? && 'IPP' || - user.gpo_verification_pending_profile.present? && 'GPO' || - user.identity_verified_with_biometric_comparison? && 'Biometric' || nil + def verification_method + return nil if user.uuid == 'anonymous-uuid' + if user.pending_in_person_enrollment.present? + :in_person_proofing + elsif user.gpo_verification_pending_profile.present? + :verify_by_mail + elsif user.identity_verified_with_biometric_comparison? + :biometric_comparison + end end def handle_successful_submission @@ -87,7 +84,7 @@ def extra_analytics_attributes account_age_in_days: account_age, account_confirmed_at: user.confirmed_at, mfa_method_counts: mfa_method_counts, - identity_verified: verified_status, + identity_verified: user.identity_verified?, identity_verification_method: verification_method, pii_like_keypaths: [[:mfa_method_counts, :phone]], } diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 8b8118374f8..cbaa9648dfe 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -164,7 +164,7 @@ webauthn: 2, }, identity_verified: true, - identity_verification_method: 'Biometric', + identity_verification_method: :biometric_comparison, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) @@ -196,7 +196,7 @@ webauthn: 2, }, identity_verified: false, - identity_verification_method: 'GPO', + identity_verification_method: :verify_by_mail, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) @@ -228,7 +228,7 @@ webauthn: 2, }, identity_verified: false, - identity_verification_method: 'IPP', + identity_verification_method: :in_person_proofing, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) From ee443a75fb7b9e1789c64d8e26f1bf66187292ab Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Tue, 17 Sep 2024 08:27:45 -0400 Subject: [PATCH 03/12] leverage user factory traits for setup --- .../delete_account_controller_spec.rb | 55 +++---------------- 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index cbaa9648dfe..4ae86645d0d 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -106,14 +106,7 @@ end it 'logs info about user verified account' do - user = create( - :user, - :fully_registered, - confirmed_at: Time.zone.now.round, - profiles: [build(:profile, :active, :verified, pii: { first_name: 'Jane' })], - ) - - create_list(:webauthn_configuration, 2, user: user) + user = create(:user, :proofed) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -125,10 +118,7 @@ user_id: user.uuid, success: true, errors: {}, - mfa_method_counts: { - phone: 1, - webauthn: 2, - }, + mfa_method_counts: { phone: 1 }, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -137,17 +127,7 @@ end it 'logs info about user biometrically verified account' do - user = create( - :user, - :fully_registered, - confirmed_at: Time.zone.now.round, - profiles: [build( - :profile, :active, :verified, pii: { first_name: 'Jane' }, - idv_level: :unsupervised_with_selfie - )], - ) - - create_list(:webauthn_configuration, 2, user: user) + user = create(:user, :proofed_with_selfie, :with_phone) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -159,10 +139,7 @@ user_id: user.uuid, success: true, errors: {}, - mfa_method_counts: { - phone: 1, - webauthn: 2, - }, + mfa_method_counts: { phone: 1 }, identity_verified: true, identity_verification_method: :biometric_comparison, account_age_in_days: 0, @@ -172,14 +149,7 @@ end it 'logs info about user pending verify by mail account' do - user = create( - :user, - :fully_registered, - confirmed_at: Time.zone.now.round, - profiles: [build(:profile, :verify_by_mail_pending, pii: { first_name: 'Jane' })], - ) - - create_list(:webauthn_configuration, 2, user: user) + user = create(:user, :with_pending_gpo_profile, :with_phone) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -191,10 +161,7 @@ user_id: user.uuid, success: true, errors: {}, - mfa_method_counts: { - phone: 1, - webauthn: 2, - }, + mfa_method_counts: { phone: 1 }, identity_verified: false, identity_verification_method: :verify_by_mail, account_age_in_days: 0, @@ -206,12 +173,9 @@ it 'logs info about user pending in person verification account' do user = create( :user, - :fully_registered, :with_pending_in_person_enrollment, - confirmed_at: Time.zone.now.round, + :with_phone, ) - - create_list(:webauthn_configuration, 2, user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -223,10 +187,7 @@ user_id: user.uuid, success: true, errors: {}, - mfa_method_counts: { - phone: 1, - webauthn: 2, - }, + mfa_method_counts: { phone: 1 }, identity_verified: false, identity_verification_method: :in_person_proofing, account_age_in_days: 0, From e55f97de86cc4b1e7eb12257ac5a46f69bc021c6 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Tue, 17 Sep 2024 13:06:35 -0400 Subject: [PATCH 04/12] remove pending states from deleting accounts --- app/services/account_reset/delete_account.rb | 6 +++--- .../account_reset/delete_account_controller_spec.rb | 10 +++++----- spec/factories/users.rb | 7 +++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index 26012bbae3a..bc931892f56 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -40,10 +40,10 @@ def track_mfa_method_counts end def verification_method - return nil if user.uuid == 'anonymous-uuid' - if user.pending_in_person_enrollment.present? + return nil if !user.identity_verified? + if user.in_person_enrollments.present? :in_person_proofing - elsif user.gpo_verification_pending_profile.present? + elsif user.active_profile.gpo_confirmation_codes.present? :verify_by_mail elsif user.identity_verified_with_biometric_comparison? :biometric_comparison diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 4ae86645d0d..10538a4455a 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -148,8 +148,8 @@ expect(response).to redirect_to account_reset_confirm_delete_account_url end - it 'logs info about user pending verify by mail account' do - user = create(:user, :with_pending_gpo_profile, :with_phone) + it 'logs info about user with a verified by mail account' do + user = create(:user, :proofed_with_gpo) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -162,7 +162,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - identity_verified: false, + identity_verified: true, identity_verification_method: :verify_by_mail, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -173,7 +173,7 @@ it 'logs info about user pending in person verification account' do user = create( :user, - :with_pending_in_person_enrollment, + :proofed_in_person_enrollment, :with_phone, ) create_account_reset_request_for(user) @@ -188,7 +188,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - identity_verified: false, + identity_verified: true, identity_verification_method: :in_person_proofing, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 4659097e929..6bba14837c3 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -226,6 +226,13 @@ end end + trait :proofed_in_person_enrollment do + proofed + after :build do |user| + create(:in_person_enrollment, status: 'passed', user: user) + end + end + trait :with_pending_gpo_profile do transient do code_sent_at { created_at } From fafa0a4a3de8a94b38fe14c8bbf28faa7d3b5ae2 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Tue, 17 Sep 2024 15:05:17 -0400 Subject: [PATCH 05/12] log proofing_components on delete --- app/services/account_reset/delete_account.rb | 18 ++++++------------ app/services/analytics_events.rb | 13 ++++++++++--- .../delete_account_controller_spec.rb | 11 ++++++++--- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index bc931892f56..f1c23e8d0e7 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -39,17 +39,6 @@ def track_mfa_method_counts @mfa_method_counts = MfaContext.new(user).enabled_two_factor_configuration_counts_hash end - def verification_method - return nil if !user.identity_verified? - if user.in_person_enrollments.present? - :in_person_proofing - elsif user.active_profile.gpo_confirmation_codes.present? - :verify_by_mail - elsif user.identity_verified_with_biometric_comparison? - :biometric_comparison - end - end - def handle_successful_submission notify_user_via_email_of_deletion send_push_notifications @@ -77,6 +66,11 @@ def notify_user_via_email_of_deletion end # rubocop:enable IdentityIdp/MailLaterLinter + def profile_components + return nil if !user.identity_verified? + ProofingComponent.create_or_find_by(user: user) + end + def extra_analytics_attributes { user_id: user.uuid, @@ -84,8 +78,8 @@ def extra_analytics_attributes account_age_in_days: account_age, account_confirmed_at: user.confirmed_at, mfa_method_counts: mfa_method_counts, + proofing_components: profile_components, identity_verified: user.identity_verified?, - identity_verification_method: verification_method, pii_like_keypaths: [[:mfa_method_counts, :phone]], } end diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 29a296b79fb..6b8de745df4 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -86,9 +86,16 @@ def account_reset_cancel_token_validation( # @param [Integer, nil] account_age_in_days number of days since the account was confirmed # @param [Time] account_confirmed_at date that account creation was confirmed # (rounded) or nil if the account was not confirmed + # @param [Hash,nil] proofing_components User's current proofing components + # @option proofing_components [String,nil] 'document_check' Vendor that verified the user's ID + # @option proofing_components [String,nil] 'document_type' Type of ID used to verify + # @option proofing_components [String,nil] 'source_check' Source used to verify user's PII + # @option proofing_components [String,nil] 'resolution_check' Vendor for identity resolution check + # @option proofing_components [String,nil] 'address_check' Method used to verify user's address + # @option proofing_components [Boolean,nil] 'threatmetrix' Whether ThreatMetrix check was done + # @option proofing_components [String,nil] 'threatmetrix_review_status' TMX decision on the user # @param [Hash] mfa_method_counts Hash of MFA method with the number of that method on the account # @param [Boolean] identity_verified if the deletion occurs on a verified account - # @param [String, nil] identity_verification_method verification method used if applicable # @param [Hash] errors Errors resulting from form validation # @param [Hash] error_details Details for errors that occurred in unsuccessful submission # An account has been deleted through the account reset flow @@ -99,8 +106,8 @@ def account_reset_delete( account_confirmed_at:, mfa_method_counts:, identity_verified:, - identity_verification_method:, errors:, + proofing_components: nil, error_details: nil, **extra ) @@ -111,8 +118,8 @@ def account_reset_delete( account_age_in_days:, account_confirmed_at:, mfa_method_counts:, + proofing_components: proofing_components, identity_verified:, - identity_verification_method:, errors:, error_details:, **extra, diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 10538a4455a..6314f88a4a9 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -107,6 +107,7 @@ it 'logs info about user verified account' do user = create(:user, :proofed) + proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -119,6 +120,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -128,6 +130,7 @@ it 'logs info about user biometrically verified account' do user = create(:user, :proofed_with_selfie, :with_phone) + proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -140,8 +143,8 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, - identity_verification_method: :biometric_comparison, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) @@ -150,6 +153,7 @@ it 'logs info about user with a verified by mail account' do user = create(:user, :proofed_with_gpo) + proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -162,8 +166,8 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, - identity_verification_method: :verify_by_mail, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) @@ -176,6 +180,7 @@ :proofed_in_person_enrollment, :with_phone, ) + proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -188,8 +193,8 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, - identity_verification_method: :in_person_proofing, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) From 359218f6b29c442fdf38278d8894ab5298c42d6b Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Tue, 17 Sep 2024 17:10:09 -0400 Subject: [PATCH 06/12] gets proofing component off of active profile --- app/services/account_reset/delete_account.rb | 2 +- .../account_reset/delete_account_controller_spec.rb | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index f1c23e8d0e7..d0617fb4a0c 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -68,7 +68,7 @@ def notify_user_via_email_of_deletion def profile_components return nil if !user.identity_verified? - ProofingComponent.create_or_find_by(user: user) + user.active_profile.proofing_components if user.active_profile? end def extra_analytics_attributes diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 6314f88a4a9..46293d40bae 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -107,7 +107,6 @@ it 'logs info about user verified account' do user = create(:user, :proofed) - proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -120,7 +119,6 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -130,7 +128,6 @@ it 'logs info about user biometrically verified account' do user = create(:user, :proofed_with_selfie, :with_phone) - proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -143,7 +140,6 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -153,7 +149,6 @@ it 'logs info about user with a verified by mail account' do user = create(:user, :proofed_with_gpo) - proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -166,7 +161,6 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -180,7 +174,6 @@ :proofed_in_person_enrollment, :with_phone, ) - proofing_components = ProofingComponent.create_or_find_by(user: user) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -193,7 +186,6 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, From 5c83224c9079c795e22c2dd2e1a5abf50f4dbbc3 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Tue, 17 Sep 2024 17:48:32 -0400 Subject: [PATCH 07/12] trying to set confirmed-at to troubleshoot twitchy spec time handling --- .../controllers/account_reset/delete_account_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 46293d40bae..58b6de8237a 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -106,7 +106,7 @@ end it 'logs info about user verified account' do - user = create(:user, :proofed) + user = create(:user, :proofed, confirmed_at: Time.zone.now.round) create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token From e07200c0c1520563a54b411f7763111478e5d27f Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Wed, 18 Sep 2024 12:06:46 -0400 Subject: [PATCH 08/12] add proofing components to user factories --- app/services/account_reset/delete_account.rb | 3 +- .../delete_account_controller_spec.rb | 20 +++++--- spec/factories/users.rb | 46 +++++++++++++++---- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index d0617fb4a0c..20a95fcda9f 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -67,8 +67,7 @@ def notify_user_via_email_of_deletion # rubocop:enable IdentityIdp/MailLaterLinter def profile_components - return nil if !user.identity_verified? - user.active_profile.proofing_components if user.active_profile? + user.active_profile.proofing_components if user.identity_verified? && user.active_profile? end def extra_analytics_attributes diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 58b6de8237a..5632111e2fc 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -106,7 +106,8 @@ end it 'logs info about user verified account' do - user = create(:user, :proofed, confirmed_at: Time.zone.now.round) + user = create(:user, :proofed) + proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -119,15 +120,18 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) - expect(response).to redirect_to account_reset_confirm_delete_account_url end it 'logs info about user biometrically verified account' do - user = create(:user, :proofed_with_selfie, :with_phone) + user = create( + :user, :proofed_with_selfie, :with_phone + ) + proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -140,15 +144,16 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) - expect(response).to redirect_to account_reset_confirm_delete_account_url end it 'logs info about user with a verified by mail account' do user = create(:user, :proofed_with_gpo) + proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -161,19 +166,20 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) - expect(response).to redirect_to account_reset_confirm_delete_account_url end - it 'logs info about user pending in person verification account' do + it 'logs info about user verified in person proofed account' do user = create( :user, :proofed_in_person_enrollment, :with_phone, ) + proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -186,11 +192,11 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, + proofing_components: proofing_components, identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, ) - expect(response).to redirect_to account_reset_confirm_delete_account_url end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 6bba14837c3..a1181dde11c 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -192,14 +192,22 @@ trait :proofed do fully_registered + confirmed_at { Time.zone.now.round } after :build do |user| - create(:profile, :active, :verified, :with_pii, user: user) + create( + :profile, + :active, + :with_pii, + user: user, + proofing_components: { document_check: 'mock', document_type: 'state_id' }, + ) end end trait :proofed_with_selfie do fully_registered + confirmed_at { Time.zone.now.round } after :build do |user| create( @@ -209,6 +217,7 @@ :with_pii, idv_level: :unsupervised_with_selfie, user: user, + proofing_components: { document_check: 'mock', document_type: 'biometric' }, ) end end @@ -226,13 +235,6 @@ end end - trait :proofed_in_person_enrollment do - proofed - after :build do |user| - create(:in_person_enrollment, status: 'passed', user: user) - end - end - trait :with_pending_gpo_profile do transient do code_sent_at { created_at } @@ -265,10 +267,34 @@ end end + trait :proofed_in_person_enrollment do + fully_registered + confirmed_at { Time.zone.now.round } + + after :build do |user| + create( + :profile, + :active, + :with_pii, + user: user, + proofing_components: { document_check: 'mock', document_type: 'ipp' }, + ) + create(:in_person_enrollment, status: 'passed', user: user) + end + end + trait :proofed_with_gpo do - proofed + fully_registered + confirmed_at { Time.zone.now.round } + after :build do |user| - profile = user.active_profile + profile = create( + :profile, + :active, + :with_pii, + user: user, + proofing_components: { document_check: 'mock', document_type: 'gpo' }, + ) gpo_code = create(:gpo_confirmation_code) profile.gpo_confirmation_codes << gpo_code device = create(:device, user: user) From 43d8c932a38727601604a438b8f48db5e4f04692 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Wed, 18 Sep 2024 13:09:02 -0400 Subject: [PATCH 09/12] add an active_profile? stub to AnonymousUser --- app/models/anonymous_user.rb | 4 ++++ app/services/account_reset/delete_account.rb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/anonymous_user.rb b/app/models/anonymous_user.rb index f3b22485419..0dc7b8adf47 100644 --- a/app/models/anonymous_user.rb +++ b/app/models/anonymous_user.rb @@ -60,4 +60,8 @@ def identity_verified_with_biometric_comparison? def identity_verified? false end + + def active_profile? + false + end end diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index 20a95fcda9f..cbbc90d504b 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -67,7 +67,7 @@ def notify_user_via_email_of_deletion # rubocop:enable IdentityIdp/MailLaterLinter def profile_components - user.active_profile.proofing_components if user.identity_verified? && user.active_profile? + user.active_profile.proofing_components if user.active_profile? end def extra_analytics_attributes From ab3535ab0380e431da117c6ea7e0bc1111abd342 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Thu, 19 Sep 2024 08:06:24 -0400 Subject: [PATCH 10/12] abbreviate variable assignment --- app/services/analytics_events.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 6b8de745df4..344f61870a4 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -118,7 +118,7 @@ def account_reset_delete( account_age_in_days:, account_confirmed_at:, mfa_method_counts:, - proofing_components: proofing_components, + proofing_components:, identity_verified:, errors:, error_details:, From 8ca9ad4db5b24a45e7bed8377d2d3517559aa7ee Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Thu, 19 Sep 2024 12:48:36 -0400 Subject: [PATCH 11/12] log profile idv level --- app/models/anonymous_user.rb | 4 ++-- app/services/account_reset/delete_account.rb | 6 +----- app/services/analytics_events.rb | 13 +++---------- .../account_reset/delete_account_controller_spec.rb | 12 ++++-------- spec/factories/users.rb | 12 +++++------- 5 files changed, 15 insertions(+), 32 deletions(-) diff --git a/app/models/anonymous_user.rb b/app/models/anonymous_user.rb index 0dc7b8adf47..6d8bf199a73 100644 --- a/app/models/anonymous_user.rb +++ b/app/models/anonymous_user.rb @@ -61,7 +61,7 @@ def identity_verified? false end - def active_profile? - false + def active_profile + nil end end diff --git a/app/services/account_reset/delete_account.rb b/app/services/account_reset/delete_account.rb index cbbc90d504b..ee0403c490c 100644 --- a/app/services/account_reset/delete_account.rb +++ b/app/services/account_reset/delete_account.rb @@ -66,10 +66,6 @@ def notify_user_via_email_of_deletion end # rubocop:enable IdentityIdp/MailLaterLinter - def profile_components - user.active_profile.proofing_components if user.active_profile? - end - def extra_analytics_attributes { user_id: user.uuid, @@ -77,7 +73,7 @@ def extra_analytics_attributes account_age_in_days: account_age, account_confirmed_at: user.confirmed_at, mfa_method_counts: mfa_method_counts, - proofing_components: profile_components, + profile_idv_level: user.active_profile&.idv_level, identity_verified: user.identity_verified?, pii_like_keypaths: [[:mfa_method_counts, :phone]], } diff --git a/app/services/analytics_events.rb b/app/services/analytics_events.rb index 344f61870a4..83da69b2c1e 100644 --- a/app/services/analytics_events.rb +++ b/app/services/analytics_events.rb @@ -86,17 +86,10 @@ def account_reset_cancel_token_validation( # @param [Integer, nil] account_age_in_days number of days since the account was confirmed # @param [Time] account_confirmed_at date that account creation was confirmed # (rounded) or nil if the account was not confirmed - # @param [Hash,nil] proofing_components User's current proofing components - # @option proofing_components [String,nil] 'document_check' Vendor that verified the user's ID - # @option proofing_components [String,nil] 'document_type' Type of ID used to verify - # @option proofing_components [String,nil] 'source_check' Source used to verify user's PII - # @option proofing_components [String,nil] 'resolution_check' Vendor for identity resolution check - # @option proofing_components [String,nil] 'address_check' Method used to verify user's address - # @option proofing_components [Boolean,nil] 'threatmetrix' Whether ThreatMetrix check was done - # @option proofing_components [String,nil] 'threatmetrix_review_status' TMX decision on the user # @param [Hash] mfa_method_counts Hash of MFA method with the number of that method on the account # @param [Boolean] identity_verified if the deletion occurs on a verified account # @param [Hash] errors Errors resulting from form validation + # @param [String, nil] profile_idv_level shows how verified the user is # @param [Hash] error_details Details for errors that occurred in unsuccessful submission # An account has been deleted through the account reset flow def account_reset_delete( @@ -107,7 +100,7 @@ def account_reset_delete( mfa_method_counts:, identity_verified:, errors:, - proofing_components: nil, + profile_idv_level: nil, error_details: nil, **extra ) @@ -118,7 +111,7 @@ def account_reset_delete( account_age_in_days:, account_confirmed_at:, mfa_method_counts:, - proofing_components:, + profile_idv_level:, identity_verified:, errors:, error_details:, diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 5632111e2fc..43f3c9abefe 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -107,7 +107,6 @@ it 'logs info about user verified account' do user = create(:user, :proofed) - proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -120,7 +119,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, + profile_idv_level: 'legacy_unsupervised', identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -131,7 +130,6 @@ user = create( :user, :proofed_with_selfie, :with_phone ) - proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -144,7 +142,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, + profile_idv_level: 'unsupervised_with_selfie', identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -153,7 +151,6 @@ it 'logs info about user with a verified by mail account' do user = create(:user, :proofed_with_gpo) - proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -166,7 +163,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, + profile_idv_level: 'legacy_unsupervised', identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, @@ -179,7 +176,6 @@ :proofed_in_person_enrollment, :with_phone, ) - proofing_components = user.active_profile.proofing_components create_account_reset_request_for(user) grant_request(user) session[:granted_token] = AccountResetRequest.first.granted_token @@ -192,7 +188,7 @@ success: true, errors: {}, mfa_method_counts: { phone: 1 }, - proofing_components: proofing_components, + profile_idv_level: 'legacy_in_person', identity_verified: true, account_age_in_days: 0, account_confirmed_at: user.confirmed_at, diff --git a/spec/factories/users.rb b/spec/factories/users.rb index a1181dde11c..b29b9289a1e 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -200,7 +200,6 @@ :active, :with_pii, user: user, - proofing_components: { document_check: 'mock', document_type: 'state_id' }, ) end end @@ -217,7 +216,6 @@ :with_pii, idv_level: :unsupervised_with_selfie, user: user, - proofing_components: { document_check: 'mock', document_type: 'biometric' }, ) end end @@ -272,14 +270,15 @@ confirmed_at { Time.zone.now.round } after :build do |user| - create( + profile = create( :profile, - :active, :with_pii, + :active, + :verified, + :in_person_verification_pending, user: user, - proofing_components: { document_check: 'mock', document_type: 'ipp' }, ) - create(:in_person_enrollment, status: 'passed', user: user) + create(:in_person_enrollment, :passed, user: user, profile: profile) end end @@ -293,7 +292,6 @@ :active, :with_pii, user: user, - proofing_components: { document_check: 'mock', document_type: 'gpo' }, ) gpo_code = create(:gpo_confirmation_code) profile.gpo_confirmation_codes << gpo_code From e85f30f97faf73b1929cef5a059935616e049751 Mon Sep 17 00:00:00 2001 From: kevinsmaster5 Date: Thu, 19 Sep 2024 14:27:36 -0400 Subject: [PATCH 12/12] remove spec for verified by mail --- .../delete_account_controller_spec.rb | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/spec/controllers/account_reset/delete_account_controller_spec.rb b/spec/controllers/account_reset/delete_account_controller_spec.rb index 43f3c9abefe..90b86b874db 100644 --- a/spec/controllers/account_reset/delete_account_controller_spec.rb +++ b/spec/controllers/account_reset/delete_account_controller_spec.rb @@ -149,27 +149,6 @@ ) end - it 'logs info about user with a verified by mail account' do - user = create(:user, :proofed_with_gpo) - create_account_reset_request_for(user) - grant_request(user) - session[:granted_token] = AccountResetRequest.first.granted_token - - delete :delete - - expect(@analytics).to have_logged_event( - 'Account Reset: delete', - user_id: user.uuid, - success: true, - errors: {}, - mfa_method_counts: { phone: 1 }, - profile_idv_level: 'legacy_unsupervised', - identity_verified: true, - account_age_in_days: 0, - account_confirmed_at: user.confirmed_at, - ) - end - it 'logs info about user verified in person proofed account' do user = create( :user,