663fde3909
Full source for loveandrosary.com: slide-based Rosary/novena/Divine Mercy Chaplet presentation tool with multi-user roles, SVG bead ring, audio uploads, donate strip, and public session profiles. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
69 lines
2.3 KiB
PHP
69 lines
2.3 KiB
PHP
<?php
|
|
/**
|
|
* includes/auth.php — multi-user role-based authentication.
|
|
*/
|
|
|
|
function _auth_start(): void {
|
|
if (session_status() === PHP_SESSION_NONE) session_start();
|
|
}
|
|
|
|
/** Redirect to login if not authenticated. */
|
|
function require_auth(): void {
|
|
_auth_start();
|
|
if (empty($_SESSION['user_id'])) {
|
|
header('Location: ' . BASE_URL . '/login');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/** Redirect/abort if user doesn't have the minimum role. */
|
|
function require_role(string $min_role): void {
|
|
require_auth();
|
|
if (!has_role($min_role)) {
|
|
http_response_code(403);
|
|
echo '<!DOCTYPE html><html><body style="font-family:system-ui;max-width:500px;margin:60px auto;text-align:center">'
|
|
. '<h1 style="color:#dc2626">Access Denied</h1>'
|
|
. '<p>You do not have permission to view this page.</p>'
|
|
. '<a href="' . BASE_URL . '/admin/">← Dashboard</a></body></html>';
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/** True if current session user has at least $min_role. */
|
|
function has_role(string $min): bool {
|
|
_auth_start();
|
|
$levels = ['user' => 1, 'superuser' => 2, 'admin' => 3, 'superadmin' => 4];
|
|
return ($levels[$_SESSION['role'] ?? ''] ?? 0) >= ($levels[$min] ?? 999);
|
|
}
|
|
|
|
/** Return current user data from session (or empty defaults). */
|
|
function current_user(): array {
|
|
_auth_start();
|
|
return [
|
|
'id' => $_SESSION['user_id'] ?? null,
|
|
'username' => $_SESSION['username'] ?? '',
|
|
'email' => $_SESSION['email'] ?? '',
|
|
'role' => $_SESSION['role'] ?? '',
|
|
'display_name' => $_SESSION['display_name'] ?? '',
|
|
'rosary_limit' => $_SESSION['rosary_limit'] ?? 1,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Check if user can create another rosary.
|
|
* Novenas count as 1 regardless of number of days.
|
|
* Returns true if under limit (or limit is -1 = unlimited).
|
|
*/
|
|
function can_create_rosary(int $user_id, int $limit): bool {
|
|
if ($limit < 0) return true; // unlimited
|
|
$pdo = get_pdo();
|
|
$st = $pdo->prepare("
|
|
SELECT
|
|
(SELECT COUNT(*) FROM sessions WHERE user_id = ? AND occasion != 'novena_deceased') +
|
|
(SELECT COUNT(*) FROM novena_groups WHERE user_id = ?)
|
|
AS total
|
|
");
|
|
$st->execute([$user_id, $user_id]);
|
|
return (int)$st->fetchColumn() < $limit;
|
|
}
|