Skip to content
Snippets Groups Projects
Commit ce16bdc0 authored by Drew Blessing's avatar Drew Blessing Committed by Robert Speicher
Browse files

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.
parent 7b50965e
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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."
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -15,26 +16,24 @@ 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
 
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.to_s(:iso8601) }
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
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment