handle_get(), 'POST' => handle_post(), default => error_out('Method not allowed', 405), }; } catch (PDOException $e) { error_out('Database error: ' . $e->getMessage(), 500); } // ─── GET /api/settings.php?key= ──────────────────────────────────────── // Returns whether the setting is set; never exposes the full value. function handle_get(): never { $key = trim((string) ($_GET['key'] ?? '')); if ($key === '') { error_out('Missing key parameter'); } $stmt = db()->prepare('SELECT setting_value FROM `system` WHERE setting_name = :key'); $stmt->execute([':key' => $key]); $row = $stmt->fetch(); $value = ($row !== false) ? $row['setting_value'] : null; $isSet = $value !== null && $value !== ''; // For non-secret settings (no "key" in the name) return the value directly $isSensitive = str_contains($key, '_key'); json_out([ 'set' => $isSet, 'hint' => $isSet && $isSensitive ? '••••••••' . substr($value, -4) : null, 'value' => $isSensitive ? null : $value, ]); } // ─── POST /api/settings.php ─────────────────────────────────────────────────── // Body: { "key": "clickatell_api_key", "value": "..." } // Upserts the setting value. function handle_post(): never { $body = json_decode((string) file_get_contents('php://input'), true); $key = trim((string) ($body['key'] ?? '')); $value = trim((string) ($body['value'] ?? '')); if ($key === '') { error_out('Missing key'); } // Only allow known setting names to prevent arbitrary writes $allowed = ['clickatell_api_key', 'clickatell_cost_per_sms', 'default_sender_id']; if (!in_array($key, $allowed, true)) { error_out('Unknown setting key', 400); } $stmt = db()->prepare( 'INSERT INTO `system` (setting_name, setting_value) VALUES (:key, :value) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)' ); $stmt->execute([':key' => $key, ':value' => $value !== '' ? $value : null]); json_out(['saved' => true]); }