More Hot-Reload related changes

* Config.get(): Returns the latest config
* Update code all over the place to use Config.get() vs Config.conf (which will be deprecated)
This commit is contained in:
Bryan Ashby 2018-06-20 19:57:06 -06:00
parent ca0149eaf0
commit 1fe46894d3
42 changed files with 320 additions and 273 deletions

View file

@ -4,7 +4,7 @@
// ENiGMA½
const Log = require('../../logger.js').log;
const { ServerModule } = require('../../server_module.js');
const Config = require('../../config.js').config;
const Config = require('../../config.js').get;
const {
splitTextAtTerms,
isAnsi,
@ -73,8 +73,9 @@ exports.getModule = class GopherModule extends ServerModule {
return;
}
this.publicHostname = Config.contentServers.gopher.publicHostname;
this.publicPort = Config.contentServers.gopher.publicPort;
const config = Config();
this.publicHostname = config.contentServers.gopher.publicHostname;
this.publicPort = config.contentServers.gopher.publicPort;
this.addRoute(/^\/?\r\n$/, this.defaultGenerator);
this.addRoute(/^\/msgarea(\/[a-z0-9_-]+(\/[a-z0-9_-]+)?(\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(_raw)?)?)?\/?\r\n$/, this.messageAreaGenerator);
@ -99,9 +100,10 @@ exports.getModule = class GopherModule extends ServerModule {
return true; // nothing to do, but not an error
}
const port = parseInt(Config.contentServers.gopher.port);
const config = Config();
const port = parseInt(config.contentServers.gopher.port);
if(isNaN(port)) {
this.log.warn( { port : Config.contentServers.gopher.port, server : ModuleInfo.name }, 'Invalid port' );
this.log.warn( { port : config.contentServers.gopher.port, server : ModuleInfo.name }, 'Invalid port' );
return false;
}
@ -109,13 +111,14 @@ exports.getModule = class GopherModule extends ServerModule {
}
get enabled() {
return _.get(Config, 'contentServers.gopher.enabled', false) && this.isConfigured();
return _.get(Config(), 'contentServers.gopher.enabled', false) && this.isConfigured();
}
isConfigured() {
// public hostname & port must be set; responses contain them!
return _.isString(_.get(Config, 'contentServers.gopher.publicHostname')) &&
_.isNumber(_.get(Config, 'contentServers.gopher.publicPort'));
const config = Config();
return _.isString(_.get(config, 'contentServers.gopher.publicHostname')) &&
_.isNumber(_.get(config, 'contentServers.gopher.publicPort'));
}
addRoute(selectorRegExp, generatorHandler) {
@ -155,7 +158,7 @@ exports.getModule = class GopherModule extends ServerModule {
defaultGenerator(selectorMatch, cb) {
this.log.trace( { selector : selectorMatch[0] }, 'Serving default content');
let bannerFile = _.get(Config, 'contentServers.gopher.bannerFile', 'startup_banner.asc');
let bannerFile = _.get(Config(), 'contentServers.gopher.bannerFile', 'startup_banner.asc');
bannerFile = paths.isAbsolute(bannerFile) ? bannerFile : paths.join(__dirname, '../../../misc', bannerFile);
fs.readFile(bannerFile, 'utf8', (err, banner) => {
if(err) {
@ -174,7 +177,7 @@ exports.getModule = class GopherModule extends ServerModule {
}
isAreaAndConfExposed(confTag, areaTag) {
const conf = _.get(Config, [ 'contentServers', 'gopher', 'messageConferences', confTag ]);
const conf = _.get(Config(), [ 'contentServers', 'gopher', 'messageConferences', confTag ]);
return Array.isArray(conf) && conf.includes(areaTag);
}
@ -281,13 +284,14 @@ ${msgBody}
});
} else if(selectorMatch[1]) {
// list areas in conf
const sysConfig = Config();
const confTag = selectorMatch[1].replace(/\r\n|\//g, '');
const conf = _.get(Config, [ 'contentServers', 'gopher', 'messageConferences', confTag ]) && getMessageConferenceByTag(confTag);
const conf = _.get(sysConfig, [ 'contentServers', 'gopher', 'messageConferences', confTag ]) && getMessageConferenceByTag(confTag);
if(!conf) {
return this.notFoundGenerator(selectorMatch, cb);
}
const areas = _.get(Config, [ 'contentServers', 'gopher', 'messageConferences', confTag ], {})
const areas = _.get(sysConfig, [ 'contentServers', 'gopher', 'messageConferences', confTag ], {})
.map(areaTag => Object.assign( { areaTag }, getMessageAreaByTag(areaTag)))
.filter(area => area && !Message.isPrivateAreaTag(area.areaTag));
@ -307,7 +311,7 @@ ${msgBody}
return cb(response);
} else {
// message area base (list confs)
const confs = Object.keys(_.get(Config, 'contentServers.gopher.messageConferences', {}))
const confs = Object.keys(_.get(Config(), 'contentServers.gopher.messageConferences', {}))
.map(confTag => Object.assign( { confTag }, getMessageConferenceByTag(confTag)))
.filter(conf => conf); // remove any baddies

View file

@ -4,7 +4,7 @@
// ENiGMA½
const Log = require('../../logger.js').log;
const ServerModule = require('../../server_module.js').ServerModule;
const Config = require('../../config.js').config;
const Config = require('../../config.js').get;
// deps
const http = require('http');
@ -55,12 +55,13 @@ exports.getModule = class WebServerModule extends ServerModule {
constructor() {
super();
this.enableHttp = Config.contentServers.web.http.enabled || false;
this.enableHttps = Config.contentServers.web.https.enabled || false;
const config = Config();
this.enableHttp = config.contentServers.web.http.enabled || false;
this.enableHttps = config.contentServers.web.https.enabled || false;
this.routes = {};
if(this.isEnabled() && Config.contentServers.web.staticRoot) {
if(this.isEnabled() && config.contentServers.web.staticRoot) {
this.addRoute({
method : 'GET',
path : '/static/.*$',
@ -77,25 +78,26 @@ exports.getModule = class WebServerModule extends ServerModule {
// Prefer HTTPS over HTTP. Be explicit about the port
// only if non-standard. Allow users to override full prefix in config.
//
if(_.isString(Config.contentServers.web.overrideUrlPrefix)) {
return `${Config.contentServers.web.overrideUrlPrefix}${pathAndQuery}`;
const config = Config();
if(_.isString(config.contentServers.web.overrideUrlPrefix)) {
return `${config.contentServers.web.overrideUrlPrefix}${pathAndQuery}`;
}
let schema;
let port;
if(Config.contentServers.web.https.enabled) {
if(config.contentServers.web.https.enabled) {
schema = 'https://';
port = (443 === Config.contentServers.web.https.port) ?
port = (443 === config.contentServers.web.https.port) ?
'' :
`:${Config.contentServers.web.https.port}`;
`:${config.contentServers.web.https.port}`;
} else {
schema = 'http://';
port = (80 === Config.contentServers.web.http.port) ?
port = (80 === config.contentServers.web.http.port) ?
'' :
`:${Config.contentServers.web.http.port}`;
`:${config.contentServers.web.http.port}`;
}
return `${schema}${Config.contentServers.web.domain}${port}${pathAndQuery}`;
return `${schema}${config.contentServers.web.domain}${port}${pathAndQuery}`;
}
isEnabled() {
@ -107,14 +109,15 @@ exports.getModule = class WebServerModule extends ServerModule {
this.httpServer = http.createServer( (req, resp) => this.routeRequest(req, resp) );
}
const config = Config();
if(this.enableHttps) {
const options = {
cert : fs.readFileSync(Config.contentServers.web.https.certPem),
key : fs.readFileSync(Config.contentServers.web.https.keyPem),
cert : fs.readFileSync(config.contentServers.web.https.certPem),
key : fs.readFileSync(config.contentServers.web.https.keyPem),
};
// additional options
Object.assign(options, Config.contentServers.web.https.options || {} );
Object.assign(options, config.contentServers.web.https.options || {} );
this.httpsServer = https.createServer(options, (req, resp) => this.routeRequest(req, resp) );
}
@ -123,13 +126,14 @@ exports.getModule = class WebServerModule extends ServerModule {
listen() {
let ok = true;
const config = Config();
[ 'http', 'https' ].forEach(service => {
const name = `${service}Server`;
if(this[name]) {
const port = parseInt(Config.contentServers.web[service].port);
const port = parseInt(config.contentServers.web[service].port);
if(isNaN(port)) {
ok = false;
return Log.warn( { port : Config.contentServers.web[service].port, server : ModuleInfo.name }, `Invalid port (${service})` );
return Log.warn( { port : config.contentServers.web[service].port, server : ModuleInfo.name }, `Invalid port (${service})` );
}
return this[name].listen(port);
}
@ -167,7 +171,7 @@ exports.getModule = class WebServerModule extends ServerModule {
}
respondWithError(resp, code, bodyText, title) {
const customErrorPage = paths.join(Config.contentServers.web.staticRoot, `${code}.html`);
const customErrorPage = paths.join(Config().contentServers.web.staticRoot, `${code}.html`);
fs.readFile(customErrorPage, 'utf8', (err, data) => {
resp.writeHead(code, { 'Content-Type' : 'text/html' } );
@ -202,14 +206,14 @@ exports.getModule = class WebServerModule extends ServerModule {
}
routeIndex(req, resp) {
const filePath = paths.join(Config.contentServers.web.staticRoot, 'index.html');
const filePath = paths.join(Config().contentServers.web.staticRoot, 'index.html');
return this.returnStaticPage(filePath, resp);
}
routeStaticFile(req, resp) {
const fileName = req.url.substr(req.url.indexOf('/', 1));
const filePath = paths.join(Config.contentServers.web.staticRoot, fileName);
const filePath = paths.join(Config().contentServers.web.staticRoot, fileName);
return this.returnStaticPage(filePath, resp);
}

View file

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('../../config.js').config;
const Config = require('../../config.js').get;
const baseClient = require('../../client.js');
const Log = require('../../logger.js').log;
const LoginServerModule = require('../../login_server_module.js');
@ -42,7 +42,8 @@ function SSHClient(clientConn) {
const username = ctx.username || '';
const password = ctx.password || '';
self.isNewUser = (Config.users.newUserNames || []).indexOf(username) > -1;
const config = Config();
self.isNewUser = (config.users.newUserNames || []).indexOf(username) > -1;
self.log.trace( { method : ctx.method, username : username, newUser : self.isNewUser }, 'SSH authentication attempt');
@ -60,7 +61,7 @@ function SSHClient(clientConn) {
// If the system is open and |isNewUser| is true, the login
// sequence is hijacked in order to start the applicaiton process.
//
if(false === Config.general.closedSystem && self.isNewUser) {
if(false === config.general.closedSystem && self.isNewUser) {
return ctx.accept();
}
@ -99,7 +100,7 @@ function SSHClient(clientConn) {
return alreadyLoggedIn(username);
}
if(loginAttempts >= Config.general.loginAttempts) {
if(loginAttempts >= config.general.loginAttempts) {
return terminateConnection();
}
@ -113,8 +114,8 @@ function SSHClient(clientConn) {
if(err) {
interactivePrompt.prompt = `Access denied\n${ctx.username}'s password: `;
} else {
const newUserNameList = _.has(Config, 'users.newUserNames') && Config.users.newUserNames.length > 0 ?
Config.users.newUserNames.map(newName => '"' + newName + '"').join(', ') :
const newUserNameList = _.has(config, 'users.newUserNames') && config.users.newUserNames.length > 0 ?
config.users.newUserNames.map(newName => '"' + newName + '"').join(', ') :
'(No new user names enabled!)';
interactivePrompt.prompt = `Access denied\n${stringFormat(artInfo.data, { newUserNames : newUserNameList })}\n${ctx.username}'s password'`;
@ -203,7 +204,7 @@ function SSHClient(clientConn) {
}
// we're ready!
const firstMenu = self.isNewUser ? Config.loginServers.ssh.firstMenuNewUser : Config.loginServers.ssh.firstMenu;
const firstMenu = self.isNewUser ? Config().loginServers.ssh.firstMenuNewUser : Config().loginServers.ssh.firstMenu;
self.emit('ready', { firstMenu : firstMenu } );
});
@ -239,18 +240,19 @@ exports.getModule = class SSHServerModule extends LoginServerModule {
}
createServer() {
const config = Config();
const serverConf = {
hostKeys : [
{
key : fs.readFileSync(Config.loginServers.ssh.privateKeyPem),
passphrase : Config.loginServers.ssh.privateKeyPass,
key : fs.readFileSync(config.loginServers.ssh.privateKeyPem),
passphrase : config.loginServers.ssh.privateKeyPass,
}
],
ident : 'enigma-bbs-' + enigVersion + '-srv',
// Note that sending 'banner' breaks at least EtherTerm!
debug : (sshDebugLine) => {
if(true === Config.loginServers.ssh.traceConnections) {
if(true === config.loginServers.ssh.traceConnections) {
Log.trace(`SSH: ${sshDebugLine}`);
}
},
@ -265,9 +267,10 @@ exports.getModule = class SSHServerModule extends LoginServerModule {
}
listen() {
const port = parseInt(Config.loginServers.ssh.port);
const config = Config();
const port = parseInt(config.loginServers.ssh.port);
if(isNaN(port)) {
Log.error( { server : ModuleInfo.name, port : Config.loginServers.ssh.port }, 'Cannot load server (invalid port)' );
Log.error( { server : ModuleInfo.name, port : config.loginServers.ssh.port }, 'Cannot load server (invalid port)' );
return false;
}

View file

@ -5,7 +5,7 @@
const baseClient = require('../../client.js');
const Log = require('../../logger.js').log;
const LoginServerModule = require('../../login_server_module.js');
const Config = require('../../config.js').config;
const Config = require('../../config.js').get;
const EnigAssert = require('../../enigma_assert.js');
const { stringFromNullTermBuffer } = require('../../string_util.js');
@ -549,7 +549,7 @@ function TelnetClient(input, output) {
});
this.connectionTrace = (info, msg) => {
if(Config.loginServers.telnet.traceConnections) {
if(Config().loginServers.telnet.traceConnections) {
const logger = self.log || Log;
return logger.trace(info, `Telnet: ${msg}`);
}
@ -568,7 +568,7 @@ function TelnetClient(input, output) {
this.readyNow = () => {
if(!this.didReady) {
this.didReady = true;
this.emit('ready', { firstMenu : Config.loginServers.telnet.firstMenu } );
this.emit('ready', { firstMenu : Config().loginServers.telnet.firstMenu } );
}
};
}
@ -879,9 +879,10 @@ exports.getModule = class TelnetServerModule extends LoginServerModule {
}
listen() {
const port = parseInt(Config.loginServers.telnet.port);
const config = Config();
const port = parseInt(config.loginServers.telnet.port);
if(isNaN(port)) {
Log.error( { server : ModuleInfo.name, port : Config.loginServers.telnet.port }, 'Cannot load server (invalid port)' );
Log.error( { server : ModuleInfo.name, port : config.loginServers.telnet.port }, 'Cannot load server (invalid port)' );
return false;
}

View file

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('../../config.js').config;
const Config = require('../../config.js').get;
const TelnetClient = require('./telnet.js').TelnetClient;
const Log = require('../../logger.js').log;
const LoginServerModule = require('../../login_server_module.js');
@ -92,7 +92,7 @@ function WebSocketClient(ws, req, serverType) {
// If the config allows it, look for 'x-forwarded-proto' as "https"
// to override |isSecure|
//
if(true === _.get(Config, 'loginServers.webSocket.proxied') &&
if(true === _.get(Config(), 'loginServers.webSocket.proxied') &&
'https' === req.headers['x-forwarded-proto'])
{
Log.debug(`Assuming secure connection due to X-Forwarded-Proto of "${req.headers['x-forwarded-proto']}"`);
@ -120,7 +120,7 @@ exports.getModule = class WebSocketLoginServer extends LoginServerModule {
// * insecure websocket (ws://)
// * secure (tls) websocket (wss://)
//
const config = _.get(Config, 'loginServers.webSocket');
const config = _.get(Config(), 'loginServers.webSocket');
if(!_.isObject(config)) {
return;
}
@ -162,7 +162,7 @@ exports.getModule = class WebSocketLoginServer extends LoginServerModule {
}
const serverName = `${ModuleInfo.name} (${serverType})`;
const port = parseInt(_.get(Config, [ 'loginServers', 'webSocket', 'secure' === serverType ? 'wss' : 'ws', 'port' ] ));
const port = parseInt(_.get(Config(), [ 'loginServers', 'webSocket', 'secure' === serverType ? 'wss' : 'ws', 'port' ] ));
if(isNaN(port)) {
Log.error( { server : serverName, port : port }, 'Cannot load server (invalid port)' );