// src/webhooks/signing.ts
import crypto from "crypto";
var SIGNATURE_HEADER = "X-AgentStep-Signature";
var TIMESTAMP_HEADER = "X-AgentStep-Timestamp";
var DEFAULT_TOLERANCE_MS = 5 * 60 * 1e3;
function headerVal(headers, name) {
  if (headers instanceof Headers) return headers.get(name);
  const target = name.toLowerCase();
  for (const [k, v] of Object.entries(headers)) {
    if (k.toLowerCase() === target) return v ?? null;
  }
  return null;
}
function computeSignature(secret, timestampMs, body) {
  const h = crypto.createHmac("sha256", secret);
  h.update(`${timestampMs}.${body}`);
  return h.digest("hex");
}
function verifyWebhookSignature(input) {
  const sigHeader = headerVal(input.headers, SIGNATURE_HEADER);
  const tsHeader = headerVal(input.headers, TIMESTAMP_HEADER);
  if (!sigHeader) return { ok: false, reason: "missing signature header" };
  if (!tsHeader) return { ok: false, reason: "missing timestamp header" };
  const ts = Number(tsHeader);
  if (!Number.isFinite(ts)) return { ok: false, reason: "invalid timestamp" };
  const now = input.nowMs ?? Date.now();
  const tolerance = input.toleranceMs ?? DEFAULT_TOLERANCE_MS;
  if (Math.abs(now - ts) > tolerance) {
    return { ok: false, reason: "timestamp outside tolerance window" };
  }
  const provided = sigHeader.startsWith("sha256=") ? sigHeader.slice(7) : sigHeader;
  const expected = computeSignature(input.secret, ts, input.body);
  if (provided.length !== expected.length) {
    return { ok: false, reason: "signature length mismatch" };
  }
  const a = Buffer.from(provided, "hex");
  const b = Buffer.from(expected, "hex");
  if (a.length !== b.length) {
    return { ok: false, reason: "signature decode mismatch" };
  }
  if (!crypto.timingSafeEqual(a, b)) {
    return { ok: false, reason: "signature mismatch" };
  }
  return { ok: true, timestampMs: ts };
}

export {
  SIGNATURE_HEADER,
  TIMESTAMP_HEADER,
  computeSignature,
  verifyWebhookSignature
};
