diff --git a/lib/devise/models/confirmable.rb b/lib/devise/models/confirmable.rb index 76d4ed68..f21ecb7f 100644 --- a/lib/devise/models/confirmable.rb +++ b/lib/devise/models/confirmable.rb @@ -50,6 +50,12 @@ module Devise # add errors def confirm! pending_any_confirmation do + if confirmation_period_expired? + self.errors.add(:email, :confirmation_period_expired, + :period => Devise::TimeInflector.time_ago_in_words(self.class.confirm_within.ago)) + return false + end + self.confirmation_token = nil self.confirmed_at = Time.now.utc @@ -86,7 +92,10 @@ module Devise # Resend confirmation token. This method does not need to generate a new token. def resend_confirmation_token - pending_any_confirmation { send_confirmation_instructions } + pending_any_confirmation do + self.confirmation_token = nil if confirmation_period_expired? + send_confirmation_instructions + end end # Overwrites active_for_authentication? for confirmation @@ -177,14 +186,8 @@ module Devise # Checks whether the record requires any confirmation. def pending_any_confirmation - expired = confirmation_period_expired? - - if (!confirmed? || pending_reconfirmation?) && !expired + if (!confirmed? || pending_reconfirmation?) yield - elsif expired - self.errors.add(:email, :confirmation_period_expired, - :period => Devise::TimeInflector.time_ago_in_words(self.class.confirm_within.ago)) - false else self.errors.add(:email, :already_confirmed) false diff --git a/test/models/confirmable_test.rb b/test/models/confirmable_test.rb index e4d260b4..3d93d6db 100644 --- a/test/models/confirmable_test.rb +++ b/test/models/confirmable_test.rb @@ -259,6 +259,16 @@ class ConfirmableTest < ActiveSupport::TestCase assert_not confirm_user_by_token_with_confirmation_sent_at(4.days.ago) end end + + test 'should generate a new token if the previous one has expired' do + swap Devise, :confirm_within => 3.days do + user = create_user + user.update_attribute(:confirmation_sent_at, 4.days.ago) + old = user.confirmation_token + user.resend_confirmation_token + assert_not_equal user.confirmation_token, old + end + end end class ReconfirmableTest < ActiveSupport::TestCase