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 379 to Production #10624

Merged
merged 35 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
050cca7
Improve failure message for unused allowed untranslated keys test (#1…
mitchellhenke May 8, 2024
659f2bf
Create a report of counts by protocol + SAML signature issues (#10537)
vrajmohan May 8, 2024
4d88740
Generate a report of issuers making LOA ACR requests (#10562)
vrajmohan May 9, 2024
3452435
LG-12376 state id update - check ssn (#10567)
svalexander May 9, 2024
a79bba6
Flattens .yml files for i18n (#10503)
zachmargolis May 9, 2024
10ae312
Remove harcoded "Login.gov" and switch to interpolation (#10580)
zachmargolis May 9, 2024
fead677
LG-12770: Update Translations to ensure better understanding in other…
mdiarra3 May 10, 2024
44a6d6f
Fail build on unnecessary allowed_extra_analytics (#10571)
aduth May 10, 2024
a9e312e
Add internationalization test against leading and trailing whitespace…
mitchellhenke May 10, 2024
ce2ba86
Configure Dependabot for security updates, major Stylelint releases (…
aduth May 10, 2024
2360757
Use patterns syntax for Dependabot groups (#10585)
aduth May 10, 2024
1b72029
Fix Dependabot security group schema (#10589)
aduth May 10, 2024
b68ef75
Revert Dependabot configuration (#10601)
aduth May 10, 2024
0afd1d8
Fix typo "exceeded" for maximum sign-in error (#10590)
aduth May 10, 2024
8cdb4ec
changelog: internal, in-person-proofing, add new skip_doc_auth name (…
racingspider May 10, 2024
37afb7e
LG-13007: clean up exit survey related. (#10572)
dawei-nava May 10, 2024
4273eba
fix error in report job where nil email array returns false (#10577)
theabrad May 10, 2024
c211ccf
Apply autocomplete attribute consistently to all forms (#10604)
aduth May 13, 2024
441f085
LG-12214: Refresh device cookie on every user event (#10606)
aduth May 13, 2024
0bf432c
Respect openid_connect_content_security_form_action_enabled configura…
mitchellhenke May 13, 2024
95e1cd1
Agnes/lg 13013 billing report multiple year helper (#10556)
samathad2023 May 13, 2024
9d24329
LG-7434: Support HTTP POST for OIDC logout route (#10573)
lmgeorge May 13, 2024
18cf649
Lg 13006 rename skip doc auth, add scaffolding (#10605)
racingspider May 13, 2024
6a7f8c8
LG-12619 Update please call email with zh translations (#10588)
svalexander May 13, 2024
f552623
Remove unnecessary allowed_extra_analytics (#10617)
aduth May 13, 2024
a0e8cc6
Agnes/lg 13018 billing report v2 (#10613)
samathad2023 May 13, 2024
ade4a03
LG-13132 Adds property to SP redirect initiated event (#10560)
kevinsmaster5 May 14, 2024
2d469a9
Optimize preload response headers to prioritize critical assets (#10612)
aduth May 14, 2024
b6ef0cd
Add resource hints for reCAPTCHA (#10616)
aduth May 14, 2024
02c9449
LG-12341: Clean up SDK files (#10582)
eileen-nava May 14, 2024
ff97682
LG-12706: Include user_id in piv_cac_login event (#10584)
aduth May 14, 2024
7f89bf2
LG-13154 remove erroneous arcgis test (#10607)
svalexander May 14, 2024
5186c21
Refactor `OpenidConnectUserInfoPresenter` to use `AuthnContextResolve…
jmhooper May 14, 2024
2207d35
LG-13317: Log 10-digit OTP A/B test params for OTP sends (#10621)
solipet May 14, 2024
f9cc372
LG-12086 | Renames CaptureDocStatusController (#10615)
n1zyy May 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100
"printWidth": 100,
"proseWrap": "never"
}
24 changes: 24 additions & 0 deletions app/controllers/concerns/openid_connect_redirect_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module OpenidConnectRedirectConcern
def oidc_redirect_method(issuer:, user_uuid:)
user_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_uuid_override_map[user_uuid]

sp_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_issuer_override_map[issuer]

user_redirect_method_override || sp_redirect_method_override ||
IdentityConfig.store.openid_connect_redirect
end

# We do not include Content-Security-Policy form-action headers if they are
# configured to be disabled and we are not using a server-side redirect.
def form_action_csp_disabled_and_not_server_side_redirect?(issuer:, user_uuid:)
!IdentityConfig.store.openid_connect_content_security_form_action_enabled &&
oidc_redirect_method(
issuer: issuer,
user_uuid: user_uuid,
) != 'server_side'
end
end
8 changes: 8 additions & 0 deletions app/controllers/concerns/recaptcha_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ module RecaptchaConcern
'https://recaptcha.google.com/recaptcha/',
].freeze

def add_recaptcha_resource_hints
response.headers['Link'] = [
response.headers['Link'],
'<https://www.google.com>;rel=preconnect',
'<https://www.gstatic.com>;rel=preconnect;crossorigin',
].compact.join(',')
end

def allow_csp_recaptcha_src
policy = current_content_security_policy
policy.script_src(*policy.script_src, *RECAPTCHA_SCRIPT_SRC)
Expand Down
7 changes: 6 additions & 1 deletion app/controllers/concerns/secure_headers_concern.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
# frozen_string_literal: true

module SecureHeadersConcern
include OpenidConnectRedirectConcern
extend ActiveSupport::Concern

def apply_secure_headers_override
return if stored_url_for_user.blank?
return unless IdentityConfig.store.openid_connect_content_security_form_action_enabled

authorize_form = OpenidConnectAuthorizeForm.new(authorize_params)
return unless authorize_form.valid?

return if form_action_csp_disabled_and_not_server_side_redirect?(
issuer: authorize_form.service_provider.issuer,
user_uuid: current_user&.uuid,
)

override_form_action_csp(csp_uris)
end

Expand Down
10 changes: 10 additions & 0 deletions app/controllers/concerns/sign_in_duration_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

module SignInDurationConcern
extend ActiveSupport::Concern

def sign_in_duration_seconds
return unless session[:sign_in_page_visited_at]
(Time.zone.now - Time.zone.parse(session[:sign_in_page_visited_at])).seconds.to_f
end
end
10 changes: 0 additions & 10 deletions app/controllers/idv/cancellations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,6 @@ def destroy
end
end

def exit
analytics.idv_cancellation_confirmed(step: params[:step])
cancel_session
if hybrid_session?
render :destroy
else
redirect_to cancelled_redirect_path
end
end

private

def barcode_step?
Expand Down
1 change: 1 addition & 0 deletions app/controllers/idv/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ def extra_view_variables
sp_name: decorated_sp_session.sp_name,
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
skip_doc_auth: idv_session.skip_doc_auth,
skip_doc_auth_from_how_to_verify: false,
skip_doc_auth_from_handoff: idv_session.skip_doc_auth_from_handoff,
opted_in_to_in_person_proofing: idv_session.opted_in_to_in_person_proofing,
doc_auth_selfie_capture:,
Expand Down
17 changes: 9 additions & 8 deletions app/controllers/idv/in_person/state_id_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ def update

pii_from_user = flow_session[:pii_from_user]
initial_state_of_same_address_as_id = pii_from_user[:same_address_as_id]
Idv::StateIdForm::ATTRIBUTES.each do |attr|
pii_from_user[attr] = flow_params[attr]
end
form_result = form.submit(flow_params)

analytics.idv_in_person_proofing_state_id_submitted(
**analytics_arguments.merge(**form_result.to_h),
)
form_result = form.submit(flow_params)

if form_result.success?
Idv::StateIdForm::ATTRIBUTES.each do |attr|
pii_from_user[attr] = flow_params[attr]
end

analytics.idv_in_person_proofing_state_id_submitted(
**analytics_arguments.merge(**form_result.to_h),
)
# Accept Date of Birth from both memorable date and input date components
formatted_dob = MemorableDateComponent.extract_date_param flow_params&.[](:dob)
pii_from_user[:dob] = formatted_dob if formatted_dob
Expand Down Expand Up @@ -130,7 +131,7 @@ def copy_state_id_address_to_residential_address(pii_from_user)
end

def updating_state_id?
pii_from_user.has_key?(:first_name)
user_session.dig(:idv, :ssn).present?
end

def parsed_dob
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

module Idv
class CaptureDocStatusController < ApplicationController
class LinkSentPollController < ApplicationController
include Idv::AvailabilityConcern

before_action :confirm_two_factor_authenticated
Expand Down
22 changes: 9 additions & 13 deletions app/controllers/openid_connect/authorization_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class AuthorizationController < ApplicationController
include AuthorizationCountConcern
include BillableEventTrackable
include ForcedReauthenticationConcern
include OpenidConnectRedirectConcern
include SignInDurationConcern

before_action :build_authorize_form_from_params, only: [:index]
before_action :block_biometric_requests_in_production, only: [:index]
Expand Down Expand Up @@ -137,7 +139,11 @@ def build_authorize_form_from_params
end

def secure_headers_override
return unless IdentityConfig.store.openid_connect_content_security_form_action_enabled
return if form_action_csp_disabled_and_not_server_side_redirect?(
issuer: @authorize_form.service_provider.issuer,
user_uuid: current_user&.uuid,
)

csp_uris = SecureHeadersAllowList.csp_with_sp_redirect_uris(
@authorize_form.redirect_uri,
@authorize_form.service_provider.redirect_uris,
Expand Down Expand Up @@ -210,29 +216,19 @@ def track_events
service_provider: @authorize_form.service_provider,
user: current_user,
)

analytics.sp_redirect_initiated(
ial: event_ial_context.ial,
billed_ial: event_ial_context.bill_for_ial_1_or_2,
sign_in_flow: session[:sign_in_flow],
vtr: sp_session[:vtr],
acr_values: sp_session[:acr_values],
sign_in_duration_seconds:,
)
track_billing_events
end

def redirect_user(redirect_uri, issuer, user_uuid)
user_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_uuid_override_map[user_uuid]

sp_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_issuer_override_map[issuer]

redirect_method =
user_redirect_method_override || sp_redirect_method_override ||
IdentityConfig.store.openid_connect_redirect

case redirect_method
case oidc_redirect_method(issuer: issuer, user_uuid: user_uuid)
when 'client_side'
@oidc_redirect_uri = redirect_uri
render(
Expand Down
70 changes: 38 additions & 32 deletions app/controllers/openid_connect/logout_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,37 @@ module OpenidConnect
class LogoutController < ApplicationController
include SecureHeadersConcern
include FullyAuthenticatable
include OpenidConnectRedirectConcern

before_action :set_devise_failure_redirect_for_concurrent_session_logout, only: [:index]
before_action :set_devise_failure_redirect_for_concurrent_session_logout,
only: [:logout]
before_action :confirm_two_factor_authenticated, only: [:delete]

def index
# Handle logout (with confirmation if initiated by relying partner)
def logout
@logout_form = build_logout_form

result = @logout_form.submit
analytics.oidc_logout_requested(**result.to_h.except(:redirect_uri))
redirect_uri = result.extra[:redirect_uri]

analytics.oidc_logout_requested(**to_event(result))

if result.success? && result.extra[:redirect_uri]
handle_successful_logout_request(result, result.extra[:redirect_uri])
if result.success? && redirect_uri
handle_successful_logout_request(result, redirect_uri)
else
render :error
end
end

# Sign out without confirmation
def delete
@logout_form = build_logout_form
result = @logout_form.submit
redirect_uri = result.extra[:redirect_uri]

analytics.oidc_logout_submitted(**result.to_h.except(:redirect_uri))
analytics.oidc_logout_submitted(**to_event(result))

if result.success? && (redirect_uri = result.extra[:redirect_uri])
analytics.logout_initiated(**result.to_h.except(:redirect_uri))
irs_attempts_api_tracker.logout_initiated(success: result.success?)

redirect_user(redirect_uri, @logout_form.service_provider&.issuer, current_user&.uuid)
sign_out
if result.success? && redirect_uri
handle_logout(result, redirect_uri)
else
render :error
end
Expand All @@ -45,17 +47,7 @@ def set_devise_failure_redirect_for_concurrent_session_logout
end

def redirect_user(redirect_uri, issuer, user_uuid)
user_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_uuid_override_map[user_uuid]

sp_redirect_method_override =
IdentityConfig.store.openid_connect_redirect_issuer_override_map[issuer]

redirect_method =
user_redirect_method_override || sp_redirect_method_override ||
IdentityConfig.store.openid_connect_redirect

case redirect_method
case oidc_redirect_method(issuer: issuer, user_uuid: user_uuid)
when 'client_side'
@oidc_redirect_uri = redirect_uri
render(
Expand All @@ -78,7 +70,10 @@ def redirect_user(redirect_uri, issuer, user_uuid)

def apply_logout_secure_headers_override(redirect_uri, service_provider)
return if service_provider.nil? || redirect_uri.nil?
return unless IdentityConfig.store.openid_connect_content_security_form_action_enabled
return if form_action_csp_disabled_and_not_server_side_redirect?(
issuer: service_provider.issuer,
user_uuid: current_user&.id,
)

uris = SecureHeadersAllowList.csp_with_sp_redirect_uris(
redirect_uri,
Expand All @@ -104,7 +99,8 @@ def build_logout_form
def handle_successful_logout_request(result, redirect_uri)
apply_logout_secure_headers_override(redirect_uri, @logout_form.service_provider)
if require_logout_confirmation?
analytics.oidc_logout_visited(**result.to_h.except(:redirect_uri))
analytics.oidc_logout_visited(**to_event(result))

@params = {
client_id: logout_params[:client_id],
post_logout_redirect_uri: logout_params[:post_logout_redirect_uri],
Expand All @@ -113,15 +109,25 @@ def handle_successful_logout_request(result, redirect_uri)
@service_provider_name = @logout_form.service_provider&.friendly_name
delete_branded_experience(logout: true)

render :index
render :confirm_logout
else
analytics.logout_initiated(**result.to_h.except(:redirect_uri))
irs_attempts_api_tracker.logout_initiated(success: result.success?)
handle_logout(result, redirect_uri)
end
end

sign_out
def handle_logout(result, redirect_uri)
analytics.logout_initiated(**to_event(result))
irs_attempts_api_tracker.logout_initiated(success: result.success?)

redirect_user(redirect_uri, @logout_form.service_provider&.issuer, current_user&.uuid)
end
sign_out

redirect_user(redirect_uri, @logout_form.service_provider&.issuer, current_user&.uuid)
end

# Convert FormResponse into loggable analytics event
# @param [FormResponse] result
def to_event(result)
result.to_h.except(:redirect_uri)
end

def logout_params
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/saml_idp_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SamlIdpController < ApplicationController
include AuthorizationCountConcern
include BillableEventTrackable
include SecureHeadersConcern
include SignInDurationConcern

prepend_before_action :skip_session_load, only: [:metadata, :remotelogout]
prepend_before_action :skip_session_expiration, only: [:metadata, :remotelogout]
Expand Down Expand Up @@ -187,6 +188,7 @@ def track_events
sign_in_flow: session[:sign_in_flow],
vtr: sp_session[:vtr],
acr_values: sp_session[:acr_values],
sign_in_duration_seconds:,
)
track_billing_events
end
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/users/phone_setup_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class PhoneSetupController < ApplicationController
before_action :confirm_recently_authenticated_2fa
before_action :check_max_phone_numbers_per_account, only: %i[index create]

after_action :add_recaptcha_resource_hints, if: :recaptcha_enabled?

helper_method :in_multi_mfa_selection_flow?

def index
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users/piv_cac_login_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ def render_prompt

def process_piv_cac_login
result = piv_cac_login_form.submit
analytics.piv_cac_login(**result.to_h)
clear_piv_cac_information
clear_piv_cac_nonce
if result.success?
process_valid_submission
else
process_invalid_submission
end
analytics.piv_cac_login(**result.to_h)
end

def piv_cac_login_form
Expand Down
1 change: 1 addition & 0 deletions app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def new
issuer: decorated_sp_session.sp_issuer,
)
analytics.sign_in_page_visit(flash: flash[:alert])
session[:sign_in_page_visited_at] = Time.zone.now.to_s
super
end

Expand Down
1 change: 1 addition & 0 deletions app/helpers/script_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def render_javascript_pack_once_tags(...)
**attributes,
crossorigin: local_crossorigin_sources? ? true : nil,
integrity: asset_sources.get_integrity(source),
nopush: false,
)
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/stylesheet_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def stylesheet_tag_once(*names)
def render_stylesheet_once_tags(*names)
stylesheet_tag_once(*names) if names.present?
return if @stylesheets.blank?
safe_join(@stylesheets.map { |stylesheet| stylesheet_link_tag(stylesheet) })
safe_join(@stylesheets.map { |stylesheet| stylesheet_link_tag(stylesheet, nopush: false) })
end
end
# rubocop:enable Rails/HelperInstanceVariable
Loading