true, 'cookie_samesite' => 'Lax', ]); } } public static function isAuthenticated(): bool { self::startSession(); return !empty($_SESSION['user_id']) && !empty($_SESSION['username']); } public static function getUsername(): string { self::startSession(); return (string)($_SESSION['username'] ?? ''); } public static function login(PDO $db, string $username, string $password): bool { self::startSession(); $stmt = $db->prepare('SELECT id, username, password_hash FROM users WHERE username = :u LIMIT 1'); $stmt->execute([':u' => trim($username)]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password_hash'])) { session_regenerate_id(true); $_SESSION['user_id'] = (int)$user['id']; $_SESSION['username'] = $user['username']; return true; } return false; } public static function logout(): void { self::startSession(); $_SESSION = []; if (ini_get('session.use_cookies')) { $params = session_get_cookie_params(); setcookie( session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly'] ); } session_destroy(); } public static function updatePassword(PDO $db, string $username, string $newPassword): void { $stmt = $db->prepare('UPDATE users SET password_hash = :p WHERE username = :u'); $stmt->execute([ ':p' => password_hash($newPassword, PASSWORD_DEFAULT), ':u' => $username, ]); } }