# 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:) users.changeset(:create, { email: email, password_digest: password_digest, player_id: player_id, confirmed: false, confirmation_token: generate_token, confirmation_sent_at: 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