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
10 changes: 10 additions & 0 deletions app/controllers/users/personal_keys_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def create
user_session[:personal_key] = create_new_code
analytics.track_event(Analytics::PROFILE_PERSONAL_KEY_CREATE)
Event.create(user_id: current_user.id, event_type: :new_personal_key)
send_new_personal_key_notification
redirect_to manage_personal_key_url
end

Expand All @@ -45,5 +46,14 @@ def next_step
def user_has_not_visited_any_sp_yet?
current_user.identities.pluck(:last_authenticated_at).compact.empty?
end

def send_new_personal_key_notification
current_user.confirmed_email_addresses.each do |email_address|
UserMailer.personal_key_regenerated(email_address.email).deliver_now
end
MfaContext.new(current_user).phone_configurations.each do |phone_configuration|
SmsPersonalKeyRegenerationNotifierJob.perform_now(phone: phone_configuration.phone)
end
end
end
end
14 changes: 14 additions & 0 deletions app/jobs/sms_personal_key_regeneration_notifier_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class SmsPersonalKeyRegenerationNotifierJob < ApplicationJob
queue_as :sms

# :reek:UtilityFunction
def perform(phone:)
TwilioService::Utils.new.send_sms(
to: phone,
body: I18n.t(
'jobs.sms_personal_key_regeneration_notifier_job.message',
app: APP_NAME
)
)
end
end
4 changes: 4 additions & 0 deletions app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ def personal_key_sign_in(email)
mail(to: email, subject: t('user_mailer.personal_key_sign_in.subject'))
end

def personal_key_regenerated(email)
mail(to: email, subject: t('user_mailer.personal_key_regenerated.subject'))
end

def account_reset_request(email_address, account_reset)
@token = account_reset&.request_token
mail(to: email_address.email, subject: t('user_mailer.account_reset_request.subject'))
Expand Down
16 changes: 16 additions & 0 deletions app/views/user_mailer/personal_key_regenerated.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
p.lead
strong == t('.intro')

table.spacer
tbody
tr
td.s10 height="10px"
| &nbsp;
table.hr
tr
th
| &nbsp;

p == t('.help_html',
reset_password_url: forgot_password_url,
account_url: account_url)
7 changes: 5 additions & 2 deletions config/locales/jobs/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ en:
in to your account. This code will expire in %{expiration} minutes."
verify_message: "%{code} is your %{app} confirmation code. Use this to confirm
your phone number. This code will expire in %{expiration} minutes."
sms_personal_key_regeneration_notifier_job:
message: A new personal key has been issued for your %{app} account. If this
wasn’t you, reset your password and contact us at security@login.gov.
sms_personal_key_sign_in_notifier_job:
message: Your personal key was just used to sign into your login.gov account.
If this wasn’t you, reset your password and contact us at security@login.gov.
message: Your personal key was just used to sign into your %{app} account. If
this wasn’t you, reset your password and contact us at security@login.gov.
5 changes: 4 additions & 1 deletion config/locales/jobs/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ es:
ingresando a su cuenta. Este código caducará en %{expiration} minutos."
verify_message: "%{code} es tu código de confirmación de %{app}. Use esto para
confirmar su número de teléfono. Este código caducará en %{expiration} minutos."
sms_personal_key_regeneration_notifier_job:
message: Se ha emitido una nueva clave personal para tu cuenta %{app}. Si no
eres tú, restablece tu contraseña y ponte en contacto con nosotros en security@login.gov.
sms_personal_key_sign_in_notifier_job:
message: Su clave personal solo se utilizó para iniciar sesión en su cuenta
login.gov. Si no fue así, reinicie su contraseña y contáctenos en security@login.gov.
%{app}. Si no fue así, reinicie su contraseña y contáctenos en security@login.gov.
6 changes: 5 additions & 1 deletion config/locales/jobs/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ fr:
verify_message: "%{code} est votre code de confirmation %{app}. Utilisez-le
pour confirmer votre numéro de téléphone. Ce code expirera dans %{expiration}
minutes."
sms_personal_key_regeneration_notifier_job:
message: Une nouvelle clé personnelle a été émise pour votre compte %{app}.
Si vous ne l'avez pas demandée, réinitialisez votre mot de passe et contactez-nous
à security@login.gov.
sms_personal_key_sign_in_notifier_job:
message: Votre clé personnelle a été utilisée pour vous connecter à votre compte
login.gov. Si ce n’était pas vous, changez votre mot de passe et contactez-nous
%{app}. Si ce n’était pas vous, changez votre mot de passe et contactez-nous
à security@login.gov.
26 changes: 22 additions & 4 deletions config/locales/user_mailer/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ en:
help: If you did not make this change, please visit the %{app} %{help_link}
or %{contact_link}.
intro: You have a new password for your %{app} account.
personal_key_regenerated:
help_html: <p>Your login.gov account was just issued a new 16-character personal
key. You're getting this email to make sure it was you.</p><p>If you just
signed in and regenerated your personal key, great! There's nothing you need
to do.</p><p>If you did not just regenerate your personal key, or if you're
not sure, please immediately take these steps to secure your account:<ol><li><strong><a
href="%{reset_password_url}">Change your password</a>.</strong> Choose a password
that you haven't already used with this account.</li><li><strong><a href="%{account_url}">Sign
in to your login.gov account</a></strong> and make sure you recognize all
of the information on your account page, including the methods you use for
two-factor authentication, such as phone number, authentication app, or security
key.</li><li><strong>On your <a href="%{account_url}">login.gov account page</a>,
request a new personal key.</strong> Remember, never share it unless you are
using it to sign into a trusted website that uses login.gov.</li></ol></p><p>You
should then contact us by calling 844-875-6446 or emailing <a href="mailto:security@login.gov">security@login.gov</a>.</p><br>Thanks,<br>The
login.gov team
intro: New personal key issued
subject: Account Security Alert
personal_key_sign_in:
help_html: <p>Your login.gov account was just signed into using your 16-character
personal key. You're getting this email to make sure it was you.</p> <p>If
Expand All @@ -55,10 +73,10 @@ en:
in to your login.gov account</a></strong> and make sure you recognize all
of the information on your account page, including the methods you use for
two-factor authentication, such as phone number, authentication app, or security
key.</li><li><strong>On your login.gov account page, request a new personal
key.</strong> Remember, never share it unless you are using it to sign into
a trusted website that uses login.gov.</li></ol></p><p>You should then contact
us by calling 844-875-6446 or emailing <a href="mailto:security@login.gov">security@login.gov</a>.</p>
key.</li><li><strong>On your <a href="%{account_url}">login.gov account page</a>,
request a new personal key.</strong> Remember, never share it unless you are
using it to sign into a trusted website that uses login.gov.</li></ol></p><p>You
should then contact us by calling 844-875-6446 or emailing <a href="mailto:security@login.gov">security@login.gov</a>.</p>
<br>Thanks,<br>The login.gov team
intro: Personal key used to sign in
subject: Account Security Alert
Expand Down
21 changes: 21 additions & 0 deletions config/locales/user_mailer/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ es:
password_changed:
help: Si no realizó este cambio, visite el %{app} %{help_link} o el %{contact_link}.
intro: Tiene una contraseña nueva para su cuenta de %{app}.
personal_key_regenerated:
help_html: <p>Tu cuenta de login.gov acaba de emitir una nueva clave personal
de 16 caracteres. Estás recibiendo este correo electrónico para verificar
que eras tú. </p><p>Si acabas de iniciar sesión y has regenerado tu clave
personal, ¡fantástico! No es necesario que hagas nada.</p><p>Si no acabas
de regenerar tu clave personal, o si no estás seguro, sigue estos pasos para
proteger tu cuenta:<ol><li><strong><a href="%{reset_password_url}">Cambia
tu contraseña</a>.</strong> Elige una contraseña que aún no hayas utilizado
con esta cuenta. </li><li><strong><a href="%{account_url}">Inicia sesión en
tu cuenta de login.gov</a></strong> y asegúrate de que reconoces toda la información
de la página de tu cuenta, como los métodos que utilizas para la autenticación
de dos factores, como el número de teléfono, la aplicación de autenticación
o la clave de seguridad. </li><li><strong>En la <a href="%{account_url}">página
de tu cuenta de login.gov</a>, solicita una nueva clave personal</strong>.
Recuerda no compartirla nunca a menos que la estés usando para acceder a un
sitio web de confianza que utilice login.gov.</li></ol></p><p>Deberías ponerte
en contacto con nosotros llamando al 844-875-6446 o enviando un correo electrónico
a <a href="mailto:security@login.gov">security@login.gov</a>.</p><br>Gracias,<br>El
equipo de login.gov
intro: Nueva clave personal emitida
subject: Alerta de seguridad de la cuenta
personal_key_sign_in:
help_html: <p>Su cuenta login.gov acaba de iniciar sesión con su clave personal
de 16 caracteres. Usted está recibiendo este e-mail para asegurarse de que
Expand Down
21 changes: 21 additions & 0 deletions config/locales/user_mailer/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,27 @@ fr:
help: Si vous n'avez pas changé votre mot de passe, veuillez visiter le %{help_link}
de %{app} ou %{contact_link}.
intro: Le mot de passe de votre compte %{app} a été changé.
personal_key_regenerated:
help_html: <p>Votre compte login.gov vient de recevoir une nouvelle clé personnelle
de 16 caractères. Le but de cet e-mail est de s'assurer que c'est bien vous
qui en êtes à l'origine.</p><p> Si vous venez de vous connecter et de régénérer
votre clé personnelle, c'est parfait ! Vous n'avez rien à faire.</p><p> Si
vous ne venez pas de régénérer votre clé personnelle, ou en cas de doute,
effectuez immédiatement les actions suivantes pour sécuriser votre compte :<ol><li><strong><a
href="%{reset_password_url}"> Modifiez votre mot de passe</a>.</strong> Choisissez
un mot de passe que vous n'avez pas encore utilisé avec ce compte.</li><li><strong><a
href="%{account_url}"> Connectez-vous à votre compte login.gov</a></strong>
et vérifiez bien que toutes les informations sur la page de votre compte sont
correctes, y compris les méthodes que vous utilisez pour l’authentification
à deux facteurs, dont le numéro de téléphone, l’application d’authentification
ou la clé de sécurité.</li><li><strong>Sur votre <a href="%{account_url}">page
de compte login.gov</a>, demandez une nouvelle clé personnelle.</strong> N'oubliez
pas de ne jamais la partager, sauf si vous l'utilisez pour vous connecter
à un site de confiance qui utilise login.gov.</li></ol></p><p>Veuillez ensuite
nous contacter en appelant le 844-875-6446 ou par e-mail à <a href="mailto:security@login.gov">security@login.gov</a>.</p><br>Merci,<br>L'équipe
login.gov
intro: Nouvelle clé personnelle émise
subject: Alerte de sécurité du compte
personal_key_sign_in:
help_html: <p>Votre compte login.gov a été connecté à l'aide de votre clé personnelle.
Vous recevez cet email pour vous assurer que c'était bien vous.</p><p>Si vous
Expand Down
19 changes: 17 additions & 2 deletions spec/features/users/regenerate_personal_key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
include PersonalKeyHelper
include SamlAuthHelper

before { stub_twilio_service }

context 'during sign up' do
scenario 'user refreshes personal key page' do
scenario 'refreshing personal key page displays the same key and does not notify the user' do
sign_up_and_view_personal_key

personal_key = scrape_personal_key

# The user should not receive an SMS and an email
expect(UserMailer).to_not receive(:personal_key_regenerated)
expect(SmsPersonalKeyRegenerationNotifierJob).to_not receive(:perform_now)

visit sign_up_personal_key_path

expect(current_path).to eq(sign_up_personal_key_path)
Expand All @@ -24,10 +30,19 @@

context 'after sign up' do
context 'regenerating personal key' do
scenario 'displays new code' do
scenario 'displays new code and notifies the user' do
user = sign_in_and_2fa_user
old_digest = user.encrypted_recovery_code_digest

# The user should receive an SMS and an email
personal_key_sign_in_mail = double
expect(personal_key_sign_in_mail).to receive(:deliver_now)
expect(UserMailer).to receive(:personal_key_regenerated).
with(user.email).
and_return(personal_key_sign_in_mail)
expect(SmsPersonalKeyRegenerationNotifierJob).to receive(:perform_now).
with(phone: user.phone_configurations.first.phone)

click_button t('account.links.regenerate_personal_key')

expect(user.reload.encrypted_recovery_code_digest).to_not eq old_digest
Expand Down
30 changes: 30 additions & 0 deletions spec/jobs/sms_personal_key_regeneration_notifier_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require 'rails_helper'

describe SmsPersonalKeyRegenerationNotifierJob do
include Features::ActiveJobHelper

before do
reset_job_queues
TwilioService::Utils.telephony_service = FakeSms
FakeSms.messages = []
end

describe '.perform' do
it 'sends a message about the personal key sign in to the user' do
allow(Figaro.env).to receive(:twilio_messaging_service_sid).and_return('fake_sid')

described_class.perform_now(phone: '+1 (202) 345-6789')

messages = FakeSms.messages

expect(messages.size).to eq(1)

msg = messages.first

expect(msg.messaging_service_sid).to eq('fake_sid')
expect(msg.to).to eq('+1 (202) 345-6789')
expect(msg.body).
to eq(I18n.t('jobs.sms_personal_key_regeneration_notifier_job.message', app: APP_NAME))
end
end
end
20 changes: 20 additions & 0 deletions spec/mailers/user_mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,26 @@
end
end

describe 'personal_key_regenerated' do
let(:mail) { UserMailer.personal_key_regenerated(user.email) }

it_behaves_like 'a system email'

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

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

it 'renders the body' do
expect(mail.html_part.body).to have_content(
t('user_mailer.personal_key_regenerated.intro')
)
end
end

describe 'signup_with_your_email' do
let(:mail) { UserMailer.signup_with_your_email(user.email) }

Expand Down