Files
gtsit/app/Auth/AdminAuth.php
2026-08-10 21:19:10 +09:00

82 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Auth;
use App\Database;
use PDO;
final class AdminAuth
{
private PDO $db;
public function __construct()
{
$this->db = Database::connection();
}
public function attempt(string $username, string $password): bool
{
$statement = $this->db->prepare(
'SELECT id, username, display_name, password_hash, is_active, failed_attempts, locked_until
FROM admins WHERE username = :username LIMIT 1'
);
$statement->execute(['username' => $username]);
$admin = $statement->fetch();
if (!$admin) {
password_verify($password, password_hash('invalid-login', PASSWORD_DEFAULT));
return false;
}
if (!(bool) $admin['is_active']) {
return false;
}
if ($admin['locked_until'] && strtotime($admin['locked_until']) > time()) {
return false;
}
if (!password_verify($password, $admin['password_hash'])) {
$failed = (int) $admin['failed_attempts'] + 1;
$lockedUntil = $failed >= 5 ? date('Y-m-d H:i:s', time() + 900) : null;
$update = $this->db->prepare('UPDATE admins SET failed_attempts = :failed, locked_until = :locked WHERE id = :id');
$update->execute(['failed' => $failed >= 5 ? 0 : $failed, 'locked' => $lockedUntil, 'id' => $admin['id']]);
return false;
}
$update = $this->db->prepare('UPDATE admins SET failed_attempts = 0, locked_until = NULL, last_login_at = NOW() WHERE id = :id');
$update->execute(['id' => $admin['id']]);
session_regenerate_id(true);
$_SESSION['admin'] = [
'id' => (int) $admin['id'],
'username' => $admin['username'],
'display_name' => $admin['display_name'],
'authenticated_at' => time(),
];
return true;
}
public static function check(): bool
{
return isset($_SESSION['admin']['id'], $_SESSION['admin']['authenticated_at'])
&& time() - (int) $_SESSION['admin']['authenticated_at'] < 7200;
}
public static function requireLogin(): void
{
if (!self::check()) {
unset($_SESSION['admin']);
redirect('/admin/login');
}
$_SESSION['admin']['authenticated_at'] = time();
}
public static function logout(): void
{
unset($_SESSION['admin']);
session_regenerate_id(true);
}
}