Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deploy RC 426 to Production #11416

Merged
merged 16 commits into from
Oct 29, 2024
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
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