Skip to content

Commit

Permalink
Ensure a new token is generated if the previous one expired
Browse files Browse the repository at this point in the history
  • Loading branch information
José Valim committed Jul 23, 2012
1 parent f4db03d commit 6e79c5c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
19 changes: 11 additions & 8 deletions lib/devise/models/confirmable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ def self.required_fields(klass)
# 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

Expand Down Expand Up @@ -86,7 +92,10 @@ def send_confirmation_instructions

# 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
Expand Down Expand Up @@ -177,14 +186,8 @@ def confirmation_period_expired?

# 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
Expand Down
10 changes: 10 additions & 0 deletions test/models/confirmable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,16 @@ def confirm_user_by_token_with_confirmation_sent_at(confirmation_sent_at)
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
Expand Down

0 comments on commit 6e79c5c

Please sign in to comment.