Absorbs the separate control-panel git repo as a subdirectory. Instances and backups directories excluded via .gitignore. Bunker Admin
74 lines
2.2 KiB
TypeScript
74 lines
2.2 KiB
TypeScript
import crypto from 'crypto';
|
|
|
|
function randomHex(bytes = 32): string {
|
|
return crypto.randomBytes(bytes).toString('hex');
|
|
}
|
|
|
|
function randomPassword(length = 16): string {
|
|
// Generate password meeting CML policy: 12+ chars, uppercase, lowercase, digit
|
|
const upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
const lower = 'abcdefghijklmnopqrstuvwxyz';
|
|
const digits = '0123456789';
|
|
// Avoid $, #, !, % — they break Docker Compose .env files
|
|
// ($=var expansion, #=comment, !=bash history, %=printf)
|
|
const special = '@&*_-+=';
|
|
const all = upper + lower + digits + special;
|
|
|
|
// Ensure at least one of each required class
|
|
const required = [
|
|
upper[crypto.randomInt(upper.length)],
|
|
lower[crypto.randomInt(lower.length)],
|
|
digits[crypto.randomInt(digits.length)],
|
|
special[crypto.randomInt(special.length)],
|
|
];
|
|
|
|
// Fill remaining with random chars
|
|
const remaining = Array.from({ length: length - required.length }, () =>
|
|
all[crypto.randomInt(all.length)]
|
|
);
|
|
|
|
// Shuffle
|
|
const chars = [...required, ...remaining];
|
|
for (let i = chars.length - 1; i > 0; i--) {
|
|
const j = crypto.randomInt(i + 1);
|
|
[chars[i], chars[j]] = [chars[j], chars[i]];
|
|
}
|
|
|
|
return chars.join('');
|
|
}
|
|
|
|
export interface InstanceSecrets {
|
|
postgresPassword: string;
|
|
redisPassword: string;
|
|
jwtAccessSecret: string;
|
|
jwtRefreshSecret: string;
|
|
encryptionKey: string;
|
|
initialAdminPassword: string;
|
|
nocodbAdminPassword: string;
|
|
grafanaAdminPassword: string;
|
|
listmonkAdminPassword: string;
|
|
listmonkApiToken: string;
|
|
giteaAdminPassword: string;
|
|
n8nEncryptionKey: string;
|
|
gancioAdminPassword: string;
|
|
}
|
|
|
|
export function generateSecrets(adminEmail: string): InstanceSecrets & { adminEmail: string } {
|
|
return {
|
|
adminEmail,
|
|
postgresPassword: randomHex(16),
|
|
redisPassword: randomHex(16),
|
|
jwtAccessSecret: randomHex(32),
|
|
jwtRefreshSecret: randomHex(32),
|
|
encryptionKey: randomHex(32),
|
|
initialAdminPassword: randomPassword(16),
|
|
nocodbAdminPassword: randomPassword(16),
|
|
grafanaAdminPassword: randomPassword(16),
|
|
listmonkAdminPassword: randomPassword(16),
|
|
listmonkApiToken: randomHex(16),
|
|
giteaAdminPassword: randomPassword(16),
|
|
n8nEncryptionKey: randomHex(32),
|
|
gancioAdminPassword: randomPassword(16),
|
|
};
|
|
}
|