45ef31e61f
Existing and new accounts default to 2FA off. Registration signs users in directly. Users can enable it under My Account. Administrators can manage it under Users & Staff. Verified password-only and opted-in email-code login flows. PHP/JavaScript checks and browser console passed.
84 lines
2.0 KiB
PHP
84 lines
2.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace FatBottom\Core;
|
|
|
|
final class Auth
|
|
{
|
|
private ?array $cachedUser = null;
|
|
private bool $resolved = false;
|
|
|
|
public function __construct(private readonly Database $db)
|
|
{
|
|
}
|
|
|
|
public function user(): ?array
|
|
{
|
|
if ($this->resolved) {
|
|
return $this->cachedUser;
|
|
}
|
|
$this->resolved = true;
|
|
$id = (int) ($_SESSION['user_id'] ?? 0);
|
|
if ($id === 0) {
|
|
return null;
|
|
}
|
|
|
|
$this->cachedUser = $this->db->fetch(
|
|
'SELECT * FROM users WHERE id = ? AND active = 1',
|
|
[$id]
|
|
);
|
|
return $this->cachedUser;
|
|
}
|
|
|
|
public function check(): bool
|
|
{
|
|
return $this->user() !== null;
|
|
}
|
|
|
|
public function login(array $user): void
|
|
{
|
|
session_regenerate_id(true);
|
|
$_SESSION['user_id'] = (int) $user['id'];
|
|
unset($_SESSION['pending_2fa_user_id'], $_SESSION['pending_verification_purpose']);
|
|
$this->resolved = true;
|
|
$this->cachedUser = $user;
|
|
}
|
|
|
|
public function logout(): void
|
|
{
|
|
unset($_SESSION['user_id'], $_SESSION['pending_2fa_user_id'], $_SESSION['pending_verification_purpose']);
|
|
session_regenerate_id(true);
|
|
$this->resolved = true;
|
|
$this->cachedUser = null;
|
|
}
|
|
|
|
public function requireLogin(): array
|
|
{
|
|
$user = $this->user();
|
|
if ($user === null) {
|
|
Http::flash('warning', 'Please sign in to continue.');
|
|
Http::redirect('/login');
|
|
}
|
|
return $user;
|
|
}
|
|
|
|
public function requireStaff(): array
|
|
{
|
|
$user = $this->requireLogin();
|
|
if (!in_array($user['role'], ['admin', 'manager', 'staff'], true)) {
|
|
Http::abort(403, 'You do not have access to the staff dashboard.');
|
|
}
|
|
return $user;
|
|
}
|
|
|
|
public function requireAdmin(): array
|
|
{
|
|
$user = $this->requireLogin();
|
|
if ($user['role'] !== 'admin') {
|
|
Http::abort(403, 'Administrator access is required.');
|
|
}
|
|
return $user;
|
|
}
|
|
}
|