Stop a scalar NPM response killing the request, and add certificate deletion
NPM answers a successful DELETE with the bare literal true, which vv_npm_raw() is typed to return an array from — so deleting or toggling a proxy host has always thrown a TypeError rather than doing the thing.
This commit is contained in:
@@ -234,7 +234,17 @@ function vv_npm_raw(string $method, string $path, array $data, string $token, ar
|
||||
'code' => (int) curl_getinfo($ch, CURLINFO_HTTP_CODE),
|
||||
]);
|
||||
curl_close($ch);
|
||||
return json_decode($body ?: '{}', true) ?: [];
|
||||
|
||||
// NPM answers a successful DELETE with the bare JSON literal `true`, not an object. This
|
||||
// function is declared `: array`, so decoding that and returning it threw a TypeError and
|
||||
// killed the request — which is what deleting a certificate did, and what deleting or toggling
|
||||
// a proxy host has always done, since those three are the only callers whose endpoint answers
|
||||
// with a scalar. Wrapped rather than returned raw, so every caller still gets an array and the
|
||||
// outcome is readable as ['result' => true].
|
||||
$decoded = json_decode($body ?: '{}', true);
|
||||
if (is_array($decoded)) return $decoded;
|
||||
if ($decoded === null) return [];
|
||||
return ['result' => $decoded];
|
||||
}
|
||||
|
||||
function vv_npm_req(string $method, string $path, array $data = []): array {
|
||||
@@ -261,6 +271,30 @@ function vv_npm_list_certs(): array {
|
||||
return array_values($list);
|
||||
}
|
||||
|
||||
// Deleting a certificate is not undoable — the private key goes with it and a replacement means a
|
||||
// fresh issuance against Let's Encrypt's rate limits. The caller is expected to have checked that
|
||||
// no proxy host still points at it; NPM will happily remove one that is in use and leave the host
|
||||
// serving nothing.
|
||||
function vv_npm_delete_cert(int $id): array {
|
||||
$r = vv_npm_req('DELETE', "/api/nginx/certificates/$id");
|
||||
if (is_array($r) && isset($r['_err'])) return ['ok' => false, 'error' => $r['_err']];
|
||||
// NPM answers `true` for a successful delete and an error object otherwise.
|
||||
if (is_array($r) && isset($r['error']))
|
||||
return ['ok' => false, 'error' => $r['error']['message'] ?? 'Delete failed'];
|
||||
return ['ok' => true];
|
||||
}
|
||||
|
||||
// Which proxy hosts reference a certificate. The guard that belongs with the delete above, so a
|
||||
// caller cannot forget to ask the question.
|
||||
function vv_npm_cert_users(int $id): array {
|
||||
$p = vv_npm_list_proxies();
|
||||
if (!($p['ok'] ?? false)) return [];
|
||||
$out = [];
|
||||
foreach ($p['proxies'] as $h)
|
||||
if ((int) ($h['certificate_id'] ?? 0) === $id) $out[] = $h;
|
||||
return $out;
|
||||
}
|
||||
|
||||
function vv_npm_create_proxy(array $data): array {
|
||||
$r = vv_npm_req('POST', '/api/nginx/proxy-hosts', $data);
|
||||
return isset($r['id']) ? ['ok' => true, 'proxy' => $r] : ['ok' => false, 'error' => $r['error'] ?? ($r['_err'] ?? 'Create failed')];
|
||||
|
||||
Reference in New Issue
Block a user