Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3ab92af
LG-12979: Create new idv_level value of 'in_person' on Profile (#10371)
gina-yamada Apr 9, 2024
d294130
Remove unused session spec helper methods (#10384)
aduth Apr 9, 2024
904a151
LG-12920: add analytics event for tracking unexpected sdk error (#10368)
Apr 9, 2024
f495687
Use form object pattern for `Idv::AddressController` submission (#10388)
jmhooper Apr 9, 2024
3a793c3
LG-12804: add ID photo and selfie content change. (#10348)
dawei-nava Apr 9, 2024
14bf28c
LG-12609 piv interstitial method (#10282)
mdiarra3 Apr 9, 2024
e578719
Rm duplicate test setup (#10380)
Apr 9, 2024
e793b76
Move logo.png into email images directory (#10389)
aduth Apr 9, 2024
b54806b
Update acuant.tsx (#10397)
Apr 9, 2024
53c3fc8
Add `Pii::Address` and use it store address in `Idv::AddressControlle…
jmhooper Apr 10, 2024
d181236
LG-13022 Allow in-person proofing to satisfy biometric comparison req…
jmhooper Apr 10, 2024
466517f
Avoid initializing geocoder in test environments (#10398)
aduth Apr 10, 2024
7d50c3d
Bump saml-idp version to 0.20.0-18f (#10396)
vrajmohan Apr 10, 2024
41532cb
LG-12571 Specify "hints" for WebAuthn security key enrollment (#10382)
kevinsmaster5 Apr 10, 2024
00404a9
Create tmp/pids directory in make setup (#10402)
zachmargolis Apr 10, 2024
2b9bab9
Change the default value of `use_vot_in_sp_requests` to true (#10403)
jmhooper Apr 10, 2024
2875f1c
LG-13003: Make sure we are checking all relevant Threatmetrix flags w…
jack-ryan-nava-pbc Apr 10, 2024
e4b127c
LG-13033: Reuse registration page for resending email confirmation (#…
aduth Apr 11, 2024
b0ac05a
LG-12103 Embed Styles into Login Button Lookbook Component (#10387)
nprimak Apr 11, 2024
46a1e81
LG-12723: Add alt text to the selfie checkmark for screen readability…
amirbey Apr 11, 2024
9878c48
LG-12320: Camera Resolution Detection (#10227)
charleyf Apr 11, 2024
7411a72
LG-10357 FSM/state-id Add feature flag (#10409)
svalexander Apr 11, 2024
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
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ gem 'rqrcode'
gem 'ruby-progressbar'
gem 'ruby-saml'
gem 'safe_target_blank', '>= 1.0.2'
gem 'saml_idp', github: '18F/saml_idp', tag: '0.19.3-18f'
gem 'saml_idp', github: '18F/saml_idp', tag: '0.20.0-18f'
gem 'scrypt'
gem 'simple_form', '>= 5.0.2'
gem 'stringex', require: false
Expand Down
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ GIT

GIT
remote: https://github.com/18F/saml_idp.git
revision: 95369fdd9336773b9983c8de71eb35a8c92e9683
tag: 0.19.3-18f
revision: f86b4c5ef4281a53b3f13a1db2c2e5839fdf077d
tag: 0.20.0-18f
specs:
saml_idp (0.19.3.pre.18f)
activesupport
Expand Down Expand Up @@ -560,7 +560,7 @@ GEM
ffi (~> 1.0)
rdoc (6.6.2)
psych (>= 4.0.0)
redacted_struct (1.1.0)
redacted_struct (2.0.0)
redcarpet (3.6.0)
redis (5.0.6)
redis-client (>= 0.9.0)
Expand Down
File renamed without changes
4 changes: 2 additions & 2 deletions app/components/login_button_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
**tag_options,
class: css_class,
) do %>
Sign in with <%= content_tag(:span, APP_NAME, class: 'login-button__logo') %>
<% end %>
Sign in with <%= inject_svg %>
<% end %>
26 changes: 24 additions & 2 deletions app/components/login_button_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,40 @@
class LoginButtonComponent < BaseComponent
VALID_COLORS = ['primary', 'primary-darker', 'primary-lighter'].freeze

attr_reader :color, :big, :tag_options
attr_reader :color, :big, :width, :height, :tag_options

def initialize(color: 'primary', big: false, **tag_options)
if !VALID_COLORS.include?(color)
raise ArgumentError, "`color` #{color}} is invalid, expected one of #{VALID_COLORS}"
end

@big = big
@width = big ? '11.1rem' : '7.4rem'
@height = big ? '1.5rem' : '1rem'
@color = color
@tag_options = tag_options
end

def svg
Rails.root.join(
'app', 'assets', 'images',
(color == 'primary-darker' ? 'logo-white.svg' : 'logo.svg')
).read
end

def inject_svg
# rubocop:disable Rails/OutputSafety
Nokogiri::HTML5.fragment(svg).tap do |doc|
doc.at_css('svg').tap do |svg|
svg[:role] = 'img'
svg[:class] = 'login-button__logo'
svg[:width] = width
svg[:height] = height
svg << "<title>#{APP_NAME}</title>"
end
end.to_s.html_safe
# rubocop:enable Rails/OutputSafety
end

def css_class
classes = ['usa-button', *tag_options[:class]]
classes << 'usa-button--big' if big
Expand Down
15 changes: 1 addition & 14 deletions app/components/login_button_component.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
@use 'uswds-core' as *;

.login-button.usa-button--big > .login-button__logo {
font-size: 1.8rem;
margin-top: -2px;
}

.login-button__logo {
margin-left: 2px;
font-size: 1.45rem;
vertical-align: middle;
color: transparent;
background: no-repeat 100% url('logo.svg');

.login-button--primary-darker & {
background-image: url('logo-white.svg');
}
margin-left: 3px;
}

.login-button.login-button--primary-lighter {
Expand Down
10 changes: 10 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ def after_sign_in_path_for(_user)
return fix_broken_personal_key_url if current_user.broken_personal_key?
return user_session.delete(:stored_location) if user_session.key?(:stored_location)
return reactivate_account_url if user_needs_to_reactivate_account?
return login_piv_cac_recommended_path if user_recommended_for_piv_cac?
return second_mfa_reminder_url if user_needs_second_mfa_reminder?
return sp_session_request_url_with_updated_params if sp_session.key?(:request_url)
signed_in_url
Expand Down Expand Up @@ -261,6 +262,15 @@ def user_needs_to_reactivate_account?
resolved_authn_context_result.identity_proofing?
end

def user_recommended_for_piv_cac?
current_user.piv_cac_recommended_dismissed_at.nil? && current_user.has_gov_or_mil_email? &&
!user_already_has_piv?
end

def user_already_has_piv?
MfaContext.new(current_user).piv_cac_configurations.present?
end

def pending_profile_newer_than_password_reset_profile?
return false if current_user.pending_profile.blank?
return false if current_user.password_reset_profile.blank?
Expand Down
7 changes: 6 additions & 1 deletion app/controllers/concerns/fraud_review_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ def handle_fraud_rejection
redirect_to_fraud_rejection if fraud_rejection?
end

# Returns true if the user has not passed IPP at the post office and is
# flagged for fraud review, or has been rejected for fraud.
# Ultimately this is to allow users who fail at the post office to create another enrollment
# bypassing the typical flow of showing the Please Call or Fraud Rejection screens.
def in_person_prevent_fraud_redirection?
IdentityConfig.store.in_person_proofing_enforce_tmx &&
current_user.ipp_enrollment_status_not_passed?
current_user.ipp_enrollment_status_not_passed? &&
(fraud_review_pending? || fraud_rejection?)
end

def redirect_to_fraud_review
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/concerns/mfa_setup_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ def suggest_second_mfa?
mfa_selection_count < 2 && mfa_context.enabled_mfa_methods_count < 2
end

def first_mfa_selection_path
confirmation_path(user_session[:mfa_selections].first)
end

def in_account_creation_flow?
user_session[:in_account_creation_flow] || false
end
Expand All @@ -68,11 +72,21 @@ def mfa_selection_index
user_session[:mfa_selection_index] || 0
end

def set_mfa_selections(selections)
user_session[:mfa_selections] = selections
end

def show_skip_additional_mfa_link?
!(mfa_context.enabled_mfa_methods_count == 1 &&
mfa_context.webauthn_platform_configurations.count == 1)
end

def check_if_possible_piv_user
if current_user.has_gov_or_mil_email? && current_user.piv_cac_recommended_dismissed_at.nil?
redirect_to login_piv_cac_recommended_path
end
end

private

def track_user_registration_mfa_setup_complete_event
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/concerns/unconfirmed_user_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def process_valid_confirmation_token
def process_unsuccessful_confirmation
@confirmation_token = params[:confirmation_token]
flash[:error] = unsuccessful_confirmation_error
redirect_to sign_up_email_resend_url(request_id: params[:_request_id])
redirect_to sign_up_register_url(request_id: params[:_request_id])
end

def unsuccessful_confirmation_error
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/frontend_log_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class FrontendLogController < ApplicationController
# rubocop:enable Layout/LineLength

ALLOWED_EVENTS = %i[
idv_camera_info_error
idv_camera_info_logged
idv_sdk_error_before_init
idv_sdk_selfie_image_capture_closed_without_photo
idv_sdk_selfie_image_capture_failed
idv_sdk_selfie_image_capture_opened
Expand Down
32 changes: 25 additions & 7 deletions app/controllers/idv/address_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ class AddressController < ApplicationController
def new
analytics.idv_address_visit

@presenter = AddressPresenter.new(pii: idv_session.pii_from_doc)
@address_form = Idv::AddressForm.new(idv_session.pii_from_doc)
@presenter = AddressPresenter.new
end

def update
clear_future_steps!
form_result = idv_form.submit(profile_params)
@address_form = Idv::AddressForm.new(idv_session.pii_from_doc)
form_result = @address_form.submit(profile_params)
analytics.idv_address_submitted(**form_result.to_h)
capture_address_edited(form_result)
if form_result.success?
Expand All @@ -33,7 +35,7 @@ def self.step_info
action: :new,
next_steps: [:verify_info],
preconditions: ->(idv_session:, user:) { idv_session.remote_document_capture_complete? },
undo_step: ->(idv_session:, user:) {},
undo_step: ->(idv_session:, user:) { idv_session.updated_user_address = nil },
)
end

Expand All @@ -44,14 +46,30 @@ def idv_form
end

def success
profile_params.each do |key, value|
idv_session.pii_from_doc[key] = value
end
idv_session.pii_from_doc = idv_session.pii_from_doc.merge(
address1: @address_form.address1,
address2: @address_form.address2,
city: @address_form.city,
state: @address_form.state,
zipcode: @address_form.zipcode,
)
idv_session.updated_user_address = address_from_form
redirect_to idv_verify_info_url
end

def failure
redirect_to idv_address_url
@presenter = AddressPresenter.new
render :new
end

def address_from_form
Pii::Address.new(
address1: @address_form.address1,
address2: @address_form.address2,
city: @address_form.city,
state: @address_form.state,
zipcode: @address_form.zipcode,
)
end

def profile_params
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/sign_up/cancellations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def ensure_in_setup
def ensure_valid_confirmation_token
return if @user
flash[:error] = error_message(@token_validator)
redirect_to sign_up_email_resend_url(request_id: params[:_request_id])
redirect_to sign_up_register_url(request_id: params[:_request_id])
end

def error_message(token_validator)
Expand Down
10 changes: 0 additions & 10 deletions app/controllers/sign_up/email_resend_controller.rb

This file was deleted.

3 changes: 2 additions & 1 deletion app/controllers/sign_up/emails_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ def show
@resend_confirmation = params[:resend].present?

email = session.delete(:email)
@resend_email_confirmation_form = ResendEmailConfirmationForm.new(email:)
terms_accepted = session.delete(:terms_accepted)
@resend_email_confirmation_form = ResendEmailConfirmationForm.new(email:, terms_accepted:)

render :show, locals: { email: email }
end
Expand Down
1 change: 1 addition & 0 deletions app/controllers/sign_up/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def process_successful_creation

resend_confirmation = params[:user][:resend]
session[:email] = @register_user_email_form.email
session[:terms_accepted] = @register_user_email_form.terms_accepted
session[:sign_in_flow] = :create_account

redirect_to sign_up_verify_email_url(resend: resend_confirmation)
Expand Down
43 changes: 43 additions & 0 deletions app/controllers/users/piv_cac_recommended_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

module Users
class PivCacRecommendedController < ApplicationController
include TwoFactorAuthenticatableMethods
include MfaSetupConcern
include SecureHeadersConcern

before_action :confirm_user_authenticated_for_2fa_setup
before_action :apply_secure_headers_override
before_action :redirect_unless_user_email_is_gov_or_mil

def show
@recommended_presenter = PivCacRecommendedPresenter.new(current_user)
analytics.piv_cac_recommended_visited
end

def confirm
UpdateUser.new(
user: current_user,
attributes: { piv_cac_recommended_dismissed_at: Time.zone.now },
).call
analytics.piv_cac_recommended(action: :accepted)
set_mfa_selections(['piv_cac'])
redirect_to first_mfa_selection_path
end

def skip
UpdateUser.new(
user: current_user,
attributes: { piv_cac_recommended_dismissed_at: Time.zone.now },
).call
analytics.piv_cac_recommended(action: :skipped)
redirect_to after_sign_in_path_for(current_user)
end

private

def redirect_unless_user_email_is_gov_or_mil
redirect_to after_sign_in_path_for(current_user) unless current_user.has_gov_or_mil_email?
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class TwoFactorAuthenticationSetupController < ApplicationController

before_action :authenticate_user
before_action :confirm_user_authenticated_for_2fa_setup
before_action :check_if_possible_piv_user

delegate :enabled_mfa_methods_count, to: :mfa_context

Expand Down Expand Up @@ -73,12 +74,7 @@ def two_factor_options_presenter

def process_valid_form
user_session[:mfa_selections] = @two_factor_options_form.selection

if user_session[:mfa_selections].first.present?
redirect_to confirmation_path(user_session[:mfa_selections].first)
else
redirect_to after_mfa_setup_path
end
redirect_to(first_mfa_selection_path || after_mfa_setup_path)
end

def two_factor_options_form_params
Expand Down
20 changes: 14 additions & 6 deletions app/forms/idv/address_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ class AddressForm
attr_accessor(*ATTRIBUTES)

def self.model_name
ActiveModel::Name.new(self, nil, 'Address')
ActiveModel::Name.new(self, nil, 'IdvForm')
end

def initialize(pii)
@pii = pii
set_ivars_with_pii(pii)
@address_edited = false
end

Expand All @@ -33,13 +33,21 @@ def submit(params)

private

def set_ivars_with_pii(pii)
pii = pii.symbolize_keys
@address1 = pii[:address1]
@address2 = pii[:address2]
@city = pii[:city]
@state = pii[:state]
@zipcode = pii[:zipcode]
end

def consume_params(params)
params.each do |key, value|
raise_invalid_address_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym)
send(:"#{key}=", value)
if send(key) != @pii[key] && (send(key).present? || @pii[key].present?)
ATTRIBUTES.each do |attribute_name|
if send(attribute_name).to_s != params[attribute_name].to_s
@address_edited = true
end
send(:"#{attribute_name}=", params[attribute_name].to_s)
end
end

Expand Down
Loading