2009-09-17 10:06:46 -04:00
|
|
|
module Devise
|
2009-10-09 07:30:25 -04:00
|
|
|
module Models
|
2009-10-09 08:27:44 -04:00
|
|
|
|
|
|
|
# Confirmable is responsible to verify if an account is already confirmed to
|
2009-10-13 16:01:42 -04:00
|
|
|
# sign in, and to send emails with confirmation instructions.
|
2009-10-09 08:27:44 -04:00
|
|
|
# Confirmation instructions are sent to the user email after creating a
|
|
|
|
# record, after updating it's email and also when manually requested by
|
|
|
|
# a new confirmation instruction request.
|
|
|
|
# Whenever the user update it's email, his account is automatically unconfirmed,
|
|
|
|
# it means it won't be able to sign in again without confirming the account
|
|
|
|
# again through the email that was sent.
|
|
|
|
# Confirmable also hooks into authenticate, to verify if the account is
|
|
|
|
# confirmed or not before authenticating the user.
|
|
|
|
# Examples:
|
|
|
|
#
|
|
|
|
# User.authenticate('email@test.com', 'password123') # true if it's confirmed, otherwise false
|
|
|
|
# User.find(1).confirm! # returns true unless it's already confirmed
|
|
|
|
# User.find(1).confirmed? # true/false
|
|
|
|
# User.find(1).send_confirmation_instructions # manually send instructions
|
|
|
|
# User.find(1).reset_confirmation! # reset confirmation status and send instructions
|
|
|
|
#
|
2009-10-09 07:30:25 -04:00
|
|
|
module Confirmable
|
2009-09-17 10:06:46 -04:00
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
def self.included(base)
|
|
|
|
base.class_eval do
|
|
|
|
extend ClassMethods
|
2009-09-17 10:06:46 -04:00
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
after_create :send_confirmation_instructions
|
|
|
|
before_update :reset_confirmation, :if => :email_changed?
|
|
|
|
after_update :send_confirmation_instructions, :if => :email_changed?
|
2009-10-15 15:43:30 -04:00
|
|
|
|
|
|
|
before_create :reset_perishable_token
|
2009-10-09 07:30:25 -04:00
|
|
|
end
|
2009-09-17 10:06:46 -04:00
|
|
|
end
|
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
# Confirm a user by setting it's confirmed_at to actual time. If the user
|
|
|
|
# is already confirmed, add en error to email field
|
|
|
|
#
|
|
|
|
def confirm!
|
2009-10-15 15:43:30 -04:00
|
|
|
unless_confirmed do
|
2009-10-09 07:30:25 -04:00
|
|
|
update_attribute(:confirmed_at, Time.now)
|
|
|
|
end
|
2009-09-17 10:06:46 -04:00
|
|
|
end
|
2009-10-08 18:50:46 -04:00
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
# Verifies whether a user is confirmed or not
|
2009-10-08 18:50:46 -04:00
|
|
|
#
|
2009-10-09 07:30:25 -04:00
|
|
|
def confirmed?
|
|
|
|
!new_record? && confirmed_at?
|
2009-10-08 18:50:46 -04:00
|
|
|
end
|
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
# Send confirmation instructions by email
|
2009-09-17 20:29:13 -04:00
|
|
|
#
|
2009-10-09 07:30:25 -04:00
|
|
|
def send_confirmation_instructions
|
|
|
|
::Notifier.deliver_confirmation_instructions(self)
|
2009-09-17 19:03:38 -04:00
|
|
|
end
|
2009-09-17 18:54:19 -04:00
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
# Remove confirmation date and send confirmation instructions, to ensure
|
|
|
|
# after sending these instructions the user won't be able to sign in without
|
|
|
|
# confirming it's account
|
2009-10-07 23:53:04 -04:00
|
|
|
#
|
2009-10-09 07:30:25 -04:00
|
|
|
def reset_confirmation!
|
2009-10-15 15:54:04 -04:00
|
|
|
unless_confirmed do
|
|
|
|
reset_confirmation
|
|
|
|
reset_perishable_token!
|
|
|
|
send_confirmation_instructions
|
|
|
|
end
|
2009-10-07 23:53:04 -04:00
|
|
|
end
|
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
private
|
|
|
|
|
|
|
|
# Remove confirmation date from the user, ensuring after a user update it's
|
|
|
|
# email, it won't be able to sign in without confirming it.
|
|
|
|
#
|
|
|
|
def reset_confirmation
|
|
|
|
self.confirmed_at = nil
|
|
|
|
end
|
|
|
|
|
2009-10-15 15:43:30 -04:00
|
|
|
# Checks whether the record is confirmed or not, yielding to the block if
|
|
|
|
# it's already confirmed, otherwise adds an error to email.
|
|
|
|
#
|
|
|
|
def unless_confirmed
|
|
|
|
unless confirmed?
|
|
|
|
yield
|
|
|
|
else
|
|
|
|
errors.add(:email, :already_confirmed, :default => 'already confirmed')
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2009-10-09 07:30:25 -04:00
|
|
|
module ClassMethods
|
|
|
|
# Attempt to find a user by it's email. If a record is found, send new
|
|
|
|
# confirmation instructions to it. If not user is found, returns a new user
|
|
|
|
# with an email not found error.
|
|
|
|
# Options must contain the user email
|
|
|
|
#
|
2009-10-10 15:20:23 -04:00
|
|
|
def send_confirmation_instructions(attributes={})
|
|
|
|
confirmable = find_or_initialize_with_error_by_email(attributes[:email])
|
2009-10-09 07:30:25 -04:00
|
|
|
confirmable.reset_confirmation! unless confirmable.new_record?
|
|
|
|
confirmable
|
|
|
|
end
|
|
|
|
|
|
|
|
# Find a user by it's confirmation token and try to confirm it.
|
|
|
|
# If no user is found, returns a new user
|
|
|
|
# If the user is already confirmed, create an error for the user
|
|
|
|
# Options must have the perishable_token
|
|
|
|
#
|
2009-10-10 15:20:23 -04:00
|
|
|
def confirm!(attributes={})
|
|
|
|
confirmable = find_or_initialize_with_error_by_perishable_token(attributes[:perishable_token])
|
2009-10-09 07:30:25 -04:00
|
|
|
confirmable.confirm! unless confirmable.new_record?
|
|
|
|
confirmable
|
|
|
|
end
|
2009-09-17 10:06:46 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|