import crypto from 'crypto';
function verifyWebhookSignature(
rawBody: Buffer,
signature: string,
timestamp: string,
secret: string,
): boolean {
// Check timestamp is within 5 minutes to prevent replay
const fiveMinutes = 5 * 60 * 1000;
const ts = parseInt(timestamp, 10) * 1000;
if (Math.abs(Date.now() - ts) > fiveMinutes) {
return false;
}
// Compute expected signature
const signedPayload = `${timestamp}.${rawBody.toString()}`;
const expected = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
const received = signature.replace('sha256=', '');
// Constant-time comparison
return crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(received, 'hex'),
);
}