songtianlun
f1f5e37d7b
- Add logging for successful email delivery - Implement error handling for email sending failures - Raise exceptions for further handling This change improves the robustness of the email activation process by logging outcomes and handling potential errors, allowing for better debugging and monitoring of email notifications.
103 lines
2.8 KiB
Ruby
103 lines
2.8 KiB
Ruby
class User < ApplicationRecord
|
|
attr_accessor :remember_token, :activation_token, :reset_token
|
|
# before_save { self.email = email.downcase }
|
|
# before_save { email.downcase! }
|
|
before_save :downcase_email
|
|
before_create :create_activation_digest
|
|
validates :name, presence: true, length: { maximum: 50 }
|
|
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
|
|
validates :email, presence: true, length: { maximum: 255 },
|
|
format: { with: VALID_EMAIL_REGEX },
|
|
uniqueness: true
|
|
has_secure_password
|
|
validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
|
|
|
|
def User.digest(string)
|
|
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
|
|
BCrypt::Engine.cost
|
|
BCrypt::Password.create(string, cost: cost)
|
|
end
|
|
|
|
def User.new_token
|
|
SecureRandom.urlsafe_base64
|
|
end
|
|
|
|
def remember
|
|
self.remember_token = User.new_token
|
|
update_attribute(:remember_digest, User.digest(remember_token))
|
|
remember_digest
|
|
end
|
|
|
|
# 返回一个会话令牌,防止会话劫持
|
|
# 简单起见,直接使用记忆令牌
|
|
def session_token
|
|
remember_digest || remember
|
|
end
|
|
|
|
class << self
|
|
def digest(string)
|
|
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
|
|
BCrypt::Engine.cost
|
|
BCrypt::Password.create(string, cost: cost)
|
|
end
|
|
|
|
def new_token
|
|
SecureRandom.urlsafe_base64
|
|
end
|
|
end
|
|
|
|
# powered by metaprogramming
|
|
def authenticated?(attribute, token)
|
|
digest = send("#{attribute}_digest")
|
|
return false if digest.nil?
|
|
BCrypt::Password.new(digest).is_password?(token)
|
|
end
|
|
|
|
def forget
|
|
update_attribute(:remember_digest, nil)
|
|
end
|
|
|
|
def activate
|
|
# update_attribute(:activated, true)
|
|
# update_attribute(:activated_at, Time.zone.now)
|
|
update_columns(activated: true, activated_at: Time.zone.now)
|
|
end
|
|
|
|
def send_activation_email
|
|
begin
|
|
result = UserMailer.account_activation(self).deliver_now
|
|
Rails.logger.info "Email sent successfully: #{result.inspect}"
|
|
rescue => e
|
|
Rails.logger.error "Failed to send email: #{e.message}"
|
|
Rails.logger.error e.backtrace.join("\n")
|
|
raise
|
|
end
|
|
end
|
|
|
|
def create_reset_digest
|
|
self.reset_token = User.new_token
|
|
update_columns(reset_digest: User.digest(reset_token),
|
|
reset_send_at: Time.zone.now)
|
|
end
|
|
|
|
def send_password_reset_email
|
|
UserMailer.password_reset(self).deliver_now
|
|
end
|
|
|
|
def password_reset_expired?
|
|
reset_send_at < 2.hours.ago
|
|
end
|
|
|
|
private
|
|
|
|
def downcase_email
|
|
# self.email = email.downcase
|
|
email.downcase!
|
|
end
|
|
|
|
def create_activation_digest
|
|
self.activation_token = User.new_token
|
|
self.activation_digest = User.digest(activation_token)
|
|
end
|
|
end
|