module Devise::Models::Confirmable
def self.required_fields(klass)
def self.required_fields(klass) required_methods = [:confirmation_token, :confirmed_at, :confirmation_sent_at] required_methods << :unconfirmed_email if klass.reconfirmable required_methods end
def active_for_authentication?
is already confirmed, it should never be blocked. Otherwise we need to
by verifying whether a user is active to sign in or not. If the user
Overwrites active_for_authentication? for confirmation
def active_for_authentication? super && (!confirmation_required? || confirmed? || confirmation_period_valid?) end
def after_password_reset
def after_password_reset super confirm! unless confirmed? end
def confirm!
is already confirmed, add an error to email field. If the user is invalid
Confirm a user by setting it's confirmed_at to actual time. If the user
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 if self.class.reconfirmable && unconfirmed_email.present? skip_reconfirmation! self.email = unconfirmed_email self.unconfirmed_email = nil # We need to validate in such cases to enforce e-mail uniqueness save(:validate => true) else save(:validate => false) end end end
def confirmation_period_expired?
confirmation_period_expired? # will always return false
# confirm_within = nil
confirmation_period_expired? # returns true
# confirm_within = 3.days and confirmation_sent_at = 4.days.ago
confirmation_period_expired? # returns false
# confirm_within = 3.days and confirmation_sent_at = 2.days.ago
Examples:
Checks if the user confirmation happens before the token becomes invalid
def confirmation_period_expired? self.class.confirm_within && (Time.now > self.confirmation_sent_at + self.class.confirm_within ) end
def confirmation_period_valid?
confirmation_period_valid? # will always return false
# allow_unconfirmed_access_for = 0.days
confirmation_period_valid? # returns false
# allow_unconfirmed_access_for = 5.days and confirmation_sent_at = 5.days.ago
confirmation_period_valid? # returns true
# allow_unconfirmed_access_for = 5.days and confirmation_sent_at = 4.days.ago
confirmation_period_valid? # returns true
# allow_unconfirmed_access_for = 1.day and confirmation_sent_at = today
Example:
Confirm_within is a model configuration, must always be an integer value.
confirmation sent date does not exceed the confirm in time configured.
We do this by calculating if the difference between today and the
Checks if the confirmation for the user is within the limit time.
def confirmation_period_valid? confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago end
def confirmation_required?
def confirmation_required? !confirmed? end
def confirmed?
def confirmed? !!confirmed_at end
def generate_confirmation_token
Generates a new random token for confirmation, and stores the time
def generate_confirmation_token self.confirmation_token = self.class.confirmation_token self.confirmation_sent_at = Time.now.utc end
def generate_confirmation_token!
def generate_confirmation_token! generate_confirmation_token && save(:validate => false) end
def inactive_message
def inactive_message !confirmed? ? :unconfirmed : super end
def pending_any_confirmation
def pending_any_confirmation if (!confirmed? || pending_reconfirmation?) yield else self.errors.add(:email, :already_confirmed) false end end
def pending_reconfirmation?
def pending_reconfirmation? self.class.reconfirmable && unconfirmed_email.present? end
def postpone_email_change?
def postpone_email_change? postpone = self.class.reconfirmable && email_changed? && !@bypass_postpone @bypass_postpone = nil postpone end
def postpone_email_change_until_confirmation
def postpone_email_change_until_confirmation @reconfirmation_required = true self.unconfirmed_email = self.email self.email = self.email_was end
def reconfirmation_required?
def reconfirmation_required? self.class.reconfirmable && @reconfirmation_required end
def resend_confirmation_token
def resend_confirmation_token pending_any_confirmation do self.confirmation_token = nil if confirmation_period_expired? send_confirmation_instructions end end
def send_confirmation_instructions
def send_confirmation_instructions self.confirmation_token = nil if reconfirmation_required? @reconfirmation_required = false generate_confirmation_token! if self.confirmation_token.blank? opts = pending_reconfirmation? ? { :to => unconfirmed_email } : { } send_devise_notification(:confirmation_instructions, opts) end
def send_on_create_confirmation_instructions
instructions on creation. This can be overriden
A callback method used to deliver confirmation
def send_on_create_confirmation_instructions send_devise_notification(:confirmation_instructions) end
def skip_confirmation!
If you don't want confirmation to be sent on create, neither a code
def skip_confirmation! self.confirmed_at = Time.now.utc end
def skip_reconfirmation!
If you don't want reconfirmation to be sent, neither a code
def skip_reconfirmation! @bypass_postpone = true end