<?php
// ═══════════════════════════════════════════════════════════════════════════════════════════════
// PURPOSE
//   Unraid API key provisioning. Runs unraid_api_key_renew.sh for this host and reports a
//   masked preview of the key that ended up in the conf — the "create key" action on the
//   setup and partnership tabs.
//
// OPERATIONAL MODEL
//   Provisioning for the local host only. There is no host parameter: the target is whatever
//   vv_detect_host() resolves to, because a key can only be created on the machine that owns
//   the API it authenticates against. A partner's key is created on the partner.
//
//   Repair, not just creation. The underlying script is the same one the array-start and
//   15-minute watchdog runs call, because the registry it writes can be cleared by a service
//   restart rather than only by a reboot. Running it against a host that already has a valid
//   key is a no-op that re-registers, which is why this endpoint is safe to press twice.
//
// DESIGN PRINCIPLES
//   Idempotent by delegation.
//       This file contains no key logic at all. Whether a key needs creating, renewing, or
//       leaving alone is decided in one place — the shell script — so the UI path and the
//       scheduled path can never diverge on that judgement.
//
//   The key is never returned.
//       Only a masked preview (first 8, last 4) leaves the server. The full value lives in
//       host*.conf, which is the only place anything reads it from. There is no workflow that
//       needs the key in a browser, so it is not sent to one.
//
// OPERATIONAL SAFEGUARDS
//   The host slot is validated before it is used to compose a conf filename.
//       vv_detect_host() can return 'unknown' when hostname matching fails, and 'unknown.conf'
//       is not a file that should be read or written. ^host\d+$ is enforced first, so a host
//       this plugin cannot identify gets a clear error instead of a confusing failure deeper
//       in the script.
//
//   A missing script is reported, not executed.
//       vv_auto_create_api_key() checks file_exists() before exec(), so a partial deploy
//       returns a named error rather than a shell failure surfacing as an empty key.
//
//   The script run is externally time-boxed.
//       `timeout 120` wraps it inside the library — PHP's own limit does not cover exec()
//       time on Linux, so a stalled unraid-api call would otherwise hold a php-fpm worker
//       open indefinitely. Exit 124 is reported as a timeout, distinctly from a script error.
//
//   Never cached.
//       Cache-Control: no-store, no-cache. A cached provisioning response would report an old
//       key preview after a genuine renewal — the one moment the preview matters.
//
//   POST only, which is what places it behind Unraid's CSRF guard.
//       The platform prepend validates the token on every POST and inspects no GET at all, so
//       a state-changing action reachable by GET is a state-changing action with no CSRF
//       protection. This was previously a GET; the callers now POST and the token travels as
//       an X-CSRF-Token header set by the shim in Varaverk.page. See README-unraid.md.
//
// REQUEST
//   POST, no parameters (the target host is the local host, by construction)
//
// RESPONSE
//   {"ok":true,"key_preview":"abcd1234...wxyz"}   or "registered" when the key is not readable
//   {"ok":false,"error":string}                   unknown host, missing script, or timeout
//
// DEPENDS ON
//   include/config.php   vv_detect_host(), vv_auto_create_api_key()
//   System_Essentials/unraid_api_key_renew.sh
// ═══════════════════════════════════════════════════════════════════════════════════════════════
header('Content-Type: application/json');
header('Cache-Control: no-store, no-cache');
require_once dirname(__DIR__) . '/include/config.php';

// POST is what puts this behind Unraid's CSRF guard — the platform prepend validates every
// POST and ignores every GET, so a state-changing action must not be reachable by GET.
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['ok' => false, 'error' => 'POST only']);
    exit;
}

$host = vv_detect_host();
if (!preg_match('/^host\d+$/', $host)) {
    echo json_encode(['ok' => false, 'error' => 'Cannot detect local host']);
    exit;
}

echo json_encode(vv_auto_create_api_key($host, $host . '.conf'));
