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
6 changes: 6 additions & 0 deletions app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,12 @@ def account_rejected
end
end

def suspended_reset_password
with_user_locale(user) do
mail(to: email_address.email, subject: t('user_mailer.suspended_reset_password.subject'))
end
end

private

def email_should_receive_nonessential_notifications?(email)
Expand Down
5 changes: 5 additions & 0 deletions app/services/request_password_reset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ def send_reset_password_instructions
if throttle.throttled?
analytics.throttler_rate_limit_triggered(throttle_type: :reset_password_email)
irs_attempts_api_tracker.forgot_password_email_rate_limited(email: email)
elsif user.suspended?
UserMailer.with(
user: user,
email_address: email_address_record,
).suspended_reset_password.deliver_now_or_later
else
token = user.set_reset_password_token
UserMailer.with(user: user, email_address: email_address_record).reset_password_instructions(
Expand Down
13 changes: 13 additions & 0 deletions app/views/user_mailer/suspended_reset_password.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<table class="spacer">
<tbody>
<tr>
<td class="s10" height="10px">
&nbsp;
</td>
</tr>
</tbody>
</table>

<p>
<%= t('user_mailer.suspended_reset_password.message', support_code: IdentityConfig.store.account_suspended_support_code, contact_number: IdentityConfig.store.idv_contact_phone_number) %>
</p>
1 change: 1 addition & 0 deletions config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ aamva_verification_url: https://example.org:12345/verification/url
all_redirect_uris_cache_duration_minutes: 2
account_reset_token_valid_for_days: 1
account_reset_wait_period_days: 1
account_suspended_support_code: EFGHI
acuant_maintenance_window_start:
acuant_maintenance_window_finish:
acuant_assure_id_password: ''
Expand Down
5 changes: 5 additions & 0 deletions config/locales/user_mailer/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,8 @@ en:
in with this email address, you can ignore this message.
link_text: Go to %{app_name}
reset_password_html: If you can’t remember your password, go to %{app_name} to reset it.
suspended_reset_password:
message: There was an issue resetting your password. Please give our contact
center a call at %{contact_number} and provide this code -
%{support_code}.
subject: We couldn’t reset your password
5 changes: 5 additions & 0 deletions config/locales/user_mailer/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,8 @@ es:
una sesión con este email, puede ignorar este mensaje.
link_text: Ir a %{app_name}
reset_password_html: Si no recuerda su contraseña, vaya a %{app_name} para restablecerla.
suspended_reset_password:
message: Se produjo un problema al restablecer su contraseña. Llame a nuestro
centro de atención al número %{contact_number} y proporcione este código
- %{support_code}.
subject: No pudimos restablecer su contraseña
5 changes: 5 additions & 0 deletions config/locales/user_mailer/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,8 @@ fr:
link_text: Allez à %{app_name}
reset_password_html: Si vous ne vous souvenez plus de votre mot de passe, allez
à %{app_name} pour le réinitialiser.
suspended_reset_password:
message: La réinitialisation de votre mot de passe a posé un problème. Veuillez
appeler notre centre d’appels au %{contact_number} et fournir ce code -
%{support_code}.
subject: Nous n’avons pas pu réinitialiser votre mot de passe
1 change: 1 addition & 0 deletions lib/identity_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def self.build_store(config_map)
config.add(:all_redirect_uris_cache_duration_minutes, type: :integer)
config.add(:account_reset_token_valid_for_days, type: :integer)
config.add(:account_reset_wait_period_days, type: :integer)
config.add(:account_suspended_support_code, type: :string)
config.add(:acuant_maintenance_window_start, type: :timestamp, allow_nil: true)
config.add(:acuant_maintenance_window_finish, type: :timestamp, allow_nil: true)
config.add(:acuant_assure_id_password)
Expand Down
7 changes: 7 additions & 0 deletions spec/mailers/previews/user_mailer_preview.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ def reset_password_instructions
)
end

def suspended_reset_password
UserMailer.with(
user: user,
email_address: email_address_record,
).suspended_reset_password
end

def password_changed
UserMailer.with(user: user, email_address: email_address_record).
password_changed(disavowal_token: SecureRandom.hex)
Expand Down
29 changes: 29 additions & 0 deletions spec/mailers/user_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,35 @@ def expect_email_body_to_have_help_and_contact_links
end
end

describe '#suspended_reset_password' do
let(:mail) do
UserMailer.with(user: user, email_address: email_address).
suspended_reset_password
end

it_behaves_like 'a system email'
it_behaves_like 'an email that respects user email locale preference'

it 'sends to the specified email' do
expect(mail.to).to eq [email_address.email]
end

it 'renders the subject' do
expect(mail.subject).to eq t('user_mailer.suspended_reset_password.subject')
end

it 'renders the body' do
expect(mail.html_part.body).
to have_content(
t(
'user_mailer.suspended_reset_password.message',
support_code: IdentityConfig.store.account_suspended_support_code,
contact_number: IdentityConfig.store.idv_contact_phone_number,
),
)
end
end

describe '#deliver_later' do
it 'does not queue email if it potentially contains sensitive value' do
user = create(:user)
Expand Down
2 changes: 1 addition & 1 deletion spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@
end

describe '#suspend!' do
context 'user is not already supsended' do
context 'user is not already suspended' do
let(:mock_session_id) { SecureRandom.uuid }
before do
UpdateUser.new(user: user, attributes: { unique_session_id: mock_session_id }).call
Expand Down
53 changes: 52 additions & 1 deletion spec/services/request_password_reset_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
end
end

it 'sends password reset instructions' do
it 'sets password reset token' do
expect { subject }.
to(change { user.reload.reset_password_token })
end
Expand All @@ -81,6 +81,57 @@
end
end

context 'when the user is found and confirmed, but is suspended' do
subject(:perform) do
described_class.new(
email: email,
irs_attempts_api_tracker: irs_attempts_api_tracker,
).perform
end

before do
user.suspend!
allow(UserMailer).to receive(:reset_password_instructions).
and_wrap_original do |impl, user, email, options|
token = options.fetch(:token)
expect(token).to be_present
expect(Devise.token_generator.digest(User, :reset_password_token, token)).
to eq(user.reset_password_token)

impl.call(user, email, **options)
end
allow(UserMailer).to receive(:suspended_reset_password).
and_wrap_original do |impl, user, email, options|
token = options.fetch(:token)
expect(token).not_to be_present

impl.call(user, email, **options)
end
end

it 'does not set a password reset token' do
expect { subject }.
not_to(change { user.reload.reset_password_token })
end

it 'sends an email to the suspended user' do
expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1)
end

it 'does not send a recovery activated push event' do
expect(PushNotification::HttpPush).not_to receive(:deliver).
with(PushNotification::RecoveryActivatedEvent.new(user: user))

subject
end

it 'does not call irs tracking method forgot_password_email_sent' do
subject

expect(irs_attempts_api_tracker).not_to have_received(:forgot_password_email_sent)
end
end

context 'when the user is found, not privileged, and not yet confirmed' do
it 'sends password reset instructions' do
allow(UserMailer).to receive(:reset_password_instructions).
Expand Down