Add notification email on invalid second authenticator (#28822)

This commit is contained in:
Claire 2024-01-22 14:55:43 +01:00 committed by GitHub
parent 18004bf227
commit e2d9635074
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 102 additions and 3 deletions

View file

@ -265,21 +265,35 @@ RSpec.describe Auth::SessionsController do
context 'when repeatedly using an invalid TOTP code before using a valid code' do
before do
stub_const('Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR', 2)
# Travel to the beginning of an hour to avoid crossing rate-limit buckets
travel_to '2023-12-20T10:00:00Z'
end
it 'does not log the user in' do
# Travel to the beginning of an hour to avoid crossing rate-limit buckets
travel_to '2023-12-20T10:00:00Z'
Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do
post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(controller.current_user).to be_nil
end
post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(controller.current_user).to be_nil
expect(flash[:alert]).to match I18n.t('users.rate_limited')
end
it 'sends a suspicious sign-in mail', :sidekiq_inline do
Auth::SessionsController::MAX_2FA_ATTEMPTS_PER_HOUR.times do
post :create, params: { user: { otp_attempt: '1234' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(controller.current_user).to be_nil
end
post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
expect(UserMailer.deliveries.size).to eq(1)
expect(UserMailer.deliveries.first.to.first).to eq(user.email)
expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.failed_2fa.subject'))
end
end
context 'when using a valid OTP' do

View file

@ -93,4 +93,9 @@ class UserMailerPreview < ActionMailer::Preview
def suspicious_sign_in
UserMailer.suspicious_sign_in(User.first, '127.0.0.1', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0', Time.now.utc)
end
# Preview this email at http://localhost:3000/rails/mailers/user_mailer/failed_2fa
def failed_2fa
UserMailer.failed_2fa(User.first, '127.0.0.1', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0', Time.now.utc)
end
end

View file

@ -135,6 +135,24 @@ describe UserMailer do
'user_mailer.suspicious_sign_in.subject'
end
describe '#failed_2fa' do
let(:ip) { '192.168.0.1' }
let(:agent) { 'NCSA_Mosaic/2.0 (Windows 3.1)' }
let(:timestamp) { Time.now.utc }
let(:mail) { described_class.failed_2fa(receiver, ip, agent, timestamp) }
it 'renders failed 2FA notification' do
receiver.update!(locale: nil)
expect(mail)
.to be_present
.and(have_body_text(I18n.t('user_mailer.failed_2fa.explanation')))
end
include_examples 'localized subject',
'user_mailer.failed_2fa.subject'
end
describe '#appeal_approved' do
let(:appeal) { Fabricate(:appeal, account: receiver.account, approved_at: Time.now.utc) }
let(:mail) { described_class.appeal_approved(receiver, appeal) }