Recevoir un envoi et vérifier qu'il vient d'IshedDB
Chaque changement arrive en POST, son corps est le changement en JSON (operationType, ns, documentKey, fullDocument, updateDescription, wallTime, _id : son jeton), avec les en-têtes CloudEvents (ce-id : le jeton du changement, pour écarter un changement déjà reçu ; ce-type : ished.change.insert…) et X-Ished-Signature : t=<secondes>,v1=<HMAC-SHA256 du texte « t.corps » avec le secret du Trigger>. Répondez 2xx en moins de 10 secondes : sinon le même changement est renvoyé plus tard (10 s, 30 s, 1 min, 5 min, 15 min, 30 min, puis chaque heure). Un Trigger planifié envoie, à chacune de ses heures, { "trigger", "schedule", "scheduledTime" : l'heure prévue } avec ce-type : ished.schedule et ce-id : <Trigger>/<heure prévue> (le même quand il est renvoyé) ; les heures manquées pendant qu'il était désactivé sont envoyées à sa réactivation (sauf avec « Ignorer… »), celles des 24 dernières heures seulement. Pour vérifier la signature, en Node.js :
import { createHmac, timingSafeEqual } from 'node:crypto';
// header: req.headers['x-ished-signature']; body: the request body as received (text)
export function isFromIshedDB(header, body, secret) {
const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const expected = createHmac('sha256', secret).update(`${t}.${body}`).digest('hex');
const recent = Math.abs(Date.now() / 1000 - Number(t)) <= 300;
return recent && expected.length === v1?.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}