prepare('SELECT id, name, email, password FROM users WHERE email = ? LIMIT 1'); $stmt->execute([$email]); $user = $stmt->fetch(); } catch (\PDOException $e) { $_SESSION['login_error'] = 'Error de base de datos.'; header('Location: /login'); exit; } if (!$user || !password_verify($password, $user['password'])) { sleep(1); // freno básico a fuerza bruta $_SESSION['login_error'] = 'Correo o contraseña incorrectos.'; header('Location: /login'); exit; } SessionAuth::login($user); header('Location: /admin/dashboard'); exit; } public static function logout(): void { SessionAuth::logout(); header('Location: /login'); exit; } // ─── Vista ─────────────────────────────────────────────────────────────── private static function renderForm(string $token, string $error): void { http_response_code(200); header('Content-Type: text/html; charset=utf-8'); $errorHtml = $error ? '

Panel de administración — Somos19D