now() - interval '5 minutes' and success = false"; $st = \App\Infrastructure\Database::pdo()->prepare($sql); $st->execute([':ip' => $ip]); $fails = (int)$st->fetchColumn(); return $fails < 10; // à ajuster } public function login(string $email, string $password, string $ip): bool { $user = $this->users->findByEmail($email); $ok = $user && $user->isActive && password_verify($password, $user->passwordHash); $pdo = \App\Infrastructure\Database::pdo(); $st = $pdo->prepare('insert into login_attempts(email, ip, success) values(:e, :ip, :s)'); $st->bindValue(':e', $email, \PDO::PARAM_STR); $st->bindValue(':ip', $ip, \PDO::PARAM_STR); $st->bindValue(':s', $ok, \PDO::PARAM_BOOL); $st->execute(); if ($ok) { \App\Infrastructure\Session::regenerate(); $_SESSION['uid'] = $user->id; $_SESSION['email'] = $user->email; } return $ok; } public function changePassword(string $userId, string $currentPassword, string $newPassword): bool { // Récupération de l’utilisateur (rapide : requête directe ; tu peux créer findById() si tu préfères) $pdo = \App\Infrastructure\Database::pdo(); $st = $pdo->prepare('select id, email, password_hash, is_active from users where id = :id'); $st->execute([':id' => $userId]); $row = $st->fetch(\PDO::FETCH_ASSOC); if (!$row || !(bool)$row['is_active']) { return false; } // Vérifier l’ancien mot de passe if (!password_verify($currentPassword, (string)$row['password_hash'])) { return false; } // Politique minimale : longueur uniquement (espaces autorisés) if (mb_strlen($newPassword) < 7) { return false; } // (optionnel) interdire seulement le caractère NUL if (strpos($newPassword, "\0") !== false) { return false; } // Mettre à jour le hash $newHash = password_hash($newPassword, PASSWORD_ARGON2ID); (new \App\Repository\UserRepository(\App\Infrastructure\Database::get()))->updatePassword($row['id'], $newHash); // (Optionnel) rotation session \App\Infrastructure\Session::regenerate(); return true; } public function register(string $email, string $password): string { $hash = password_hash($password, PASSWORD_ARGON2ID); return $this->users->create($email, $hash); } public static function requireAuth(): void { if (!isset($_SESSION['uid'])) { header('Location: /login'); exit; } } public static function logout(): void { $_SESSION = []; session_destroy(); } }