Skip to content

Commit

Permalink
Merge pull request #11759 from 18F/stages/rc-2025-01-16
Browse files Browse the repository at this point in the history
Deploy RC 444 to Production
  • Loading branch information
jmhooper authored Jan 16, 2025
2 parents 116345a + a1584b0 commit d853850
Show file tree
Hide file tree
Showing 42 changed files with 481 additions and 415 deletions.
7 changes: 5 additions & 2 deletions app/controllers/concerns/backup_code_reminder_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

module BackupCodeReminderConcern
def user_needs_backup_code_reminder?
return false if user_session[:dismissed_backup_code_reminder]
user_backup_codes_configured? && user_last_signed_in_more_than_5_months_ago?
end

private

def user_backup_codes_configured?
MfaContext.new(current_user).backup_code_configurations.present?
end

def user_last_signed_in_more_than_5_months_ago?
second_last_signed_in_at = current_user.second_last_signed_in_at
second_last_signed_in_at && second_last_signed_in_at < 5.months.ago
current_user.created_at.before?(5.months.ago) &&
current_user.second_last_signed_in_at(since: 5.months.ago).blank?
end
end
2 changes: 2 additions & 0 deletions app/controllers/concerns/idv/document_capture_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def selfie_requirement_met?
end

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
return if vendor == expected_doc_auth_vendor
return if vendor == Idp::Constants::Vendors::LEXIS_NEXIS &&
Expand Down
2 changes: 0 additions & 2 deletions app/controllers/idv/in_person/ready_to_verify_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class ReadyToVerifyController < ApplicationController

def show
@is_enhanced_ipp = resolved_authn_context_result.enhanced_ipp?
@show_closed_post_office_banner =
IdentityConfig.store.in_person_proofing_post_office_closed_alert_enabled
analytics.idv_in_person_ready_to_verify_visit(**opt_in_analytics_properties)
@presenter = ReadyToVerifyPresenter.new(
enrollment: enrollment,
Expand Down
29 changes: 29 additions & 0 deletions app/controllers/users/backup_code_reminder_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

module Users
class BackupCodeReminderController < ApplicationController
before_action :confirm_two_factor_authenticated

def show
flash.now[:success] = t('notices.authenticated_successfully')
analytics.backup_code_reminder_visited
end

def update
user_session[:dismissed_backup_code_reminder] = true
analytics.backup_code_reminder_submitted(has_codes: has_codes?)

if has_codes?
redirect_to after_sign_in_path_for(current_user)
else
redirect_to backup_code_regenerate_path
end
end

private

def has_codes?
params[:has_codes].present?
end
end
end
6 changes: 1 addition & 5 deletions app/controllers/users/backup_code_setup_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class BackupCodeSetupController < ApplicationController
before_action :set_backup_code_setup_presenter
before_action :apply_secure_headers_override
before_action :authorize_backup_code_disable, only: [:delete]
before_action :confirm_recently_authenticated_2fa, except: [:reminder, :continue]
before_action :confirm_recently_authenticated_2fa, except: [:continue]
before_action :validate_multi_mfa_selection, only: [:index]

helper_method :in_multi_mfa_selection_flow?
Expand Down Expand Up @@ -69,10 +69,6 @@ def delete
end
end

def reminder
flash.now[:success] = t('notices.authenticated_successfully')
end

def confirm_backup_codes; end

private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ function AcuantCapture(
>
<FullScreen
ref={fullScreenRef}
label={t('doc_auth.accessible_labels.document_capture_dialog')}
label={t('doc_auth.headings.selfie_capture')}
hideCloseButton
>
<AcuantSelfieCaptureCanvas
Expand Down
14 changes: 0 additions & 14 deletions app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,6 @@ def in_person_ready_to_verify(enrollment:, is_enhanced_ipp:)
is_enhanced_ipp: is_enhanced_ipp,
)
@is_enhanced_ipp = is_enhanced_ipp
@show_closed_post_office_banner =
IdentityConfig.store.in_person_proofing_post_office_closed_alert_enabled

mail(
to: email_address.email,
Expand All @@ -328,8 +326,6 @@ def in_person_ready_to_verify_reminder(enrollment:)
).image_data

@is_enhanced_ipp = enrollment.enhanced_ipp?
@show_closed_post_office_banner =
IdentityConfig.store.in_person_proofing_post_office_closed_alert_enabled

with_user_locale(user) do
@presenter = Idv::InPerson::ReadyToVerifyPresenter.new(
Expand Down Expand Up @@ -439,16 +435,6 @@ def account_reinstated
end
end

def in_person_post_office_closed
with_user_locale(user) do
@hide_title = true
mail(
to: email_address.email,
subject: t('in_person_proofing.post_office_closed.email.subject'),
)
end
end

private

attr_reader :user, :email_address
Expand Down
13 changes: 10 additions & 3 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,17 @@ def sign_in_count(since:)
.count
end

def second_last_signed_in_at
# Returns the date of the last fully-authenticated sign-in before the most recent.
#
# A `since` time argument is required, to optimize performance based on database indices for
# querying a user's events.
def second_last_signed_in_at(since:)
events
.where(event_type: 'sign_in_after_2fa')
.order(created_at: :desc).limit(2).pluck(:created_at).second
.where(event_type: :sign_in_after_2fa, created_at: since..)
.order(created_at: :desc)
.limit(2)
.pluck(:created_at)
.second
end

def connected_apps
Expand Down
13 changes: 13 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,19 @@ def backup_code_regenerate_visit(in_account_creation_flow:, **extra)
track_event('Backup Code Regenerate Visited', in_account_creation_flow:, **extra)
end

# @param [Boolean] has_codes Whether the user still has access to their backup codes.
# Tracks when the user submits to confirm whether they still have access to their backup codes
# when signing in for the first time in at least 5 months.
def backup_code_reminder_submitted(has_codes:, **extra)
track_event(:backup_code_reminder_submitted, has_codes:, **extra)
end

# Tracks when the user is prompted to confirm that they still have access to their backup codes
# when signing in for the first time in at least 5 months.
def backup_code_reminder_visited
track_event(:backup_code_reminder_visited)
end

# Track user creating new BackupCodeSetupForm, record form submission Hash
# @param [Boolean] success Whether form validation was successful
# @param [Hash] mfa_method_counts Hash of MFA method with the number of that method on the account
Expand Down
18 changes: 4 additions & 14 deletions app/services/doc_auth/lexis_nexis/doc_pii_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ def read_pii(true_id_product)
state_id_type_slug = id_auth_field_data['Fields_DocumentClassName']
state_id_type = DocAuth::Response::ID_TYPE_SLUGS[state_id_type_slug]

state_id_data = Pii::StateId.new(
Pii::StateId.new(
first_name: id_auth_field_data['Fields_FirstName'],
last_name: id_auth_field_data['Fields_Surname'],
middle_name: id_auth_field_data['Fields_MiddleName'],
name_suffix: nil,
name_suffix: id_auth_field_data['Fields_NameSuffix'],
address1: id_auth_field_data['Fields_AddressLine1'],
address2: id_auth_field_data['Fields_AddressLine2'],
city: id_auth_field_data['Fields_City'],
Expand All @@ -42,8 +42,8 @@ def read_pii(true_id_product)
month: id_auth_field_data['Fields_DOB_Month'],
day: id_auth_field_data['Fields_DOB_Day'],
),
sex: nil,
height: nil,
sex: parse_sex_value(id_auth_field_data['Fields_Sex']),
height: parse_height_value(id_auth_field_data['Fields_Height']),
weight: nil,
eye_color: nil,
state_id_expiration: parse_date(
Expand All @@ -61,16 +61,6 @@ def read_pii(true_id_product)
state_id_type: state_id_type,
issuing_country_code: id_auth_field_data['Fields_CountryCode'],
)

if IdentityConfig.store.doc_auth_read_additional_pii_attributes_enabled
state_id_data = state_id_data.with(
name_suffix: id_auth_field_data['Fields_NameSuffix'],
sex: parse_sex_value(id_auth_field_data['Fields_Sex']),
height: parse_height_value(id_auth_field_data['Fields_Height']),
)
end

state_id_data
end

def parse_date(year:, month:, day:)
Expand Down
24 changes: 10 additions & 14 deletions app/services/proofing/aamva/request/verification_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,12 @@ def add_user_provided_data_to_body
REXML::XPath.first(document, xpath).add_text(data)
end

if IdentityConfig.store.aamva_send_middle_name
add_optional_element(
'nc:PersonMiddleName',
value: applicant.middle_name,
document:,
inside: '//nc:PersonName',
)
end
add_optional_element(
'nc:PersonMiddleName',
value: applicant.middle_name,
document:,
inside: '//nc:PersonName',
)

add_optional_element(
'nc:PersonNameSuffixText',
Expand Down Expand Up @@ -123,12 +121,10 @@ def add_user_provided_data_to_body
inside: '//dldv:verifyDriverLicenseDataRequest',
)

if IdentityConfig.store.aamva_send_id_type
add_state_id_type(
applicant.state_id_data.state_id_type,
document,
)
end
add_state_id_type(
applicant.state_id_data.state_id_type,
document,
)

@body = document.to_s
end
Expand Down
8 changes: 0 additions & 8 deletions app/views/idv/in_person/ready_to_verify/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,6 @@
</section>
<% end %>

<%# Alert %>
<% if @show_closed_post_office_banner %>
<%= render AlertComponent.new(type: :warning, class: 'margin-y-4', text_tag: :div) do %>
<p class="margin-bottom-1 margin-top-0 h3"><strong><%= t('in_person_proofing.post_office_closed.heading') %></strong></p>
<p><%= t('in_person_proofing.post_office_closed.body') %></p>
<% end %>
<% end %>

<% if !@is_enhanced_ipp %>
<h3><%= t('in_person_proofing.body.location.change_location_heading') %></h3>
<p class="margin-bottom-4">
Expand Down
2 changes: 0 additions & 2 deletions app/views/user_mailer/in_person_post_office_closed.html.erb

This file was deleted.

15 changes: 0 additions & 15 deletions app/views/user_mailer/shared/_in_person_ready_to_verify.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -275,21 +275,6 @@
</div>
<% end %>

<%# alert %>
<% if @show_closed_post_office_banner %>
<table class="usa-alert usa-alert--warning margin-y-4">
<tr>
<td style="width:16px;">
<%= image_tag('email/warning.png', width: 16, height: 16, alt: '', style: 'margin-top: 4px;') %>
</td>
<td>
<p class="margin-bottom-1"><strong><%= t('in_person_proofing.post_office_closed.heading') %></strong></p>
<p class="margin-bottom-0"><%= t('in_person_proofing.post_office_closed.body') %></p>
</td>
</tr>
</table>
<% end %>

<% if !@is_enhanced_ipp %>
<h3><%= t('in_person_proofing.body.location.change_location_heading') %></h3>
<p class="margin-bottom-4">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<% self.title = t('forms.backup_code.title') %>
<% self.title = t('forms.backup_code_reminder.heading') %>

<%= image_tag asset_url('user-signup.svg'), width: 107, height: 119, alt: '', class: 'margin-bottom-4', aria: { hidden: true } %>

<%= render PageHeadingComponent.new.with_content(t('forms.backup_code_reminder.heading')) %>

<p class='margin-top-1 margin-bottom-4'>
<p>
<%= t('forms.backup_code_reminder.body_info') %>
</p>

<%= button_to(
account_path,
method: :get,
class: 'usa-button usa-button--wide usa-button--big margin-bottom-3',
) do %>
<%= t('forms.backup_code_reminder.have_codes') %>
<% end %>
<div class="margin-top-5 margin-bottom-2">
<%= render ButtonComponent.new(
url: account_path,
big: true,
wide: true,
).with_content(t('forms.backup_code_reminder.have_codes')) %>
</div>

<%= link_to t('forms.backup_code_reminder.need_new_codes'), backup_code_regenerate_path %>
8 changes: 1 addition & 7 deletions config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ aamva_auth_url: 'https://example.org:12345/auth/url'
aamva_cert_enabled: true
aamva_private_key: ''
aamva_public_key: ''
aamva_send_id_type: true
aamva_send_middle_name: true
aamva_supported_jurisdictions: '["AL","AR","AZ","CO","CT","DC","DE","FL","GA","HI","IA","ID","IL","IN","KS","KY","MA","MD","ME","MI","MO","MS","MT","NC","ND","NE","NH","NJ","NM","NV","OH","OK","OR","PA","RI","SC","SD","TN","TX","VA","VT","WA","WI","WV","WY"]'
aamva_verification_request_timeout: 5.0
aamva_verification_url: https://example.org:12345/verification/url
Expand Down Expand Up @@ -106,7 +104,7 @@ doc_auth_error_sharpness_threshold: 40
doc_auth_max_attempts: 5
doc_auth_max_capture_attempts_before_native_camera: 3
doc_auth_max_submission_attempts_before_native_camera: 3
doc_auth_read_additional_pii_attributes_enabled: false
doc_auth_redirect_to_correct_vendor_disabled: false
doc_auth_selfie_desktop_test_mode: false
doc_auth_socure_wait_polling_refresh_max_seconds: 15
doc_auth_socure_wait_polling_timeout_minutes: 2
Expand Down Expand Up @@ -195,7 +193,6 @@ in_person_outage_message_enabled: false
in_person_proofing_enabled: false
in_person_proofing_enforce_tmx: false
in_person_proofing_opt_in_enabled: false
in_person_proofing_post_office_closed_alert_enabled: true
in_person_results_delay_in_hours: 1
in_person_send_proofing_notifications_enabled: false
in_person_stop_expiring_enrollments: false
Expand Down Expand Up @@ -516,8 +513,6 @@ development:
#
production:
aamva_auth_url: 'https://authentication-cert.aamva.org/Authentication/Authenticate.svc'
aamva_send_id_type: false
aamva_send_middle_name: false
aamva_verification_url: 'https://verificationservices-cert.aamva.org:18449/dldv/2.1/online'
disable_email_sending: false
disable_logout_get_request: false
Expand Down Expand Up @@ -564,7 +559,6 @@ test:
hmac_fingerprinter_key: a2c813d4dca919340866ba58063e4072adc459b767a74cf2666d5c1eef3861db26708e7437abde1755eb24f4034386b0fea1850a1cb7e56bff8fae3cc6ade96c
hmac_fingerprinter_key_queue: '["old-key-one", "old-key-two"]'
identity_pki_disabled: true
in_person_proofing_post_office_closed_alert_enabled: false
lexisnexis_trueid_account_id: 'test_account'
lockout_period_in_minutes: 5
logins_per_email_and_ip_limit: 2
Expand Down
5 changes: 0 additions & 5 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1327,11 +1327,6 @@ in_person_proofing.headings.state_id_milestone_2: Enter the information on your
in_person_proofing.headings.switch_back: Switch back to your computer to prepare to verify your identity in person
in_person_proofing.headings.update_address: Update your current address
in_person_proofing.headings.update_state_id: Update the information on your ID
in_person_proofing.post_office_closed.body: Post Office locations will resume regular hours on Friday, January 10, 2025.
in_person_proofing.post_office_closed.email.body_html: <strong>You will not be able to visit a Post Office on Thursday, January 9, 2025 to finish verifying your identity.</strong> Post Office locations will resume regular hours on Friday, January 10, 2025.
in_person_proofing.post_office_closed.email.heading: All Post Offices will be closed on January 9, 2025 to honor former President Jimmy Carter
in_person_proofing.post_office_closed.email.subject: All Post Offices will be closed on Thursday, January 9, 2025
in_person_proofing.post_office_closed.heading: All Post Offices will be closed on Thursday, January 9, 2025 to honor former President Jimmy Carter.
in_person_proofing.process.barcode.caption_label: Enrollment code
in_person_proofing.process.barcode.heading: Show your %{app_name} barcode
in_person_proofing.process.barcode.info: The retail associate needs to scan your barcode at the top of this page. You can print this page or show it on your mobile device.
Expand Down
5 changes: 0 additions & 5 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1338,11 +1338,6 @@ in_person_proofing.headings.state_id_milestone_2: Ingrese la información de su
in_person_proofing.headings.switch_back: Vuelva a su computadora para preparar la verificación de su identidad en persona
in_person_proofing.headings.update_address: Actualice su dirección actual
in_person_proofing.headings.update_state_id: Actualice la información de su identificación
in_person_proofing.post_office_closed.body: Las oficinas de correos reanudarán su horario habitual el viernes 10 de enero de 2025.
in_person_proofing.post_office_closed.email.body_html: <strong>No podrás visitar una Oficina de Correos el jueves 9 de enero de 2025 para terminar de verificar tu identidad.</strong> Las oficinas de correos reanudarán su horario habitual el viernes 10 de enero de 2025.
in_person_proofing.post_office_closed.email.heading: Todas las oficinas de correos estarán cerradas el 9 de enero de 2025 en honor al expresidente Jimmy Carter
in_person_proofing.post_office_closed.email.subject: Todas las oficinas de correos estarán cerradas el jueves 9 de enero de 2025
in_person_proofing.post_office_closed.heading: Todas las oficinas de correos estarán cerradas el jueves 9 de enero de 2025 en honor al ex presidente Jimmy Carter.
in_person_proofing.process.barcode.caption_label: Código de registro
in_person_proofing.process.barcode.heading: Muestre su código de barras de %{app_name}
in_person_proofing.process.barcode.info: El empleado debe escanear el código de barras que aparece en la parte superior de esta página. Puede imprimir esta página o mostrarla en su dispositivo móvil.
Expand Down
Loading

0 comments on commit d853850

Please sign in to comment.