mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 18:22:48 +03:00
Release v3.8.42 — full CHANGELOG in CHANGELOG.md. CI: 103 checks green incl. CodeQL (all languages), Semgrep, all 8 unit shards, coverage, Node 24 compat, and integration tests. Full unit suite validated locally: 19437 pass / 0 fail. The 3 red checks are advisory and do not gate main (no required status checks): SonarCloud/SonarQube new-code coverage gate, and PR Test Policy (test-masking detector flagging the legitimate dead-Phind provider removal in #5530 — reviewed, correct). Includes cycle-close reconciliation + repair of inherited base-red tests from #5480/#5527/#5427/#5521 that the PR->release fast-path did not exercise.
78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import { getDbInstance } from "./core";
|
|
import { sanitizeErrorMessage } from "@omniroute/open-sse/utils/error";
|
|
|
|
export interface WebhookDelivery {
|
|
id: number;
|
|
webhook_id: string;
|
|
event_type: string;
|
|
status: string;
|
|
http_status: number | null;
|
|
latency_ms: number | null;
|
|
error: string | null;
|
|
payload_snapshot: string | null;
|
|
created_at: string;
|
|
}
|
|
|
|
/** Safe projection for the deliveries list API — excludes `payload_snapshot`
|
|
* by default so audit-list responses never leak the captured request body. */
|
|
export type WebhookDeliverySafe = Omit<WebhookDelivery, "payload_snapshot">;
|
|
|
|
const MAX_DELIVERIES_PER_WEBHOOK = 100;
|
|
|
|
export function insertDelivery(opts: {
|
|
webhookId: string;
|
|
eventType: string;
|
|
status: string;
|
|
httpStatus?: number | null;
|
|
latencyMs?: number | null;
|
|
error?: string | null;
|
|
payloadSnapshot?: string | null;
|
|
}): void {
|
|
const db = getDbInstance();
|
|
const insertStmt = db.prepare(
|
|
`INSERT INTO webhook_deliveries
|
|
(webhook_id, event_type, status, http_status, latency_ms, error, payload_snapshot)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
|
);
|
|
const rotateStmt = db.prepare(
|
|
`DELETE FROM webhook_deliveries
|
|
WHERE webhook_id = ?
|
|
AND id NOT IN (
|
|
SELECT id FROM webhook_deliveries
|
|
WHERE webhook_id = ?
|
|
ORDER BY created_at DESC, id DESC
|
|
LIMIT ?
|
|
)`
|
|
);
|
|
// Sanitize the error before persistence so raw stack traces, hostnames or
|
|
// upstream-internal messages never enter the audit log. The audit log is
|
|
// read back via the deliveries API and rendered in the dashboard.
|
|
const sanitizedError = opts.error != null ? sanitizeErrorMessage(opts.error) || null : null;
|
|
db.transaction(() => {
|
|
insertStmt.run(
|
|
opts.webhookId,
|
|
opts.eventType,
|
|
opts.status,
|
|
opts.httpStatus ?? null,
|
|
opts.latencyMs ?? null,
|
|
sanitizedError,
|
|
opts.payloadSnapshot ?? null
|
|
);
|
|
rotateStmt.run(opts.webhookId, opts.webhookId, MAX_DELIVERIES_PER_WEBHOOK);
|
|
})();
|
|
}
|
|
|
|
/** List recent deliveries excluding `payload_snapshot` (default — used by UI). */
|
|
export function getDeliveries(webhookId: string, limit: number): WebhookDeliverySafe[] {
|
|
const db = getDbInstance();
|
|
return db
|
|
.prepare(
|
|
`SELECT id, webhook_id, event_type, status, http_status, latency_ms, error, created_at
|
|
FROM webhook_deliveries
|
|
WHERE webhook_id = ?
|
|
ORDER BY created_at DESC, id DESC
|
|
LIMIT ?`
|
|
)
|
|
.all(webhookId, limit) as WebhookDeliverySafe[];
|
|
}
|