Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f92f802
Update Monthly Report email logic to match "yesterday" approach (#9511)
zachmargolis Nov 2, 2023
d5f82fb
Fix flaky spec around DST changes (#9512)
soniaconnolly Nov 2, 2023
2b7c12d
Update error handling for Cloudwatch (#9526)
zachmargolis Nov 2, 2023
d366044
Hide missing title errors from user (#9522)
zachmargolis Nov 2, 2023
92b45cc
add hybrid flow to analytics spec (#9525)
amirbey Nov 2, 2023
de8c91a
LG-11302: Add aria labels to forms on hybrid handoff page (#9524)
night-jellyfish Nov 3, 2023
3afe340
LG-11363 Update content to emphasize visiting the PO in IPP (#9494)
gina-yamada Nov 3, 2023
df17dd2
Add IconListComponent ViewComponent (#9504)
aduth Nov 3, 2023
fa721e7
Refactor Personal Key selection presenter as sign-in selection (#9528)
aduth Nov 3, 2023
4da8e2f
Revise title helper as getter setter (#9529)
aduth Nov 3, 2023
7a24e02
Fix Typo (#9491)
VaibhavWakde52 Nov 3, 2023
c772cef
LG-11376: Remove unneeded feature toggle (#9485)
mdiarra3 Nov 3, 2023
78621bb
Add test coverage for application title helpers (#9533)
aduth Nov 3, 2023
f6ccb6d
Add "new verified users" to Monthly Key Metrics Report (LG-11164) (#9…
zachmargolis Nov 3, 2023
043e441
Clarify Monthly Key Metrics Report (#9531)
zachmargolis Nov 3, 2023
7d0179c
LG-11427 Frontend Logging for `phone_with_camera` (#9481)
charleyf Nov 3, 2023
8a6d6b2
Fix translation for email footer help text (account suspension) (#9534)
zachmargolis Nov 3, 2023
89963a7
LG-11317 account ref string for sms (#9474)
jack-ryan-nava-pbc Nov 3, 2023
c6d5ec3
Lint analytics event exceptions on actual name (#9539)
aduth Nov 3, 2023
5209813
Add environment to the body of the monthly key metrics report (LG-114…
zachmargolis Nov 3, 2023
376decd
LG-11427: add phone_with_camera to hybrid analytics test (#9543)
amirbey Nov 3, 2023
82a9a2c
Amirbey/fix missing attributes in frontend events (#9535)
amirbey Nov 3, 2023
2c07328
Update Lograge configuration to ignore active ping controller (#9541)
aduth Nov 6, 2023
d174774
Add Selfie to FE: Feature Flag (#9536)
charleyf Nov 6, 2023
aebe216
Avoid appending info for ignored Lograge actions (#9544)
aduth Nov 6, 2023
9d57ca9
LG 11141 Break up MFA selection presenter classes for Backup codes (#…
kevinsmaster5 Nov 6, 2023
a95d7a5
Start writing decrypted PII to the session based on profile ID (#9515)
jmhooper Nov 6, 2023
bf6b8b3
LG-11355: IPP Opt-in Choices (#9452)
allthesignals Nov 6, 2023
b30f574
Fix icon in report mailer email (#9548)
zachmargolis Nov 6, 2023
285cd35
Add Selfie to FE: Conditional Passiveliveness Script Load (#9546)
charleyf Nov 6, 2023
6435383
Retire the `SsnForm` (#9550)
jmhooper Nov 6, 2023
769a65f
LG-10728 Add a rate limit screen for GPO verification code (#9500)
theabrad Nov 6, 2023
cf88ff0
Bump phonelib from 0.8.4 to 0.8.5 (#9549)
dependabot[bot] Nov 6, 2023
1ca89b5
LG-11318 unify SsnController templates (#9547)
soniaconnolly Nov 6, 2023
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
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ GEM
pg (1.5.4)
pg_query (4.2.3)
google-protobuf (>= 3.22.3)
phonelib (0.8.4)
phonelib (0.8.5)
pkcs11 (0.3.4)
premailer (1.21.0)
addressable
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@ lint_yarn_workspaces: ## Lints Yarn workspace packages
scripts/validate-workspaces.js

lint_asset_bundle_size: ## Lints JavaScript and CSS compiled bundle size
find app/assets/builds/application.css -size -270000c | grep .
@# This enforces an asset size budget to ensure that download sizes are reasonable and to protect
@# against accidentally importing large pieces of third-party libraries. If you're here debugging
@# a failing build, check to ensure that you've not added more JavaScript or CSS than necessary,
@# and you have no options to split that from the common bundles. If you need to increase this
@# budget and accept the fact that this will force end-users to endure longer load times, you
@# should set the new budget to within a few thousand bytes of the production-compiled size.
find app/assets/builds/application.css -size -235000c | grep .
find public/packs/js/application-*.digested.js -size -5000c | grep .

lint_migrations:
Expand Down
1 change: 1 addition & 0 deletions app/assets/images/idv/in-person.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/images/idv/remote.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion app/assets/stylesheets/_uswds.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
@forward 'usa-collection';
@forward 'usa-form';
@forward 'usa-header';
@forward 'usa-icon-list';
@forward 'usa-icon';
@forward 'usa-layout-grid';
@forward 'usa-link';
Expand Down
1 change: 1 addition & 0 deletions app/assets/stylesheets/components/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
@forward 'password';
@forward 'profile-section';
@forward 'personal-key';
@forward 'radio-button';
@forward 'spinner-button';
@forward 'spinner-dots';
@forward 'step-indicator';
Expand Down
28 changes: 28 additions & 0 deletions app/assets/stylesheets/components/_radio-button.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@use 'uswds-core' as *;

@include at-media('tablet') {
.usa-radio__label-illustrated-large {
.usa-radio__image {
@include u-position('absolute');
@include u-left(2);
@include u-top(50px);
}

.usa-radio__label--text {
@include u-margin-left(6);
}
}
}

.usa-radio__input--tile + .usa-radio__label--illustrated.usa-radio__label-illustrated-large {
.usa-radio__image {
@include u-width(88px);
@include u-height('auto');
}

.usa-radio__label--text {
h3 {
@include u-text('gray-70');
}
}
}
9 changes: 9 additions & 0 deletions app/assets/stylesheets/tables-report.css.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
@forward 'uswds-core';
@forward 'usa-prose';
@forward 'usa-table';
@forward 'usa-alert';

.table-number {
font-variant-numeric: tabular-nums;
text-align: right;
}

.usa-alert.usa-alert--info.usa-alert--email {
.usa-alert__body {
&:before {
background-image: url('email/info.png');
}
}
}
5 changes: 5 additions & 0 deletions app/components/icon_list_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<%= content_tag(:ul, **tag_options, class: css_class) do %>
<% items.each do |item| %>
<%= item %>
<% end %>
<% end %>
35 changes: 35 additions & 0 deletions app/components/icon_list_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class IconListComponent < BaseComponent
renders_many :items, ->(**kwargs, &block) do
IconListItemComponent.new(icon:, color:, **kwargs, &block)
end

attr_reader :icon, :size, :color, :tag_options

def initialize(icon: nil, size: 'md', color: nil, **tag_options)
@icon = icon
@size = size
@color = color
@tag_options = tag_options
end

def css_class
classes = ['usa-icon-list', *tag_options[:class]]
classes << ["usa-icon-list--size-#{size}"] if size
classes
end

class IconListItemComponent < BaseComponent
attr_reader :icon, :color

def initialize(icon:, color:)
@icon = icon
@color = color
end

def icon_css_class
classes = ['usa-icon-list__icon']
classes << "text-#{color}" if color
classes
end
end
end
3 changes: 3 additions & 0 deletions app/components/icon_list_component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@use 'uswds-core' as *;

@forward 'usa-icon-list';
6 changes: 6 additions & 0 deletions app/components/icon_list_item_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<li class="usa-icon-list__item">
<%= content_tag(:div, class: icon_css_class) do %>
<%= render IconComponent.new(icon: icon) %>
<% end %>
<div class="usa-icon-list__content"><%= content %></div>
</li>
4 changes: 2 additions & 2 deletions app/components/process_list_component.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class ProcessListComponent < BaseComponent
renders_many :items, ->(**kwargs, &block) {
renders_many :items, ->(**kwargs, &block) do
ProcessListItemComponent.new(heading_level:, **kwargs, &block)
}
end

attr_reader :heading_level, :big, :connected, :tag_options

Expand Down
4 changes: 4 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ def session_expires_at

# for lograge
def append_info_to_payload(payload)
return if Lograge.lograge_config.ignore_actions&.include?(
"#{Lograge.controller_field(payload)}##{payload[:action]}",
)

payload[:user_id] = analytics_user.uuid unless @skip_session_load

payload[:git_sha] = IdentityConfig::GIT_SHA
Expand Down
17 changes: 15 additions & 2 deletions app/controllers/concerns/ial2_profile_concern.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
module Ial2ProfileConcern
extend ActiveSupport::Concern

def cache_active_profile(raw_password)
def cache_profiles(raw_password)
pending_profile = current_user.pending_profile
if pending_profile.present?
cache_profile_and_handle_errors(raw_password, pending_profile)
end

active_profile = current_user.active_profile
if active_profile.present?
cache_profile_and_handle_errors(raw_password, active_profile)
end
end

private

def cache_profile_and_handle_errors(raw_password, profile)
cacher = Pii::Cacher.new(current_user, user_session)
profile = current_user.active_or_pending_profile
begin
cacher.save(raw_password, profile)
rescue Encryption::EncryptionError => err
Expand Down
10 changes: 5 additions & 5 deletions app/controllers/concerns/idv/verify_info_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,11 @@ def async_state_done(current_async_state)
failure_reason: irs_attempts_api_tracker.parse_failure_reason(form_response),
)

form_response = form_response.merge(check_ssn) if form_response.success?
form_response.extra[:ssn_is_unique] = DuplicateSsnFinder.new(
ssn: idv_session.ssn,
user: current_user,
).ssn_is_unique?

summarize_result_and_rate_limit(form_response)
delete_async

Expand Down Expand Up @@ -305,10 +309,6 @@ def log_idv_verification_submitted_event(success: false, failure_reason: nil)
)
end

def check_ssn
Idv::SsnForm.new(current_user).submit(ssn: idv_session.ssn)
end

def move_applicant_to_idv_session
idv_session.applicant = pii
idv_session.applicant[:ssn] = idv_session.ssn
Expand Down
8 changes: 6 additions & 2 deletions app/controllers/idv/agreement_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ def update
if result.success?
idv_session.idv_consent_given = true

redirect_to idv_hybrid_handoff_url
if IdentityConfig.store.in_person_proofing_opt_in_enabled
redirect_to idv_how_to_verify_url
else
redirect_to idv_hybrid_handoff_url
end
else
redirect_to idv_agreement_url
end
Expand All @@ -42,7 +46,7 @@ def self.step_info
Idv::StepInfo.new(
key: :agreement,
controller: controller_name,
next_steps: [:hybrid_handoff, :document_capture, :phone_question],
next_steps: [:hybrid_handoff, :document_capture, :phone_question, :how_to_verify],
preconditions: ->(idv_session:, user:) { idv_session.welcome_visited },
)
end
Expand Down
17 changes: 4 additions & 13 deletions app/controllers/idv/by_mail/enter_code_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def index
)

if rate_limiter.limited?
render_rate_limited
redirect_to idv_enter_code_rate_limited_url
return
end

Expand All @@ -46,9 +46,10 @@ def pii

def create
if rate_limiter.limited?
render_rate_limited
redirect_to idv_enter_code_rate_limited_url
return
end

rate_limiter.increment!

@gpo_verify_form = build_gpo_verify_form
Expand All @@ -61,7 +62,7 @@ def create
)

if !result.success?
flash[:error] = @gpo_verify_form.errors.first.message
flash[:error] = @gpo_verify_form.errors.first.message if !rate_limiter.limited?
redirect_to idv_verify_by_mail_enter_code_url
return
end
Expand Down Expand Up @@ -119,16 +120,6 @@ def rate_limiter
)
end

def render_rate_limited
irs_attempts_api_tracker.idv_gpo_verification_rate_limited
analytics.rate_limit_reached(
limiter_type: :verify_gpo_key,
)

@expires_at = rate_limiter.expires_at
render :rate_limited
end

def build_gpo_verify_form
GpoVerifyForm.new(
user: current_user,
Expand Down
34 changes: 34 additions & 0 deletions app/controllers/idv/by_mail/enter_code_rate_limited_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Idv
module ByMail
class EnterCodeRateLimitedController < ApplicationController
include IdvSession
include FraudReviewConcern

before_action :confirm_two_factor_authenticated
before_action :confirm_verification_needed

def index
irs_attempts_api_tracker.idv_gpo_verification_rate_limited
analytics.rate_limit_reached(
limiter_type: :verify_gpo_key,
)

@expires_at = rate_limiter.expires_at
end

private

def rate_limiter
@rate_limiter ||= RateLimiter.new(
user: current_user,
rate_limit_type: :verify_gpo_key,
)
end

def confirm_verification_needed
return if current_user.gpo_verification_pending_profile?
redirect_to account_url
end
end
end
end
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 @@ -47,6 +47,7 @@ def extra_view_variables
flow_path: 'standard',
sp_name: decorated_sp_session.sp_name,
failure_to_proof_url: return_to_sp_failure_to_proof_url(step: 'document_capture'),
phone_with_camera: idv_session.phone_with_camera,
}.merge(
acuant_sdk_upgrade_a_b_testing_variables,
phone_question_ab_test_analytics_bucket,
Expand Down
64 changes: 64 additions & 0 deletions app/controllers/idv/how_to_verify_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
module Idv
class HowToVerifyController < ApplicationController
include IdvStepConcern
include RenderConditionConcern

before_action :confirm_step_allowed

check_or_render_not_found -> { self.class.enabled? }

def show
analytics.idv_doc_auth_how_to_verify_visited(**analytics_arguments)
@idv_how_to_verify_form = Idv::HowToVerifyForm.new
end

def update
result = Idv::HowToVerifyForm.new.submit(how_to_verify_form_params)

analytics.idv_doc_auth_how_to_verify_submitted(
**analytics_arguments.merge(result.to_h),
)

if result.success?
if how_to_verify_form_params['selection'] == Idv::HowToVerifyForm::REMOTE
redirect_to idv_hybrid_handoff_url
else
redirect_to idv_document_capture_url
end
else
flash[:error] = result.first_error_message
redirect_to idv_how_to_verify_url
end
end

def self.step_info
Idv::StepInfo.new(
key: :how_to_verify,
controller: controller_name,
next_steps: [:hybrid_handoff, :document_capture],
preconditions: ->(idv_session:, user:) do
self.enabled?
end,
)
end

def self.enabled?
IdentityConfig.store.in_person_proofing_opt_in_enabled
end

private

def analytics_arguments
{
step: 'how_to_verify',
analytics_id: 'Doc Auth',
}
end

def how_to_verify_form_params
params.require(:idv_how_to_verify_form).permit(:selection, selection: [])
rescue ActionController::ParameterMissing
ActionController::Parameters.new(selection: [])
end
end
end
Loading