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
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ GEM
pg (1.5.9)
pg_query (6.1.0)
google-protobuf (>= 3.25.3)
phonelib (0.10.7)
phonelib (0.10.8)
pkcs11 (0.3.4)
premailer (1.27.0)
addressable
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/concerns/idv/choose_id_type_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ def dos_passport_api_healthy?(
response.success?
end

def locals_attrs(analytics:, presenter:, url_for: nil)
def locals_attrs(analytics:, presenter:, form_submit_url: nil)
dos_passport_api_down = !dos_passport_api_healthy?(analytics:)
{
presenter:,
url_for:,
form_submit_url:,
dos_passport_api_down:,
auto_check_value: dos_passport_api_down ? :drivers_license : selected_id_type,
}
Expand Down
8 changes: 8 additions & 0 deletions app/controllers/concerns/idv/phone_otp_rate_limitable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,19 @@ def reset_attempt_count_if_user_no_longer_locked_out

def handle_too_many_otp_sends
analytics.idv_phone_confirmation_otp_rate_limit_sends
# TODO: Attempts API PII phone_number: current_user.phone
attempts_api_tracker.idv_rate_limited(
limiter_type: :phone_otp,
)
handle_max_attempts('otp_requests')
end

def handle_too_many_otp_attempts
analytics.idv_phone_confirmation_otp_rate_limit_attempts
# TODO: Attempts API PII phone_number: current_user.phone
attempts_api_tracker.idv_rate_limited(
limiter_type: :phone_otp,
)
handle_max_attempts('otp_login_attempts')
end

Expand Down
20 changes: 2 additions & 18 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,9 @@ def idv_failure(result)
)

if ssn_rate_limiter.limited?
idv_failure_log_rate_limited(:proof_ssn)
redirect_to idv_session_errors_ssn_failure_url
rate_limit_redirect!(:proof_ssn, step_name: STEP_NAME)
elsif resolution_rate_limiter.limited?
idv_failure_log_rate_limited(:idv_resolution)
redirect_to rate_limited_url
rate_limit_redirect!(:idv_resolution, step_name: STEP_NAME)
elsif has_exception && is_mva_exception
idv_failure_log_warning
redirect_to state_id_warning_url
Expand All @@ -147,20 +145,6 @@ def idv_failure(result)
end
end

def idv_failure_log_rate_limited(rate_limit_type)
if rate_limit_type == :proof_ssn
analytics.rate_limit_reached(
limiter_type: :proof_ssn,
step_name: STEP_NAME,
)
elsif rate_limit_type == :idv_resolution
analytics.rate_limit_reached(
limiter_type: :idv_resolution,
step_name: STEP_NAME,
)
end
end

def idv_failure_log_error
analytics.idv_doc_auth_exception_visited(
step_name: STEP_NAME,
Expand Down
8 changes: 6 additions & 2 deletions app/controllers/concerns/rate_limit_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def confirm_not_rate_limited_after_doc_auth
end

def confirm_not_rate_limited_for_phone_address_verification
# TODO: Attempts API PII add phone number
if idv_attempter_rate_limited?(:proof_address)
rate_limit_redirect!(:proof_address)
return true
Expand All @@ -44,12 +45,15 @@ def confirm_not_rate_limited_for_phone_and_letter_address_verification
if idv_attempter_rate_limited?(:proof_address) && gpo_verify_by_mail_policy.rate_limited?
rate_limit_redirect!(:proof_address)
return true
elsif idv_attempter_rate_limited?(:proof_address) || gpo_verify_by_mail_policy.rate_limited?
attempts_api_tracker.idv_rate_limited(limiter_type: :proof_address)
end
end

def rate_limit_redirect!(rate_limit_type)
def rate_limit_redirect!(rate_limit_type, step_name: nil)
if idv_attempter_rate_limited?(rate_limit_type)
analytics.rate_limit_reached(limiter_type: rate_limit_type)
analytics.rate_limit_reached(limiter_type: rate_limit_type, step_name:)
attempts_api_tracker.idv_rate_limited(limiter_type: rate_limit_type)
rate_limited_redirect(rate_limit_type)
return true
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ def index
analytics.rate_limit_reached(
limiter_type: :verify_gpo_key,
)
attempts_api_tracker.idv_rate_limited(
limiter_type: :verify_gpo_key,
)

@expires_at = rate_limiter.expires_at
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/choose_id_type_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def show
locals: locals_attrs(
analytics:,
presenter: Idv::ChooseIdTypePresenter.new,
url_for: idv_choose_id_type_path,
form_submit_url: idv_choose_id_type_path,
),
layout: true
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def self.step_info
Idv::StepInfo.new(
key: :document_capture,
controller: self,
next_steps: [:ssn, :ipp_state_id],
next_steps: [:ssn, :ipp_state_id, :ipp_choose_id_type],
preconditions: ->(idv_session:, user:) {
idv_session.flow_path == 'standard' && (
# mobile
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/idv/hybrid_handoff_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ def rate_limited_failure
analytics.rate_limit_reached(
limiter_type: :idv_send_link,
)
# TODO: Attempts API PII Add phone_number: formatted_destination_phone,
attempts_api_tracker.idv_rate_limited(
limiter_type: :idv_send_link,
)
message = I18n.t(
'doc_auth.errors.send_link_limited',
timeout: distance_of_time_in_words(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def show
locals: locals_attrs(
analytics:,
presenter: Idv::HybridMobile::ChooseIdTypePresenter.new,
url_for: idv_hybrid_mobile_choose_id_type_path,
form_submit_url: idv_hybrid_mobile_choose_id_type_path,
)
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/idv/image_uploads_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ def image_upload_form
@image_upload_form ||= Idv::ApiImageUploadForm.new(
params,
acuant_sdk_upgrade_ab_test_bucket: ab_test_bucket(:ACUANT_SDK),
analytics:,
attempts_api_tracker:,
service_provider: current_sp,
analytics: analytics,
uuid_prefix: current_sp&.app_id,
liveness_checking_required: resolved_authn_context_result.facial_match?,
)
Expand Down
51 changes: 48 additions & 3 deletions app/controllers/idv/in_person/choose_id_type_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,48 @@ def show
analytics.idv_in_person_proofing_choose_id_type_visited(**analytics_arguments)

render 'idv/shared/choose_id_type',
locals: locals_attrs(analytics:, presenter: Idv::InPerson::ChooseIdTypePresenter.new),
locals: locals_attrs(
analytics:,
presenter: Idv::InPerson::ChooseIdTypePresenter.new,
form_submit_url: idv_in_person_choose_id_type_url,
),
layout: true
end

def update
clear_future_steps!

form = Idv::ChooseIdTypeForm.new
result = form.submit(allowed_params)

analytics.idv_in_person_proofing_choose_id_type_submitted(
**analytics_arguments
.merge(**result.to_h)
.merge(chosen_id_type: form.chosen_id_type),
)

if result.success?
set_chosen_id_type
redirect_to chosen_id_type_url(form.chosen_id_type)
else
redirect_to idv_in_person_choose_id_type_url
end
end

def self.step_info
Idv::StepInfo.new(
key: :ipp_choose_id_type,
controller: self,
next_steps: [],
next_steps: [:ipp_state_id],
preconditions: ->(idv_session:, user:) {
idv_session.in_person_passports_allowed? && user.has_establishing_in_person_enrollment?
},
undo_step: -> {},
undo_step: ->(idv_session:, user:) do
if idv_session.document_capture_session_uuid
DocumentCaptureSession.find_by(uuid: idv_session.document_capture_session_uuid)
&.update!(passport_status: idv_session.passport_allowed ? 'allowed' : nil)
end
end,
)
end

Expand All @@ -40,4 +66,23 @@ def analytics_arguments
}.merge(ab_test_analytics_buckets)
.merge(extra_analytics_properties)
end

def allowed_params
choose_id_type_form_params
end

def chosen_id_type_url(type)
id_type_to_route_url[type]
end

def id_type_to_route_url
{
'passport' => idv_in_person_passport_url,
'drivers_license' => idv_in_person_state_id_url,
}
end

def set_chosen_id_type
set_passport_requested
end
end
6 changes: 6 additions & 0 deletions app/controllers/idv/in_person/passport_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

class Idv::InPerson::PassportController < ApplicationController
def show
end
end
5 changes: 3 additions & 2 deletions app/controllers/idv/phone_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ def handle_proofing_failure

def step
@step ||= Idv::PhoneStep.new(
idv_session: idv_session,
idv_session:,
trace_id: amzn_trace_id,
analytics: analytics,
analytics:,
attempts_api_tracker:,
)
end

Expand Down
8 changes: 8 additions & 0 deletions app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ def handle_valid_authentication
user_session[:platform_authenticator_available] =
params[:platform_authenticator_available] == 'true'
check_password_compromised
check_for_duplicate_profiles
redirect_to next_url_after_valid_authentication
end

Expand Down Expand Up @@ -311,6 +312,13 @@ def check_password_compromised
update_user_password_compromised_checked_at
end

def check_for_duplicate_profiles
DuplicateProfileChecker.new(
user: current_user,
user_session: user_session, sp: sp_from_sp_session
).check_for_duplicate_profiles
end

def eligible_for_password_lookup?
FeatureManagement.check_password_enabled? &&
randomize_check_password?
Expand Down
13 changes: 11 additions & 2 deletions app/forms/idv/api_image_upload_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ def initialize(
service_provider:,
acuant_sdk_upgrade_ab_test_bucket:,
analytics: nil,
attempts_api_tracker: nil,
uuid_prefix: nil,
liveness_checking_required: false
)
@params = params
@service_provider = service_provider
@acuant_sdk_upgrade_ab_test_bucket = acuant_sdk_upgrade_ab_test_bucket
@analytics = analytics
@attempts_api_tracker = attempts_api_tracker
@readable = {}
@uuid_prefix = uuid_prefix
@liveness_checking_required = liveness_checking_required
Expand Down Expand Up @@ -70,8 +72,14 @@ def submit

private

attr_reader :params, :analytics, :service_provider, :form_response, :uuid_prefix,
:liveness_checking_required, :acuant_sdk_upgrade_ab_test_bucket
attr_reader :acuant_sdk_upgrade_ab_test_bucket,
:analytics,
:attempts_api_tracker,
:form_response,
:liveness_checking_required,
:params,
:service_provider,
:uuid_prefix

def abandon_any_ipp_progress
user_id && User.find(user_id).establishing_in_person_enrollment&.cancel
Expand Down Expand Up @@ -358,6 +366,7 @@ def limit_if_rate_limited

def track_rate_limited
analytics.rate_limit_reached(limiter_type: :idv_doc_auth)
attempts_api_tracker.idv_rate_limited(limiter_type: :idv_doc_auth)
end

def document_capture_session_uuid
Expand Down
1 change: 0 additions & 1 deletion app/jobs/reports/api_transaction_count_report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ def perform(date = Time.zone.yesterday.end_of_day)
end

ReportMailer.tables_report(
title: 'API Transaction Count Report',
email: email_addresses,
subject: "API Transaction Count Report - #{report_date.to_date}",
reports: reports,
Expand Down
33 changes: 33 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3115,6 +3115,39 @@ def idv_in_person_proofing_address_visited(
)
end

# @param [Boolean] success
# @param ["hybrid","standard"] flow_path Document capture user flow
# @param [String] step Current IdV step
# @param [String] analytics_id Current IdV flow identifier
# @param ['drivers_license', 'passport'] chosen_id_type Chosen id type of the user
# @param [Boolean] opted_in_to_in_person_proofing Whether user opted into in person proofing
# @param [Boolean] skip_hybrid_handoff Whether skipped hybrid handoff A/B test is active
# @param [Hash] error_details
def idv_in_person_proofing_choose_id_type_submitted(
success:,
flow_path:,
step:,
analytics_id:,
chosen_id_type:,
opted_in_to_in_person_proofing: nil,
skip_hybrid_handoff: nil,
error_details: nil,
**extra
)
track_event(
:idv_in_person_proofing_choose_id_type_submitted,
success:,
flow_path:,
step:,
analytics_id:,
chosen_id_type:,
opted_in_to_in_person_proofing:,
skip_hybrid_handoff:,
error_details:,
**extra,
)
end

# @param ["hybrid","standard"] flow_path Document capture user flow
# @param [String] step Current IdV step
# @param [String] analytics_id
Expand Down
11 changes: 11 additions & 0 deletions app/services/attempts_api/tracker_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ def idv_reproof
track_event('idv-reproof')
end

# The user has exceeded the rate limit during idv document upload
# @param limiter_type [String<'idv_doc_auth', 'idv_resolution', 'proof_ssn', 'proof_address',
# 'confirmation', 'idv_send_link']
# Type of rate limit
def idv_rate_limited(limiter_type:)
track_event(
'idv-rate-limited',
limiter_type:,
)
end

# @param [Boolean] success True if account successfully deleted
# A User deletes their Login.gov account
def logged_in_account_purged(success:)
Expand Down
4 changes: 2 additions & 2 deletions app/services/doc_auth/dos/requests/mrz_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ def request_headers
{
'Content-Type': 'application/json',
'X-Correlation-ID': correlation_id,
client_id: IdentityConfig.store.dos_passport_client_id,
client_secret: IdentityConfig.store.dos_passport_client_secret,
'Client-Id': IdentityConfig.store.dos_passport_client_id,
'Client-Secret': IdentityConfig.store.dos_passport_client_secret,
}
end

Expand Down
Loading