Skip to content
19 changes: 19 additions & 0 deletions app/controllers/api/attempts/certs_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Api
module Attempts
class CertsController < ApplicationController
prepend_before_action :skip_session_load
prepend_before_action :skip_session_expiration
skip_before_action :disable_caching

JSON = AttemptsApiCertsPresenter.new.certs.freeze

def index
expires_in 1.week, public: true

render json: JSON
end
end
end
end
12 changes: 10 additions & 2 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def fix_broken_personal_key_url
def after_sign_in_path_for(_user)
return rules_of_use_path if !current_user.accepted_rules_of_use_still_valid?
return user_please_call_url if current_user.suspended?
return duplicate_profiles_detected_url if user_duplicate_profiles_detected?
return manage_password_url if session[:redirect_to_change_password].present?
return authentication_methods_setup_url if user_needs_sp_auth_method_setup?
return fix_broken_personal_key_url if current_user.broken_personal_key?
Expand All @@ -259,7 +260,6 @@ def after_sign_in_path_for(_user)
return login_piv_cac_recommended_path if user_recommended_for_piv_cac?
return second_mfa_reminder_url if user_needs_second_mfa_reminder?
return backup_code_reminder_url if user_needs_backup_code_reminder?
return duplicate_profiles_detected_url if user_duplicate_profiles_detected?
return sp_session_request_url_with_updated_params if sp_session.key?(:request_url)
signed_in_url
end
Expand Down Expand Up @@ -547,7 +547,10 @@ def user_duplicate_profiles_detected?
profile = current_user&.active_profile
return false unless profile
return false unless user_in_one_account_verification_bucket?
user_session[:duplicate_profile_ids].present?
DuplicateProfile.involving_profile(
profile_id: profile.id,
service_provider: current_sp&.issuer,
).present?
end

def sp_eligible_for_one_account?
Expand All @@ -560,4 +563,9 @@ def handle_banned_user
sign_out
redirect_to banned_user_url
end

def handle_duplicate_profile_user
return unless user_duplicate_profiles_detected?
redirect_to duplicate_profiles_detected_url
end
end
12 changes: 10 additions & 2 deletions app/controllers/concerns/idv/choose_id_type_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ def chosen_id_type

def set_passport_requested
if chosen_id_type == 'passport'
document_capture_session.update!(passport_status: 'requested')
unless document_capture_session.passport_requested?
document_capture_session.update!(
passport_status: 'requested',
doc_auth_vendor: nil,
)
end
else
document_capture_session.update!(passport_status: 'not_requested')
document_capture_session.update!(
passport_status: 'not_requested',
doc_auth_vendor: nil,
)
end
end

Expand Down
77 changes: 41 additions & 36 deletions app/controllers/concerns/idv/doc_auth_vendor_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,6 @@ module Idv
module DocAuthVendorConcern
include AbTestingConcern

# @returns[String] String identifying the vendor to use for doc auth.
def doc_auth_vendor
idv_session.bucketed_doc_auth_vendor ||= begin
bucket = nil
if socure_user_set.maxed_users?
bucket = choose_non_socure_bucket
elsif resolved_authn_context_result.facial_match?
bucket = ab_test_bucket(:DOC_AUTH_SELFIE_VENDOR)
elsif idv_session.passport_allowed
bucket = ab_test_bucket(:DOC_AUTH_PASSPORT_VENDOR)
else
bucket = ab_test_bucket(:DOC_AUTH_VENDOR)
end

if bucket == :socure
if !add_user_to_socure_set
bucket = choose_non_socure_bucket # force to lexis_nexis if max user reached
end
end

DocAuthRouter.doc_auth_vendor_for_bucket(
bucket,
selfie: resolved_authn_context_result.facial_match?,
passport_allowed: idv_session.passport_allowed,
)
end
end

def doc_auth_vendor_enabled?(vendor)
return true if IdentityConfig.store.doc_auth_vendor_default == vendor
return false unless IdentityConfig.store.doc_auth_vendor_switching_enabled
Expand Down Expand Up @@ -60,6 +32,12 @@ def doc_auth_selfie_vendor_enabled?(vendor)
end
end

def update_doc_auth_vendor(user: current_user)
if document_capture_session.doc_auth_vendor.blank?
document_capture_session.update!(doc_auth_vendor: bucketed_doc_auth_vendor(user))
end
end

private

def choose_non_socure_bucket
Expand All @@ -74,17 +52,44 @@ def socure_user_set
@socure_user_set ||= SocureUserSet.new
end

def add_user_to_socure_set
uuid = current_user&.uuid
if uuid.nil? && defined?(document_capture_user)
uuid = document_capture_user&.uuid
end

if uuid
return socure_user_set.add_user!(user_uuid: uuid)
def add_user_to_socure_set(user)
if user&.uuid
return socure_user_set.add_user!(user_uuid: user.uuid)
end

false
end

# @returns[String] String identifying the vendor to use for doc auth.
def bucketed_doc_auth_vendor(user)
@bucketed_doc_auth_vendor ||= begin
bucket = nil
if socure_user_set.maxed_users?
bucket = choose_non_socure_bucket
elsif resolved_authn_context_result.facial_match?
if document_capture_session.passport_requested?
bucket = choose_non_socure_bucket
else
bucket = ab_test_bucket(:DOC_AUTH_SELFIE_VENDOR, user:)
end
elsif document_capture_session.passport_requested?
bucket = ab_test_bucket(:DOC_AUTH_PASSPORT_VENDOR, user:)
else
bucket = ab_test_bucket(:DOC_AUTH_VENDOR, user:)
end

if bucket == :socure
if !add_user_to_socure_set(user)
bucket = choose_non_socure_bucket # force to lexis_nexis if max user reached
end
end

DocAuthRouter.doc_auth_vendor_for_bucket(
bucket,
selfie: resolved_authn_context_result.facial_match?,
passport_requested: document_capture_session.passport_requested?,
)
end
end
end
end
4 changes: 0 additions & 4 deletions app/controllers/concerns/idv/document_capture_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,6 @@ def track_document_request_event(document_request:, document_response:, timer:)
analytics.idv_socure_document_request_submitted(**analytics_hash)
end

def choose_id_type_path
idv_choose_id_type_path
end

def doc_auth_upload_enabled?
# false for now until we consolidate this method with desktop_selfie_test_mode_enabled
false
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ def async_state_done(current_async_state)
[:errors, :ssn],
[:errors, :state_id_jurisdiction],
[:proofing_results, :context, :stages, :resolution, :errors, :ssn],
[:proofing_results, :context, :stages, :resolution, :reason_codes],
[:proofing_results, :context, :stages, :residential_address, :errors, :ssn],
[:proofing_results, :context, :stages, :threatmetrix, :response_body, :first_name],
[:proofing_results, :context, :stages, :state_id, :state_id_jurisdiction],
Expand Down Expand Up @@ -234,8 +235,7 @@ def async_state_done(current_async_state)

def next_step_url
return idv_request_letter_url if FeatureManagement.idv_by_mail_only? ||
idv_session.gpo_request_letter_visited ||
idv_session.gpo_letter_requested
idv_session.gpo_request_letter_visited
idv_phone_url
end

Expand Down
19 changes: 17 additions & 2 deletions app/controllers/concerns/idv_step_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,32 @@ def confirm_hybrid_handoff_needed
if params[:redo]
idv_session.redo_document_capture = true
end

# If we previously skipped hybrid handoff, keep doing that.
# If hybrid flow is unavailable, skip it.
# But don't store that we skipped it in idv_session, in case it is back to
# available when the user tries to redo document capture.
if idv_session.skip_hybrid_handoff? || !FeatureManagement.idv_allow_hybrid_flow?
idv_session.flow_path = 'standard'
redirect_to vendor_document_capture_url

if in_person_proofing_route_enabled?
redirect_to idv_how_to_verify_url
elsif idv_session.passport_allowed
redirect_to idv_choose_id_type_url
else
redirect_to vendor_document_capture_url
end
end
end

def in_person_proofing_route_enabled?
IdentityConfig.store.in_person_proofing_enabled &&
IdentityConfig.store.in_person_proofing_opt_in_enabled &&
IdentityConfig.store.in_person_doc_auth_button_enabled &&
Idv::InPersonConfig.enabled_for_issuer?(
decorated_sp_session.sp_issuer,
)
end

def vendor_document_capture_url
case document_capture_session.doc_auth_vendor
when Idp::Constants::Vendors::SOCURE,
Expand Down
32 changes: 13 additions & 19 deletions app/controllers/duplicate_profiles_detected_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,44 +6,38 @@ class DuplicateProfilesDetectedController < ApplicationController

def show
@dupe_profiles_detected_presenter = DuplicateProfilesDetectedPresenter.new(
user: current_user, user_session: user_session,
user: current_user,
dupe_profile: dupe_profile,
)
notify_users_of_duplicate_profile_sign_in
analytics.one_account_duplicate_profiles_detected
end

def do_not_recognize_profiles
analytics.one_account_unknown_profile_detected

user_session.delete(:duplicate_profile_ids)

redirect_to after_sign_in_path_for(current_user)
end

def recognize_all_profiles
analytics.one_account_recognize_all_profiles

user_session.delete(:duplicate_profile_ids)
redirect_to after_sign_in_path_for(current_user)
end

private

def redirect_unless_user_has_active_duplicate_profile_confirmation
if current_user&.active_profile.present?
if user_session[:duplicate_profile_ids].present?
if dupe_profile.present?
return
end
end
redirect_to root_url
end

def dupe_profile
@dupe_profile ||= DuplicateProfile.involving_profile(
profile_id: current_user.active_profile.id,
service_provider: current_sp&.issuer,
)
end

def notify_users_of_duplicate_profile_sign_in
return unless user_session[:duplicate_profile_ids].present?
return unless dupe_profile
return if user_session[:dupe_profiles_notified]
agency_name = current_sp.friendly_name || current_sp.agency&.name

user_session[:duplicate_profile_ids].each do |profile_id|
dupe_profile.profile_ids.each do |profile_id|
next if current_user.active_profile.id == profile_id
profile = Profile.find(profile_id)
AlertUserDuplicateProfileDiscoveredJob.perform_later(
user: profile.user,
Expand Down
8 changes: 3 additions & 5 deletions app/controllers/idv/address_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ def new

@address_form = build_address_form
@presenter = AddressPresenter.new(
gpo_request_letter_visited: idv_session.gpo_request_letter_visited ||
idv_session.gpo_letter_requested,
gpo_request_letter_visited: idv_session.gpo_request_letter_visited,
address_update_request: address_update_request?,
)
end
Expand Down Expand Up @@ -81,8 +80,7 @@ def success

def failure
@presenter = AddressPresenter.new(
gpo_request_letter_visited: idv_session.gpo_request_letter_visited ||
idv_session.gpo_letter_requested,
gpo_request_letter_visited: idv_session.gpo_request_letter_visited,
address_update_request: address_update_request?,
)
render :new
Expand Down Expand Up @@ -119,7 +117,7 @@ def profile_params
end

def step_indicator_steps
if idv_session.gpo_request_letter_visited || idv_session.gpo_letter_requested
if idv_session.gpo_request_letter_visited
return StepIndicatorConcern::STEP_INDICATOR_STEPS_GPO
end

Expand Down
27 changes: 3 additions & 24 deletions app/controllers/idv/agreement_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,10 @@ def update

if result.success?
idv_session.idv_consent_given_at = Time.zone.now
idv_session.opted_in_to_in_person_proofing = false
idv_session.skip_doc_auth_from_how_to_verify = false

if params[:skip_hybrid_handoff]
if in_person_proofing_route_enabled?
redirect_to idv_how_to_verify_url
elsif idv_session.passport_allowed
idv_session.opted_in_to_in_person_proofing = false
idv_session.skip_doc_auth_from_how_to_verify = false
redirect_to idv_choose_id_type_url
else
redirect_to idv_how_to_verify_url
end
else
idv_session.opted_in_to_in_person_proofing = false
idv_session.skip_doc_auth_from_how_to_verify = false
redirect_to idv_hybrid_handoff_url
end
redirect_to idv_hybrid_handoff_url
else
render :show
end
Expand Down Expand Up @@ -85,15 +73,6 @@ def analytics_arguments
}.merge(ab_test_analytics_buckets)
end

def in_person_proofing_route_enabled?
IdentityConfig.store.in_person_proofing_enabled &&
IdentityConfig.store.in_person_proofing_opt_in_enabled &&
IdentityConfig.store.in_person_doc_auth_button_enabled &&
Idv::InPersonConfig.enabled_for_issuer?(
decorated_sp_session.sp_issuer,
)
end

def skip_to_capture
idv_session.flow_path = 'standard'

Expand Down
1 change: 0 additions & 1 deletion app/controllers/idv/by_mail/request_letter_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def index
Funnel::DocAuth::RegisterStep.new(current_user.id, current_sp&.issuer)
.call(:usps_address, :view, true)
idv_session.gpo_request_letter_visited = true
idv_session.gpo_letter_requested = true
analytics.idv_request_letter_visited
end

Expand Down
Loading