*/ private array $app; public function __construct() { $this->app = Bootstrap::config('app'); } public function isLoggedIn(): bool { return isset($_SESSION['admin_logged_in'], $_SESSION['admin_username']) && $_SESSION['admin_logged_in'] === true && is_string($_SESSION['admin_username']) && $_SESSION['admin_username'] !== ''; } public function login(string $username, string $password): bool { $username = trim($username); if ($username === '' || $password === '') { return false; } $credentials = $this->credentialTable(); foreach ($credentials as $entry) { if (!is_array($entry)) { continue; } $configuredUsername = trim((string) ($entry['username'] ?? '')); $hash = (string) ($entry['password_hash'] ?? ''); if ($configuredUsername === '' || $hash === '') { continue; } if (!hash_equals(strtolower($configuredUsername), strtolower($username))) { continue; } if (!password_verify($password, $hash)) { return false; } $_SESSION['admin_logged_in'] = true; $_SESSION['admin_username'] = $configuredUsername; $_SESSION['admin_login_at'] = time(); session_regenerate_id(true); return true; } return false; } public function logout(): void { $_SESSION = []; if (ini_get('session.use_cookies')) { $params = session_get_cookie_params(); setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], (bool) $params['secure'], (bool) $params['httponly']); } session_destroy(); } public function requireLogin(): void { $timeout = (int) ($this->app['admin']['session_timeout_seconds'] ?? 3600); $loginAt = (int) ($_SESSION['admin_login_at'] ?? 0); if ($this->isLoggedIn() && $loginAt > 0 && (time() - $loginAt) > $timeout) { $this->logout(); } if (!$this->isLoggedIn()) { header('Location: ' . Bootstrap::url('admin/login.php')); exit; } } /** @return array */ private function credentialTable(): array { $table = $this->app['admin']['credentials'] ?? []; return is_array($table) ? $table : []; } }