74 lines · 1.6 KB
Raw Download
1
<?php
2
/**
3
 * Session handling, login checks, and CSRF helpers.
4
 */
5
6
require_once __DIR__ . '/../config.php';
7
8
if (session_status() === PHP_SESSION_NONE) {
9
    session_start();
10
}
11
12
function is_logged_in(): bool
13
{
14
    return !empty($_SESSION['auth']);
15
}
16
17
/**
18
 * Verify credentials against the config. Returns true and sets the session
19
 * on success.
20
 */
21
function attempt_login(string $user, string $pass): bool
22
{
23
    if (hash_equals(ADMIN_USER, $user) && password_verify($pass, ADMIN_PASS_HASH)) {
24
        session_regenerate_id(true);
25
        $_SESSION['auth'] = true;
26
        return true;
27
    }
28
    return false;
29
}
30
31
function logout(): void
32
{
33
    $_SESSION = [];
34
    session_destroy();
35
}
36
37
/**
38
 * Redirect to the login page if the current request is not authenticated.
39
 */
40
function require_login(): void
41
{
42
    if (!is_logged_in()) {
43
        header('Location: ' . BASE_PATH . '/admin/login.php');
44
        exit;
45
    }
46
}
47
48
// ---- CSRF -------------------------------------------------------------------
49
50
function csrf_token(): string
51
{
52
    if (empty($_SESSION['csrf'])) {
53
        $_SESSION['csrf'] = bin2hex(random_bytes(32));
54
    }
55
    return $_SESSION['csrf'];
56
}
57
58
function csrf_field(): string
59
{
60
    return '<input type="hidden" name="csrf" value="' . htmlspecialchars(csrf_token(), ENT_QUOTES) . '">';
61
}
62
63
/**
64
 * Validate the CSRF token on a POST request. Halts with 400 on failure.
65
 */
66
function csrf_verify(): void
67
{
68
    $sent = $_POST['csrf'] ?? '';
69
    if (empty($_SESSION['csrf']) || !hash_equals($_SESSION['csrf'], (string) $sent)) {
70
        http_response_code(400);
71
        exit('Invalid CSRF token.');
72
    }
73
}
74