updated config handler to autogenerate secrets and default user structure
Co-authored-by: Spacelord <Spacelord09@users.noreply.github.com>
This commit is contained in:
parent
6fa2797903
commit
2371089f88
@ -1,5 +1,6 @@
|
||||
import fs from 'node:fs';
|
||||
import _ from 'lodash';
|
||||
import { randomUUID, randomBytes } from 'crypto';
|
||||
|
||||
export type configObject = Record<any, any>;
|
||||
|
||||
@ -14,6 +15,7 @@ export default class config {
|
||||
#configPath: string;
|
||||
//global = {[key: string] : string}
|
||||
global: configObject;
|
||||
replaceSecrets: boolean;
|
||||
|
||||
/**
|
||||
* Creates an instance of config.
|
||||
@ -22,9 +24,10 @@ export default class config {
|
||||
* @param {string} configPath Path to config file.
|
||||
* @param {object} configPreset Default config object with default values.
|
||||
*/
|
||||
constructor(configPath: string, configPreset: object) {
|
||||
constructor(configPath: string, replaceSecrets: boolean, configPreset: object) {
|
||||
this.#configPath = configPath;
|
||||
this.global = configPreset;
|
||||
this.replaceSecrets = replaceSecrets;
|
||||
|
||||
try {
|
||||
// Read config
|
||||
@ -52,6 +55,12 @@ export default class config {
|
||||
*/
|
||||
save_config() {
|
||||
try {
|
||||
// If enabled replace tokens defines as "gen" with random token
|
||||
if (this.replaceSecrets) {
|
||||
// Replace tokens with value "gen"
|
||||
this.generate_secrets(this.global, 'gen')
|
||||
}
|
||||
|
||||
fs.writeFileSync(this.#configPath, JSON.stringify(this.global, null, 8));
|
||||
} catch (err) {
|
||||
console.error(`Could not write config file at ${this.#configPath} due to: ${err}`);
|
||||
@ -59,31 +68,73 @@ export default class config {
|
||||
}
|
||||
console.log(`Successfully written config file to ${this.#configPath}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces each item matching the value of placeholder with a random UUID.
|
||||
* Thanks to https://stackoverflow.com/questions/8085004/iterate-through-nested-javascript-objects
|
||||
* @param {configObject} obj
|
||||
*/
|
||||
generate_secrets(obj: configObject, placeholder: string) {
|
||||
const stack = [obj];
|
||||
while (stack?.length > 0) {
|
||||
const currentObj = stack.pop();
|
||||
Object.keys(currentObj).forEach((key) => {
|
||||
|
||||
if (currentObj[key] === placeholder) {
|
||||
console.log('Generating secret: ' + key);
|
||||
currentObj[key] = randomBytes(48).toString('base64').replace(/\W/g, '');
|
||||
}
|
||||
|
||||
if (typeof currentObj[key] === 'object' && currentObj[key] !== null) {
|
||||
stack.push(currentObj[key]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
**** Example ****
|
||||
|
||||
import configHandler from './assets/configHandler.js';
|
||||
import ConfigHandlerNG from './assets/configHandlerNG.js';
|
||||
|
||||
// Create a new config instance.
|
||||
export const config = new ConfigHandler(__path + '/config.json', {
|
||||
db_connection_string: 'mysql://USER:PASSWORD@HOST:3306/DATABASE',
|
||||
http_listen_address: '127.0.0.1',
|
||||
http_port: 3000,
|
||||
sentry_dsn: 'https://ID@sentry.example.com/PROJECTID',
|
||||
debug: false
|
||||
});
|
||||
export const config = new ConfigHandler(__path + '/config.json', true, {
|
||||
test1: 't1',
|
||||
test2: 't2',
|
||||
test3: 'gen',
|
||||
test4: 't4',
|
||||
test5: 'gen',
|
||||
testObj: {
|
||||
local: {
|
||||
active: true,
|
||||
users: {
|
||||
user1: 'gen',
|
||||
user2: 'gen',
|
||||
user3: 'gen',
|
||||
user4: 'gen',
|
||||
|
||||
}
|
||||
},
|
||||
oidc: {
|
||||
active: false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Base Config:');
|
||||
console.log(config.global);
|
||||
|
||||
console.log('Add some new key to config and call save_config.');
|
||||
console.log('Add some new key to config and call save_config().');
|
||||
config.global.NewKey = 'ThisIsANewKey!'
|
||||
config.save_config()
|
||||
|
||||
console.log('This will add a new key with value gen, but gen gets replaced with a random UUID when save_config() is called.');
|
||||
config.global.someSecret = 'gen'
|
||||
config.save_config() // global.someSecret is getting replaced with some random UUID since it was set to 'gen'.
|
||||
|
||||
console.log('Complete Config:');
|
||||
console.log(config.global);
|
||||
*/
|
||||
|
23
src/index.ts
23
src/index.ts
@ -7,6 +7,7 @@ import * as eta from 'eta';
|
||||
import bodyParser from 'body-parser';
|
||||
import session from 'express-session';
|
||||
import passport from 'passport';
|
||||
import _ from 'lodash';
|
||||
|
||||
// Sentry
|
||||
import * as Sentry from '@sentry/node';
|
||||
@ -35,19 +36,18 @@ export const log = {
|
||||
};
|
||||
|
||||
// Create a new config instance.
|
||||
export const config = new ConfigHandler(__path + '/config.json', {
|
||||
export const config = new ConfigHandler(__path + '/config.json', true, {
|
||||
db_connection_string: 'mysql://USER:PASSWORD@HOST:3306/DATABASE',
|
||||
http_listen_address: '127.0.0.1',
|
||||
http_port: 3000,
|
||||
sentry_dsn: 'https://ID@sentry.example.com/PROJECTID',
|
||||
debug: false,
|
||||
auth: {
|
||||
cookie_secret: 'gen',
|
||||
cookie_secure: true,
|
||||
local: {
|
||||
active: true,
|
||||
users: {
|
||||
user: 'password',
|
||||
user1: 'password'
|
||||
}
|
||||
users: {}
|
||||
},
|
||||
oidc: {
|
||||
active: false
|
||||
@ -55,6 +55,15 @@ export const config = new ConfigHandler(__path + '/config.json', {
|
||||
}
|
||||
});
|
||||
|
||||
// If no local User exists, create the default with a generated password
|
||||
if (_.isEqual(config.global.auth.local.users, {})) {
|
||||
config.global.auth.local.users = {
|
||||
'flowAdmin': 'gen',
|
||||
};
|
||||
config.save_config();
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add errorhandling with some sort of message.
|
||||
export const prisma = new PrismaClient({
|
||||
datasources: {
|
||||
@ -113,10 +122,10 @@ app.use(bodyParser.json());
|
||||
// TODO: Move secret to config -> Autogenerate.
|
||||
app.use(
|
||||
session({
|
||||
secret: 'keyboard cat',
|
||||
secret: config.global.auth.cookie_secret,
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: { secure: false }
|
||||
cookie: { secure: config.global.auth.cookie_secure }
|
||||
})
|
||||
);
|
||||
app.use(passport.authenticate('session'));
|
||||
|
Loading…
Reference in New Issue
Block a user