- Change `user.send(:activate)` to `user.activate` for clarity. - Fix typo in email parameter from `emial` to `email` in password reset. - Update render calls to include status codes for better error handling. - Modify password reset email method to accept a user parameter. - Update tests to reflect changes in password reset functionality. These changes improve the clarity of the user activation process and ensure that the password reset functionality works correctly with proper error handling and user feedback.
92 lines
2.5 KiB
Ruby
92 lines
2.5 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
|
|
UserMailer.account_activation(self).deliver_now
|
|
end
|
|
|
|
def create_reset_digest
|
|
self.reset_token = User.new_token
|
|
update_attribute(:reset_digest, User.digest(reset_token))
|
|
update_attribute(:reset_sent_at, Time.zone.now)
|
|
end
|
|
|
|
def send_password_reset_email
|
|
UserMailer.password_reset(self).deliver_now
|
|
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
|