Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4bbb95a
LG-9086: Preemptively refresh USPS auth tokens (#8035)
Mar 23, 2023
bffe423
Update weekly Cloudwatch specs for clarity (#8053)
zachmargolis Mar 23, 2023
1ba00c5
Remove parallel usage in setup and test commands (#8058)
Mar 23, 2023
1e03713
Do not return 500 for CSRF token failures for address search controll…
jack-ryan-nava-pbc Mar 23, 2023
7cd2770
LG-9118: Throttle phone verification on submit (#8028)
matthinz Mar 23, 2023
048b559
Update controller error catching to use case/when (#8061)
zachmargolis Mar 23, 2023
7681e81
Improve styling of partner alert content (#8057)
aduth Mar 23, 2023
c3105cc
Use existing Redis pool for Rack::Attack rate limiting (#8066)
Mar 23, 2023
fb439d8
Fix Content Security Policy errors when redirecting to service provid…
Mar 23, 2023
4a1eb8b
LG-8867: New page to inform user of GPO only (#8011)
solipet Mar 24, 2023
9ab5e95
Add automatic CSRF refresh on session keepalive (#8067)
aduth Mar 24, 2023
52e8769
Remove ETag middleware to disable ETag for all requests (#8069)
aduth Mar 24, 2023
fe86d34
LG-9219: Ignore parameter errors in NewRelic logging (#8070)
aduth Mar 24, 2023
fd7e3ee
Rescue external server errors in location search controllers to avoid…
Mar 24, 2023
f1daadd
Make SpinnerButton form-aware for invalid form submissions (#7803)
aduth Mar 24, 2023
e4d87ce
Change re-authentication to only require a second factor rather than …
Mar 24, 2023
7e7b99f
LG-9139: Support double address verification on address page (#8041)
eileen-nava Mar 24, 2023
0e55f6b
LG-9098 DocumentCaptureController#update, desktop flow, feature flagg…
soniaconnolly Mar 27, 2023
a264ccc
Indicate `ruby` location for `rbenv` instructions (#8018)
Mar 27, 2023
f3e58e2
migrate over bin/query-cloudwatch script: (#8075)
Sgtpluck Mar 27, 2023
2294ace
Update re-authentication logic when confirming user is authenticated …
Mar 27, 2023
5be3d48
Merge remote-tracking branch 'origin/stages/prod' into stages/rc-2023…
aduth Mar 27, 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
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ group :development, :test do
gem 'i18n-tasks', '~> 1.0'
gem 'knapsack'
gem 'nokogiri', '~> 1.14.0'
gem 'parallel_tests', '~> 3.8.0'
gem 'pg_query', require: false
gem 'pry-byebug'
gem 'pry-doc'
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,6 @@ GEM
openssl (> 2.0, < 3.1)
orm_adapter (0.5.0)
parallel (1.22.1)
parallel_tests (3.8.1)
parallel
parser (3.2.0.0)
ast (~> 2.4.1)
pg (1.4.5)
Expand Down Expand Up @@ -776,7 +774,6 @@ DEPENDENCIES
newrelic_rpm (~> 8.0)
nokogiri (~> 1.14.0)
octokit (>= 4.25.0)
parallel_tests (~> 3.8.0)
pg
pg_query
phonelib
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ browsers.json: yarn.lock .browserslistrc ## Generates browsers.json browser supp
yarn generate-browsers-json

test: export RAILS_ENV := test
test: $(CONFIG) ## Runs RSpec and yarn tests in parallel
bundle exec rake parallel:spec && yarn test
test: $(CONFIG) ## Runs RSpec and yarn tests
bundle exec rspec && yarn test

test_serial: export RAILS_ENV := test
test_serial: $(CONFIG) ## Runs RSpec and yarn tests serially
Expand Down
4 changes: 4 additions & 0 deletions app/assets/stylesheets/components/_alert.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@
transform: translateY(-50%);
}
}

.usa-alert__text > p:last-child {
margin-bottom: 0;
}
2 changes: 1 addition & 1 deletion app/components/vendor_outage_alert_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ def outages
end

def vendor_status
@vendor_status ||= VendorStatus.new
@vendor_status ||= OutageStatus.new
end
end
7 changes: 7 additions & 0 deletions app/controllers/concerns/api/csrf_token_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Api
module CsrfTokenConcern
def add_csrf_token_header_to_response
response.set_header('X-CSRF-Token', form_authenticity_token)
end
end
end
4 changes: 3 additions & 1 deletion app/controllers/concerns/idv/document_capture_concern.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module Idv
module DocumentCaptureConcern
def override_document_capture_step_csp
return if params[:step] != 'document_capture'
if !IdentityConfig.store.doc_auth_document_capture_controller_enabled
return if params[:step] != 'document_capture'
end

policy = current_content_security_policy
policy.connect_src(*policy.connect_src, 'us.acas.acuant.net')
Expand Down
10 changes: 10 additions & 0 deletions app/controllers/concerns/idv/step_utilities_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,15 @@ def irs_reproofing?
service_provider: current_sp,
).present?
end

def document_capture_session
@document_capture_session ||= DocumentCaptureSession.find_by(
uuid: flow_session[document_capture_session_uuid_key],
)
end

def document_capture_session_uuid_key
:document_capture_session_uuid
end
end
end
7 changes: 6 additions & 1 deletion app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,19 @@ def async_state_done(current_async_state)
move_applicant_to_idv_session
idv_session.mark_verify_info_step_complete!
idv_session.invalidate_steps_after_verify_info!
redirect_to idv_phone_url
redirect_to next_step_url
else
idv_session.invalidate_verify_info_step!
end

analytics.idv_doc_auth_verify_proofing_results(**form_response.to_h)
end

def next_step_url
return idv_gpo_url if OutageStatus.new.gpo_only?
idv_phone_url
end

def summarize_result_and_throttle_failures(summary_result)
if summary_result.success?
add_proofing_components
Expand Down
35 changes: 32 additions & 3 deletions app/controllers/concerns/reauthentication_required_concern.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
module ReauthenticationRequiredConcern
include MfaSetupConcern

def confirm_recently_authenticated
if IdentityConfig.store.reauthentication_for_second_factor_management_enabled
confirm_recently_authenticated_2fa
else
@reauthn = reauthn?
return unless user_signed_in?
return if recently_authenticated?

prompt_for_current_password
end
end

def confirm_recently_authenticated_2fa
@reauthn = reauthn?
return unless user_signed_in?
return if recently_authenticated?
return unless user_fully_authenticated?
non_remembered_device_authentication = user_session[:auth_method].present? &&
user_session[:auth_method] != 'remember_device'
return if recently_authenticated? && non_remembered_device_authentication
return if in_multi_mfa_selection_flow?

analytics.user_2fa_reauthentication_required(
auth_method: user_session[:auth_method],
authenticated_at: user_session[:authn_at],
)

prompt_for_current_password
prompt_for_second_factor
end

private
Expand All @@ -24,6 +46,13 @@ def prompt_for_current_password
redirect_to user_password_confirm_url
end

def prompt_for_second_factor
store_location(request.url)
user_session[:context] = 'reauthentication'

redirect_to login_two_factor_options_path(reauthn: true)
end

def factor_from_controller_name
{
# see LG-5701, translate these
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/concerns/remember_device_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ def save_remember_device_preference
end

def check_remember_device_preference
return unless UserSessionContext.authentication_or_reauthentication_context?(context)
if IdentityConfig.store.reauthentication_for_second_factor_management_enabled
return unless UserSessionContext.authentication_context?(context)
else
return unless UserSessionContext.authentication_or_reauthentication_context?(context)
end
return if remember_device_cookie.nil?
return unless remember_device_cookie.valid_for_user?(
user: current_user,
Expand Down
29 changes: 24 additions & 5 deletions app/controllers/idv/doc_auth_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,30 @@ def flow_session
end

def check_for_outage
if VendorStatus.new.any_ial2_vendor_outage?
session[:vendor_outage_redirect] = current_step
session[:vendor_outage_redirect_from_idv] = true
redirect_to vendor_outage_url
end
return if flow_session[:skip_vendor_outage]

return redirect_for_proofing_vendor_outage if OutageStatus.new.any_idv_vendor_outage?
return redirect_for_gpo_only if FeatureManagement.idv_gpo_only?
end

def redirect_for_proofing_vendor_outage
session[:vendor_outage_redirect] = current_step
session[:vendor_outage_redirect_from_idv] = true

redirect_to vendor_outage_url
end

def redirect_for_gpo_only
return redirect_to vendor_outage_url unless FeatureManagement.gpo_verification_enabled?

# During a phone outage, skip the hybrid handoff
# step and go straight to document upload
flow_session[:skip_upload_step] = true unless FeatureManagement.idv_allow_hybrid_flow?

session[:vendor_outage_redirect] = current_step
session[:vendor_outage_redirect_from_idv] = true

redirect_to idv_mail_only_warning_url
end
end
end
105 changes: 97 additions & 8 deletions app/controllers/idv/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,35 @@ class DocumentCaptureController < ApplicationController
include IdvSession
include StepIndicatorConcern
include StepUtilitiesConcern
include DocumentCaptureConcern

before_action :render_404_if_document_capture_controller_disabled
before_action :confirm_two_factor_authenticated
before_action :confirm_agreement_step_complete
before_action :override_document_capture_step_csp

def show
increment_step_counts

analytics.idv_doc_auth_document_capture_visited(**analytics_arguments)

Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).
call('document_capture', :view, true)

render :show, locals: extra_view_variables
end

def update
handle_stored_result

analytics.idv_doc_auth_document_capture_submitted(**analytics_arguments)

Funnel::DocAuth::RegisterStep.new(current_user.id, sp_session[:issuer]).
call('document_capture', :update, true)

redirect_to idv_ssn_url
end

def extra_view_variables
url_builder = ImageUploadPresignedUrlGenerator.new

Expand All @@ -33,7 +50,6 @@ def extra_view_variables
transaction_id: flow_session[:document_capture_session_uuid],
),
}.merge(
native_camera_ab_testing_variables,
acuant_sdk_upgrade_a_b_testing_variables,
in_person_cta_variant_testing_variables,
)
Expand All @@ -45,6 +61,12 @@ def render_404_if_document_capture_controller_disabled
render_not_found unless IdentityConfig.store.doc_auth_document_capture_controller_enabled
end

def confirm_agreement_step_complete
return if flow_session['Idv::Steps::AgreementStep']

redirect_to idv_doc_auth_url
end

def analytics_arguments
{
flow_path: flow_path,
Expand All @@ -65,13 +87,6 @@ def increment_step_counts
current_flow_step_counts['Idv::Steps::DocumentCaptureStep'] += 1
end

def native_camera_ab_testing_variables
{
acuant_sdk_upgrade_ab_test_bucket:
AbTests::ACUANT_SDK.bucket(flow_session[:document_capture_session_uuid]),
}
end

def acuant_sdk_upgrade_a_b_testing_variables
bucket = AbTests::ACUANT_SDK.bucket(flow_session[:document_capture_session_uuid])
testing_enabled = IdentityConfig.store.idv_acuant_sdk_upgrade_a_b_testing_enabled
Expand All @@ -97,5 +112,79 @@ def in_person_cta_variant_testing_variables
in_person_cta_variant_active: bucket,
}
end

def handle_stored_result
if stored_result&.success?
save_proofing_components
extract_pii_from_doc(stored_result, store_in_session: !hybrid_flow_mobile?)
else
extra = { stored_result_present: stored_result.present? }
failure(I18n.t('doc_auth.errors.general.network_error'), extra)
end
end

def stored_result
return @stored_result if defined?(@stored_result)
@stored_result = document_capture_session&.load_result
end

def save_proofing_components
return unless current_user

doc_auth_vendor = DocAuthRouter.doc_auth_vendor(
discriminator: flow_session[document_capture_session_uuid_key],
analytics: analytics,
)

component_attributes = {
document_check: doc_auth_vendor,
document_type: 'state_id',
}
ProofingComponent.create_or_find_by(user: current_user).update(component_attributes)
end

def hybrid_flow_mobile?
user_id_from_token.present?
end

def user_id_from_token
flow_session[:doc_capture_user_id]
end

# copied from doc_auth_base_step.rb
# @param [DocAuth::Response,
# DocumentCaptureSessionAsyncResult,
# DocumentCaptureSessionResult] response
def extract_pii_from_doc(response, store_in_session: false)
pii_from_doc = response.pii_from_doc.merge(
uuid: effective_user.uuid,
phone: effective_user.phone_configurations.take&.phone,
uuid_prefix: ServiceProvider.find_by(issuer: sp_session[:issuer])&.app_id,
)

flow_session[:had_barcode_read_failure] = response.attention_with_barcode?
if store_in_session
flow_session[:pii_from_doc] ||= {}
flow_session[:pii_from_doc].merge!(pii_from_doc)
idv_session.clear_applicant!
end
track_document_state(pii_from_doc[:state])
end

def track_document_state(state)
return unless IdentityConfig.store.state_tracking_enabled && state
doc_auth_log = DocAuthLog.find_by(user_id: current_user.id)
return unless doc_auth_log
doc_auth_log.state = state
doc_auth_log.save!
end

# copied from Flow::Failure module
def failure(message, extra = nil)
flow_session[:error_message] = message
form_response_params = { success: false, errors: { message: message } }
form_response_params[:extra] = extra unless extra.nil?
FormResponse.new(**form_response_params)
end
end
end
17 changes: 17 additions & 0 deletions app/controllers/idv/gpo_only_warning_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Idv
class GpoOnlyWarningController < ApplicationController
include IdvSession
include StepIndicatorConcern

before_action :confirm_two_factor_authenticated

def show
user_session['idv/doc_auth'][:skip_vendor_outage] = true
render :show, locals: { current_sp:, exit_url: }
end

def exit_url
current_sp&.return_to_sp_url || account_path
end
end
end
Loading