Use devise paranoid mode and ensure the same message is returned every time
Skipped CI because it has already passed. Had to rebase due to CHANGELOG.
This commit is contained in:
parent
7b50965e99
commit
f4ec906e90
|
@ -32,6 +32,9 @@ v 8.2.3
|
|||
- Fix Error 500s when creating global milestones with Unicode characters (Stan Hu)
|
||||
- Update documentation for "Guest" permissions
|
||||
- Properly convert Emoji-only comments into Award Emojis
|
||||
- Enable devise paranoid mode to prevent user enumeration attack
|
||||
|
||||
v 8.2.3
|
||||
- Webhook payload has an added, modified and removed properties for each commit
|
||||
- Fix 500 error when creating a merge request that removes a submodule
|
||||
|
||||
|
|
|
@ -40,7 +40,9 @@ class PasswordsController < Devise::PasswordsController
|
|||
def throttle_reset
|
||||
return unless resource && resource.recently_sent_password_reset?
|
||||
|
||||
redirect_to new_password_path(resource_name),
|
||||
alert: I18n.t('devise.passwords.recently_reset')
|
||||
# Throttle reset attempts, but return a normal message to
|
||||
# avoid user enumeration attack.
|
||||
redirect_to new_user_session_path,
|
||||
notice: I18n.t('devise.passwords.send_paranoid_instructions')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,7 +60,7 @@ Devise.setup do |config|
|
|||
# It will change confirmation, password recovery and other workflows
|
||||
# to behave the same regardless if the e-mail provided was right or wrong.
|
||||
# Does not affect registerable.
|
||||
# config.paranoid = true
|
||||
config.paranoid = true
|
||||
|
||||
# ==> Configuration for :database_authenticatable
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
|
||||
|
|
|
@ -30,7 +30,6 @@ en:
|
|||
success: "Successfully authenticated from %{kind} account."
|
||||
passwords:
|
||||
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
|
||||
recently_reset: "Instructions about how to reset your password have already been sent recently. Please wait a few minutes to try again."
|
||||
send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
|
||||
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
||||
updated: "Your password has been changed successfully. You are now signed in."
|
||||
|
|
|
@ -3,11 +3,12 @@ require 'spec_helper'
|
|||
feature 'Password reset', feature: true do
|
||||
describe 'throttling' do
|
||||
it 'sends reset instructions when not previously sent' do
|
||||
visit root_path
|
||||
forgot_password(create(:user))
|
||||
user = create(:user)
|
||||
forgot_password(user)
|
||||
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
|
||||
expect(current_path).to eq new_user_session_path
|
||||
expect(user.recently_sent_password_reset?).to be_truthy
|
||||
end
|
||||
|
||||
it 'sends reset instructions when previously sent more than a minute ago' do
|
||||
|
@ -15,26 +16,25 @@ feature 'Password reset', feature: true do
|
|||
user.send_reset_password_instructions
|
||||
user.update_attribute(:reset_password_sent_at, 5.minutes.ago)
|
||||
|
||||
visit root_path
|
||||
forgot_password(user)
|
||||
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_instructions'))
|
||||
expect{ forgot_password(user) }.to change{ user.reset_password_sent_at }
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
|
||||
expect(current_path).to eq new_user_session_path
|
||||
end
|
||||
|
||||
it "throttles multiple resets in a short timespan" do
|
||||
it 'throttles multiple resets in a short timespan' do
|
||||
user = create(:user)
|
||||
user.send_reset_password_instructions
|
||||
# Reload because PG handles datetime less precisely than Ruby/Rails
|
||||
user.reload
|
||||
|
||||
visit root_path
|
||||
forgot_password(user)
|
||||
|
||||
expect(page).to have_content(I18n.t('devise.passwords.recently_reset'))
|
||||
expect(current_path).to eq new_user_password_path
|
||||
expect{ forgot_password(user) }.not_to change{ user.reset_password_sent_at }
|
||||
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
|
||||
expect(current_path).to eq new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
def forgot_password(user)
|
||||
visit root_path
|
||||
click_on 'Forgot your password?'
|
||||
fill_in 'Email', with: user.email
|
||||
click_button 'Reset password'
|
||||
|
|
Loading…
Reference in New Issue