59 lines
1.6 KiB
JavaScript
59 lines
1.6 KiB
JavaScript
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;
|
|
|
|
for (const worker of Object.values(cluster.workers)) {
|
|
worker.once('message', (m) => {
|
|
if (m.ready)
|
|
worker.send({ rateSalt, streamSalt });
|
|
|
|
if (!--remaining)
|
|
resolve();
|
|
});
|
|
}
|
|
} 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();
|
|
}
|