Files
euchre_camp/app/repositories/users.rb
T

119 lines
3.0 KiB
Ruby

# frozen_string_literal: true
module EuchreCamp
module Repositories
class Users < ::EuchreCamp::Repository[:users]
# Find user by ID
def by_id(id)
users.by_pk(id).one
end
# Find user by email
def by_email(email)
users.where(email: email).one
end
# Find user by player ID
def by_player_id(player_id)
users.where(player_id: player_id).one
end
# Create new user
def create(email:, password_digest:, player_id:, role: 'player', confirmed: false)
users.changeset(:create, {
email: email,
password_digest: password_digest,
player_id: player_id,
role: role,
confirmed: confirmed,
confirmation_token: confirmed ? nil : generate_token,
confirmation_sent_at: confirmed ? nil : Time.now
}).commit
end
# Confirm user account
def confirm(token)
user = users.where(confirmation_token: token).one
return nil unless user
users.where(id: user[:id]).update(
confirmed: true,
confirmation_token: nil,
confirmation_sent_at: nil
)
user
end
# Request password reset
def request_password_reset(email)
user = by_email(email)
return nil unless user
token = generate_token
users.where(id: user[:id]).update(
reset_password_token: token,
reset_password_sent_at: Time.now
)
token
end
# Reset password
def reset_password(token, new_password_digest)
user = users.where(reset_password_token: token).one
return nil unless user
# Check if token is expired (1 hour)
if user[:reset_password_sent_at] && user[:reset_password_sent_at] < (Time.now - 3600)
return nil
end
users.where(id: user[:id]).update(
password_digest: new_password_digest,
reset_password_token: nil,
reset_password_sent_at: nil
)
user
end
# Record successful login
def record_login(user_id, ip_address)
users.where(id: user_id).update(
last_login_at: Time.now,
last_login_ip: ip_address,
failed_login_attempts: 0,
locked_until: nil
)
end
# Record failed login
def record_failed_login(user_id)
user = users.where(id: user_id).one
return unless user
attempts = user[:failed_login_attempts] + 1
locked_until = attempts >= 5 ? (Time.now + 900) : nil # Lock for 15 minutes after 5 attempts
users.where(id: user_id).update(
failed_login_attempts: attempts,
locked_until: locked_until
)
end
# Check if account is locked
def account_locked?(user_id)
user = users.where(id: user_id).one
return false unless user
user[:locked_until] && user[:locked_until] > Time.now
end
private
def generate_token
SecureRandom.urlsafe_base64(32)
end
end
end
end