Maintenance: Improve 'Forgot Password' handling.

This commit is contained in:
Martin Gruner 2022-03-09 13:38:42 +01:00
parent e74af6e4bc
commit f052c2a33f
2 changed files with 55 additions and 21 deletions

View file

@ -490,15 +490,13 @@ returns
# try second lookup with email # try second lookup with email
user ||= User.find_by(email: username.downcase.strip, active: true) user ||= User.find_by(email: username.downcase.strip, active: true)
# check if email address exists return if !user || !user.email
return if !user
return if !user.email
# generate token # Discard any possible previous tokens for safety reasons.
token = Token.create(action: 'PasswordReset', user_id: user.id) Token.where(action: 'PasswordReset', user_id: user.id).destroy_all
{ {
token: token, token: Token.create(action: 'PasswordReset', user_id: user.id, persistent: false),
user: user, user: user,
} }
end end

View file

@ -3,6 +3,7 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe 'Password Reset', type: :system do RSpec.describe 'Password Reset', type: :system do
context 'when logged in already' do
before do before do
visit 'password_reset' visit 'password_reset'
end end
@ -10,24 +11,59 @@ RSpec.describe 'Password Reset', type: :system do
it 'logged in user cannot open password reset' do it 'logged in user cannot open password reset' do
expect(page).to have_no_text 'password' expect(page).to have_no_text 'password'
end end
end
context 'when not logged in', authenticated_as: false do context 'when not logged in', authenticated_as: false do
it 'proceeds with non-existant user' do def request_reset
fill_in 'username', with: 'nonexisting' visit 'password_reset'
fill_in 'username', with: username
click '.reset_password .btn--primary' click '.reset_password .btn--primary'
expect(page).to have_text 'sent password reset instructions'
end end
it 'proceeds with an actual user' do before do
user = create(:agent) freeze_time
request_reset
end
fill_in 'username', with: user.email context 'with non-existant user' do
let(:username) { 'nonexisting' }
click '.reset_password .btn--primary'
it 'pretends to proceed' do
expect(page).to have_text 'sent password reset instructions' expect(page).to have_text 'sent password reset instructions'
end end
end end
context 'with existing user' do
let(:user) { create(:agent) }
let(:username) { user.email }
let(:generated_tokens) { Token.where(action: 'PasswordReset', user_id: user.id) }
it 'proceeds' do
expect(page).to have_text 'sent password reset instructions'
end
it 'creates a token' do
expect(generated_tokens.count).to eq 1
end
it 'token will expire' do
expect(generated_tokens.first.persistent).to be false
end
context 'when submitting multiple times' do
before do
refresh
request_reset # a second time now
end
it 'proceeds' do
expect(page).to have_text 'sent password reset instructions'
end
it 'discards the previous token' do
expect(generated_tokens.count).to eq 1
end
end
end
end
end end