Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions app/controllers/idv/gpo_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class GpoController < ApplicationController
before_action :confirm_idv_needed
before_action :confirm_user_completed_idv_profile_step
before_action :confirm_mail_not_spammed
before_action :confirm_profile_not_too_old

def index
@presenter = GpoPresenter.new(current_user, url_options)
Expand Down Expand Up @@ -38,6 +39,10 @@ def gpo_mail_service

private

def confirm_profile_not_too_old
redirect_to idv_path if gpo_mail_service.profile_too_old?
end

def step_indicator_current_step
if resend_requested?
:get_a_letter
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/idv/gpo_verify_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ class GpoVerifyController < ApplicationController
def index
analytics.idv_gpo_verification_visited
gpo_mail = Idv::GpoMail.new(current_user)
@mail_spammed = gpo_mail.mail_spammed?
@gpo_verify_form = GpoVerifyForm.new(user: current_user, pii: pii)
@code = session[:last_gpo_confirmation_code] if FeatureManagement.reveal_gpo_code?

@user_can_request_another_gpo_code =
FeatureManagement.gpo_verification_enabled? &&
!gpo_mail.mail_spammed? &&
!gpo_mail.profile_too_old?

if throttle.throttled?
render_throttled
else
Expand Down
9 changes: 9 additions & 0 deletions app/services/idv/gpo_mail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ def mail_spammed?
max_events? && updated_within_last_month?
end

def profile_too_old?
return false if !current_user.pending_profile

min_creation_date = IdentityConfig.store.
gpo_max_profile_age_to_send_letter_in_days.days.ago

current_user.pending_profile.created_at < min_creation_date
end

private

attr_reader :current_user
Expand Down
2 changes: 1 addition & 1 deletion app/views/idv/gpo_verify/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
</div>
<% end %>

<% if FeatureManagement.gpo_verification_enabled? && !@mail_spammed %>
<% if @user_can_request_another_gpo_code %>
<%= link_to t('idv.messages.gpo.resend'), idv_gpo_path, class: 'display-block margin-bottom-2' %>
<% end %>

Expand Down
1 change: 1 addition & 0 deletions config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ good_job_max_threads: 5
good_job_queues: 'default:5;low:1;*'
good_job_queue_select_limit: 5_000
gpo_designated_receiver_pii: '{}'
gpo_max_profile_age_to_send_letter_in_days: 30
hide_phone_mfa_signup: false
identity_pki_disabled: false
identity_pki_local_dev: false
Expand Down
1 change: 1 addition & 0 deletions lib/identity_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ def self.build_store(config_map)
config.add(:good_job_queues, type: :string)
config.add(:good_job_queue_select_limit, type: :integer)
config.add(:gpo_designated_receiver_pii, type: :json, options: { symbolize_names: true })
config.add(:gpo_max_profile_age_to_send_letter_in_days, type: :integer)
config.add(:hide_phone_mfa_signup, type: :boolean)
config.add(:hmac_fingerprinter_key, type: :string)
config.add(:hmac_fingerprinter_key_queue, type: :json)
Expand Down
29 changes: 29 additions & 0 deletions spec/controllers/idv/gpo_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
:confirm_two_factor_authenticated,
:confirm_idv_needed,
:confirm_mail_not_spammed,
:confirm_profile_not_too_old,
)
end

Expand Down Expand Up @@ -95,6 +96,34 @@
expect(assigns(:step_indicator_current_step)).to eq(:get_a_letter)
end
end

context 'user has a pending profile' do
let(:profile_created_at) { Time.zone.now }
let(:pending_profile) do
create(
:profile,
:with_pii,
user: user,
created_at: profile_created_at,
)
end
before do
allow(user).to receive(:pending_profile).and_return(pending_profile)
end

it 'renders ok' do
get :index
expect(response).to be_ok
end

context 'but pending profile is too old to send another letter' do
let(:profile_created_at) { Time.zone.now - 31.days }
it 'redirects back to /verify' do
get :index
expect(response).to redirect_to(idv_path)
end
end
end
end

describe '#create' do
Expand Down
17 changes: 17 additions & 0 deletions spec/controllers/idv/gpo_verify_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@
let(:otp) { 'ABC123' }
let(:submitted_otp) { otp }
let(:user) { create(:user) }
let(:profile_created_at) { Time.zone.now }
let(:pending_profile) do
create(
:profile,
:with_pii,
user: user,
proofing_components: proofing_components,
created_at: profile_created_at,
)
end
let(:proofing_components) { nil }
let(:threatmetrix_enabled) { false }
let(:gpo_enabled) { true }

before do
stub_analytics
Expand All @@ -32,6 +35,7 @@

allow(IdentityConfig.store).to receive(:proofing_device_profiling).
and_return(threatmetrix_enabled ? :enabled : :disabled)
allow(IdentityConfig.store).to receive(:enable_usps_verification).and_return(gpo_enabled)
end

describe '#index' do
Expand All @@ -48,13 +52,26 @@
expect(response).to render_template('idv/gpo_verify/index')
end

it 'sets @user_can_request_another_gpo_code to true' do
action
expect(assigns(:user_can_request_another_gpo_code)).to eql(true)
end

it 'shows throttled page is user is throttled' do
Throttle.new(throttle_type: :verify_gpo_key, user: user).increment_to_throttled!

action

expect(response).to render_template(:throttled)
end

context 'but that profile is > 30 days old' do
let(:profile_created_at) { 31.days.ago }
it 'sets @user_can_request_another_gpo_code to false' do
action
expect(assigns(:user_can_request_another_gpo_code)).to eql(false)
end
end
end

context 'user does not have pending profile' do
Expand Down
35 changes: 34 additions & 1 deletion spec/features/idv/steps/gpo_step_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,35 @@
expect(page).to have_current_path(idv_come_back_later_path)
end

context 'too much time has passed' do
let(:days_passed) { 31 }
let(:max_days_before_resend_disabled) { 30 }

before do
allow(IdentityConfig.store).to receive(:gpo_max_profile_age_to_send_letter_in_days).
and_return(max_days_before_resend_disabled)
end

it 'does not present the user the option to to resend' do
complete_idv_and_sign_out
travel_to(days_passed.days.from_now) do
sign_in_live_with_2fa(user)
expect(page).to have_current_path(idv_gpo_verify_path)
expect(page).not_to have_css('.usa-button', text: t('idv.buttons.mail.resend'))
end
end

it 'does not allow the user to go to the resend page manually' do
complete_idv_and_sign_out
travel_to(days_passed.days.from_now) do
sign_in_live_with_2fa(user)
visit idv_gpo_path
expect(page).to have_current_path(idv_gpo_verify_path)
expect(page).not_to have_css('.usa-button', text: t('idv.buttons.mail.resend'))
end
end
end

it 'allows the user to return to gpo otp confirmation' do
complete_idv_and_return_to_gpo_step
click_doc_auth_back_link
Expand All @@ -44,7 +73,7 @@
expect_user_to_be_unverified(user)
end

def complete_idv_and_return_to_gpo_step
def complete_idv_and_sign_out
start_idv_from_sp
complete_idv_steps_before_gpo_step(user)
click_on t('idv.buttons.mail.send')
Expand All @@ -53,6 +82,10 @@ def complete_idv_and_return_to_gpo_step
visit root_path
click_on t('forms.verify_profile.return_to_profile')
first(:link, t('links.sign_out')).click
end

def complete_idv_and_return_to_gpo_step
complete_idv_and_sign_out
sign_in_live_with_2fa(user)
click_on t('idv.messages.gpo.resend')
end
Expand Down
39 changes: 39 additions & 0 deletions spec/views/idv/gpo_verify/index.html.erb_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'rails_helper'

describe 'idv/gpo_verify/index.html.erb' do
let(:user) do
create(:user)
end

let(:pii) do
{}
end

before do
allow(view).to receive(:step_indicator_steps).and_return({})
@gpo_verify_form = GpoVerifyForm.new(
user: user,
pii: pii,
otp: '1234',
)
end

context 'user is allowed to request another GPO letter' do
before do
@user_can_request_another_gpo_code = true
render
end
it 'includes the send another letter link' do
expect(rendered).to have_link(t('idv.messages.gpo.resend'), href: idv_gpo_path)
end
end
context 'user is NOT allowed to request another GPO letter' do
before do
@user_can_request_another_gpo_code = false
render
end
it 'does not include the send another letter link' do
expect(rendered).not_to have_link(t('idv.messages.gpo.resend'), href: idv_gpo_path)
end
end
end