<?php
declare(strict_types=1);

function csrf_token(): string {
  if (empty($_SESSION['_op_csrf'])) {
    $_SESSION['_op_csrf'] = bin2hex(random_bytes(32));
  }
  return (string)$_SESSION['_op_csrf'];
}

function csrf_input(): string {
  $t = htmlspecialchars(csrf_token(), ENT_QUOTES, 'UTF-8');
  return '<input type="hidden" name="csrf_token" value="' . $t . '">';
}

function csrf_validate(?string $token): bool {
  if (empty($_SESSION['_op_csrf'])) return false;
  if ($token === null) return false;
  return hash_equals((string)$_SESSION['_op_csrf'], (string)$token);
}

function require_csrf(): void {
  $token = $_POST['csrf_token'] ?? ($_GET['csrf_token'] ?? null);
  if (!csrf_validate(is_string($token) ? $token : null)) {
    http_response_code(403);
    echo 'Forbidden (CSRF)';
    exit;
  }
}
