| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 | const fs      = require('fs');const NodeRSA = require('node-rsa');const logger  = require('../logger').global;const keysFile = '/data/keys.json';let instance = null;// 1. Load from config file first (not recommended anymore)// 2. Use config env variables nextconst configure = () => {	const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';	if (fs.existsSync(filename)) {		let configData;		try {			configData = require(filename);		} catch (err) {			// do nothing		}		if (configData && configData.database) {			logger.info(`Using configuration from file: ${filename}`);			instance      = configData;			instance.keys = getKeys();			return;		}	}	const envMysqlHost = process.env.DB_MYSQL_HOST || null;	const envMysqlUser = process.env.DB_MYSQL_USER || null;	const envMysqlName = process.env.DB_MYSQL_NAME || null;	if (envMysqlHost && envMysqlUser && envMysqlName) {		// we have enough mysql creds to go with mysql		logger.info('Using MySQL configuration');		instance = {			database: {				engine:   'mysql',				host:     envMysqlHost,				port:     process.env.DB_MYSQL_PORT || 3306,				user:     envMysqlUser,				password: process.env.DB_MYSQL_PASSWORD,				name:     envMysqlName,			},			keys: getKeys(),		};		return;	}	const envSqliteFile = process.env.DB_SQLITE_FILE || '/data/database.sqlite';	logger.info(`Using Sqlite: ${envSqliteFile}`);	instance = {		database: {			engine: 'knex-native',			knex:   {				client:     'sqlite3',				connection: {					filename: envSqliteFile				},				useNullAsDefault: true			}		},		keys: getKeys(),	};};const getKeys = () => {	// Get keys from file	if (!fs.existsSync(keysFile)) {		generateKeys();	} else if (process.env.DEBUG) {		logger.info('Keys file exists OK');	}	try {		return require(keysFile);	} catch (err) {		logger.error('Could not read JWT key pair from config file: ' + keysFile, err);		process.exit(1);	}};const generateKeys = () => {	logger.info('Creating a new JWT key pair...');	// Now create the keys and save them in the config.	const key = new NodeRSA({ b: 2048 });	key.generateKeyPair();	const keys = {		key: key.exportKey('private').toString(),		pub: key.exportKey('public').toString(),	};	// Write keys config	try {		fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2));	} catch (err) {		logger.error('Could not write JWT key pair to config file: ' + keysFile + ': ' . err.message);		process.exit(1);	}	logger.info('Wrote JWT key pair to config file: ' + keysFile);};module.exports = {	/**	 *	 * @param   {string}  key   ie: 'database' or 'database.engine'	 * @returns {boolean}	 */	has: function(key) {		instance === null && configure();		const keys = key.split('.');		let level  = instance;		let has    = true;		keys.forEach((keyItem) =>{			if (typeof level[keyItem] === 'undefined') {				has = false;			} else {				level = level[keyItem];			}		});		return has;	},	/**	 * Gets a specific key from the top level	 *	 * @param {string} key	 * @returns {*}	 */	get: function (key) {		instance === null && configure();		if (key && typeof instance[key] !== 'undefined') {			return instance[key];		}		return instance;	},	/**	 * Is this a sqlite configuration?	 *	 * @returns {boolean}	 */	isSqlite: function () {		instance === null && configure();		return instance.database.knex && instance.database.knex.client === 'sqlite3';	},	/**	 * Are we running in debug mdoe?	 *	 * @returns {boolean}	 */	debug: function () {		return !!process.env.DEBUG;	},	/**	 * Returns a public key	 *	 * @returns {string}	 */	getPublicKey: function () {		instance === null && configure();		return instance.keys.pub;	},	/**	 * Returns a private key	 *	 * @returns {string}	 */	getPrivateKey: function () {		instance === null && configure();		return instance.keys.key;	},	/**	 * @returns {boolean}	 */	useLetsencryptStaging: function () {		return !!process.env.LE_STAGING;	}};
 |