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_confirmation
end
self.update_attribute(:invite_code, nil)
def after_confirmation
Example:
confirms.
used to insert your own logic that is only run after the user successfully
A callback initiated after successfully confirming. This can be
def after_confirmation end
def confirm(args = {})
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(args = {}) 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.confirmed_at = Time.now.utc saved = if pending_reconfirmation? 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: args[:ensure_valid] == true) end after_confirmation if saved saved 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 && self.confirmation_sent_at && (Time.now.utc > self.confirmation_sent_at.utc + self.class.confirm_within) end
def confirmation_period_valid?
confirmation_period_valid? # will always return true
# allow_unconfirmed_access_for = nil
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:
allow_unconfirmed_access_for 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? return true if self.class.allow_unconfirmed_access_for.nil? return false if self.class.allow_unconfirmed_access_for == 0.days 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
def generate_confirmation_token if self.confirmation_token && !confirmation_period_expired? @raw_confirmation_token = self.confirmation_token else self.confirmation_token = @raw_confirmation_token = Devise.friendly_token self.confirmation_sent_at = Time.now.utc end 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 initialize(*args, &block)
def initialize(*args, &block) @bypass_confirmation_postpone = false @skip_reconfirmation_in_callback = false @reconfirmation_required = false @skip_confirmation_notification = false @raw_confirmation_token = nil 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 && devise_will_save_change_to_email? && !@bypass_confirmation_postpone && self.email.present? && (!@skip_reconfirmation_in_callback || !self.devise_email_in_database.nil?) @bypass_confirmation_postpone = false postpone end
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token @reconfirmation_required = true self.unconfirmed_email = self.email self.email = self.devise_email_in_database self.confirmation_token = nil generate_confirmation_token end
def reconfirmation_required?
def reconfirmation_required? self.class.reconfirmable && @reconfirmation_required && (self.email.present? || self.unconfirmed_email.present?) end
def resend_confirmation_instructions
Resend confirmation token.
def resend_confirmation_instructions pending_any_confirmation do send_confirmation_instructions end end
def send_confirmation_instructions
def send_confirmation_instructions unless @raw_confirmation_token generate_confirmation_token! end opts = pending_reconfirmation? ? { to: unconfirmed_email } : { } send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts) end
def send_confirmation_notification?
def send_confirmation_notification? confirmation_required? && !@skip_confirmation_notification && self.email.present? end
def send_email_changed_notification?
With reconfirmable, notify the original email when the user first
def send_email_changed_notification? if self.class.reconfirmable self.class.send_email_changed_notification && reconfirmation_required? else super end end
def send_on_create_confirmation_instructions
instructions on creation. This can be overridden
A callback method used to deliver confirmation
def send_on_create_confirmation_instructions send_confirmation_instructions end
def send_reconfirmation_instructions
def send_reconfirmation_instructions @reconfirmation_required = false unless @skip_confirmation_notification send_confirmation_instructions end 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_confirmation_notification!
Skips sending the confirmation/reconfirmation notification email after_create/after_update. Unlike
def skip_confirmation_notification! @skip_confirmation_notification = true end
def skip_reconfirmation!
If you don't want reconfirmation to be sent, neither a code
def skip_reconfirmation! @bypass_confirmation_postpone = true end
def skip_reconfirmation_in_callback!
To not require reconfirmation after creating with #save called in a
def skip_reconfirmation_in_callback! @skip_reconfirmation_in_callback = true end