Sign up

Verifying the signature

Check that every notice comes from Closeford.

Compute the HMAC-SHA256 of the timestamp and the raw body with your signing secret, and compare it with the X-Webhook-Signature header before accepting the notice.

import crypto from "node:crypto";

// raw = the request body as received (string), before JSON.parse
export function verify(raw, headers, secret) {
  const ts = headers["x-webhook-timestamp"];
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${raw}`)
    .digest("hex");
  const got = headers["x-webhook-signature"] ?? "";
  return got.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}