const crypto = require("crypto");
function timingSafeEqualHex(a, b) {
const aBuf = Buffer.from(a, "hex");
const bBuf = Buffer.from(b, "hex");
if (aBuf.length !== bBuf.length) return false;
return crypto.timingSafeEqual(aBuf, bBuf);
}
function verifyPraetoWebhook({ rawBody, headers, secret, toleranceSeconds = 300 }) {
const deliveryId = headers["praeto-delivery-id"];
const timestamp = headers["praeto-timestamp"];
const signatureHeader = headers["praeto-signature"];
if (!deliveryId || !timestamp || !signatureHeader) return false;
const timestampMs = Date.parse(timestamp);
if (!Number.isFinite(timestampMs)) return false;
const ageSeconds = Math.abs(Date.now() - timestampMs) / 1000;
if (ageSeconds > toleranceSeconds) return false;
const base = `${deliveryId}.${timestamp}.${rawBody}`;
const expected = crypto.createHmac("sha256", secret).update(base).digest("hex");
const provided = signatureHeader
.split(",")
.map((part) => part.trim())
.filter((part) => part.startsWith("v1="))
.map((part) => part.slice(3));
return provided.some((sig) => timingSafeEqualHex(sig, expected));
}