v1.0.0.6
Publisium
- <?php
-
- declare(strict_types=1);
-
- require_once __DIR__ . '/database.php';
-
- final class Auth
- {
- public const ROLE_SUPER_ADMIN = 'super_admin';
- public const ROLE_EDITOR_IN_CHIEF = 'editor_in_chief';
- public const ROLE_MANAGING_EDITOR = 'managing_editor';
- public const ROLE_SENIOR_WRITER = 'senior_writer';
- public const ROLE_WRITER = 'writer';
- public const ROLE_PROOFREADER = 'proofreader';
-
- private const ROLE_LEVELS = [
- self::ROLE_SUPER_ADMIN => 60,
- self::ROLE_EDITOR_IN_CHIEF => 50,
- self::ROLE_MANAGING_EDITOR => 40,
- self::ROLE_SENIOR_WRITER => 30,
- self::ROLE_WRITER => 20,
- self::ROLE_PROOFREADER => 10,
- ];
-
- private static ?array $current = null;
-
- public static function boot(): void
- {
- Config::startSession(Config::get('SESSION_COOKIE_NAME', 'publisium_session'));
- }
-
- public static function verifyCredentials(string $username, string $password): ?array
- {
- $statement = Database::site()->prepare(
- 'SELECT * FROM team_accounts WHERE (username = :username OR email = :email) AND status = :status LIMIT 1'
- );
- $statement->execute(['username' => $username, 'email' => $username, 'status' => 'active']);
- $account = $statement->fetch();
-
- if (!$account || !password_verify($password, $account['password_hash'])) {
- return null;
- }
-
- return $account;
- }
-
- public static function completeLogin(array $account): void
- {
- session_regenerate_id(true);
- unset($_SESSION['team_2fa']);
- $_SESSION['team_account_id'] = (int) $account['id'];
- $_SESSION['team_role'] = $account['role'];
-
- $update = Database::site()->prepare('UPDATE team_accounts SET last_login_at = NOW() WHERE id = :id');
- $update->execute(['id' => $account['id']]);
- }
-
- public static function startTwoFactor(array $account): void
- {
- session_regenerate_id(true);
- $_SESSION['team_2fa'] = ['id' => (int) $account['id'], 'expires' => time() + 300];
- }
-
- public static function pendingTwoFactorAccount(): ?array
- {
- $pending = $_SESSION['team_2fa'] ?? null;
- if (!is_array($pending) || (int) ($pending['expires'] ?? 0) < time()) {
- unset($_SESSION['team_2fa']);
- return null;
- }
-
- $statement = Database::site()->prepare('SELECT * FROM team_accounts WHERE id = :id AND status = :status LIMIT 1');
- $statement->execute(['id' => (int) $pending['id'], 'status' => 'active']);
- $account = $statement->fetch();
-
- if (!$account) {
- unset($_SESSION['team_2fa']);
- return null;
- }
-
- return $account;
- }
-
- public static function cancelTwoFactor(): void
- {
- unset($_SESSION['team_2fa']);
- }
-
- public static function logout(): void
- {
- self::$current = null;
- $_SESSION = [];
- session_destroy();
- }
-
- public static function check(): bool
- {
- return self::user() !== null;
- }
-
- public static function user(): ?array
- {
- if (!isset($_SESSION['team_account_id'])) {
- return null;
- }
-
- if (self::$current !== null) {
- return self::$current;
- }
-
- $statement = Database::site()->prepare('SELECT * FROM team_accounts WHERE id = :id LIMIT 1');
- $statement->execute(['id' => $_SESSION['team_account_id']]);
- $account = $statement->fetch();
-
- if (!$account || $account['status'] !== 'active') {
- self::logout();
- return null;
- }
-
- $_SESSION['team_role'] = $account['role'];
- self::$current = $account;
- return self::$current;
- }
-
- public static function role(): ?string
- {
- return self::user()['role'] ?? null;
- }
-
- public static function hasRoleAtLeast(string $role): bool
- {
- $current = self::role();
- if ($current === null || !isset(self::ROLE_LEVELS[$current]) || !isset(self::ROLE_LEVELS[$role])) {
- return false;
- }
-
- return self::ROLE_LEVELS[$current] >= self::ROLE_LEVELS[$role];
- }
-
- public static function isAdministrative(): bool
- {
- return self::hasRoleAtLeast(self::ROLE_MANAGING_EDITOR);
- }
-
- public static function canPublishDirectly(): bool
- {
- return self::hasRoleAtLeast(self::ROLE_SENIOR_WRITER);
- }
-
- public static function canModerate(): bool
- {
- return self::hasRoleAtLeast(self::ROLE_MANAGING_EDITOR);
- }
-
- public static function requireLogin(): void
- {
- if (!self::check()) {
- header('Location: team-login.php');
- exit;
- }
- }
-
- public static function requireRoleAtLeast(string $role): void
- {
- self::requireLogin();
- if (!self::hasRoleAtLeast($role)) {
- http_response_code(403);
- echo 'You don’t have access to this page. Ask an administrator if you need it.';
- exit;
- }
- }
-
- public static function roleLabel(string $role): string
- {
- return match ($role) {
- self::ROLE_SUPER_ADMIN => 'Super Admin',
- self::ROLE_EDITOR_IN_CHIEF => 'Editor-in-Chief',
- self::ROLE_MANAGING_EDITOR => 'Managing Editor',
- self::ROLE_SENIOR_WRITER => 'Senior Writer',
- self::ROLE_WRITER => 'Writer',
- self::ROLE_PROOFREADER => 'Proofreader',
- default => 'Unknown',
- };
- }
- }
-