Aller au contenu
Krizaka TS
Krizaka TS

@krizaka/webhooks

Des webhooks signés et idempotents, dans les deux sens : livrés avec reprises, vérifiés et appliqués une fois.

Installer

bashTerminal
npm install @krizaka/webhooks

Le README ci-dessous est celui du paquet sur npm, en anglais.

Signed and idempotent webhooks, both ways.

Out. An owner registers endpoints (https, public host; the secret is shown once and kept sealed); the product emits an event with a stable id, which is queued once per endpoint however often it is emitted; deliverDue sends what is due, signed (x-krizaka-signature: t=<s>,v1=<hmac of "<t>.<body>">), retries with a backoff, gives up after maxAttempts and keeps the log (deliveries).

In. receiveWebhook verifies the signature over the raw body (with a replay window), records the event id first, applies once; a replay is "duplicate"; if applying throws, the record is removed so the sender's retry applies it.

import { createWebhooks, webhooksMigration, receiveWebhook } from "@krizaka/webhooks";

await db.query(webhooksMigration("accounts")); // once, in your migrations (idempotent)
const hooks = createWebhooks({ query, rules: { events: ["booking.created", "invoice.paid"], maxAttempts: 6, backoffSeconds: [30, 300, 1800, 7200, 43200] }, secrets: { seal, open } });
await hooks.emit(ownerId, { id: `booking:${id}`, type: "booking.created", payload }, now);
await hooks.deliverDue(now, send); // from a tick: `send` is your fetch (no redirects, short timeout, refuses private addresses)

The product keeps: the HTTP call (send), sealing the secret, when deliverDue runs, the quota per plan, its audit and its routes. Nothing here reads the clock.

Exports

Les 22 noms que le paquet exporte, lus dans ses types.

NomNatureCe que c’est
createWebhooksfonctionOutgoing webhooks over the product's PostgreSQL (see webhooksMigration): endpoints, one queued delivery per endpoint and event, signed retries, a log.
DeliveryViewtype
endpointUrlProblemfonction
EndpointViewtype
EVENT_ID_HEADERconstante
EVENT_TYPE_HEADERconstante
newEndpointSecretfonctionA new endpoint secret: shown once, kept sealed.
OutgoingRequesttype
QuerytypeA SQL executor: the rows of a statement and its parameters (the product's pool).
receiveWebhookfonctionAn incoming webhook, applied exactly once: the signature is checked over the RAW body (a bad one is WEBHOOK_SIGNATURE), the event id is recorded first (a r…
SendtypeThe product's HTTP call: no redirects, a short timeout, and it refuses to connect to a private address.
SIGNATURE_HEADERconstanteThe signature of a webhook: t=&lt;unix seconds>,v1=&lt;hex HMAC-SHA256 of "&lt;t>.&lt;raw body>"> (the scheme payment processors use, so a receiver's code is the one e…
signBodyfonctionSigning is @krizaka/payments' own (the same scheme, one implementation): this adds the header name and a verdict instead of a throw.
VerifyResulttype
verifySignaturefonctionChecks a signature header over the raw body: well-formed, not older than the tolerance (or from the future), and equal in constant time.
WEBHOOK_CODEconstante
WebhookCodetype
WebhookDepstype
WebhookErrorclasse
WebhookRulestype
Webhookstype
webhooksMigrationfonctionThe tables of the webhooks: an owner's endpoints, the deliveries queued for them (one per endpoint and event — queuing twice is a no-op), and the inbound eve…

Paquet

Version sur npm0.2.0 (npm)
LicenceApache-2.0
Node.js>=22
Dépendancesdate-fns ^4.4.0, @krizaka/payments ^0.1.0
Code sourcewebhooks

Journal des versions

0.2.0

Minor changes

  • Signing and verification are @krizaka/payments' own (one implementation of the scheme, no copy).

0.1.0

Minor changes

  • First release: signatures and their verification, the endpoint address rules, outgoing endpoints / queue / delivery with retries and a log, incoming events applied once, the PostgreSQL migration.

Sur cette page