Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
42de237
LG-10330 Make i18N into own Package (#9192)
gina-yamada Sep 13, 2023
89a7cac
Create 30,60,90-day lookback proofing rate report (LG-10621) (#9186)
n1zyy Sep 14, 2023
4f0ad04
Revert "LG-10886 remove ssn from flow session (#9182)" (#9209)
aduth Sep 14, 2023
54ae544
Require recent authentication before deleting account (#9183)
Sep 14, 2023
446f114
LG-10530: Officially turn on new GPO routes (#9184)
matthinz Sep 14, 2023
3af6cde
Add Industry Rate to Proofing Rate Report (LG-10621) (#9203)
zachmargolis Sep 14, 2023
fe1dafa
Add additional parallellism to ProofingRateReport (#9212)
zachmargolis Sep 14, 2023
a7ed678
Try replacing NewRelic browser instrumentation with custom error hand…
aduth Sep 14, 2023
5bd3926
Remove NewRelic domains from CSP (#9216)
aduth Sep 15, 2023
3387240
Upgrade NewRelic gem (#9205)
Sep 15, 2023
e486b44
Add logging to debug ssn 50/50 state issue. (#9215)
soniaconnolly Sep 15, 2023
bd65c56
LG-11014: Log created at for latest WebAuthn config for failed attemp…
aduth Sep 15, 2023
0fcc3a7
Fix JavaScript dead code elimination (#9217)
aduth Sep 15, 2023
f534ffe
Remove password toggle click frontend event (#9218)
aduth Sep 15, 2023
45be3c0
Jmax/lg 10682 only one gpo letter per day (#9189)
jmax-gsa Sep 15, 2023
91ec809
Fix identity verification session error tests to use the correct rate…
Sep 15, 2023
e6614e7
Do not consider a rate limit expired if there is no value (#9221)
Sep 15, 2023
a196093
Update CI image SHA (#9227)
Sep 18, 2023
5d7aa45
Merge branch 'stages/prod' into stages/rc-2023-09-18
Sep 18, 2023
7d82009
Finish removing ssn from flow session (revert the revert) (#9229)
soniaconnolly Sep 18, 2023
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
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ gem 'msgpack', '~> 1.6'
gem 'maxminddb'
gem 'multiset'
gem 'net-sftp'
gem 'newrelic_rpm', '~> 8.0'
gem 'newrelic_rpm', '~> 9.0'
gem 'puma', '~> 5.6.7'
gem 'pg'
gem 'phonelib'
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ GEM
net-smtp (0.3.3)
net-protocol
net-ssh (6.1.0)
newrelic_rpm (8.15.0)
newrelic_rpm (9.5.0)
nio4r (2.5.9)
nokogiri (1.14.5)
mini_portile2 (~> 2.8.0)
Expand Down Expand Up @@ -770,7 +770,7 @@ DEPENDENCIES
msgpack (~> 1.6)
multiset
net-sftp
newrelic_rpm (~> 8.0)
newrelic_rpm (~> 9.0)
nokogiri (~> 1.14.0)
pg
pg_query
Expand Down
12 changes: 5 additions & 7 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def shared_update
# TEMPORARY DEBUGGING
logger.info("ResolutionJobDebug: user_uuid=#{current_user.uuid} old=#{pii[:ssn].present?} new=#{idv_session.ssn.present?} controller=#{self.class.name}")
# rubocop:enable Layout/LineLength
pii[:ssn] ||= idv_session.ssn # Required for proof_resolution job
pii[:ssn] = idv_session.ssn # Required for proof_resolution job
Idv::Agent.new(pii).proof_resolution(
document_capture_session,
should_proof_state_id: should_use_aamva?(pii),
Expand Down Expand Up @@ -74,9 +74,8 @@ def resolution_rate_limiter
end

def ssn_rate_limiter
ssn = idv_session.ssn || pii[:ssn]
@ssn_rate_limiter ||= RateLimiter.new(
target: Pii::Fingerprinter.fingerprint(ssn),
target: Pii::Fingerprinter.fingerprint(idv_session.ssn),
rate_limit_type: :proof_ssn,
)
end
Expand Down Expand Up @@ -306,19 +305,18 @@ def log_idv_verification_submitted_event(success: false, failure_reason: nil)
last_name: pii_from_doc[:last_name],
date_of_birth: pii_from_doc[:dob],
address: pii_from_doc[:address1],
ssn: idv_session.ssn || pii_from_doc[:ssn],
ssn: idv_session.ssn,
failure_reason: failure_reason,
)
end

def check_ssn
ssn = idv_session.ssn || pii[:ssn]
Idv::SsnForm.new(current_user).submit(ssn: ssn)
Idv::SsnForm.new(current_user).submit(ssn: idv_session.ssn)
end

def move_applicant_to_idv_session
idv_session.applicant = pii
idv_session.applicant[:ssn] ||= idv_session.ssn
idv_session.applicant[:ssn] = idv_session.ssn
idv_session.applicant['uuid'] = current_user.uuid
delete_pii
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/concerns/idv_step_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def flow_path
private

def confirm_ssn_step_complete
return if pii.present? && (idv_session.ssn.present? || pii[:ssn].present?)
return if pii.present? && idv_session.ssn.present?
redirect_to prev_url
end

Expand Down
6 changes: 2 additions & 4 deletions app/controllers/concerns/rate_limit_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ def idv_attempter_rate_limited?(rate_limit_type)
end

def pii_ssn
return unless defined?(flow_session) && defined?(idv_session) && user_session
pii_from_doc_ssn = idv_session&.ssn || flow_session[:pii_from_doc]&.[](:ssn)
return pii_from_doc_ssn if pii_from_doc_ssn
flow_session[:pii_from_user]&.[](:ssn)
return unless defined?(idv_session) && user_session
idv_session&.ssn
end
end
4 changes: 2 additions & 2 deletions app/controllers/frontend_log_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class FrontendLogController < ApplicationController
# Please try to keep this list alphabetical as well!
# rubocop:disable Layout/LineLength
EVENT_MAP = {
'Frontend Error' => FrontendErrorLogger.method(:track_error),
'IdV: consent checkbox toggled' => :idv_consent_checkbox_toggled,
'IdV: download personal key' => :idv_personal_key_downloaded,
'IdV: location submitted' => :idv_in_person_location_submitted,
Expand All @@ -26,11 +27,10 @@ class FrontendLogController < ApplicationController
'IdV: user clicked what to bring link on ready to verify page' => :idv_in_person_ready_to_verify_what_to_bring_link_clicked,
'IdV: verify in person troubleshooting option clicked' => :idv_verify_in_person_troubleshooting_option_clicked,
'Multi-Factor Authentication: download backup code' => :multi_factor_auth_backup_code_download,
'Show Password button clicked' => :show_password_button_clicked,
'Sign In: IdV requirements accordion clicked' => :sign_in_idv_requirements_accordion_clicked,
'User prompted before navigation' => :user_prompted_before_navigation,
'User prompted before navigation and still on page' => :user_prompted_before_navigation_and_still_on_page,
}.transform_values { |method| AnalyticsEvents.instance_method(method) }.freeze
}.freeze
# rubocop:enable Layout/LineLength

def create
Expand Down
250 changes: 126 additions & 124 deletions app/controllers/idv/by_mail/enter_code_controller.rb
Original file line number Diff line number Diff line change
@@ -1,155 +1,157 @@
module Idv::ByMail
class EnterCodeController < ApplicationController
include IdvSession
include Idv::StepIndicatorConcern
include FraudReviewConcern

prepend_before_action :note_if_user_did_not_receive_letter
before_action :confirm_two_factor_authenticated
before_action :confirm_verification_needed

def index
# GPO reminder emails include an "I did not receive my letter!" link that results in
# slightly different copy on this screen.
@user_did_not_receive_letter = !!params[:did_not_receive_letter]

analytics.idv_verify_by_mail_enter_code_visited(
source: if @user_did_not_receive_letter then 'gpo_reminder_email' end,
)

if rate_limiter.limited?
render_rate_limited
return
end

gpo_mail = Idv::GpoMail.new(current_user)
@gpo_verify_form = GpoVerifyForm.new(user: current_user, pii: pii)
@code = session[:last_gpo_confirmation_code] if FeatureManagement.reveal_gpo_code?

@should_prompt_user_to_request_another_letter =
FeatureManagement.gpo_verification_enabled? &&
!gpo_mail.mail_spammed? &&
!gpo_mail.profile_too_old?
module Idv
module ByMail
class EnterCodeController < ApplicationController
include IdvSession
include Idv::StepIndicatorConcern
include FraudReviewConcern

prepend_before_action :note_if_user_did_not_receive_letter
before_action :confirm_two_factor_authenticated
before_action :confirm_verification_needed

def index
# GPO reminder emails include an "I did not receive my letter!" link that results in
# slightly different copy on this screen.
@user_did_not_receive_letter = !!params[:did_not_receive_letter]

analytics.idv_verify_by_mail_enter_code_visited(
source: if @user_did_not_receive_letter then 'gpo_reminder_email' end,
)

if pii_locked?
redirect_to capture_password_url
else
render :index
if rate_limiter.limited?
render_rate_limited
return
end

gpo_mail = Idv::GpoMail.new(current_user)
@gpo_verify_form = GpoVerifyForm.new(user: current_user, pii: pii)
@code = session[:last_gpo_confirmation_code] if FeatureManagement.reveal_gpo_code?

@should_prompt_user_to_request_another_letter =
FeatureManagement.gpo_verification_enabled? &&
!gpo_mail.mail_spammed? &&
!gpo_mail.profile_too_old?

if pii_locked?
redirect_to capture_password_url
else
render :index
end
end
end

def pii
Pii::Cacher.new(current_user, user_session).fetch
end

def create
if rate_limiter.limited?
render_rate_limited
return
def pii
Pii::Cacher.new(current_user, user_session).fetch
end
rate_limiter.increment!

@gpo_verify_form = build_gpo_verify_form
def create
if rate_limiter.limited?
render_rate_limited
return
end
rate_limiter.increment!

result = @gpo_verify_form.submit
analytics.idv_verify_by_mail_enter_code_submitted(**result.to_h)
irs_attempts_api_tracker.idv_gpo_verification_submitted(
success: result.success?,
failure_reason: irs_attempts_api_tracker.parse_failure_reason(result),
)
@gpo_verify_form = build_gpo_verify_form

if !result.success?
flash[:error] = @gpo_verify_form.errors.first.message
redirect_to idv_verify_by_mail_enter_code_url
return
end
result = @gpo_verify_form.submit
analytics.idv_verify_by_mail_enter_code_submitted(**result.to_h)
irs_attempts_api_tracker.idv_gpo_verification_submitted(
success: result.success?,
failure_reason: irs_attempts_api_tracker.parse_failure_reason(result),
)

prepare_for_personal_key
if !result.success?
flash[:error] = @gpo_verify_form.errors.first.message
redirect_to idv_verify_by_mail_enter_code_url
return
end

redirect_to idv_personal_key_url
end
prepare_for_personal_key

private
redirect_to idv_personal_key_url
end

def pending_in_person_enrollment?
return false unless IdentityConfig.store.in_person_proofing_enabled
current_user.pending_in_person_enrollment.present?
end
private

def account_not_ready_to_be_activated?
fraud_check_failed? || pending_in_person_enrollment?
end
def pending_in_person_enrollment?
return false unless IdentityConfig.store.in_person_proofing_enabled
current_user.pending_in_person_enrollment.present?
end

def note_if_user_did_not_receive_letter
if !current_user && params[:did_not_receive_letter]
# Stash that the user didn't receive their letter.
# Once the authentication process completes, they'll be redirected to complete their
# GPO verification...
session[:gpo_user_did_not_receive_letter] = true
def account_not_ready_to_be_activated?
fraud_check_failed? || pending_in_person_enrollment?
end

if current_user && session.delete(:gpo_user_did_not_receive_letter)
# ...and we can pick things up here.
redirect_to idv_verify_by_mail_enter_code_path(did_not_receive_letter: 1)
def note_if_user_did_not_receive_letter
if !current_user && params[:did_not_receive_letter]
# Stash that the user didn't receive their letter.
# Once the authentication process completes, they'll be redirected to complete their
# GPO verification...
session[:gpo_user_did_not_receive_letter] = true
end

if current_user && session.delete(:gpo_user_did_not_receive_letter)
# ...and we can pick things up here.
redirect_to idv_verify_by_mail_enter_code_path(did_not_receive_letter: 1)
end
end
end

def prepare_for_personal_key
unless account_not_ready_to_be_activated?
event, _disavowal_token = create_user_event(:account_verified)
def prepare_for_personal_key
unless account_not_ready_to_be_activated?
event, _disavowal_token = create_user_event(:account_verified)

UserAlerts::AlertUserAboutAccountVerified.call(
user: current_user,
date_time: event.created_at,
sp_name: decorated_session.sp_name,
)
flash[:success] = t('account.index.verification.success')
end

idv_session.address_verification_mechanism = 'gpo'
idv_session.address_confirmed!
end

UserAlerts::AlertUserAboutAccountVerified.call(
def rate_limiter
@rate_limiter ||= RateLimiter.new(
user: current_user,
date_time: event.created_at,
sp_name: decorated_session.sp_name,
rate_limit_type: :verify_gpo_key,
)
flash[:success] = t('account.index.verification.success')
end

idv_session.address_verification_mechanism = 'gpo'
idv_session.address_confirmed!
end

def rate_limiter
@rate_limiter ||= RateLimiter.new(
user: current_user,
rate_limit_type: :verify_gpo_key,
)
end

def render_rate_limited
irs_attempts_api_tracker.idv_gpo_verification_rate_limited
analytics.rate_limit_reached(
limiter_type: :verify_gpo_key,
)
def render_rate_limited
irs_attempts_api_tracker.idv_gpo_verification_rate_limited
analytics.rate_limit_reached(
limiter_type: :verify_gpo_key,
)

@expires_at = rate_limiter.expires_at
render :rate_limited
end
@expires_at = rate_limiter.expires_at
render :rate_limited
end

def build_gpo_verify_form
GpoVerifyForm.new(
user: current_user,
pii: pii,
otp: params_otp,
)
end
def build_gpo_verify_form
GpoVerifyForm.new(
user: current_user,
pii: pii,
otp: params_otp,
)
end

def params_otp
params.require(:gpo_verify_form).permit(:otp)[:otp]
end
def params_otp
params.require(:gpo_verify_form).permit(:otp)[:otp]
end

def confirm_verification_needed
return if current_user.gpo_verification_pending_profile?
redirect_to account_url
end
def confirm_verification_needed
return if current_user.gpo_verification_pending_profile?
redirect_to account_url
end

def threatmetrix_enabled?
FeatureManagement.proofing_device_profiling_decisioning_enabled?
end
def threatmetrix_enabled?
FeatureManagement.proofing_device_profiling_decisioning_enabled?
end

def pii_locked?
!Pii::Cacher.new(current_user, user_session).exists_in_session?
def pii_locked?
!Pii::Cacher.new(current_user, user_session).exists_in_session?
end
end
end
end
Loading