Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to not automatically sign in a user after changing a password #4569

Merged
merged 3 commits into from Dec 28, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 25 additions & 7 deletions app/controllers/devise/registrations_controller.rb
Expand Up @@ -50,12 +50,9 @@ def update
resource_updated = update_resource(resource, account_update_params)
yield resource if block_given?
if resource_updated
if is_flashing_format?
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
:update_needs_confirmation : :updated
set_flash_message :notice, flash_key
end
bypass_sign_in resource, scope: resource_name
set_flash_message_for_update(resource, prev_unconfirmed_email)
bypass_sign_in resource, scope: resource_name if sign_in_after_change_password?

respond_with resource, location: after_update_path_for(resource)
else
clean_up_passwords resource
Expand Down Expand Up @@ -127,7 +124,7 @@ def after_inactive_sign_up_path_for(resource)
# The default url to be used after updating a resource. You need to overwrite
# this method in your own RegistrationsController.
def after_update_path_for(resource)
signed_in_root_path(resource)
sign_in_after_change_password? ? signed_in_root_path(resource) : new_session_path(resource_name)
end

# Authenticates the current scope and gets the current resource from the session.
Expand All @@ -147,4 +144,25 @@ def account_update_params
def translation_scope
'devise.registrations'
end

private
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required to be private? Other methods above are protected. I'm subclassing and overriding some methods of Devise::RegistrationsController and need to copy these new private methods during the gem version upgrade.


def set_flash_message_for_update(resource, prev_unconfirmed_email)
return unless is_flashing_format?

flash_key = if update_needs_confirmation?(resource, prev_unconfirmed_email)
:update_needs_confirmation
elsif sign_in_after_change_password?
:updated
else
:updated_but_not_signed_in
end
set_flash_message :notice, flash_key
end

def sign_in_after_change_password?
return true if account_update_params[:password].blank?

Devise.sign_in_after_change_password
end
end
1 change: 1 addition & 0 deletions config/locales/en.yml
Expand Up @@ -44,6 +44,7 @@ en:
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
updated: "Your account has been updated successfully."
updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again"
sessions:
signed_in: "Signed in successfully."
signed_out: "Signed out successfully."
Expand Down
4 changes: 4 additions & 0 deletions lib/devise.rb
Expand Up @@ -293,6 +293,10 @@ module Test
mattr_accessor :token_generator
@@token_generator = nil

# When set to false, changing a password does not automatically sign in a user
mattr_accessor :sign_in_after_change_password
@@sign_in_after_change_password = true

def self.rails51? # :nodoc:
Rails.gem_version >= Gem::Version.new("5.1.x")
end
Expand Down
2 changes: 2 additions & 0 deletions lib/devise/models/registerable.rb
Expand Up @@ -21,6 +21,8 @@ module ClassMethods
def new_with_session(params, session)
new(params)
end

Devise::Models.config(self, :sign_in_after_change_password)
end
end
end
Expand Down
8 changes: 7 additions & 1 deletion lib/generators/templates/devise.rb
Expand Up @@ -9,7 +9,7 @@
# Devise will use the `secret_key_base` as its `secret_key`
# by default. You can change it below and use your own secret key.
# config.secret_key = '<%= SecureRandom.hex(64) %>'

# ==> Controller configuration
# Configure the parent class to the devise controllers.
# config.parent_controller = 'DeviseController'
Expand Down Expand Up @@ -290,4 +290,10 @@
# ActiveSupport.on_load(:devise_failure_app) do
# include Turbolinks::Controller
# end

# ==> Configuration for :registerable

# When set to false, does not sign a user in automatically after their password is
# changed. Defaults to true, so a user is signed in automatically after changing a password.
# config.sign_in_after_change_password = true
end
33 changes: 33 additions & 0 deletions test/integration/registerable_test.rb
Expand Up @@ -179,6 +179,39 @@ def user_sign_up
assert warden.authenticated?(:user)
end

test 'a signed in user should not be able to use the website after changing their password if config.sign_in_after_change_password is false' do
swap Devise, sign_in_after_change_password: false do
sign_in_as_user
get edit_user_registration_path

fill_in 'password', with: '1234567890'
fill_in 'password confirmation', with: '1234567890'
fill_in 'current password', with: '12345678'
click_button 'Update'

assert_contain 'Your account has been updated successfully, but since your password was changed, you need to sign in again'
assert_equal new_user_session_path, @request.path
refute warden.authenticated?(:user)
end
end

test 'a signed in user should be able to use the website after changing its email with config.sign_in_after_change_password is false' do
swap Devise, sign_in_after_change_password: false do
sign_in_as_user
get edit_user_registration_path

fill_in 'email', with: 'user.new@example.com'
fill_in 'current password', with: '12345678'
click_button 'Update'

assert_current_url '/'
assert_contain 'Your account has been updated successfully.'

assert warden.authenticated?(:user)
assert_equal "user.new@example.com", User.to_adapter.find_first.email
end
end

test 'a signed in user should not change their current user with invalid password' do
sign_in_as_user
get edit_user_registration_path
Expand Down
6 changes: 6 additions & 0 deletions test/rails_app/config/initializers/devise.rb
Expand Up @@ -180,6 +180,12 @@
# manager.default_strategies(scope: :user).unshift :some_external_strategy
# end

# ==> Configuration for :registerable

# When set to false, does not sign a user in automatically after their password is
# changed. Defaults to true, so a user is signed in automatically after changing a password.
# config.sign_in_after_change_password = true

ActiveSupport.on_load(:devise_failure_app) do
require "lazy_load_test_module"
include LazyLoadTestModule
Expand Down