<?php
// =============================================================================
// CSRF token helpers
// =============================================================================

function csrf_token() {
    if (empty($_SESSION['csrf'])) {
        $_SESSION['csrf'] = bin2hex(random_bytes(16));
    }
    return $_SESSION['csrf'];
}

function csrf_check($token) {
    if (empty($_SESSION['csrf']) || !is_string($token)) {
        return false;
    }
    return hash_equals($_SESSION['csrf'], $token);
}

function csrf_require_post() {
    $tok = '';
    if (isset($_POST['_csrf'])) {
        $tok = $_POST['_csrf'];
    } elseif (isset($_SERVER['HTTP_X_CSRF_TOKEN'])) {
        $tok = $_SERVER['HTTP_X_CSRF_TOKEN'];
    } else {
        // Allow JSON requests to pass the token in their body
        $body = json_request_body();
        if (isset($body['_csrf'])) {
            $tok = $body['_csrf'];
        }
    }
    if (!csrf_check($tok)) {
        json_error('invalid csrf token', 403);
    }
}

function csrf_field() {
    return '<input type="hidden" name="_csrf" value="' . h(csrf_token()) . '">';
}
