import crypto from "node:crypto";
function verifyGamecartSignature({ secret, signatureHeader, eventId, rawBody }) {
const parts = Object.fromEntries(
signatureHeader.split(",").map((part) => {
const [key, value] = part.trim().split("=", 2);
return [key, value];
})
);
const timestamp = Number(parts.t);
const submitted = parts.v1;
if (!Number.isFinite(timestamp) || !/^[a-f0-9]{64}$/i.test(submitted ?? "")) {
return false;
}
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - timestamp) > 5 * 60) return false;
const canonical = `${timestamp}.${eventId}.${rawBody}`;
const expected = crypto
.createHmac("sha256", secret)
.update(canonical, "utf8")
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(submitted, "hex")
);
}