Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
938e5c0
LG-10248: Send in-person proofing notifications based on the status u…
NavaTim Jul 25, 2023
f05e3dd
Updating to add rails console access command (#8852)
stephencshelton Jul 25, 2023
7c3e03f
LG-9853 ssn add update route (#8844)
svalexander Jul 25, 2023
a5aa1bc
Add hostdata metadata to review apps (#8854)
Jul 25, 2023
76139f4
Remove acuant_maintenance_window configs (#8858)
matthinz Jul 25, 2023
ba0bdd0
Add A/B test buckets to idv_phone_of_record_visited (#8864)
soniaconnolly Jul 25, 2023
3fc7f04
LG-9499: Add banner to alert user they already tried to verify with a…
amirbey Jul 26, 2023
a17969e
LG-10126: SendProofingNotificationJob refactor (#8843)
Jul 26, 2023
7f058ae
LG-10440 Remove `Profile#has_proofed_before?` and related IRS attempt…
jmhooper Jul 26, 2023
e89448f
LG-8763 Log that a profile is pending on password reset (#8872)
jmhooper Jul 26, 2023
ac3a4c8
LG-10313: Blocking associated emails for Gmail when suspended (#8868)
olatifflexion Jul 26, 2023
20d8632
Lg 10190 remove reproof at from profiles 2 of 2 (#8816)
Jul 26, 2023
cef3fc6
LG-10252 Rename throttle translation tags (#8874)
soniaconnolly Jul 26, 2023
dd9d4cf
Render non-passkey-restricted WebAuthn input as visible (#8830)
aduth Jul 27, 2023
8403732
LG-10362: New Image Capture Page Language (#8851)
charleyf Jul 27, 2023
40d3599
LG-10121 remove verified_at from users who have not finished verifica…
theabrad Jul 27, 2023
7ae572c
LG-10457: Track unexpected WebAuthn errors (#8859)
aduth Jul 27, 2023
93ecd59
LG-9968 Switch back to `fraud_review_pending_at` to determine if a us…
jmhooper Jul 27, 2023
a0eb28d
Require re-authentication during MFA setup flow (#8879)
Jul 27, 2023
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
18 changes: 14 additions & 4 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -320,13 +320,17 @@ review-app:
{"name": "POSTGRES_WORKER_HOST", "value": "$CI_ENVIRONMENT_SLUG-identity-idp-chart-postgres.review-apps"},
{"name": "POSTGRES_WORKER_USERNAME", "value": "postgres"},
{"name": "POSTGRES_WORKER_PASSWORD", "value": "postgres"},
{"name": "LOGIN_ENV", "value": "dev"},
{"name": "RAILS_OFFLINE", "value": "true"},
{"name": "REDIS_IRS_ATTEMPTS_API_URL", "value": "redis://$CI_ENVIRONMENT_SLUG-identity-idp-chart-redis.review-apps:6379/2"},
{"name": "REDIS_THROTTLE_URL", "value": "redis://$CI_ENVIRONMENT_SLUG-identity-idp-chart-redis.review-apps:6379/1"},
{"name": "REDIS_URL", "value": "redis://$CI_ENVIRONMENT_SLUG-identity-idp-chart-redis.review-apps:6379"},
{"name": "ASSET_HOST", "value": "https://$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov"},
{"name": "DOMAIN_NAME", "value": "$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov"}
{"name": "DOMAIN_NAME", "value": "$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov"},
{"name": "LOGIN_DATACENTER", "value": "true" },
{"name": "LOGIN_DOMAIN", "value": "identitysandbox.gov"},
{"name": "LOGIN_ENV", "value": "$CI_ENVIRONMENT_SLUG" },
{"name": "LOGIN_HOST_ROLE", "value": "idp" },
{"name": "LOGIN_SKIP_REMOTE_CONFIG", "value": "true" }
]
EOF
)
Expand All @@ -343,13 +347,17 @@ review-app:
{"name": "POSTGRES_WORKER_HOST", "value": "$CI_ENVIRONMENT_SLUG-identity-idp-chart-postgres.review-apps"},
{"name": "POSTGRES_WORKER_USERNAME", "value": "postgres"},
{"name": "POSTGRES_WORKER_PASSWORD", "value": "postgres"},
{"name": "LOGIN_ENV", "value": "dev"},
{"name": "RAILS_OFFLINE", "value": "true"},
{"name": "REDIS_IRS_ATTEMPTS_API_URL", "value": "redis://$CI_ENVIRONMENT_SLUG-identity-idp-chart-redis.review-apps:6379/2"},
{"name": "REDIS_THROTTLE_URL", "value": "redis://$CI_ENVIRONMENT_SLUG-identity-idp-chart-redis.review-apps:6379/1"},
{"name": "REDIS_URL", "value": "redis://$CI_ENVIRONMENT_SLUG-identity-idp-chart-redis.review-apps:6379"},
{"name": "ASSET_HOST", "value": "https://$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov"},
{"name": "DOMAIN_NAME", "value": "$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov"}
{"name": "DOMAIN_NAME", "value": "$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov"},
{"name": "LOGIN_DATACENTER", "value": "true" },
{"name": "LOGIN_DOMAIN", "value": "identitysandbox.gov"},
{"name": "LOGIN_ENV", "value": "$CI_ENVIRONMENT_SLUG" },
{"name": "LOGIN_HOST_ROLE", "value": "worker" },
{"name": "LOGIN_SKIP_REMOTE_CONFIG", "value": "true" }
]
EOF
)
Expand All @@ -366,6 +374,8 @@ review-app:
--set-json idp.ingress.hosts="[{\"host\": \"$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov\", \"paths\": [{\"path\": \"/\", \"pathType\": \"Prefix\"}]}]"
$CI_ENVIRONMENT_SLUG ./charts
- echo "DNS may take a while to propagate, so be patient if it doesn't show up right away"
- echo "To access the rails console, first run 'aws-vault exec sandbox-power -- aws eks update-kubeconfig --name review_app'"
- echo "Then run 'aws-vault exec sandbox-power -- kubectl exec -it service/$CI_ENVIRONMENT_SLUG-identity-idp-chart-idp -n review-apps -- /app/bin/rails console'"
environment:
name: review/$CI_COMMIT_REF_NAME
url: https://$CI_ENVIRONMENT_SLUG.review-app.identitysandbox.gov
Expand Down
20 changes: 10 additions & 10 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
GIT
remote: https://github.com/18F/identity-hostdata.git
revision: e33cbdb3a9c8826f6fc2b1f857fb713a4a233750
revision: 9e2e0441cd93307cbfc5d5b8d4b3b7b4219394fb
tag: v3.4.2
specs:
identity-hostdata (3.4.1)
identity-hostdata (3.4.2)
activesupport (>= 6.1, < 8)
aws-sdk-s3 (~> 1.8)

Expand Down Expand Up @@ -139,28 +139,28 @@ GEM
ast (2.4.2)
awrence (1.2.1)
aws-eventstream (1.2.0)
aws-partitions (1.684.0)
aws-partitions (1.792.0)
aws-sdk-cloudwatchlogs (1.49.0)
aws-sdk-core (~> 3, >= 3.122.0)
aws-sigv4 (~> 1.1)
aws-sdk-core (3.168.4)
aws-sdk-core (3.179.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.61.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (1.71.0)
aws-sdk-core (~> 3, >= 3.177.0)
aws-sigv4 (~> 1.1)
aws-sdk-pinpoint (1.62.0)
aws-sdk-core (~> 3, >= 3.122.0)
aws-sigv4 (~> 1.1)
aws-sdk-pinpointsmsvoice (1.29.0)
aws-sdk-core (~> 3, >= 3.122.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.117.2)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-s3 (1.132.0)
aws-sdk-core (~> 3, >= 3.179.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
aws-sigv4 (~> 1.6)
aws-sdk-ses (1.44.0)
aws-sdk-core (~> 3, >= 3.122.0)
aws-sigv4 (~> 1.1)
Expand All @@ -170,7 +170,7 @@ GEM
aws-sdk-sqs (1.53.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.5.2)
aws-sigv4 (1.6.0)
aws-eventstream (~> 1, >= 1.0.2)
axe-core-api (4.3.2)
dumb_delegator
Expand Down
4 changes: 2 additions & 2 deletions app/assets/stylesheets/components/_file-input.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@use 'uswds-core' as *;
@use '../utilities/typography' as *;

// ===============================================
// Pending upstream Login Design System revisions:
Expand Down Expand Up @@ -45,15 +46,14 @@

.usa-file-input__banner-text {
@include u-font-family('sans');
@extend %h2;
color: color('primary');
display: block;
font-size: 1.625rem;
letter-spacing: 0.4px;
line-height: 1.5;
// For content to appear as vertically centered, offset the larger line-height of the banner to
// match the space below the drag text.
margin-top: ((1.5rem - size('body', '2xs')) - ((1.625rem * 1.5) - 1.625rem)) * 0.5;
text-transform: uppercase;

+ .usa-file-input__drag-text {
@include u-display('block');
Expand Down
12 changes: 9 additions & 3 deletions app/components/webauthn_input_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ def call
:'lg-webauthn-input',
content,
**tag_options,
hidden: true,
platform: platform?.presence,
'passkey-supported-only': passkey_supported_only?.presence,
**initial_hidden_tag_options,
'show-unsupported-passkey': show_unsupported_passkey?.presence,
)
end

def initial_hidden_tag_options
if platform? && passkey_supported_only?
{ hidden: true }
else
{ class: 'js' }
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ def confirm_recently_authenticated_2fa
non_remembered_device_authentication = user_session[:auth_method].present? &&
user_session[:auth_method] != 'remember_device'
return if recently_authenticated? && non_remembered_device_authentication
return if in_multi_mfa_selection_flow?

analytics.user_2fa_reauthentication_required(
auth_method: user_session[:auth_method],
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/hybrid_handoff_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def rate_limited_failure
throttle_type: :idv_send_link,
)
message = I18n.t(
'errors.doc_auth.send_link_throttle',
'errors.doc_auth.send_link_limited',
timeout: distance_of_time_in_words(
Time.zone.now,
[rate_limiter.expires_at, Time.zone.now].compact.max,
Expand Down
8 changes: 2 additions & 6 deletions app/controllers/idv/in_person/ssn_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ def update
analytics.idv_doc_auth_ssn_submitted(
**analytics_arguments.merge(form_response.to_h),
)
# This event is not currently logging but should be kept as decided in LG-10110
irs_attempts_api_tracker.idv_ssn_submitted(
ssn: params[:doc_auth][:ssn],
)

if form_response.success?
flow_session['pii_from_user'][:ssn] = params[:doc_auth][:ssn]

idv_session.invalidate_steps_after_ssn!
redirect_to next_url
redirect_to idv_in_person_verify_info_url
else
@error_message = form_response.first_error_message
render :show, locals: extra_view_variables
Expand Down Expand Up @@ -73,10 +73,6 @@ def confirm_repeat_ssn
redirect_to idv_in_person_verify_info_url
end

def next_url
idv_in_person_verify_info_url
end

def analytics_arguments
{
flow_path: flow_path,
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/idv/phone_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def new
Funnel::DocAuth::RegisterStep.new(current_user.id, current_sp&.issuer).
call(:verify_phone, :view, true)

analytics.idv_phone_of_record_visited
analytics.idv_phone_of_record_visited(**ab_test_analytics_buckets)
render :new, locals: { gpo_letter_available: gpo_letter_available }
elsif async_state.missing?
analytics.proofing_address_result_missing
Expand Down Expand Up @@ -141,6 +141,7 @@ def set_idv_form
previous_params: idv_session.previous_phone_step_params,
allowed_countries:
PhoneNumberCapabilities::ADDRESS_IDENTITY_PROOFING_SUPPORTED_COUNTRY_CODES,
failed_phone_numbers: idv_session.failed_phone_step_numbers,
)
end

Expand Down
1 change: 0 additions & 1 deletion app/controllers/sign_up/completions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ def show

def update
track_completion_event('agency-page')
irs_attempts_api_tracker.idv_reproof # if current_user.profiles&.last&.has_proofed_before?
update_verified_attributes
send_in_person_completion_survey
if decider.go_back_to_mobile_app?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ def webauthn_params

def handle_too_many_confirmation_sends
flash[:error] = t(
'errors.messages.phone_confirmation_throttled',
'errors.messages.phone_confirmation_limited',
timeout: distance_of_time_in_words(
Time.zone.now,
[phone_confirmation_rate_limiter.expires_at, Time.zone.now].compact.max,
Expand Down
9 changes: 5 additions & 4 deletions app/forms/gpo_verify_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ def initialize(user:, pii:, otp: nil)

def submit
result = valid?
threatmetrix_check_failed = fraud_review_checker.fraud_check_failed?
fraud_check_failed = pending_profile&.fraud_pending_reason.present?

if result
pending_profile&.remove_gpo_deactivation_reason
if pending_in_person_enrollment?
UspsInPersonProofing::EnrollmentHelper.schedule_in_person_enrollment(user, pii)
pending_profile&.deactivate(:in_person_verification_pending)
elsif fraud_review_checker.fraud_check_failed? && threatmetrix_enabled?
elsif fraud_check_failed && threatmetrix_enabled?
pending_profile&.deactivate_for_fraud_review
elsif fraud_review_checker.fraud_check_failed?
elsif fraud_check_failed
pending_profile&.activate_after_fraud_review_unnecessary
else
activate_profile
Expand All @@ -40,7 +41,7 @@ def submit
enqueued_at: gpo_confirmation_code&.code_sent_at,
pii_like_keypaths: [[:errors, :otp], [:error_details, :otp]],
pending_in_person_enrollment: pending_in_person_enrollment?,
threatmetrix_check_failed: threatmetrix_check_failed,
fraud_check_failed: fraud_check_failed,
},
)
end
Expand Down
2 changes: 1 addition & 1 deletion app/forms/idv/api_image_upload_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def limit_if_rate_limited
return unless document_capture_session
return unless rate_limited?

errors.add(:limit, t('errors.doc_auth.throttled_heading'), type: :throttled)
errors.add(:limit, t('errors.doc_auth.rate_limited_heading'), type: :throttled)
end

def track_rate_limited
Expand Down
15 changes: 10 additions & 5 deletions app/forms/idv/phone_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class PhoneForm
ALL_DELIVERY_METHODS = [:sms, :voice].freeze

attr_reader :user, :phone, :allowed_countries, :delivery_methods, :international_code,
:otp_delivery_preference
:otp_delivery_preference, :failed_phone_numbers

validate :validate_valid_phone_for_allowed_countries
validate :validate_phone_delivery_methods
Expand All @@ -19,12 +19,14 @@ def initialize(
user:,
previous_params:,
allowed_countries: nil,
delivery_methods: ALL_DELIVERY_METHODS
delivery_methods: ALL_DELIVERY_METHODS,
failed_phone_numbers: []
)
previous_params ||= {}
@user = user
@allowed_countries = allowed_countries
@delivery_methods = delivery_methods
@failed_phone_numbers = failed_phone_numbers

@international_code, @phone = determine_initial_values(
**previous_params.
Expand Down Expand Up @@ -59,9 +61,12 @@ def determine_initial_values(international_code: nil, phone: nil)
international_code ||= country_code_for(phone)
end

phone = PhoneFormatter.format(phone, country_code: international_code)

[international_code, phone]
if failed_phone_numbers.include?(Phonelib.parse(phone).e164)
[nil, nil]
else
phone = PhoneFormatter.format(phone, country_code: international_code)
[international_code, phone]
end
end

def country_code_for(phone)
Expand Down
7 changes: 7 additions & 0 deletions app/forms/register_user_email_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def process_successful_submission(request_id, instructions)
# already taken and if so, we act as if the user registration was successful.
if email_address_record&.user&.suspended?
send_suspended_user_email(email_address_record)
elsif blocked_email_address
send_suspended_user_email(blocked_email_address)
elsif email_taken? && user_unconfirmed?
update_user_language_preference
send_sign_up_unconfirmed_email(request_id)
Expand Down Expand Up @@ -175,4 +177,9 @@ def existing_user
def email_request_id(request_id)
request_id if request_id.present? && ServiceProviderRequestProxy.find_by(uuid: request_id)
end

def blocked_email_address
return @blocked_email_address if defined?(@blocked_email_address)
@blocked_email_address = SuspendedEmail.find_with_email(email)
end
end
15 changes: 9 additions & 6 deletions app/forms/reset_password_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class ResetPasswordForm

def initialize(user)
@user = user
@active_profile = user.active_profile
@pending_profile = user.pending_profile

self.reset_password_token = @user.reset_password_token
end

Expand All @@ -23,7 +26,7 @@ def submit(params)

private

attr_reader :success
attr_reader :success, :active_profile, :pending_profile

def valid_token
if !user.persisted?
Expand Down Expand Up @@ -55,11 +58,9 @@ def update_user
end

def mark_profile_inactive
profile = user.active_profile
return if profile.blank?
return if active_profile.blank?

@profile_deactivated = true
profile&.deactivate(:password_reset)
active_profile.deactivate(:password_reset)
Funnel::DocAuth::ResetSteps.call(user.id)
user.proofing_component&.destroy
end
Expand All @@ -82,7 +83,9 @@ def invalid_account?
def extra_analytics_attributes
{
user_id: user.uuid,
profile_deactivated: (@profile_deactivated == true),
profile_deactivated: active_profile.present?,
pending_profile_invalidated: pending_profile.present?,
pending_profile_pending_reasons: (pending_profile&.pending_reasons || [])&.join(','),
}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ function DocumentCapture({ onStepChange = () => {} }: DocumentCaptureProps) {
pii: submissionError.pii,
})(ReviewIssuesStep)
: ReviewIssuesStep,
title: t('errors.doc_auth.throttled_heading'),
title: t('errors.doc_auth.rate_limited_heading'),
},
] as FormStep[]
).concat(inPersonSteps)
Expand Down
Loading