// src/connectors/webhooks.ts
import { createHmac, timingSafeEqual } from "crypto";
var DEFAULT_SIGNATURE_TOLERANCE_SECONDS = 5 * 60;
function parseStripeSignatureHeader(header) {
  const acc = { sigs: [] };
  for (const part of header.split(",")) {
    const idx = part.indexOf("=");
    if (idx < 0) continue;
    const key = part.slice(0, idx).trim();
    const val = part.slice(idx + 1).trim();
    if (key === "t") {
      const n = Number(val);
      if (Number.isFinite(n)) acc.ts = n;
    } else if (key === "v1") {
      acc.sigs.push(val);
    }
  }
  if (acc.ts === void 0 || acc.sigs.length === 0) return null;
  return { t: acc.ts, sigs: acc.sigs };
}
function verifyStripeSignature(rawBody, signatureHeader, secret, options = {}) {
  const parsed = parseStripeSignatureHeader(signatureHeader);
  if (!parsed) return false;
  const tolerance = options.toleranceSeconds ?? DEFAULT_SIGNATURE_TOLERANCE_SECONDS;
  const now = options.now ?? Math.floor(Date.now() / 1e3);
  if (Math.abs(now - parsed.t) > tolerance) return false;
  const expected = createHmac("sha256", secret).update(`${parsed.t}.${rawBody}`).digest("hex");
  const expectedBuf = Buffer.from(expected, "utf8");
  for (const sig of parsed.sigs) {
    const sigBuf = Buffer.from(sig, "utf8");
    if (sigBuf.length !== expectedBuf.length) continue;
    if (timingSafeEqual(sigBuf, expectedBuf)) return true;
  }
  return false;
}
function verifySlackSignature(rawBody, signatureHeader, timestampHeader, secret, options = {}) {
  if (!signatureHeader.startsWith("v0=")) return false;
  const ts = Number(timestampHeader);
  if (!Number.isFinite(ts)) return false;
  const tolerance = options.toleranceSeconds ?? DEFAULT_SIGNATURE_TOLERANCE_SECONDS;
  const now = options.now ?? Math.floor(Date.now() / 1e3);
  if (Math.abs(now - ts) > tolerance) return false;
  const expected = "v0=" + createHmac("sha256", secret).update(`v0:${ts}:${rawBody}`).digest("hex");
  const expectedBuf = Buffer.from(expected, "utf8");
  const sigBuf = Buffer.from(signatureHeader, "utf8");
  if (sigBuf.length !== expectedBuf.length) return false;
  return timingSafeEqual(sigBuf, expectedBuf);
}
function verifyHmacSignature(rawBody, signatureHeader, secret, options = {}) {
  const algorithm = options.algorithm ?? "sha256";
  const prefix = options.signaturePrefix ?? "";
  const lower = options.lowercaseHex ?? true;
  let candidate = signatureHeader;
  if (prefix) {
    if (!candidate.startsWith(prefix)) return false;
    candidate = candidate.slice(prefix.length);
  }
  if (lower) candidate = candidate.toLowerCase();
  const expected = createHmac(algorithm, secret).update(rawBody).digest("hex");
  const expectedBuf = Buffer.from(expected, "utf8");
  const sigBuf = Buffer.from(candidate, "utf8");
  if (sigBuf.length !== expectedBuf.length) return false;
  return timingSafeEqual(sigBuf, expectedBuf);
}
function verifyTwilioSignature(input, options = {}) {
  if (!input.authToken) {
    return options.skipWhenAuthTokenMissing === true;
  }
  const signature = input.signatureHeader;
  if (!signature || Array.isArray(signature)) return false;
  if (!input.fullUrl) return false;
  const data = options.bodyAsRaw === true ? input.fullUrl + (options.rawBody ?? "") : Object.keys(input.params ?? {}).sort().reduce((acc, key) => acc + key + (input.params[key] ?? ""), input.fullUrl);
  const expected = createHmac("sha1", input.authToken).update(data).digest("base64");
  const expectedBuf = Buffer.from(expected);
  const sigBuf = Buffer.from(signature);
  if (expectedBuf.length !== sigBuf.length) return false;
  return timingSafeEqual(expectedBuf, sigBuf);
}
function firstHeader(headers, name) {
  const v = headers[name] ?? headers[name.toLowerCase()] ?? Object.entries(headers).find(([key]) => key.toLowerCase() === name.toLowerCase())?.[1];
  if (Array.isArray(v)) return v[0];
  return typeof v === "string" ? v : void 0;
}

export {
  DEFAULT_SIGNATURE_TOLERANCE_SECONDS,
  parseStripeSignatureHeader,
  verifyStripeSignature,
  verifySlackSignature,
  verifyHmacSignature,
  verifyTwilioSignature,
  firstHeader
};
//# sourceMappingURL=chunk-2TW2QKGZ.js.map