Webhooks og signaturer
Sett opp endepunkter under Admin → Webhooks: en URL, et sett hendelser og en whsec_…-signeringshemmelighet som vises ved opprettelse. Nyttelastene bærer med vilje id-er og navn på endrede felter (pluss grove verdier som et statusord) — hent detaljer gjennom lese-API-et, der nøkkel-scopene gjelder.
Hendelser
| Hendelse | Utløses når |
|---|---|
item.updated | En gjenstands felter ble endret. |
item.moved | En gjenstand byttet lokasjon. |
service_entry.created | En serviceoppføring ble logget. |
loan.checked_out | Utstyr gikk ut. |
loan.checked_in | Utstyr kom tilbake. |
qr.assigned | En kode ble knyttet til en gjenstand. |
Levering
Hver POST bærer tre hoder: X-Leidang-Event, X-Leidang-Timestamp (unix-sekunder) og X-Leidang-Signature — sha256=<hex HMAC-SHA256(hemmelighet, timestamp.body)>. Et ikke-2xx-svar prøves på nytt inntil to ganger med økende ventetid; hvert leveringsutfall kan inspiseres under Admin → Webhooks.
Verifisere signaturen
Beregn HMAC-en over den eksakte timestamp.rawBody-strengen før du parser innholdet, sammenlign i konstant tid, og avvis gamle tidsstempler for å lukke replay-vinduer:
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyLeidangWebhook(secret, req, rawBody) {
const timestamp = req.headers["x-leidang-timestamp"];
const header = req.headers["x-leidang-signature"]; // "sha256=<hex>"
if (!timestamp || !header) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected =
"sha256=" + createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(header);
return a.length === b.length && timingSafeEqual(a, b);
}