@runcore-sh/runcore 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dictionary.json +2 -2
- package/dist/activity/log.js +2 -2
- package/dist/activity/log.js.map +1 -1
- package/dist/agents/governed-spawn.d.ts.map +1 -1
- package/dist/cli.js +101 -11
- package/dist/cli.js.map +1 -1
- package/dist/extensions/cache.d.ts +57 -0
- package/dist/extensions/cache.d.ts.map +1 -0
- package/dist/extensions/cache.js +173 -0
- package/dist/extensions/cache.js.map +1 -0
- package/dist/extensions/client.d.ts +55 -0
- package/dist/extensions/client.d.ts.map +1 -0
- package/dist/extensions/client.js +120 -0
- package/dist/extensions/client.js.map +1 -0
- package/dist/extensions/index.d.ts +13 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +12 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/loader.d.ts +50 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +166 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/manifest.d.ts +38 -0
- package/dist/extensions/manifest.d.ts.map +1 -0
- package/dist/extensions/manifest.js +17 -0
- package/dist/extensions/manifest.js.map +1 -0
- package/dist/extensions/stubs.d.ts +27 -0
- package/dist/extensions/stubs.d.ts.map +1 -0
- package/dist/extensions/stubs.js +45 -0
- package/dist/extensions/stubs.js.map +1 -0
- package/dist/lib/audit.js +2 -2
- package/dist/lib/audit.js.map +1 -1
- package/dist/lib/brain-migrate.d.ts +21 -0
- package/dist/lib/brain-migrate.d.ts.map +1 -0
- package/dist/lib/brain-migrate.js +137 -0
- package/dist/lib/brain-migrate.js.map +1 -0
- package/dist/lib/paths.d.ts +27 -0
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +65 -0
- package/dist/lib/paths.js.map +1 -1
- package/dist/llm/call-log.d.ts +40 -0
- package/dist/llm/call-log.d.ts.map +1 -0
- package/dist/llm/call-log.js +35 -0
- package/dist/llm/call-log.js.map +1 -0
- package/dist/llm/complete.d.ts +6 -0
- package/dist/llm/complete.d.ts.map +1 -1
- package/dist/llm/complete.js +27 -0
- package/dist/llm/complete.js.map +1 -1
- package/dist/mcp-server.js +118 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/memory/file-backed.d.ts +4 -0
- package/dist/memory/file-backed.d.ts.map +1 -1
- package/dist/memory/file-backed.js +4 -0
- package/dist/memory/file-backed.js.map +1 -1
- package/dist/memory/vector-index.d.ts +4 -12
- package/dist/memory/vector-index.d.ts.map +1 -1
- package/dist/memory/vector-index.js +11 -93
- package/dist/memory/vector-index.js.map +1 -1
- package/dist/search/brain-docs.d.ts +17 -7
- package/dist/search/brain-docs.d.ts.map +1 -1
- package/dist/search/brain-docs.js +170 -52
- package/dist/search/brain-docs.js.map +1 -1
- package/dist/search/brain-rag.d.ts +45 -0
- package/dist/search/brain-rag.d.ts.map +1 -0
- package/dist/search/brain-rag.js +275 -0
- package/dist/search/brain-rag.js.map +1 -0
- package/dist/search/chunker.d.ts +24 -0
- package/dist/search/chunker.d.ts.map +1 -0
- package/dist/search/chunker.js +95 -0
- package/dist/search/chunker.js.map +1 -0
- package/dist/search/embedder.d.ts +16 -0
- package/dist/search/embedder.d.ts.map +1 -0
- package/dist/search/embedder.js +108 -0
- package/dist/search/embedder.js.map +1 -0
- package/dist/search/file-watcher.d.ts +11 -0
- package/dist/search/file-watcher.d.ts.map +1 -0
- package/dist/search/file-watcher.js +86 -0
- package/dist/search/file-watcher.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +814 -472
- package/dist/server.js.map +1 -1
- package/dist/sessions/store.d.ts +9 -0
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js.map +1 -1
- package/dist/settings.d.ts +26 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +78 -2
- package/dist/settings.js.map +1 -1
- package/dist/tracing/init.d.ts +1 -1
- package/dist/tracing/init.d.ts.map +1 -1
- package/dist/utils/logger.js +2 -2
- package/dist/utils/logger.js.map +1 -1
- package/module-tiers.json +164 -0
- package/package.json +9 -13
- package/public/avatar/cache/1184385ec5522b57.mp4 +0 -0
- package/public/avatar/cache/1f15f6a1ebd7e439.mp4 +0 -0
- package/public/avatar/cache/2c7e47ff0bdeb8d1.mp4 +0 -0
- package/public/avatar/cache/5f308566f7abb8f2.mp4 +0 -0
- package/public/avatar/cache/62f9cfba848d724e.mp4 +0 -0
- package/public/avatar/cache/6d64e657e6bf2aab.mp4 +0 -0
- package/public/avatar/cache/763ad0349e0b6f26.mp4 +0 -0
- package/public/avatar/cache/81a516cfd461b2b9.mp4 +0 -0
- package/public/avatar/cache/9366de15fd6910ca.mp4 +0 -0
- package/public/avatar/cache/ade41a846b283895.mp4 +0 -0
- package/public/avatar/cache/b6066e5c65383eec.mp4 +0 -0
- package/public/avatar/cache/edadb75d37891fc7.mp4 +0 -0
- package/public/avatar/cache/f0ae159640621dd9.mp4 +0 -0
- package/public/avatar/cache/fc2e5419adf29d96.mp4 +0 -0
- package/public/index.html +379 -59
- package/dist/agents/autonomous.js +0 -749
- package/dist/agents/autonomous.js.map +0 -1
- package/dist/agents/commit.js +0 -113
- package/dist/agents/commit.js.map +0 -1
- package/dist/agents/continue.js +0 -158
- package/dist/agents/continue.js.map +0 -1
- package/dist/agents/cooldown.js +0 -397
- package/dist/agents/cooldown.js.map +0 -1
- package/dist/agents/dedup-guard.js +0 -131
- package/dist/agents/dedup-guard.js.map +0 -1
- package/dist/agents/feed.js +0 -176
- package/dist/agents/feed.js.map +0 -1
- package/dist/agents/governance.js +0 -292
- package/dist/agents/governance.js.map +0 -1
- package/dist/agents/governed-spawn.js +0 -192
- package/dist/agents/governed-spawn.js.map +0 -1
- package/dist/agents/heartbeat.js +0 -324
- package/dist/agents/heartbeat.js.map +0 -1
- package/dist/agents/instance-manager.js +0 -850
- package/dist/agents/instance-manager.js.map +0 -1
- package/dist/agents/issue-reporter.js +0 -123
- package/dist/agents/issue-reporter.js.map +0 -1
- package/dist/agents/issues.js +0 -141
- package/dist/agents/issues.js.map +0 -1
- package/dist/agents/locks.js +0 -234
- package/dist/agents/locks.js.map +0 -1
- package/dist/agents/memory.js +0 -93
- package/dist/agents/memory.js.map +0 -1
- package/dist/agents/monitor.js +0 -235
- package/dist/agents/monitor.js.map +0 -1
- package/dist/agents/orchestration.js +0 -715
- package/dist/agents/orchestration.js.map +0 -1
- package/dist/agents/recover.js +0 -166
- package/dist/agents/recover.js.map +0 -1
- package/dist/agents/reflection.js +0 -199
- package/dist/agents/reflection.js.map +0 -1
- package/dist/agents/runtime/bus.js +0 -174
- package/dist/agents/runtime/bus.js.map +0 -1
- package/dist/agents/runtime/config.js +0 -101
- package/dist/agents/runtime/config.js.map +0 -1
- package/dist/agents/runtime/driver.js +0 -214
- package/dist/agents/runtime/driver.js.map +0 -1
- package/dist/agents/runtime/errors.js +0 -40
- package/dist/agents/runtime/errors.js.map +0 -1
- package/dist/agents/runtime/index.js +0 -54
- package/dist/agents/runtime/index.js.map +0 -1
- package/dist/agents/runtime/lifecycle.js +0 -116
- package/dist/agents/runtime/lifecycle.js.map +0 -1
- package/dist/agents/runtime/manager.js +0 -948
- package/dist/agents/runtime/manager.js.map +0 -1
- package/dist/agents/runtime/registry.js +0 -195
- package/dist/agents/runtime/registry.js.map +0 -1
- package/dist/agents/runtime/resources.js +0 -146
- package/dist/agents/runtime/resources.js.map +0 -1
- package/dist/agents/runtime/types.js +0 -24
- package/dist/agents/runtime/types.js.map +0 -1
- package/dist/agents/spawn-policy.js +0 -202
- package/dist/agents/spawn-policy.js.map +0 -1
- package/dist/agents/spawn.js +0 -970
- package/dist/agents/spawn.js.map +0 -1
- package/dist/agents/triage.js +0 -81
- package/dist/agents/triage.js.map +0 -1
- package/dist/agents/workflow.js +0 -543
- package/dist/agents/workflow.js.map +0 -1
- package/dist/avatar/client.js +0 -172
- package/dist/avatar/client.js.map +0 -1
- package/dist/avatar/sidecar.js +0 -125
- package/dist/avatar/sidecar.js.map +0 -1
- package/dist/browser/sessions.js +0 -122
- package/dist/browser/sessions.js.map +0 -1
- package/dist/capabilities/definitions/browser.js +0 -242
- package/dist/capabilities/definitions/browser.js.map +0 -1
- package/dist/channels/whatsapp.js +0 -200
- package/dist/channels/whatsapp.js.map +0 -1
- package/dist/credentials/store.js +0 -189
- package/dist/credentials/store.js.map +0 -1
- package/dist/files/deep-index.js +0 -337
- package/dist/files/deep-index.js.map +0 -1
- package/dist/files/extract.js +0 -33
- package/dist/files/extract.js.map +0 -1
- package/dist/files/gdrive.js +0 -246
- package/dist/files/gdrive.js.map +0 -1
- package/dist/github/client.js +0 -408
- package/dist/github/client.js.map +0 -1
- package/dist/github/commit-analysis.js +0 -276
- package/dist/github/commit-analysis.js.map +0 -1
- package/dist/github/contributor-stats.js +0 -119
- package/dist/github/contributor-stats.js.map +0 -1
- package/dist/github/issue-sla.js +0 -220
- package/dist/github/issue-sla.js.map +0 -1
- package/dist/github/issue-triage.js +0 -286
- package/dist/github/issue-triage.js.map +0 -1
- package/dist/github/pr-readiness.js +0 -197
- package/dist/github/pr-readiness.js.map +0 -1
- package/dist/github/pr-review.js +0 -410
- package/dist/github/pr-review.js.map +0 -1
- package/dist/github/release-notes.js +0 -227
- package/dist/github/release-notes.js.map +0 -1
- package/dist/github/repo-health.js +0 -303
- package/dist/github/repo-health.js.map +0 -1
- package/dist/github/retry.js +0 -117
- package/dist/github/retry.js.map +0 -1
- package/dist/github/types.js +0 -8
- package/dist/github/types.js.map +0 -1
- package/dist/github/webhooks.js +0 -153
- package/dist/github/webhooks.js.map +0 -1
- package/dist/google/auth.js +0 -325
- package/dist/google/auth.js.map +0 -1
- package/dist/google/calendar-timer.js +0 -91
- package/dist/google/calendar-timer.js.map +0 -1
- package/dist/google/calendar.js +0 -270
- package/dist/google/calendar.js.map +0 -1
- package/dist/google/docs.js +0 -309
- package/dist/google/docs.js.map +0 -1
- package/dist/google/gmail-send.js +0 -219
- package/dist/google/gmail-send.js.map +0 -1
- package/dist/google/gmail-timer.js +0 -223
- package/dist/google/gmail-timer.js.map +0 -1
- package/dist/google/gmail.js +0 -470
- package/dist/google/gmail.js.map +0 -1
- package/dist/google/plugin.js +0 -169
- package/dist/google/plugin.js.map +0 -1
- package/dist/google/tasks-timer.js +0 -107
- package/dist/google/tasks-timer.js.map +0 -1
- package/dist/google/tasks.js +0 -331
- package/dist/google/tasks.js.map +0 -1
- package/dist/google/temporal.js +0 -176
- package/dist/google/temporal.js.map +0 -1
- package/dist/integrations/gate.js +0 -100
- package/dist/integrations/gate.js.map +0 -1
- package/dist/integrations/github.js +0 -331
- package/dist/integrations/github.js.map +0 -1
- package/dist/integrations/google-tasks.js +0 -432
- package/dist/integrations/google-tasks.js.map +0 -1
- package/dist/mdns.js +0 -110
- package/dist/mdns.js.map +0 -1
- package/dist/notifications/channel.js +0 -83
- package/dist/notifications/channel.js.map +0 -1
- package/dist/notifications/channels/adapter.js +0 -55
- package/dist/notifications/channels/adapter.js.map +0 -1
- package/dist/notifications/channels/index.js +0 -6
- package/dist/notifications/channels/index.js.map +0 -1
- package/dist/notifications/channels/log.js +0 -29
- package/dist/notifications/channels/log.js.map +0 -1
- package/dist/notifications/email.js +0 -72
- package/dist/notifications/email.js.map +0 -1
- package/dist/notifications/engine.js +0 -198
- package/dist/notifications/engine.js.map +0 -1
- package/dist/notifications/index.js +0 -24
- package/dist/notifications/index.js.map +0 -1
- package/dist/notifications/phone.js +0 -48
- package/dist/notifications/phone.js.map +0 -1
- package/dist/notifications/sms.js +0 -65
- package/dist/notifications/sms.js.map +0 -1
- package/dist/notifications/types.js +0 -14
- package/dist/notifications/types.js.map +0 -1
- package/dist/notifications/webhook.js +0 -65
- package/dist/notifications/webhook.js.map +0 -1
- package/dist/resend/inbox.js +0 -199
- package/dist/resend/inbox.js.map +0 -1
- package/dist/resend/webhooks.js +0 -244
- package/dist/resend/webhooks.js.map +0 -1
- package/dist/search/browse.js +0 -225
- package/dist/search/browse.js.map +0 -1
- package/dist/search/perplexity.js +0 -41
- package/dist/search/perplexity.js.map +0 -1
- package/dist/slack/channels.js +0 -277
- package/dist/slack/channels.js.map +0 -1
- package/dist/slack/client.js +0 -468
- package/dist/slack/client.js.map +0 -1
- package/dist/slack/retry.js +0 -100
- package/dist/slack/retry.js.map +0 -1
- package/dist/slack/types.js +0 -52
- package/dist/slack/types.js.map +0 -1
- package/dist/slack/webhooks.js +0 -285
- package/dist/slack/webhooks.js.map +0 -1
- package/dist/stt/client.js +0 -66
- package/dist/stt/client.js.map +0 -1
- package/dist/stt/sidecar.js +0 -115
- package/dist/stt/sidecar.js.map +0 -1
- package/dist/tracing/bridge.js +0 -70
- package/dist/tracing/bridge.js.map +0 -1
- package/dist/tracing/correlation.js +0 -49
- package/dist/tracing/correlation.js.map +0 -1
- package/dist/tracing/index.js +0 -18
- package/dist/tracing/index.js.map +0 -1
- package/dist/tracing/init.js +0 -81
- package/dist/tracing/init.js.map +0 -1
- package/dist/tracing/instrument.js +0 -145
- package/dist/tracing/instrument.js.map +0 -1
- package/dist/tracing/middleware.js +0 -69
- package/dist/tracing/middleware.js.map +0 -1
- package/dist/tracing/tracer.js +0 -327
- package/dist/tracing/tracer.js.map +0 -1
- package/dist/tts/client.js +0 -48
- package/dist/tts/client.js.map +0 -1
- package/dist/tts/sidecar.js +0 -148
- package/dist/tts/sidecar.js.map +0 -1
- package/dist/twilio/call.js +0 -79
- package/dist/twilio/call.js.map +0 -1
- package/dist/vault/matcher.js +0 -197
- package/dist/vault/matcher.js.map +0 -1
- package/dist/vault/personal.js +0 -163
- package/dist/vault/personal.js.map +0 -1
- package/dist/vault/policy.js +0 -159
- package/dist/vault/policy.js.map +0 -1
- package/dist/vault/store.js +0 -122
- package/dist/vault/store.js.map +0 -1
- package/dist/vault/transfer.js +0 -188
- package/dist/vault/transfer.js.map +0 -1
- package/dist/volumes/index.js +0 -2
- package/dist/volumes/index.js.map +0 -1
- package/dist/volumes/manager.js +0 -462
- package/dist/volumes/manager.js.map +0 -1
- package/dist/volumes/types.js +0 -8
- package/dist/volumes/types.js.map +0 -1
- package/dist/webhooks/config.js +0 -214
- package/dist/webhooks/config.js.map +0 -1
- package/dist/webhooks/event-log.js +0 -132
- package/dist/webhooks/event-log.js.map +0 -1
- package/dist/webhooks/handler.js +0 -103
- package/dist/webhooks/handler.js.map +0 -1
- package/dist/webhooks/handlers.js +0 -231
- package/dist/webhooks/handlers.js.map +0 -1
- package/dist/webhooks/index.js +0 -33
- package/dist/webhooks/index.js.map +0 -1
- package/dist/webhooks/mount.js +0 -400
- package/dist/webhooks/mount.js.map +0 -1
- package/dist/webhooks/registry.js +0 -143
- package/dist/webhooks/registry.js.map +0 -1
- package/dist/webhooks/relay.js +0 -53
- package/dist/webhooks/relay.js.map +0 -1
- package/dist/webhooks/retry.js +0 -270
- package/dist/webhooks/retry.js.map +0 -1
- package/dist/webhooks/router.js +0 -290
- package/dist/webhooks/router.js.map +0 -1
- package/dist/webhooks/twilio.js +0 -129
- package/dist/webhooks/twilio.js.map +0 -1
- package/dist/webhooks/types.js +0 -8
- package/dist/webhooks/types.js.map +0 -1
- package/dist/webhooks/verify.js +0 -154
- package/dist/webhooks/verify.js.map +0 -1
package/dist/webhooks/mount.js
DELETED
|
@@ -1,400 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Webhook route mounting for Hono.
|
|
3
|
-
*
|
|
4
|
-
* Provides helpers to mount webhook endpoints on a Hono app:
|
|
5
|
-
* - `mountWebhookAdmin(app)` — Admin/management endpoints for listing providers,
|
|
6
|
-
* checking health, viewing stats, and managing configuration.
|
|
7
|
-
* - `createWebhookMiddleware(providerName)` — Reusable verification middleware
|
|
8
|
-
* that routes can compose with provider-specific response handling.
|
|
9
|
-
*/
|
|
10
|
-
import { logActivity } from "../activity/log.js";
|
|
11
|
-
import { getProvider, listProviders, getProviderStats, getAllProviderStats, getProviderHealth, getAllProviderHealth, } from "./registry.js";
|
|
12
|
-
import { routeWebhook, routeWebhookRequest, } from "./router.js";
|
|
13
|
-
import { getProviderConfig, setProviderConfig, getProviderSecret, isProviderEnabled, validateConfig, listConfiguredProviders, } from "./config.js";
|
|
14
|
-
import { DeadLetterQueue } from "./retry.js";
|
|
15
|
-
import { getRecentEvents, getEventLogSummary, clearEventLog, startEventTimer, } from "./event-log.js";
|
|
16
|
-
// ── Shared dead-letter queue (lazy-initialized) ─────────────────────────────
|
|
17
|
-
let dlq = null;
|
|
18
|
-
/** Get the shared dead-letter queue instance. Lazy-initializes on first access
|
|
19
|
-
* to avoid sync file I/O + logActivity() at module import time. */
|
|
20
|
-
export function getDeadLetterQueue() {
|
|
21
|
-
if (!dlq) {
|
|
22
|
-
dlq = new DeadLetterQueue(200, "brain/webhooks/dlq.json");
|
|
23
|
-
}
|
|
24
|
-
return dlq;
|
|
25
|
-
}
|
|
26
|
-
// ── Verification helper ──────────────────────────────────────────────────────
|
|
27
|
-
/**
|
|
28
|
-
* Verify a webhook request for a given provider.
|
|
29
|
-
* Looks up the provider in the registry, resolves the secret, and calls verify().
|
|
30
|
-
* Returns { valid, error? } — does not throw.
|
|
31
|
-
*/
|
|
32
|
-
export function verifyWebhookRequest(providerName, rawBody, headers, opts) {
|
|
33
|
-
const start = performance.now();
|
|
34
|
-
const provider = getProvider(providerName);
|
|
35
|
-
if (!provider) {
|
|
36
|
-
return { valid: false, error: `Unknown provider: ${providerName}`, durationMs: performance.now() - start };
|
|
37
|
-
}
|
|
38
|
-
if (!isProviderEnabled(providerName)) {
|
|
39
|
-
return { valid: false, error: `Provider ${providerName} is disabled`, durationMs: performance.now() - start };
|
|
40
|
-
}
|
|
41
|
-
const secret = getProviderSecret(providerName);
|
|
42
|
-
if (!secret) {
|
|
43
|
-
// No secret configured — allow in dev mode
|
|
44
|
-
return { valid: true, durationMs: performance.now() - start };
|
|
45
|
-
}
|
|
46
|
-
const config = getProviderConfig(providerName);
|
|
47
|
-
const sigHeader = config?.signatureHeader ?? "x-signature";
|
|
48
|
-
const signature = headers[sigHeader] ?? "";
|
|
49
|
-
const ctx = {
|
|
50
|
-
rawBody,
|
|
51
|
-
signature,
|
|
52
|
-
secret,
|
|
53
|
-
headers,
|
|
54
|
-
url: opts?.url,
|
|
55
|
-
params: opts?.params,
|
|
56
|
-
};
|
|
57
|
-
const verifyStart = performance.now();
|
|
58
|
-
const valid = provider.verify(ctx);
|
|
59
|
-
const verifyMs = performance.now() - verifyStart;
|
|
60
|
-
const totalMs = performance.now() - start;
|
|
61
|
-
if (totalMs > 100) {
|
|
62
|
-
logActivity({
|
|
63
|
-
source: "system",
|
|
64
|
-
summary: `[perf] verifyWebhookRequest(${providerName}) took ${totalMs.toFixed(1)}ms (verify:${verifyMs.toFixed(1)}ms)`,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (!valid) {
|
|
68
|
-
return { valid: false, error: "Invalid webhook signature", durationMs: totalMs };
|
|
69
|
-
}
|
|
70
|
-
return { valid: true, durationMs: totalMs };
|
|
71
|
-
}
|
|
72
|
-
// ── Route processing helper ──────────────────────────────────────────────────
|
|
73
|
-
/**
|
|
74
|
-
* Process a verified webhook payload through the registry.
|
|
75
|
-
* Call this after verification succeeds. Handles error wrapping and DLQ.
|
|
76
|
-
*/
|
|
77
|
-
export async function processVerifiedWebhook(providerName, payload, ctx) {
|
|
78
|
-
const start = performance.now();
|
|
79
|
-
const result = await routeWebhook(providerName, payload, undefined, ctx);
|
|
80
|
-
const routeMs = performance.now() - start;
|
|
81
|
-
if (!result.handled) {
|
|
82
|
-
const dlqStart = performance.now();
|
|
83
|
-
getDeadLetterQueue().add({
|
|
84
|
-
provider: providerName,
|
|
85
|
-
payload,
|
|
86
|
-
error: {
|
|
87
|
-
kind: "permanent",
|
|
88
|
-
message: result.message,
|
|
89
|
-
provider: providerName,
|
|
90
|
-
timestamp: new Date().toISOString(),
|
|
91
|
-
},
|
|
92
|
-
receivedAt: new Date().toISOString(),
|
|
93
|
-
attempts: 1,
|
|
94
|
-
});
|
|
95
|
-
const dlqMs = performance.now() - dlqStart;
|
|
96
|
-
if (dlqMs > 50) {
|
|
97
|
-
logActivity({
|
|
98
|
-
source: "system",
|
|
99
|
-
summary: `[perf] DLQ add for ${providerName} took ${dlqMs.toFixed(1)}ms`,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
const totalMs = performance.now() - start;
|
|
104
|
-
if (totalMs > 500) {
|
|
105
|
-
logActivity({
|
|
106
|
-
source: "system",
|
|
107
|
-
summary: `[perf] processVerifiedWebhook(${providerName}) took ${totalMs.toFixed(1)}ms (route:${routeMs.toFixed(1)}ms)`,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
return result;
|
|
111
|
-
}
|
|
112
|
-
// ── Admin route mounting ─────────────────────────────────────────────────────
|
|
113
|
-
/**
|
|
114
|
-
* Mount webhook admin/management endpoints on a Hono app.
|
|
115
|
-
* Adds routes under `/api/webhooks/` for provider management, health, stats,
|
|
116
|
-
* configuration, and dead-letter queue inspection.
|
|
117
|
-
*
|
|
118
|
-
* Routes:
|
|
119
|
-
* - GET /api/webhooks/providers — List registered providers
|
|
120
|
-
* - GET /api/webhooks/providers/:name — Get provider detail (config + stats + health)
|
|
121
|
-
* - GET /api/webhooks/health — Health summary for all providers
|
|
122
|
-
* - GET /api/webhooks/stats — Stats for all providers
|
|
123
|
-
* - GET /api/webhooks/config/validate — Validate webhook configuration
|
|
124
|
-
* - POST /api/webhooks/config/:name — Update provider configuration
|
|
125
|
-
* - GET /api/webhooks/dlq — List dead-letter queue entries
|
|
126
|
-
* - DELETE /api/webhooks/dlq/:id — Remove a DLQ entry
|
|
127
|
-
* - POST /api/webhooks/dlq/:id/retry — Retry a DLQ entry
|
|
128
|
-
* - GET /api/webhooks/events — Recent event log (debugging)
|
|
129
|
-
* - GET /api/webhooks/events/summary — Event log summary statistics
|
|
130
|
-
* - DELETE /api/webhooks/events — Clear event log
|
|
131
|
-
* - POST /api/webhooks/test/:name — Send a test payload to a provider
|
|
132
|
-
*/
|
|
133
|
-
export function mountWebhookAdmin(app) {
|
|
134
|
-
const mountStart = performance.now();
|
|
135
|
-
// List all registered providers
|
|
136
|
-
app.get("/api/webhooks/providers", (c) => {
|
|
137
|
-
const providers = listProviders();
|
|
138
|
-
const configured = listConfiguredProviders();
|
|
139
|
-
return c.json({
|
|
140
|
-
providers: providers.map((name) => ({
|
|
141
|
-
name,
|
|
142
|
-
registered: true,
|
|
143
|
-
configured: configured.includes(name),
|
|
144
|
-
enabled: isProviderEnabled(name),
|
|
145
|
-
})),
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
// Get detail for a specific provider
|
|
149
|
-
app.get("/api/webhooks/providers/:name", (c) => {
|
|
150
|
-
const name = c.req.param("name");
|
|
151
|
-
const provider = getProvider(name);
|
|
152
|
-
if (!provider) {
|
|
153
|
-
return c.json({ error: `Provider "${name}" not found` }, 404);
|
|
154
|
-
}
|
|
155
|
-
const stats = getProviderStats(name);
|
|
156
|
-
const health = getProviderHealth(name);
|
|
157
|
-
const config = getProviderConfig(name);
|
|
158
|
-
return c.json({
|
|
159
|
-
name,
|
|
160
|
-
enabled: isProviderEnabled(name),
|
|
161
|
-
config: config
|
|
162
|
-
? { ...config, secret: config.secret ? "***" : undefined }
|
|
163
|
-
: null,
|
|
164
|
-
stats: stats ?? null,
|
|
165
|
-
health: health ?? null,
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
// Health summary for all providers
|
|
169
|
-
app.get("/api/webhooks/health", (c) => {
|
|
170
|
-
const threshold = parseFloat(c.req.query("threshold") ?? "0.5");
|
|
171
|
-
const health = getAllProviderHealth(threshold);
|
|
172
|
-
return c.json({ providers: health });
|
|
173
|
-
});
|
|
174
|
-
// Stats for all providers
|
|
175
|
-
app.get("/api/webhooks/stats", (c) => {
|
|
176
|
-
const stats = getAllProviderStats();
|
|
177
|
-
return c.json({ providers: stats });
|
|
178
|
-
});
|
|
179
|
-
// Validate configuration
|
|
180
|
-
app.get("/api/webhooks/config/validate", (c) => {
|
|
181
|
-
const issues = validateConfig();
|
|
182
|
-
const hasIssues = Object.keys(issues).length > 0;
|
|
183
|
-
return c.json({ valid: !hasIssues, issues });
|
|
184
|
-
});
|
|
185
|
-
// Update provider configuration
|
|
186
|
-
app.post("/api/webhooks/config/:name", async (c) => {
|
|
187
|
-
const name = c.req.param("name");
|
|
188
|
-
const body = await c.req.json();
|
|
189
|
-
setProviderConfig({ name, ...body });
|
|
190
|
-
logActivity({
|
|
191
|
-
source: "system",
|
|
192
|
-
summary: `Webhook config updated for ${name}`,
|
|
193
|
-
});
|
|
194
|
-
return c.json({ ok: true, message: `Configuration updated for ${name}` });
|
|
195
|
-
});
|
|
196
|
-
// Dead-letter queue: list entries
|
|
197
|
-
app.get("/api/webhooks/dlq", (c) => {
|
|
198
|
-
const provider = c.req.query("provider");
|
|
199
|
-
const entries = getDeadLetterQueue().list(provider ?? undefined);
|
|
200
|
-
return c.json({ size: entries.length, entries });
|
|
201
|
-
});
|
|
202
|
-
// Dead-letter queue: remove entry
|
|
203
|
-
app.delete("/api/webhooks/dlq/:id", (c) => {
|
|
204
|
-
const id = c.req.param("id");
|
|
205
|
-
const removed = getDeadLetterQueue().remove(id);
|
|
206
|
-
if (!removed) {
|
|
207
|
-
return c.json({ error: `DLQ entry "${id}" not found` }, 404);
|
|
208
|
-
}
|
|
209
|
-
return c.json({ ok: true, message: `Removed DLQ entry ${id}` });
|
|
210
|
-
});
|
|
211
|
-
// Dead-letter queue: retry an entry
|
|
212
|
-
app.post("/api/webhooks/dlq/:id/retry", async (c) => {
|
|
213
|
-
const id = c.req.param("id");
|
|
214
|
-
const queue = getDeadLetterQueue();
|
|
215
|
-
const entries = queue.list();
|
|
216
|
-
const entry = entries.find((e) => e.id === id);
|
|
217
|
-
if (!entry) {
|
|
218
|
-
return c.json({ error: `DLQ entry "${id}" not found` }, 404);
|
|
219
|
-
}
|
|
220
|
-
const result = await routeWebhook(entry.provider, entry.payload);
|
|
221
|
-
if (result.handled) {
|
|
222
|
-
queue.remove(id);
|
|
223
|
-
}
|
|
224
|
-
return c.json({
|
|
225
|
-
ok: result.handled,
|
|
226
|
-
message: result.message,
|
|
227
|
-
removed: result.handled,
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
// ── Event log endpoints ───────────────────────────────────────────────────
|
|
231
|
-
// Recent event log (debugging)
|
|
232
|
-
app.get("/api/webhooks/events", (c) => {
|
|
233
|
-
const provider = c.req.query("provider") ?? undefined;
|
|
234
|
-
const successStr = c.req.query("success");
|
|
235
|
-
const success = successStr === "true" ? true : successStr === "false" ? false : undefined;
|
|
236
|
-
const limit = parseInt(c.req.query("limit") ?? "50", 10);
|
|
237
|
-
const since = c.req.query("since") ?? undefined;
|
|
238
|
-
const events = getRecentEvents({ provider, success, limit, since });
|
|
239
|
-
return c.json({ count: events.length, events });
|
|
240
|
-
});
|
|
241
|
-
// Event log summary
|
|
242
|
-
app.get("/api/webhooks/events/summary", (c) => {
|
|
243
|
-
const summary = getEventLogSummary();
|
|
244
|
-
return c.json(summary);
|
|
245
|
-
});
|
|
246
|
-
// Clear event log
|
|
247
|
-
app.delete("/api/webhooks/events", (c) => {
|
|
248
|
-
const provider = c.req.query("provider") ?? undefined;
|
|
249
|
-
const cleared = clearEventLog(provider);
|
|
250
|
-
return c.json({ ok: true, cleared });
|
|
251
|
-
});
|
|
252
|
-
// ── Test endpoint ────────────────────────────────────────────────────────
|
|
253
|
-
// Send a test payload to a provider (bypasses signature verification)
|
|
254
|
-
app.post("/api/webhooks/test/:name", async (c) => {
|
|
255
|
-
const name = c.req.param("name");
|
|
256
|
-
const provider = getProvider(name);
|
|
257
|
-
if (!provider) {
|
|
258
|
-
return c.json({ error: `Provider "${name}" not found` }, 404);
|
|
259
|
-
}
|
|
260
|
-
if (!isProviderEnabled(name)) {
|
|
261
|
-
return c.json({ error: `Provider "${name}" is disabled` }, 400);
|
|
262
|
-
}
|
|
263
|
-
let payload;
|
|
264
|
-
try {
|
|
265
|
-
payload = await c.req.json();
|
|
266
|
-
}
|
|
267
|
-
catch {
|
|
268
|
-
return c.json({ error: "Invalid JSON body" }, 400);
|
|
269
|
-
}
|
|
270
|
-
const finish = startEventTimer(name, { eventType: "test" });
|
|
271
|
-
try {
|
|
272
|
-
const result = await provider.process(payload);
|
|
273
|
-
finish({
|
|
274
|
-
success: result.handled,
|
|
275
|
-
message: result.message,
|
|
276
|
-
});
|
|
277
|
-
return c.json({ ok: true, result });
|
|
278
|
-
}
|
|
279
|
-
catch (err) {
|
|
280
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
281
|
-
finish({ success: false, message: msg, error: msg });
|
|
282
|
-
return c.json({ ok: false, error: msg }, 500);
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
const routesMs = (performance.now() - mountStart).toFixed(1);
|
|
286
|
-
const logStart = performance.now();
|
|
287
|
-
logActivity({
|
|
288
|
-
source: "system",
|
|
289
|
-
summary: `Webhook admin routes mounted at /api/webhooks/ (routes:${routesMs}ms)`,
|
|
290
|
-
});
|
|
291
|
-
const logMs = (performance.now() - logStart).toFixed(1);
|
|
292
|
-
const totalMs = (performance.now() - mountStart).toFixed(1);
|
|
293
|
-
if (parseFloat(logMs) > 5) {
|
|
294
|
-
logActivity({
|
|
295
|
-
source: "system",
|
|
296
|
-
summary: `[perf] mountWebhookAdmin logActivity took ${logMs}ms`,
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
if (parseFloat(totalMs) > 50) {
|
|
300
|
-
logActivity({
|
|
301
|
-
source: "system",
|
|
302
|
-
summary: `[perf] mountWebhookAdmin total: ${totalMs}ms (routes:${routesMs}ms, log:${logMs}ms)`,
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Create a Hono route handler that verifies and processes webhooks
|
|
308
|
-
* through the generic registry. Use this to replace inline verification code.
|
|
309
|
-
*
|
|
310
|
-
* Usage:
|
|
311
|
-
* app.post("/api/my-service/webhooks", createWebhookRoute({
|
|
312
|
-
* provider: "my-service",
|
|
313
|
-
* processorCtx: { store: myStore },
|
|
314
|
-
* }));
|
|
315
|
-
*/
|
|
316
|
-
export function createWebhookRoute(opts) {
|
|
317
|
-
return async (c) => {
|
|
318
|
-
const rawBody = await c.req.text();
|
|
319
|
-
// Build headers map (lowercase keys)
|
|
320
|
-
const headers = {};
|
|
321
|
-
c.req.raw.headers.forEach((value, key) => {
|
|
322
|
-
headers[key.toLowerCase()] = value;
|
|
323
|
-
});
|
|
324
|
-
// Build URL for providers that need it (e.g., Twilio)
|
|
325
|
-
const proto = headers["x-forwarded-proto"] ?? "https";
|
|
326
|
-
const host = headers["host"] ?? "localhost";
|
|
327
|
-
const pathName = new URL(c.req.url).pathname;
|
|
328
|
-
const fullUrl = `${proto}://${host}${pathName}`;
|
|
329
|
-
// Start event timer for the event log
|
|
330
|
-
const deliveryId = headers["x-request-id"] ?? headers["x-github-delivery"] ?? undefined;
|
|
331
|
-
const finish = startEventTimer(opts.provider, { deliveryId });
|
|
332
|
-
// Verify signature
|
|
333
|
-
const verification = verifyWebhookRequest(opts.provider, rawBody, headers, {
|
|
334
|
-
url: fullUrl,
|
|
335
|
-
});
|
|
336
|
-
if (!verification.valid) {
|
|
337
|
-
finish({
|
|
338
|
-
success: false,
|
|
339
|
-
message: verification.error ?? "Signature verification failed",
|
|
340
|
-
error: verification.error,
|
|
341
|
-
statusCode: 401,
|
|
342
|
-
});
|
|
343
|
-
return c.json({ error: verification.error }, 401);
|
|
344
|
-
}
|
|
345
|
-
// Parse body
|
|
346
|
-
let parsed;
|
|
347
|
-
const contentType = headers["content-type"] ?? "";
|
|
348
|
-
if (contentType.includes("application/json")) {
|
|
349
|
-
try {
|
|
350
|
-
parsed = JSON.parse(rawBody);
|
|
351
|
-
}
|
|
352
|
-
catch {
|
|
353
|
-
finish({ success: false, message: "Invalid JSON body", statusCode: 400 });
|
|
354
|
-
return c.json({ error: "Invalid JSON body" }, 400);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
358
|
-
const params = {};
|
|
359
|
-
const pairs = rawBody.split("&");
|
|
360
|
-
for (const pair of pairs) {
|
|
361
|
-
const eqIdx = pair.indexOf("=");
|
|
362
|
-
if (eqIdx === -1)
|
|
363
|
-
continue;
|
|
364
|
-
const key = decodeURIComponent(pair.slice(0, eqIdx).replace(/\+/g, " "));
|
|
365
|
-
const value = decodeURIComponent(pair.slice(eqIdx + 1).replace(/\+/g, " "));
|
|
366
|
-
params[key] = value;
|
|
367
|
-
}
|
|
368
|
-
parsed = params;
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
parsed = rawBody;
|
|
372
|
-
}
|
|
373
|
-
// Route through the middleware pipeline
|
|
374
|
-
const result = await routeWebhookRequest({
|
|
375
|
-
method: c.req.method,
|
|
376
|
-
url: fullUrl,
|
|
377
|
-
headers,
|
|
378
|
-
body: rawBody,
|
|
379
|
-
parsed,
|
|
380
|
-
provider: opts.provider,
|
|
381
|
-
}, {
|
|
382
|
-
processorCtx: opts.processorCtx,
|
|
383
|
-
middleware: opts.middleware,
|
|
384
|
-
});
|
|
385
|
-
// Log the event
|
|
386
|
-
finish({
|
|
387
|
-
success: result.handled,
|
|
388
|
-
message: result.message,
|
|
389
|
-
statusCode: 200,
|
|
390
|
-
});
|
|
391
|
-
// Custom response transformation
|
|
392
|
-
if (opts.transformResponse) {
|
|
393
|
-
const custom = opts.transformResponse(result, c);
|
|
394
|
-
if (custom)
|
|
395
|
-
return custom;
|
|
396
|
-
}
|
|
397
|
-
return c.json(result);
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
//# sourceMappingURL=mount.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../../src/webhooks/mount.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic webhook registry.
|
|
3
|
-
*
|
|
4
|
-
* Provider registration, lookup, stats tracking, and health monitoring.
|
|
5
|
-
* Signature verification, routing, retry, and configuration live in
|
|
6
|
-
* their own modules — this file re-exports them for backward compatibility.
|
|
7
|
-
*/
|
|
8
|
-
import { createLogger } from "../utils/logger.js";
|
|
9
|
-
const log = createLogger("webhooks.registry");
|
|
10
|
-
export { hmacSha256Hex, hmacSha256Base64, hmacSha1Base64, timingSafeCompare, isTimestampFresh, } from "./verify.js";
|
|
11
|
-
export { withWebhookRetry } from "./retry.js";
|
|
12
|
-
export { routeWebhook, routeWebhookRequest, composeMiddleware, validateRequest, deduplicateRequests, createWebhookEvent, } from "./router.js";
|
|
13
|
-
// ── Registry ─────────────────────────────────────────────────────────────────
|
|
14
|
-
const providers = new Map();
|
|
15
|
-
/**
|
|
16
|
-
* Register a webhook provider.
|
|
17
|
-
* Skips re-registration if a provider with the same name is already registered.
|
|
18
|
-
* Uses debug logging instead of activity log to prevent the trace insight engine
|
|
19
|
-
* from flagging normal startup registrations as bottlenecks (DASH-61, DASH-62).
|
|
20
|
-
*/
|
|
21
|
-
export function registerProvider(provider) {
|
|
22
|
-
if (providers.has(provider.name))
|
|
23
|
-
return;
|
|
24
|
-
providers.set(provider.name, provider);
|
|
25
|
-
log.debug(`Webhook provider registered: ${provider.name}`);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Register multiple providers in a single batch.
|
|
29
|
-
* Skips providers that are already registered by name, avoiding duplicate
|
|
30
|
-
* registrations across watch-mode restarts or repeated calls.
|
|
31
|
-
* Uses debug logging instead of activity log to prevent the trace insight
|
|
32
|
-
* engine from flagging normal startup registrations as bottlenecks (DASH-61, DASH-62).
|
|
33
|
-
*/
|
|
34
|
-
export function registerProviders(list) {
|
|
35
|
-
const registered = [];
|
|
36
|
-
const skipped = [];
|
|
37
|
-
for (const provider of list) {
|
|
38
|
-
if (providers.has(provider.name)) {
|
|
39
|
-
skipped.push(provider.name);
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
providers.set(provider.name, provider);
|
|
43
|
-
registered.push(provider.name);
|
|
44
|
-
}
|
|
45
|
-
if (registered.length > 0) {
|
|
46
|
-
log.debug(`Webhook providers registered: [${registered.join(", ")}]`);
|
|
47
|
-
}
|
|
48
|
-
if (skipped.length > 0) {
|
|
49
|
-
log.debug(`Webhook providers skipped (already registered): [${skipped.join(", ")}]`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/** Get a registered provider by name. */
|
|
53
|
-
export function getProvider(name) {
|
|
54
|
-
return providers.get(name);
|
|
55
|
-
}
|
|
56
|
-
/** List all registered provider names. */
|
|
57
|
-
export function listProviders() {
|
|
58
|
-
return [...providers.keys()];
|
|
59
|
-
}
|
|
60
|
-
/** Remove a provider by name. */
|
|
61
|
-
export function removeProvider(name) {
|
|
62
|
-
return providers.delete(name);
|
|
63
|
-
}
|
|
64
|
-
// ── Provider Stats ──────────────────────────────────────────────────────────
|
|
65
|
-
const statsMap = new Map();
|
|
66
|
-
function getOrCreateStats(name) {
|
|
67
|
-
let stats = statsMap.get(name);
|
|
68
|
-
if (!stats) {
|
|
69
|
-
stats = {
|
|
70
|
-
name,
|
|
71
|
-
invocations: 0,
|
|
72
|
-
successes: 0,
|
|
73
|
-
failures: 0,
|
|
74
|
-
lastInvokedAt: null,
|
|
75
|
-
lastErrorAt: null,
|
|
76
|
-
lastError: null,
|
|
77
|
-
};
|
|
78
|
-
statsMap.set(name, stats);
|
|
79
|
-
}
|
|
80
|
-
return stats;
|
|
81
|
-
}
|
|
82
|
-
/** Record a successful webhook invocation. */
|
|
83
|
-
export function recordSuccess(providerName) {
|
|
84
|
-
const stats = getOrCreateStats(providerName);
|
|
85
|
-
stats.invocations++;
|
|
86
|
-
stats.successes++;
|
|
87
|
-
stats.lastInvokedAt = new Date().toISOString();
|
|
88
|
-
}
|
|
89
|
-
/** Record a failed webhook invocation. */
|
|
90
|
-
export function recordFailure(providerName, error) {
|
|
91
|
-
const stats = getOrCreateStats(providerName);
|
|
92
|
-
stats.invocations++;
|
|
93
|
-
stats.failures++;
|
|
94
|
-
stats.lastInvokedAt = new Date().toISOString();
|
|
95
|
-
stats.lastErrorAt = new Date().toISOString();
|
|
96
|
-
stats.lastError = error;
|
|
97
|
-
}
|
|
98
|
-
/** Get stats for a specific provider. */
|
|
99
|
-
export function getProviderStats(name) {
|
|
100
|
-
return statsMap.get(name);
|
|
101
|
-
}
|
|
102
|
-
/** Get stats for all providers. */
|
|
103
|
-
export function getAllProviderStats() {
|
|
104
|
-
return [...statsMap.values()];
|
|
105
|
-
}
|
|
106
|
-
/** Reset stats (useful in tests). Pass a name to reset one provider, or omit to reset all. */
|
|
107
|
-
export function resetProviderStats(name) {
|
|
108
|
-
if (name) {
|
|
109
|
-
statsMap.delete(name);
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
statsMap.clear();
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// ── Provider Health ──────────────────────────────────────────────────────────
|
|
116
|
-
/**
|
|
117
|
-
* Get health summary for a provider based on failure rate.
|
|
118
|
-
* @param name Provider name.
|
|
119
|
-
* @param failureThreshold Failure rate (0–1) above which status is "degraded". Default: 0.5.
|
|
120
|
-
*/
|
|
121
|
-
export function getProviderHealth(name, failureThreshold = 0.5) {
|
|
122
|
-
const stats = statsMap.get(name);
|
|
123
|
-
if (!stats)
|
|
124
|
-
return undefined;
|
|
125
|
-
if (stats.invocations === 0) {
|
|
126
|
-
return { name, health: "unknown", failureRate: 0, stats };
|
|
127
|
-
}
|
|
128
|
-
const failureRate = stats.failures / stats.invocations;
|
|
129
|
-
const health = failureRate >= failureThreshold ? "degraded" : "healthy";
|
|
130
|
-
return { name, health, failureRate, stats };
|
|
131
|
-
}
|
|
132
|
-
/** Get health summaries for all registered providers. */
|
|
133
|
-
export function getAllProviderHealth(failureThreshold = 0.5) {
|
|
134
|
-
return [...providers.keys()].map((name) => {
|
|
135
|
-
return (getProviderHealth(name, failureThreshold) ?? {
|
|
136
|
-
name,
|
|
137
|
-
health: "unknown",
|
|
138
|
-
failureRate: 0,
|
|
139
|
-
stats: getOrCreateStats(name),
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=registry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/webhooks/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/webhooks/relay.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Relay webhook verification and processing.
|
|
3
|
-
*
|
|
4
|
-
* Handles incoming messages relayed from the Cloudflare Worker (whatsapp-relay).
|
|
5
|
-
* The Worker has already verified the Twilio signature — this module verifies
|
|
6
|
-
* the relay's own HMAC-SHA256 signature to ensure the request is authentic.
|
|
7
|
-
*
|
|
8
|
-
* Relay signature scheme:
|
|
9
|
-
* HMAC-SHA256("{timestamp}.{body}", RELAY_SECRET) → hex
|
|
10
|
-
* Sent in X-Relay-Signature header, timestamp in X-Relay-Timestamp.
|
|
11
|
-
* Replays rejected if timestamp is older than 5 minutes.
|
|
12
|
-
*/
|
|
13
|
-
import { hmacSha256Hex, timingSafeCompare, isTimestampFresh } from "./verify.js";
|
|
14
|
-
import { logActivity } from "../activity/log.js";
|
|
15
|
-
// ── Constants ────────────────────────────────────────────────────────────────
|
|
16
|
-
/** Maximum age (seconds) for relay timestamps. Default: 300 (5 min). */
|
|
17
|
-
const MAX_RELAY_TIMESTAMP_AGE = 300;
|
|
18
|
-
/**
|
|
19
|
-
* Verify a relay request from the Cloudflare Worker.
|
|
20
|
-
*
|
|
21
|
-
* @param rawBody The raw request body (URL-encoded form data)
|
|
22
|
-
* @param headers Request headers (lowercase keys)
|
|
23
|
-
* @param secret The shared relay secret (RELAY_SECRET env var)
|
|
24
|
-
*/
|
|
25
|
-
export function verifyRelaySignature(rawBody, headers, secret) {
|
|
26
|
-
if (!secret) {
|
|
27
|
-
return { valid: false, error: "RELAY_SECRET not configured" };
|
|
28
|
-
}
|
|
29
|
-
const signature = headers["x-relay-signature"];
|
|
30
|
-
if (!signature) {
|
|
31
|
-
return { valid: false, error: "Missing X-Relay-Signature header" };
|
|
32
|
-
}
|
|
33
|
-
const timestamp = headers["x-relay-timestamp"];
|
|
34
|
-
if (!timestamp) {
|
|
35
|
-
return { valid: false, error: "Missing X-Relay-Timestamp header" };
|
|
36
|
-
}
|
|
37
|
-
const ts = parseInt(timestamp, 10);
|
|
38
|
-
if (!isTimestampFresh(ts, MAX_RELAY_TIMESTAMP_AGE)) {
|
|
39
|
-
return { valid: false, error: "Relay timestamp expired or invalid" };
|
|
40
|
-
}
|
|
41
|
-
// The Worker signs: "{timestamp}.{body}"
|
|
42
|
-
const payload = `${timestamp}.${rawBody}`;
|
|
43
|
-
const expected = hmacSha256Hex(payload, secret);
|
|
44
|
-
if (!timingSafeCompare(signature, expected)) {
|
|
45
|
-
return { valid: false, error: "Invalid relay signature" };
|
|
46
|
-
}
|
|
47
|
-
logActivity({
|
|
48
|
-
source: "system",
|
|
49
|
-
summary: "Relay webhook verified (whatsapp-relay worker)",
|
|
50
|
-
});
|
|
51
|
-
return { valid: true };
|
|
52
|
-
}
|
|
53
|
-
//# sourceMappingURL=relay.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/webhooks/relay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,gFAAgF;AAEhF,wEAAwE;AACxE,MAAM,uBAAuB,GAAG,GAAG,CAAC;AASpC;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,OAA+B,EAC/B,MAAc;IAEd,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IACrE,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IACrE,CAAC;IAED,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,uBAAuB,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;IACvE,CAAC;IAED,yCAAyC;IACzC,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,OAAO,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAEhD,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;IAC5D,CAAC;IAED,WAAW,CAAC;QACV,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,gDAAgD;KAC1D,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|