enabled=0|1 // // RESPONSE // {"ok":true,"error":null} // {"ok":false,"error":"POST only"|"Invalid id"|"Failed to write master.conf"} // // DEPENDS ON // include/scheduler.php vv_conf_toggle_script() → vv_conf_edit() → vv_write_conf_raw() // Configurations/master.conf the *_SCRIPTS arrays // ═══════════════════════════════════════════════════════════════════════════════════════════════ header('Content-Type: application/json'); require_once dirname(__DIR__) . '/include/scheduler.php'; if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['ok' => false, 'error' => 'POST only']); exit; } $id = trim($_POST['id'] ?? ''); $enabled = ($_POST['enabled'] ?? '0') === '1'; // Which orchestrator's list this click came from. Optional for callers that have only one, but // the scheduler always sends it: without it the toggle acts on whichever array declares the // script first, which for a script listed in three is right by luck at best. $array = trim($_POST['array'] ?? ''); if (!$id || !preg_match('/^[a-zA-Z0-9_.\/\-]+\.sh$/', $id) || str_contains($id, '..')) { echo json_encode(['ok' => false, 'error' => 'Invalid id']); exit; } // Shaped like the arrays it may name and nothing else. It is compared against array names read // out of master.conf rather than used to build a pattern, but a value that cannot be an array // name has no legitimate target and is refused rather than quietly ignored — silently falling // back to first-match is how this went wrong in the first place. if ($array !== '' && !preg_match('/^[A-Z][A-Z0-9_]*_SCRIPTS$/', $array)) { echo json_encode(['ok' => false, 'error' => 'Invalid array']); exit; } $ok = vv_conf_toggle_script($id, $enabled, $array !== '' ? $array : null); echo json_encode(['ok' => $ok, 'error' => $ok ? null : 'Failed to write master.conf']);