const crypto = require('crypto'); const http = require('http'); const HMAC_SECRET = 'f6aeeb774a009d7b2a2bea348ea23c5f82de55ca38f3f3a2263ecc3cca1314b1'; const API_KEY = 'f176d279faef1256d209d921e85cd5e27c19ec3b6f057c6829c9ccb18be9af85'; const CENTRIFUGO_PORT = 8787; const CHANNEL = 'projects-browser'; function createJWT(sub, expSeconds = 86400) { const header = { alg: 'HS256', typ: 'JWT' }; const payload = { sub, exp: Math.floor(Date.now() / 1000) + expSeconds }; const b64 = (obj) => Buffer.from(JSON.stringify(obj)).toString('base64url'); const h = b64(header); const p = b64(payload); const sig = crypto.createHmac('sha256', HMAC_SECRET).update(`${h}.${p}`).digest('base64url'); return `${h}.${p}.${sig}`; } function publish(data) { const body = JSON.stringify({ method: 'publish', params: { channel: CHANNEL, data } }); const req = http.request({ hostname: '127.0.0.1', port: CENTRIFUGO_PORT, path: '/api', method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `apikey ${API_KEY}`, }, }, (res) => { // drain response res.resume(); }); req.on('error', (err) => { console.error('Centrifugo publish error:', err.message); }); req.write(body); req.end(); } function publishStatus(slug, status, extra = {}) { publish({ type: 'status', slug, status, ...extra }); } function publishScreenshot(slug) { publish({ type: 'screenshot', slug, url: `/screenshots/${slug}.png?t=${Date.now()}` }); } module.exports = { createJWT, publish, publishStatus, publishScreenshot, CHANNEL };