integrations: webhooks and API tokens
ci / check (push) Successful in 54s
ci / images (push) Successful in 21s

API tokens (Settings -> API tokens): Authorization: Bearer sp_<40 base62>,
stored as sha256, shown once. A token acts as its admin with their current
role and stops when they're disabled; Bearer requests skip the CSRF header
and never fall back to the cookie. A token can't manage tokens.

Webhooks (Settings -> Webhooks): call.started/answered/ended,
voicemail.new, emergency.call, trunk/extension registration changes, from
the live state; queued per webhook, sent every 10 s with
X-SelfPhoneNG-Signature (HMAC of timestamp.body), retried after 1 m, 5 m,
30 m, 2 h, 12 h, then failed. Private/loopback targets are refused in the
connection's own DNS lookup (no rebinding), unless allowed. Send test and
a delivery log per webhook.

The e2e found voicemail.new missing for mailboxes without a user: the
voicemail scan now queues it for every mailbox. vmpin.test.ts gets 180 s:
Git Bash forks make it ~85 s on Windows (the earlier flaky gate run).

Task: M11-T5
This commit is contained in:
iamdoubz committed 2026-10-19 19:40:47 -05:00
1 parent d229ed2c45
commit 60846afddd
17 files changed
+1319 -8

No files matched your search

+6 -1
View File
@@ -21,6 +21,7 @@ import type { LiveState } from './live/state.ts';
import { cleanupRecordings } from './routes/recordings.ts';
import { audit } from './services/audit.ts';
import { backupDue, runBackup } from './services/backup.ts';
import { deliverDue } from './services/webhooks.ts';
import type { SendMail } from './services/mail.ts';
import { getSetting, setSetting } from './services/settings.ts';
@@ -232,5 +233,9 @@ export function startJobs(d: JobDeps): () => void {
};
tick();
const timer = setInterval(tick, 60_000);
return () => clearInterval(timer);
const hooks = setInterval(() => run('webhookDelivery', () => deliverDue(d.db)), 10_000);
return () => {
clearInterval(timer);
clearInterval(hooks);
};
}