// Run the receiver separately, then: WEBHOOK_SECRET=... node webhook-replay.mjs // Signs synthetic events. No email is sent. import assert from 'node:assert/strict'; import { Webhook } from 'standardwebhooks'; if (!process.env.WEBHOOK_SECRET) throw new Error('Set WEBHOOK_SECRET to match the receiver'); const webhook = new Webhook(process.env.WEBHOOK_SECRET); const id = 'fixture-delivery-42'; const body = JSON.stringify({ id, type: 'email.accepted', createdAt: '2026-10-04T12:00:00Z', data: { messageId: 'fixture-message-42' } }); const timestamp = new Date(); const signature = webhook.sign(id, timestamp, body); const headers = { 'content-type': 'application/json', 'webhook-id': id, 'webhook-timestamp': String(Math.floor(timestamp.getTime() / 1000)), 'webhook-signature': signature }; for (let i = 0; i < 2; i++) { const response = await fetch('http://127.0.0.1:3028/webhook', { method: 'POST', headers, body }); assert.equal(response.status, 204); } const tampered = await fetch('http://127.0.0.1:3028/webhook', { method: 'POST', headers, body: body.replace('accepted', 'bounced') }); assert.equal(tampered.status, 401); console.log('Replay accepted twice; tampering rejected. Query the inbox: one stored event.');