pdo = Database::getInstance()->getPdo(); } public function create(string $username, string $email, string $password): int { $hash = password_hash($password, PASSWORD_DEFAULT); $token = bin2hex(random_bytes(32)); $stmt = $this->pdo->prepare( 'INSERT INTO users (username, email, password_hash, verification_token) VALUES (:username, :email, :hash, :token)' ); $stmt->execute([ 'username' => $username, 'email' => $email, 'hash' => $hash, 'token' => $token, ]); return (int) $this->pdo->lastInsertId(); } public function findByUsername(string $username): ?array { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE username = :username'); $stmt->execute(['username' => $username]); $row = $stmt->fetch(); return $row ?: null; } public function findByEmail(string $email): ?array { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE email = :email'); $stmt->execute(['email' => $email]); $row = $stmt->fetch(); return $row ?: null; } public function findById(int $id): ?array { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->execute(['id' => $id]); $row = $stmt->fetch(); return $row ?: null; } public function findByVerificationToken(string $token): ?array { $stmt = $this->pdo->prepare('SELECT * FROM users WHERE verification_token = :token'); $stmt->execute(['token' => $token]); $row = $stmt->fetch(); return $row ?: null; } public function verify(int $id): void { $stmt = $this->pdo->prepare( 'UPDATE users SET is_verified = TRUE, verification_token = NULL WHERE id = :id' ); $stmt->execute(['id' => $id]); } public function setResetToken(int $id): string { $token = bin2hex(random_bytes(32)); // Token expires in 1 hour $expires = date('Y-m-d H:i:s', time() + 3600); $stmt = $this->pdo->prepare( 'UPDATE users SET reset_token = :token, reset_token_expires = :expires WHERE id = :id' ); $stmt->execute(['token' => $token, 'expires' => $expires, 'id' => $id]); return $token; } public function findByResetToken(string $token): ?array { $stmt = $this->pdo->prepare( 'SELECT * FROM users WHERE reset_token = :token AND reset_token_expires > NOW()' ); $stmt->execute(['token' => $token]); $row = $stmt->fetch(); return $row ?: null; } public function updatePassword(int $id, string $password): void { $hash = password_hash($password, PASSWORD_DEFAULT); $stmt = $this->pdo->prepare( 'UPDATE users SET password_hash = :hash, reset_token = NULL, reset_token_expires = NULL WHERE id = :id' ); $stmt->execute(['hash' => $hash, 'id' => $id]); } public function getVerificationToken(int $id): ?string { $stmt = $this->pdo->prepare('SELECT verification_token FROM users WHERE id = :id'); $stmt->execute(['id' => $id]); $row = $stmt->fetch(); return $row ? $row['verification_token'] : null; } }