Spaces:
Paused
Paused
| 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(); | |
| } | |