Skip to content

Commit

Permalink
Merge pull request #11416 from 18F/stages/rc-2024-10-29
Browse files Browse the repository at this point in the history
Deploy RC 426 to Production
  • Loading branch information
solipet authored Oct 29, 2024
2 parents db6d5e9 + 1e55a4b commit 34fe0d9
Show file tree
Hide file tree
Showing 105 changed files with 1,739 additions and 660 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,9 @@ Style/NumericLiteralPrefix:
Style/OneLineConditional:
Enabled: true

Style/OpenStructUse:
Enabled: true

Style/OptionalArguments:
Enabled: true

Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ gem 'faker'
gem 'faraday-retry'
gem 'fugit'
gem 'foundation_emails'
gem 'good_job', '~> 3.0'
gem 'good_job', '~> 4.0'
gem 'http_accept_language'
gem 'identity-hostdata', github: '18F/identity-hostdata', tag: 'v4.0.0'
gem 'identity-logging', github: '18F/identity-logging', tag: 'v0.1.1'
Expand Down
24 changes: 12 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,13 @@ GEM
ffi (~> 1.0)
globalid (1.2.1)
activesupport (>= 6.1)
good_job (3.99.1)
activejob (>= 6.0.0)
activerecord (>= 6.0.0)
concurrent-ruby (>= 1.0.2)
fugit (>= 1.1)
railties (>= 6.0.0)
thor (>= 0.14.1)
good_job (4.4.2)
activejob (>= 6.1.0)
activerecord (>= 6.1.0)
concurrent-ruby (>= 1.3.1)
fugit (>= 1.11.0)
railties (>= 6.1.0)
thor (>= 1.0.0)
google-protobuf (4.28.2)
bigdecimal
rake (>= 13)
Expand All @@ -357,7 +357,7 @@ GEM
htmlbeautifier (1.4.3)
htmlentities (4.3.4)
http_accept_language (2.1.1)
i18n (1.14.5)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.12)
activesupport (>= 4.0.2)
Expand All @@ -372,7 +372,7 @@ GEM
terminal-table (>= 1.5.1)
ice_nine (0.11.2)
io-console (0.7.2)
irb (1.13.2)
irb (1.14.1)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jmespath (1.6.2)
Expand Down Expand Up @@ -742,8 +742,8 @@ GEM
nokogiri (~> 1.11)
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.36)
zeitwerk (2.6.16)
yard (0.9.37)
zeitwerk (2.7.1)
zlib (3.0.0)
zonebie (0.6.1)
zxcvbn (0.1.9)
Expand Down Expand Up @@ -789,7 +789,7 @@ DEPENDENCIES
faraday-retry
foundation_emails
fugit
good_job (~> 3.0)
good_job (~> 4.0)
http_accept_language
i18n-tasks (~> 1.0)
identity-hostdata!
Expand Down
Binary file added app/assets/images/email/letter-success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,10 @@ def async_state_done(current_async_state)
[:proofing_results, :context, :stages, :resolution, :errors, :ssn],
[:proofing_results, :context, :stages, :residential_address, :errors, :ssn],
[:proofing_results, :context, :stages, :threatmetrix, :response_body, :first_name],
[:same_address_as_id],
[:proofing_results, :context, :stages, :state_id, :state_id_jurisdiction],
[:proofing_results, :biographical_info, :identity_doc_address_state],
[:proofing_results, :biographical_info, :state_id_jurisdiction],
[:proofing_results, :biographical_info, :same_address_as_id],
[:proofing_results, :biographical_info],
],
},
)
Expand Down Expand Up @@ -291,7 +290,12 @@ def idv_result_to_form_response(
FormResponse.new(
success: result[:success],
errors: result[:errors],
extra: extra.merge(proofing_results: result.except(:errors, :success)),
extra: extra.merge(
proofing_results: {
**result.except(:errors, :success),
biographical_info: result[:biographical_info]&.except(:same_address_as_id),
},
),
)
end

Expand Down
9 changes: 1 addition & 8 deletions app/controllers/concerns/idv_step_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,11 @@ def confirm_hybrid_handoff_needed
private

def extra_analytics_properties
extra = {
{
pii_like_keypaths: [
[:same_address_as_id],
[:proofing_results, :context, :stages, :state_id, :state_id_jurisdiction],
],
}

unless flow_session.dig(:pii_from_user, :same_address_as_id).nil?
extra[:same_address_as_id] =
flow_session[:pii_from_user][:same_address_as_id].to_s == 'true'
end
extra
end

def letter_recently_enqueued?
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/concerns/saml_idp_auth_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ def link_identity_from_session_data

def email_address_id
return nil unless IdentityConfig.store.feature_select_email_to_share_enabled
return user_session[:selected_email_id] if user_session[:selected_email_id].present?
if user_session[:selected_email_id_for_linked_identity].present?
return user_session[:selected_email_id_for_linked_identity]
end
identity = current_user.identities.find_by(service_provider: sp_session['issuer'])
email_id = identity&.email_address_id
return email_id if email_id.is_a? Integer
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/idv/hybrid_handoff_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ def self.selected_remote(idv_session:)
if IdentityConfig.store.in_person_proofing_opt_in_enabled &&
IdentityConfig.store.in_person_proofing_enabled &&
idv_session.service_provider&.in_person_proofing_enabled
idv_session.skip_doc_auth == false
idv_session.skip_doc_auth_from_how_to_verify == false ||
idv_session.skip_doc_auth == false
else
idv_session.skip_doc_auth.nil? ||
idv_session.skip_doc_auth_from_how_to_verify.nil? ||
idv_session.skip_doc_auth_from_how_to_verify == false || idv_session.skip_doc_auth.nil? ||
idv_session.skip_doc_auth == false
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/in_person/address_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def redirect_to_next_page

def confirm_in_person_state_id_step_complete
return if pii_from_user&.has_key?(:identity_doc_address1)
redirect_to idv_in_person_proofing_state_id_url
redirect_to idv_in_person_state_id_url
end

def confirm_in_person_address_step_needed
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/in_person_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class InPersonController < ApplicationController

FLOW_STATE_MACHINE_SETTINGS = {
step_url: :idv_in_person_step_url,
final_url: :idv_in_person_proofing_state_id_url,
final_url: :idv_in_person_state_id_url,
flow: Idv::Flows::InPersonFlow,
analytics_id: 'In Person Proofing',
}.freeze
Expand Down
12 changes: 11 additions & 1 deletion app/controllers/openid_connect/authorization_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ def link_identity_to_service_provider

def email_address_id
return nil unless IdentityConfig.store.feature_select_email_to_share_enabled
return user_session[:selected_email_id] if user_session[:selected_email_id].present?
if user_session[:selected_email_id_for_linked_identity].present?
return user_session[:selected_email_id_for_linked_identity]
end
identity = current_user.identities.find_by(service_provider: sp_session['issuer'])
identity&.email_address_id
end
Expand Down Expand Up @@ -174,6 +176,7 @@ def pre_validate_authorize_form
user_fully_authenticated: user_fully_authenticated?,
referer: request.referer,
vtr_param: params[:vtr],
unknown_authn_contexts:,
),
)
return if result.success?
Expand Down Expand Up @@ -258,5 +261,12 @@ def redirect_user(redirect_uri, issuer, user_uuid)
def sp_handoff_bouncer
@sp_handoff_bouncer ||= SpHandoffBouncer.new(sp_session)
end

def unknown_authn_contexts
return nil if params[:vtr].present? || params[:acr_values].blank?

(params[:acr_values].split - Saml::Idp::Constants::VALID_AUTHN_CONTEXTS).
join(' ').presence
end
end
end
9 changes: 9 additions & 0 deletions app/controllers/redirect/marketing_site_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Redirect
class MarketingSiteController < RedirectController
def show
redirect_to_and_log(MarketingSite.base_url)
end
end
end
25 changes: 24 additions & 1 deletion app/controllers/saml_idp_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def capture_analytics
request_signed: saml_request.signed?,
matching_cert_serial:,
requested_nameid_format: saml_request.name_id_format,
unknown_authn_contexts:,
)

if result.success? && saml_request.signed?
Expand All @@ -151,12 +152,13 @@ def log_external_saml_auth_request

analytics.saml_auth_request(
requested_ial: requested_ial,
authn_context: saml_request&.requested_authn_contexts,
authn_context: requested_authn_contexts,
requested_aal_authn_context: FederatedProtocols::Saml.new(saml_request).aal,
requested_vtr_authn_contexts: saml_request&.requested_vtr_authn_contexts.presence,
force_authn: saml_request&.force_authn?,
final_auth_request: sp_session[:final_auth_request],
service_provider: saml_request&.issuer,
unknown_authn_contexts:,
user_fully_authenticated: user_fully_authenticated?,
)
end
Expand Down Expand Up @@ -227,4 +229,25 @@ def resolved_authn_context_int_ial
def require_path_year
render_not_found if params[:path_year].blank?
end

def unknown_authn_contexts
return nil if saml_request.requested_vtr_authn_contexts.present?
return nil if requested_authn_contexts.blank?

unmatched_authn_contexts.reject do |authn_context|
authn_context.match(req_attrs_regexp)
end.join(' ').presence
end

def unmatched_authn_contexts
requested_authn_contexts - Saml::Idp::Constants::VALID_AUTHN_CONTEXTS
end

def requested_authn_contexts
@request_authn_contexts || saml_request&.requested_authn_contexts
end

def req_attrs_regexp
Regexp.escape(Saml::Idp::Constants::REQUESTED_ATTRIBUTES_CLASSREF)
end
end
6 changes: 3 additions & 3 deletions app/controllers/sign_up/completions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ def update
track_completion_event('agency-page')
update_verified_attributes
send_in_person_completion_survey
if user_session[:selected_email_id].nil?
user_session[:selected_email_id] = EmailContext.new(current_user).
if user_session[:selected_email_id_for_linked_identity].nil?
user_session[:selected_email_id_for_linked_identity] = EmailContext.new(current_user).
last_sign_in_email_address.id
end
if decider.go_back_to_mobile_app?
Expand Down Expand Up @@ -53,7 +53,7 @@ def completions_presenter
requested_attributes: decorated_sp_session.requested_attributes.map(&:to_sym),
ial2_requested: ial2_requested?,
completion_context: needs_completion_screen_reason,
selected_email_id: user_session[:selected_email_id],
selected_email_id: user_session[:selected_email_id_for_linked_identity],
)
end

Expand Down
6 changes: 3 additions & 3 deletions app/controllers/sign_up/select_email_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def create
analytics.sp_select_email_submitted(**result.to_h, needs_completion_screen_reason:)

if result.success?
user_session[:selected_email_id] = form_params[:selected_email_id]
user_session[:selected_email_id_for_linked_identity] = form_params[:selected_email_id]
redirect_to sign_up_completed_path
else
flash[:error] = result.first_error_message
Expand All @@ -47,8 +47,8 @@ def form_params
end

def last_email
if user_session[:selected_email_id]
user_emails.find(user_session[:selected_email_id]).email
if user_session[:selected_email_id_for_linked_identity]
user_emails.find(user_session[:selected_email_id_for_linked_identity]).email
else
EmailContext.new(current_user).last_sign_in_email_address.email
end
Expand Down
1 change: 1 addition & 0 deletions app/forms/recaptcha_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def log_analytics(result: nil, error: nil)
evaluated_as_valid: recaptcha_result_valid?(result),
exception_class: error&.class&.name,
form_class: self.class.name,
recaptcha_action:,
**extra_analytics_properties,
)
end
Expand Down
12 changes: 11 additions & 1 deletion app/helpers/locale_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ def with_user_locale(user, &block)
locale = user.email_language

if I18n.locale_available?(locale)
I18n.with_locale(locale, &block)
if defined?(url_options)
I18n.with_locale(locale) do
url_options_locale = url_options[:locale]
url_options[:locale] = locale
block.call
ensure
url_options[:locale] = url_options_locale
end
else
I18n.with_locale(locale, &block)
end
else
Rails.logger.warn("user_id=#{user.uuid} has bad email_language=#{locale}") if locale.present?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ function DocumentCapture({ onStepChange = () => {} }: DocumentCaptureProps) {
const { flowPath } = useContext(UploadContext);
const { trackSubmitEvent, trackVisitEvent } = useContext(AnalyticsContext);
const { isSelfieCaptureEnabled } = useContext(SelfieCaptureContext);
const { inPersonFullAddressEntryEnabled, inPersonURL, skipDocAuth, skipDocAuthFromHandoff } =
useContext(InPersonContext);
const {
inPersonFullAddressEntryEnabled,
inPersonURL,
skipDocAuth,
skipDocAuthFromHandoff,
skipDocAuthFromHowToVerify,
} = useContext(InPersonContext);
useDidUpdateEffect(onStepChange, [stepName]);
useEffect(() => {
if (stepName) {
Expand Down Expand Up @@ -135,9 +140,9 @@ function DocumentCapture({ onStepChange = () => {} }: DocumentCaptureProps) {
if (submissionError && formValues) {
initialValues = formValues;
}
// If the user got here by opting-in to in-person proofing, when skipDocAuth === true,
// If the user got here by opting-in to in-person proofing, when skipDocAuthFromHowToVerify === true || skipDocAuth === true,
// then set steps to inPersonSteps
const isInPersonStepEnabled = skipDocAuth || skipDocAuthFromHandoff;
const isInPersonStepEnabled = skipDocAuthFromHowToVerify || skipDocAuthFromHandoff || skipDocAuth;
const inPersonSteps: FormStep[] =
inPersonURL === undefined
? []
Expand All @@ -151,7 +156,7 @@ function DocumentCapture({ onStepChange = () => {} }: DocumentCaptureProps) {
} else if (submissionError) {
steps = [reviewFormStep, ...inPersonSteps];
}
// If the user got here by opting-in to in-person proofing, when skipDocAuth === true;
// If the user got here by opting-in to in-person proofing, when skipDocAuthFromHowToVerify === true || skipDocAuth === true;
// or opting-in ipp from handoff page, and selfie is required, when skipDocAuthFromHandoff === true
// then set stepIndicatorPath to VerifyFlowPath.IN_PERSON
const stepIndicatorPath =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function InPersonPrepareStep({ toPreviousStep }) {
inPersonOutageMessageEnabled,
inPersonOutageExpectedUpdateDate,
skipDocAuth,
skipDocAuthFromHowToVerify,
skipDocAuthFromHandoff,
howToVerifyURL,
previousStepURL,
Expand All @@ -29,7 +30,7 @@ function InPersonPrepareStep({ toPreviousStep }) {
if (skipDocAuthFromHandoff && previousStepURL) {
// directly from handoff page
forceRedirect(previousStepURL);
} else if (skipDocAuth && howToVerifyURL) {
} else if ((skipDocAuthFromHowToVerify || skipDocAuth) && howToVerifyURL) {
forceRedirect(howToVerifyURL);
} else {
toPreviousStep();
Expand Down
7 changes: 7 additions & 0 deletions app/javascript/packages/document-capture/context/in-person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export interface InPersonContextProps {
*/
skipDocAuth?: boolean;

/**
* When skipDocAuthFromHowToVerify is true and in_person_proofing_opt_in_enabled is true,
* users are directed to the beginning of the IPP flow. This is set to true when
* they choose Opt-in IPP on the new How To Verify page
*/
skipDocAuthFromHowToVerify?: boolean;

/**
* Flag set when user select IPP from handoff page when IPP is available
* and selfie is required
Expand Down
Loading

0 comments on commit 34fe0d9

Please sign in to comment.