const crypto = require('crypto'); const nodemailer = require('nodemailer'); const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET || 'change-me-webhook-secret'; const WEBHOOK_BASE_URL = (process.env.WEBHOOK_BASE_URL || 'http://localhost:3002').replace(/\/$/, ''); const WEBHOOK_TTL_HOURS = parseInt(process.env.WEBHOOK_TTL_HOURS || '72'); const NOTIFY_TO = process.env.NOTIFY_TO || ''; function getTransporter() { return nodemailer.createTransport({ host: process.env.SMTP_HOST || 'smtp.mailgun.org', port: parseInt(process.env.SMTP_PORT || '587'), secure: false, auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS, }, }); } function generateToken(requestId, amount, expiresAt) { const payload = `${requestId}|${amount}|${expiresAt}`; return crypto.createHmac('sha256', WEBHOOK_SECRET).update(payload).digest('hex'); } function verifyToken(requestId, amount, expires, token) { if (Date.now() > parseInt(expires)) return false; const expected = generateToken(requestId, amount, expires); try { return crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(token, 'hex')); } catch { return false; } } function buildWebhookUrl(path, requestId, amount, expiresAt) { const token = generateToken(requestId, amount, expiresAt); return `${WEBHOOK_BASE_URL}/api/webhooks/${path}/${requestId}?token=${token}&amount=${amount}&expires=${expiresAt}`; } function buildEmail(request) { const expiresAt = Date.now() + (WEBHOOK_TTL_HOURS * 60 * 60 * 1000); const expiryDate = new Date(expiresAt).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', }); const presets = [ { label: 'Approve 5M', amount: 5000000, color: '#4ade80' }, { label: 'Approve 10M', amount: 10000000, color: '#4ade80' }, { label: 'Approve 20M', amount: 20000000, color: '#4ade80' }, ]; const approveButtons = presets.map(p => { const url = buildWebhookUrl('approve', request.id, p.amount, expiresAt); return `${p.label}`; }).join('\n '); const customUrl = buildWebhookUrl('custom', request.id, 'custom', expiresAt); const rejectUrl = buildWebhookUrl('reject', request.id, 'reject', expiresAt); return `