You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
swissoid-back/scripts/generate-session-secrets.js

57 lines
1.7 KiB
JavaScript

#!/usr/bin/env node
/**
* Helper CLI to generate SESSION_SECRET and STATE_SIGNING_SECRET values.
*
* Usage:
* node scripts/generate-session-secrets.js
*
* Optional flags:
* --session-bytes=<number> (default: 48)
* --state-bytes=<number> (default: 32)
* --derive-state (derive STATE_SIGNING_SECRET from SESSION_SECRET)
*/
const { randomBytes } = require('node:crypto');
const defaults = {
sessionBytes: 48,
stateBytes: 32,
deriveState: false,
};
const options = process.argv.slice(2).reduce((acc, arg) => {
if (arg.startsWith('--session-bytes=')) {
acc.sessionBytes = parseInt(arg.split('=')[1], 10);
} else if (arg.startsWith('--state-bytes=')) {
acc.stateBytes = parseInt(arg.split('=')[1], 10);
} else if (arg === '--derive-state') {
acc.deriveState = true;
}
return acc;
}, { ...defaults });
const validateBytes = (value, flagName) => {
if (!Number.isInteger(value) || value <= 0) {
console.error(`Invalid value for ${flagName}. Expected a positive integer, received: ${value}`);
process.exit(1);
}
};
validateBytes(options.sessionBytes, '--session-bytes');
if (!options.deriveState) {
validateBytes(options.stateBytes, '--state-bytes');
}
const generateSecret = (bytes) => randomBytes(bytes).toString('base64');
const sessionSecret = generateSecret(options.sessionBytes);
const stateSecret = options.deriveState
? `${sessionSecret}-state-signing`
: generateSecret(options.stateBytes);
console.log(`SESSION_SECRET=${sessionSecret}`);
console.log(`STATE_SIGNING_SECRET=${stateSecret}`);
console.log('\n# Copy the values above into your deployment secret store (.env, Vault, etc.).');
console.log('# Keep them private and rotate on a regular schedule.');