Skip to content

Commit

Permalink
Merge pull request #11778 from 18F/stages/rc-2025-01-21
Browse files Browse the repository at this point in the history
Deploy RC 445 to Production
  • Loading branch information
jmdembe authored Jan 21, 2025
2 parents d853850 + fabd0f7 commit e42909e
Show file tree
Hide file tree
Showing 75 changed files with 831 additions and 305 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ pinpoint_check_scheduled:
--channel "#login-appdev" \
--webhook "${SLACK_WEBHOOK}" \
--raise \
--text "$(printf "Pinpoint supported countries check in GitLab failed.\nBuild Results: ${CI_JOB_URL}.\nCheck results locally with 'make lint_country_dialing_codes'")""
--text "$(printf "Pinpoint supported countries check in GitLab failed.\nBuild Results: ${CI_JOB_URL}.\nCheck results locally with 'make lint_country_dialing_codes'")"
fi
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ gem 'cssbundling-rails'
gem 'devise', '~> 4.8'
gem 'dotiw', '>= 4.0.1'
gem 'faraday', '~> 2'
gem 'faker'
gem 'faraday-retry'
gem 'fugit'
gem 'foundation_emails'
Expand Down Expand Up @@ -129,6 +128,7 @@ end
group :test do
gem 'axe-core-rspec', '~> 4.2'
gem 'bundler-audit', require: false
gem 'faker'
gem 'simplecov', '~> 0.22.0', require: false
gem 'simplecov-cobertura'
gem 'simplecov_json_formatter'
Expand Down
13 changes: 7 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,18 @@ test_serial: export RAILS_ENV := test
test_serial: $(CONFIG) ## Runs RSpec and yarn tests serially
bundle exec rake spec && yarn test

tmp/$(HOST)-$(PORT).key tmp/$(HOST)-$(PORT).crt: ## Self-signed cert for local HTTPS development
tmp/$(HOST).key tmp/$(HOST).crt: ## Self-signed cert for local HTTPS development
mkdir -p tmp
openssl req \
-newkey rsa:2048 \
-x509 \
-sha256 \
-nodes \
-days 365 \
-subj "/C=US/ST=District of Columbia/L=Washington/O=GSA/OU=Login.gov/CN=$(HOST):$(PORT)" \
-keyout tmp/$(HOST)-$(PORT).key \
-out tmp/$(HOST)-$(PORT).crt
-subj "/C=US/ST=District of Columbia/L=Washington/O=GSA/OU=Login.gov/CN=$(HOST)" \
-addext "subjectAltName=IP:$(HOST)" \
-keyout tmp/$(HOST).key \
-out tmp/$(HOST).crt

run: browsers.json ## Runs the development server
foreman start -p $(PORT)
Expand All @@ -226,8 +227,8 @@ urn:
@echo "⚱️"
make run

run-https: tmp/$(HOST)-$(PORT).key tmp/$(HOST)-$(PORT).crt ## Runs the development server with HTTPS
HTTPS=on FOREMAN_HOST="ssl://$(HOST):$(PORT)?key=tmp/$(HOST)-$(PORT).key&cert=tmp/$(HOST)-$(PORT).crt" foreman start -p $(PORT)
run-https: tmp/$(HOST).key tmp/$(HOST).crt ## Runs the development server with HTTPS
HTTPS=on FOREMAN_HOST="ssl://$(HOST):$(PORT)?key=tmp/$(HOST).key&cert=tmp/$(HOST).crt" foreman start -p $(PORT)

normalize_yaml: ## Normalizes YAML files (alphabetizes keys, fixes line length, smart quotes)
yarn normalize-yaml .rubocop.yml --disable-sort-keys --disable-smart-punctuation
Expand Down
10 changes: 10 additions & 0 deletions app/assets/stylesheets/components/_step-indicator.scss
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,18 @@ lg-step-indicator {
position: relative;
text-align: center;

// In cases when browser text zoom is very high (i.e. the root font-size has
// been drastically increased), the step indicator will overflow the viewport
// by _a lot_. In those cases, 33% of the viewport will not be wide enough to
// keep the individual steps from crowding each other.
//
// This min-width takes effect under those circumstances, keeping individual
// steps far enough apart to remain legible.
min-width: 4rem;

@include at-media('tablet') {
flex: 1 1 0%;
min-width: auto;
}
}

Expand Down
7 changes: 7 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class ApplicationController < ActionController::Base
prepend_before_action :set_locale
before_action :disable_caching
before_action :cache_issuer_in_cookie
after_action :store_web_locale_in_session

def session_expires_at
return if @skip_session_expiration || @skip_session_load
Expand Down Expand Up @@ -400,6 +401,12 @@ def set_locale
I18n.locale = LocaleChooser.new(params[:locale], request).locale
end

def store_web_locale_in_session
return unless user_signed_in?

user_session[:web_locale] = I18n.locale.to_s
end

def pii_requested_but_locked?
if resolved_authn_context_result.identity_proofing? || resolved_authn_context_result.ialmax?
current_user.identity_verified? &&
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/concerns/idv/document_capture_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def error_hash(message)
def extract_pii_from_doc(user, store_in_session: false)
if defined?(idv_session) # hybrid mobile does not have idv_session
idv_session.had_barcode_read_failure = stored_result.attention_with_barcode?
# See also Idv::InPerson::StateIdController#update
idv_session.doc_auth_vendor = doc_auth_vendor
if store_in_session
idv_session.pii_from_doc = stored_result.pii_from_doc
idv_session.selfie_check_performed = stored_result.selfie_check_performed?
Expand All @@ -58,7 +60,7 @@ def selfie_requirement_met?
stored_result.selfie_check_performed?
end

def redirect_to_correct_vendor(vendor, in_hybrid_mobile)
def redirect_to_correct_vendor(vendor, in_hybrid_mobile:)
return if IdentityConfig.store.doc_auth_redirect_to_correct_vendor_disabled

expected_doc_auth_vendor = doc_auth_vendor
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/idv/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class DocumentCaptureController < ApplicationController
before_action :confirm_step_allowed, unless: -> { allow_direct_ipp? }
before_action :override_csp_to_allow_acuant
before_action :set_usps_form_presenter
before_action -> { redirect_to_correct_vendor(Idp::Constants::Vendors::LEXIS_NEXIS, false) },
only: [:show], unless: -> { allow_direct_ipp? }
before_action -> do
redirect_to_correct_vendor(Idp::Constants::Vendors::LEXIS_NEXIS, in_hybrid_mobile: false)
end, only: [:show], unless: -> { allow_direct_ipp? }

def show
analytics.idv_doc_auth_document_capture_visited(**analytics_arguments)
Expand Down Expand Up @@ -48,6 +49,7 @@ def update
def direct_in_person
attributes = {
remaining_submit_attempts: rate_limiter.remaining_count,
flow_path: :standard,
}.merge(ab_test_analytics_buckets)
analytics.idv_in_person_direct_start(**attributes)

Expand Down Expand Up @@ -75,6 +77,7 @@ def self.step_info
idv_session.had_barcode_attention_error = nil
idv_session.had_barcode_read_failure = nil
idv_session.selfie_check_performed = nil
idv_session.doc_auth_vendor = nil
end,
)
end
Expand All @@ -90,8 +93,10 @@ def extra_view_variables
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
skip_doc_auth_from_how_to_verify: idv_session.skip_doc_auth_from_how_to_verify,
skip_doc_auth_from_handoff: idv_session.skip_doc_auth_from_handoff,
skip_doc_auth_from_socure: idv_session.skip_doc_auth_from_socure,
opted_in_to_in_person_proofing: idv_session.opted_in_to_in_person_proofing,
doc_auth_selfie_capture: resolved_authn_context_result.facial_match?,
socure_errors_timeout_url: idv_socure_errors_timeout_url,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
Expand Down
36 changes: 34 additions & 2 deletions app/controllers/idv/hybrid_mobile/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ class DocumentCaptureController < ApplicationController
before_action :override_csp_to_allow_acuant
before_action :confirm_document_capture_needed, only: :show
before_action :set_usps_form_presenter
before_action -> { redirect_to_correct_vendor(Idp::Constants::Vendors::LEXIS_NEXIS, true) },
only: :show
before_action -> do
redirect_to_correct_vendor(Idp::Constants::Vendors::LEXIS_NEXIS, in_hybrid_mobile: true)
end, only: [:show], unless: -> { allow_direct_ipp? }

def show
analytics.idv_doc_auth_document_capture_visited(**analytics_arguments)
Expand Down Expand Up @@ -43,13 +44,27 @@ def update
end
end

# Given that the start of the IPP flow is in the TrueID doc_auth React app,
# we need a generic, direct way to start the IPP flow
def direct_in_person
attributes = {
remaining_submit_attempts: rate_limiter.remaining_count,
flow_path: :hybrid,
}.merge(ab_test_analytics_buckets)
analytics.idv_in_person_direct_start(**attributes)

redirect_to idv_hybrid_mobile_document_capture_url(step: :idv_doc_auth)
end

def extra_view_variables
{
flow_path: 'hybrid',
mock_client: doc_auth_vendor == 'mock',
document_capture_session_uuid: document_capture_session_uuid,
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
doc_auth_selfie_capture: resolved_authn_context_result.facial_match?,
skip_doc_auth_from_socure: @skip_doc_auth_from_socure,
socure_errors_timeout_url: idv_hybrid_mobile_socure_errors_timeout_url,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
)
Expand All @@ -69,6 +84,19 @@ def analytics_arguments
)
end

def allow_direct_ipp?
return false if params[:step].blank?
return false if params[:action].to_s != 'show' && params[:action] != 'direct_in_person'
# Only allow direct access to document capture if IPP available
return false unless IdentityConfig.store.in_person_doc_auth_button_enabled &&
Idv::InPersonConfig.enabled_for_issuer?(sp_session[:issuer])

# allow
@previous_step_url = params[:step] == 'hybrid_handoff' ? idv_hybrid_handoff_path : nil
@skip_doc_auth_from_socure = true
true
end

def confirm_document_capture_needed
return unless stored_result&.success?
return if redo_document_capture_pending?
Expand All @@ -86,6 +114,10 @@ def redo_document_capture_pending?
def set_usps_form_presenter
@presenter = Idv::InPerson::UspsFormPresenter.new
end

def rate_limiter
RateLimiter.new(user: document_capture_user, rate_limit_type: :idv_doc_auth)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ class DocumentCaptureController < ApplicationController

check_or_render_not_found -> { IdentityConfig.store.socure_docv_enabled }
before_action :check_valid_document_capture_session, except: [:update]
before_action -> { redirect_to_correct_vendor(Idp::Constants::Vendors::SOCURE, true) },
only: :show
before_action -> do
redirect_to_correct_vendor(Idp::Constants::Vendors::SOCURE, in_hybrid_mobile: true)
end, only: :show
before_action :fetch_test_verification_data, only: [:update]

def show
Expand Down Expand Up @@ -97,9 +98,7 @@ def wait_for_result?
# If the stored_result is nil, the job fetching the results has not completed.
analytics.idv_doc_auth_document_capture_polling_wait_visited(**analytics_arguments)
if wait_timed_out?
# flash[:error] = I18n.t('errors.doc_auth.polling_timeout')
# TODO: redirect to try again page LG-14873/14952/15059
render plain: 'Technical difficulties!!!', status: :ok
redirect_to idv_hybrid_mobile_socure_errors_timeout_path
else
@refresh_interval =
IdentityConfig.store.doc_auth_socure_wait_polling_refresh_max_seconds
Expand Down
73 changes: 73 additions & 0 deletions app/controllers/idv/hybrid_mobile/socure/errors_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

module Idv
module HybridMobile
module Socure
class ErrorsController < ApplicationController
include DocumentCaptureConcern
include HybridMobileConcern
include AvailabilityConcern
include StepIndicatorConcern
include SocureErrorsConcern

def show
error_code = error_code_for(handle_stored_result)
track_event(error_code: error_code)
@presenter = socure_errors_presenter(error_code)
end

def timeout
track_event(error_code: :timeout)
@presenter = socure_errors_presenter(:timeout)
render :show
end

def self.step_info
Idv::StepInfo.new(
key: :hybrid_socure_errors,
controller: self,
action: :timeout,
next_steps: [FlowPolicy::FINAL],
preconditions: ->(idv_session:, user:) do
true
end,
undo_step: ->(idv_session:, user:) {},
)
end

private

def rate_limiter
RateLimiter.new(user: document_capture_session&.user, rate_limit_type: :idv_doc_auth)
end

def remaining_submit_attempts
@remaining_submit_attempts ||= rate_limiter.remaining_count
end

def track_event(error_code:)
attributes = {
error_code:,
remaining_submit_attempts:,
}

analytics.idv_doc_auth_socure_error_visited(**attributes)
end

def socure_errors_presenter(error_code)
SocureErrorPresenter.new(
error_code:,
remaining_attempts: remaining_submit_attempts,
sp_name: service_provider&.friendly_name || APP_NAME,
issuer: service_provider&.issuer,
flow_path: :hybrid,
)
end

def service_provider
@service_provider ||= ServiceProvider.find_by(issuer: document_capture_session&.issuer)
end
end
end
end
end
2 changes: 2 additions & 0 deletions app/controllers/idv/in_person/state_id_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def update
redirect_url = idv_in_person_ssn_url
end

idv_session.doc_auth_vendor = Idp::Constants::Vendors::USPS
redirect_to redirect_url
else
render :show, locals: extra_view_variables
Expand Down Expand Up @@ -85,6 +86,7 @@ def self.step_info
pii_from_user[:identity_doc_city] = nil
pii_from_user[:identity_doc_zipcode] = nil
pii_from_user[:identity_doc_state] = nil
idv_session.doc_auth_vendor = nil
end,
)
end
Expand Down
1 change: 1 addition & 0 deletions app/controllers/idv/link_sent_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def self.step_info
idv_session.had_barcode_attention_error = nil
idv_session.had_barcode_read_failure = nil
idv_session.selfie_check_performed = nil
idv_session.doc_auth_vendor = nil
end,
)
end
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/idv/socure/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ class DocumentCaptureController < ApplicationController
check_or_render_not_found -> { IdentityConfig.store.socure_docv_enabled }
before_action :confirm_not_rate_limited
before_action :confirm_step_allowed
before_action -> { redirect_to_correct_vendor(Idp::Constants::Vendors::SOCURE, false) },
only: :show
before_action -> do
redirect_to_correct_vendor(Idp::Constants::Vendors::SOCURE, in_hybrid_mobile: false)
end, only: :show
before_action :fetch_test_verification_data, only: [:update]

# reconsider and maybe remove these when implementing the real
Expand Down Expand Up @@ -105,6 +106,7 @@ def self.step_info
idv_session.pii_from_doc = nil
idv_session.socure_docv_wait_polling_started_at = nil
idv_session.invalidate_in_person_pii_from_user!
idv_session.doc_auth_vendor = nil
end,
)
end
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/idv/socure/errors_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ def self.step_info
action: :timeout,
next_steps: [FlowPolicy::FINAL],
preconditions: ->(idv_session:, user:) do
# idv_session.socure_docv_wait_polling_started_at.present?
true
end,
undo_step: ->(idv_session:, user:) {},
Expand All @@ -55,6 +54,9 @@ def track_event(error_code:)
end

def socure_errors_presenter(error_code)
# There really isn't a good place to set this
idv_session.skip_doc_auth_from_socure = true if flow_path == 'standard'

SocureErrorPresenter.new(
error_code:,
remaining_attempts: remaining_submit_attempts,
Expand Down
Loading

0 comments on commit e42909e

Please sign in to comment.