aboutsummaryrefslogtreecommitdiff
path: root/api/debug/agent-replies.php
blob: 070c0e6ff6c9299c43e5d323bc8d12bbe72ca37a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
// api/debug/agent-replies.php — outbound half of the maintenance thread.
// Hermes (or the operator) writes replies here; the in-page agent reads them with
// `feedback-inbox`. nginx gates this path behind the WebX11 admin session, so it is
// owner-only: never expose it in the public debug/course location block.
require_once __DIR__ . '/config.php';

define('REPLIES_DIR', __DIR__ . '/../../data/maintenance');
define('REPLIES_FILE', REPLIES_DIR . '/replies.json');

if (!is_dir(REPLIES_DIR)) {
    @mkdir(REPLIES_DIR, 0775, true);
    @chgrp(REPLIES_DIR, 'www-data');
}

$method = $_SERVER['REQUEST_METHOD'];

if ($method === 'GET') {
    $since = $_GET['since'] ?? null;
    $all = load_json(REPLIES_FILE);
    if (!is_array($all)) $all = [];
    if ($since) {
        $all = array_values(array_filter($all, fn($r) => ($r['created_at'] ?? '') > $since));
    }
    json_response(['success' => true, 'replies' => array_slice($all, -100)]);
}

if ($method !== 'POST') {
    error_response('Method not allowed', 405);
}

$raw = file_get_contents('php://input');
if (!$raw) error_response('Empty request body');
if (strlen($raw) > 16384) error_response('Payload too large (max 16KB)', 413);

$p = json_decode($raw, true);
if (!is_array($p)) error_response('Invalid JSON');

$body = trim((string)($p['body'] ?? ''));
if ($body === '') error_response('body is required');
if (mb_strlen($body) > 2000) $body = mb_substr($body, 0, 2000);

$list = load_json(REPLIES_FILE);
if (!is_array($list)) $list = [];

$author = (($p['author'] ?? 'hermes') === 'newos4') ? 'newos4' : 'hermes';
$entry = [
    'id' => 'REP-' . gmdate('Ymd-His') . '-' . substr(bin2hex(random_bytes(3)), 0, 6),
    'created_at' => gmdate('c'),
    'author' => $author,
    'body' => $body,
];

$list[] = $entry;
save_json(REPLIES_FILE, array_slice($list, -200));

json_response(['success' => true, 'id' => $entry['id']], 201);