import cluster from "node:cluster"; import { createHmac, randomBytes } from "node:crypto"; const generateSalt = () => { if (cluster.isPrimary) return randomBytes(64); return null; } let rateSalt = generateSalt(); let streamSalt = generateSalt(); export const syncSecrets = () => { return new Promise((resolve, reject) => { if (cluster.isPrimary) { let remaining = Object.values(cluster.workers).length; const handleReady = (worker, m) => { if (m.ready) worker.send({ rateSalt, streamSalt }); if (!--remaining) resolve(); } for (const worker of Object.values(cluster.workers)) { worker.once( 'message', (m) => handleReady(worker, m) ); } } else if (cluster.isWorker) { if (rateSalt || streamSalt) return reject(); process.send({ ready: true }); process.once('message', (message) => { if (rateSalt || streamSalt) return reject(); if (message.rateSalt && message.streamSalt) { streamSalt = Buffer.from(message.streamSalt); rateSalt = Buffer.from(message.rateSalt); resolve(); } }); } else reject(); }); } export const hashHmac = (value, type) => { let salt; if (type === 'rate') salt = rateSalt; else if (type === 'stream') salt = streamSalt; else throw "unknown salt"; return createHmac("sha256", salt).update(value).digest(); }