> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praeto.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js Signature Verification

> Verify Praeto webhook signatures in Node.js.

# Node.js Signature Verification

```js theme={null}
const crypto = require("crypto");

function timingSafeEqualString(a, b) {
  const aBuf = Buffer.from(a, "utf8");
  const bBuf = Buffer.from(b, "utf8");
  if (aBuf.length !== bBuf.length) return false;
  return crypto.timingSafeEqual(aBuf, bBuf);
}

function verifyPraetoSignature({ 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 = "v1=" + crypto
    .createHmac("sha256", secret)
    .update(base, "utf8")
    .digest("hex");

  return signatureHeader
    .split(",")
    .map((part) => part.trim())
    .some((candidate) => timingSafeEqualString(candidate, expected));
}
```
