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?

calculate if the confirm time has not expired for this user.
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 = {})

add errors
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?

Callback to overwrite if confirmation is required or not.
def confirmation_required?
  !confirmed?
end

def confirmed?

Verifies whether a user is confirmed or not
def confirmed?
  !!confirmed_at
end

def generate_confirmation_token

the time this token is being generated in confirmation_sent_at
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

The message to be shown if the account is inactive.
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

Checks whether the record requires 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

Regenerates the token if the period is expired.
Resend confirmation token.
def resend_confirmation_instructions
  pending_any_confirmation do
    send_confirmation_instructions
  end
end

def send_confirmation_instructions

Send confirmation instructions by email
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?

requests the email change, instead of when the change is confirmed.
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

in models to map to a nice sign up e-mail.
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!

to be generated, call 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!

#skip_confirmation!, record still requires confirmation.
Skips sending the confirmation/reconfirmation notification email after_create/after_update. Unlike
def skip_confirmation_notification!
  @skip_confirmation_notification = true
end

def skip_reconfirmation!

to be generated, call 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!

callback call skip_create_confirmation!
To not require reconfirmation after creating with #save called in a
def skip_reconfirmation_in_callback!
  @skip_reconfirmation_in_callback = true
end