diff --git a/lib/devise/models/recoverable.rb b/lib/devise/models/recoverable.rb index d6782977..35dc8b44 100644 --- a/lib/devise/models/recoverable.rb +++ b/lib/devise/models/recoverable.rb @@ -27,10 +27,16 @@ module Devise end included do + def expire_reset_token? + # Expire the reset token only if the e-mail or password were changed + # since the last time the record was saved to the database. An admin + # may want to retain the token to give the newly-created user a chance + # to set the password for the first time. + persisted? && (email_changed? || encrypted_password_changed?) + end + before_save do - if email_changed? || encrypted_password_changed? - clear_reset_password_token - end + clear_reset_password_token if expire_reset_token? end end diff --git a/test/models/recoverable_test.rb b/test/models/recoverable_test.rb index 8198698b..fc9ef949 100644 --- a/test/models/recoverable_test.rb +++ b/test/models/recoverable_test.rb @@ -42,6 +42,17 @@ class RecoverableTest < ActiveSupport::TestCase assert_nil user.reset_password_token end + test 'should not clear reset password token for new user' do + user = new_user + assert_nil user.reset_password_token + + user.send_reset_password_instructions + assert_present user.reset_password_token + + user.save + assert_present user.reset_password_token + end + test 'should clear reset password token if changing password' do user = create_user assert_nil user.reset_password_token