discourse/app/models/email_token.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

116 lines
2.9 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2013-02-05 14:16:51 -05:00
class EmailToken < ActiveRecord::Base
belongs_to :user
validates :token, :user_id, :email, presence: true
2013-02-05 14:16:51 -05:00
before_validation(on: :create) do
2013-02-05 14:16:51 -05:00
self.token = EmailToken.generate_token
2014-07-14 10:16:24 -04:00
self.email = self.email.downcase if self.email
2013-02-05 14:16:51 -05:00
end
after_create do
# Expire the previous tokens
2016-05-02 17:15:32 -04:00
EmailToken.where(user_id: self.user_id)
.where("id != ?", self.id)
.update_all(expired: true)
2013-02-05 14:16:51 -05:00
end
def self.token_length
16
end
def self.valid_after
2014-07-01 19:08:25 -04:00
SiteSetting.email_token_valid_hours.hours.ago
end
def self.unconfirmed
where(confirmed: false)
end
def self.active
where(expired: false).where('created_at > ?', valid_after)
end
2013-02-05 14:16:51 -05:00
def self.generate_token
SecureRandom.hex(EmailToken.token_length)
end
def self.valid_token_format?(token)
2016-05-02 17:15:32 -04:00
token.present? && token =~ /\h{#{token.length / 2}}/i
end
def self.atomic_confirm(token)
failure = { success: false }
return failure unless valid_token_format?(token)
2013-02-05 14:16:51 -05:00
email_token = confirmable(token)
return failure if email_token.blank?
2013-02-05 14:16:51 -05:00
user = email_token.user
failure[:user] = user
row_count = EmailToken.where(confirmed: false, id: email_token.id, expired: false).update_all 'confirmed = true'
2016-05-02 17:15:32 -04:00
if row_count == 1
2016-05-02 17:15:32 -04:00
{ success: true, user: user, email_token: email_token }
else
failure
end
end
def self.confirm(token, skip_reviewable: false)
2013-02-05 14:16:51 -05:00
User.transaction do
result = atomic_confirm(token)
user = result[:user]
if result[:success]
2013-02-05 14:16:51 -05:00
# If we are activating the user, send the welcome message
user.send_welcome_message = !user.active?
user.email = result[:email_token].email
user.active = true
user.custom_fields.delete('activation_reminder')
2013-02-05 14:16:51 -05:00
user.save!
user.create_reviewable unless skip_reviewable
user.set_automatic_groups
DiscourseEvent.trigger(:user_confirmed_email, user)
2013-02-05 14:16:51 -05:00
end
if user
if Invite.redeem_from_email(user.email).present?
user.reload
end
user
end
end
2013-02-05 14:16:51 -05:00
rescue ActiveRecord::RecordInvalid
# If the user's email is already taken, just return nil (failure)
end
def self.confirmable(token)
2016-05-02 17:15:32 -04:00
EmailToken.where(token: token)
.where(expired: false, confirmed: false)
.where("created_at >= ?", EmailToken.valid_after)
2016-05-02 17:15:32 -04:00
.includes(:user)
.first
end
2013-02-05 14:16:51 -05:00
end
# == Schema Information
#
# Table name: email_tokens
#
# id :integer not null, primary key
# user_id :integer not null
2019-01-11 14:29:56 -05:00
# email :string not null
# token :string not null
# confirmed :boolean default(FALSE), not null
# expired :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
2014-08-22 13:01:44 -04:00
# index_email_tokens_on_token (token) UNIQUE
# index_email_tokens_on_user_id (user_id)
#