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

@ -10,7 +10,8 @@ This document attempts to track **major** changes and additions in ENiGMA½. For
* Setting the `data` member of an object will cause form submissions to use this value instead of the selected items index.
* See the default `luciano_blocktronics` `matrix` menu for example usage.
* You can now set the `sort` property on a menu to sort items. If `true` items are sorted by `text`. If the value is a string, it represents the key in menu objects to sort by.
* Hot-reload of configuration files such as menu.hjson, config.hjson, your themes.hjson, etc.: When a file is saved, it will be hot-reloaded into the running system
* Note that any custom modules should make use of the new Config.get() method.
## 0.0.8-alpha
* [Mystic BBS style](http://wiki.mysticbbs.com/doku.php?id=displaycodes) extended pipe color codes. These allow for example, to set "iCE" background colors.

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const stringFormat = require('./string_format.js');
const Errors = require('./enig_error.js').Errors;
const resolveMimeType = require('./mime_util.js').resolveMimeType;
@ -61,10 +61,11 @@ module.exports = class ArchiveUtil {
//
// Load configuration
//
if(_.has(Config, 'archives.archivers')) {
Object.keys(Config.archives.archivers).forEach(archKey => {
const config = Config();
if(_.has(config, 'archives.archivers')) {
Object.keys(config.archives.archivers).forEach(archKey => {
const archConfig = Config.archives.archivers[archKey];
const archConfig = config.archives.archivers[archKey];
const archiver = new Archiver(archConfig);
if(!archiver.ok()) {
@ -75,7 +76,7 @@ module.exports = class ArchiveUtil {
});
}
if(_.isObject(Config.fileTypes)) {
if(_.isObject(config.fileTypes)) {
const updateSig = (ft) => {
ft.sig = Buffer.from(ft.sig, 'hex');
ft.offset = ft.offset || 0;
@ -87,8 +88,8 @@ module.exports = class ArchiveUtil {
}
};
Object.keys(Config.fileTypes).forEach(mimeType => {
const fileType = Config.fileTypes[mimeType];
Object.keys(config.fileTypes).forEach(mimeType => {
const fileType = config.fileTypes[mimeType];
if(Array.isArray(fileType)) {
fileType.forEach(ft => {
if(ft.sig) {
@ -109,7 +110,8 @@ module.exports = class ArchiveUtil {
return;
}
let fileType = _.get(Config, [ 'fileTypes', mimeType ] );
const config = Config();
let fileType = _.get(config, [ 'fileTypes', mimeType ] );
if(Array.isArray(fileType)) {
if(!justExtention) {
@ -125,7 +127,7 @@ module.exports = class ArchiveUtil {
}
if(fileType.archiveHandler) {
return _.get( Config, [ 'archives', 'archivers', fileType.archiveHandler ] );
return _.get( config, [ 'archives', 'archivers', fileType.archiveHandler ] );
}
}
@ -151,7 +153,7 @@ module.exports = class ArchiveUtil {
return cb(err);
}
const archFormat = _.findKey(Config.fileTypes, fileTypeInfo => {
const archFormat = _.findKey(Config().fileTypes, fileTypeInfo => {
const fileTypeInfos = Array.isArray(fileTypeInfo) ? fileTypeInfo : [ fileTypeInfo ];
return fileTypeInfos.find(fti => {
if(!fti.sig || !fti.archiveHandler) {

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const miscUtil = require('./misc_util.js');
const ansi = require('./ansi_term.js');
const aep = require('./ansi_escape_parser.js');
@ -126,7 +126,7 @@ function getArtFromPath(path, options, cb) {
function getArt(name, options, cb) {
const ext = paths.extname(name);
options.basePath = miscUtil.valueWithDefault(options.basePath, Config.paths.art);
options.basePath = miscUtil.valueWithDefault(options.basePath, Config().paths.art);
options.asAnsi = miscUtil.valueWithDefault(options.asAnsi, true);
// :TODO: make use of asAnsi option and convert from supported -> ansi

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const StatLog = require('./stat_log.js');
// deps
@ -95,7 +95,7 @@ function resolveConfigAsset(spec) {
assert('config' === asset.type);
const path = asset.asset.split('.');
let conf = Config;
let conf = Config();
for(let i = 0; i < path.length; ++i) {
if(_.isUndefined(conf[path[i]])) {
return spec;

View File

@ -35,7 +35,7 @@
const term = require('./client_term.js');
const ansi = require('./ansi_term.js');
const User = require('./user.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const MenuStack = require('./menu_stack.js');
const ACS = require('./acs.js');
const Events = require('./events.js');
@ -400,7 +400,7 @@ function Client(/*input, output*/) {
}
if(key || ch) {
if(Config.logging.traceUserKeyboardInput) {
if(Config().logging.traceUserKeyboardInput) {
self.log.trace( { key : key, ch : escape(ch) }, 'User keyboard input'); // jshint ignore:line
}
@ -440,8 +440,8 @@ Client.prototype.startIdleMonitor = function() {
const nowMs = Date.now();
const idleLogoutSeconds = this.user.isAuthenticated() ?
Config.misc.idleLogoutSeconds :
Config.misc.preAuthIdleLogoutSeconds;
Config().misc.idleLogoutSeconds :
Config().misc.preAuthIdleLogoutSeconds;
if(nowMs - this.lastKeyPressMs >= (idleLogoutSeconds * 1000)) {
this.emit('idle timeout');

View File

@ -13,6 +13,8 @@ const assert = require('assert');
exports.init = init;
exports.getDefaultPath = getDefaultPath;
let currentConfiguration = {};
function hasMessageConferenceAndArea(config) {
assert(_.isObject(config.messageConferences)); // we create one ourself!
@ -67,12 +69,10 @@ function mergeValidateAndFinalize(config, cb) {
return callback(null, mergedConfig);
},
function setIt(mergedConfig, callback) {
exports.config = mergedConfig;
exports.config.get = (path) => {
return _.get(exports.config, path);
};
// :TODO: .config property is to be deprecated once conversions are done
exports.config = currentConfiguration = mergedConfig;
exports.get = () => currentConfiguration;
return callback(null);
}
],

View File

@ -1,7 +1,7 @@
/* jslint node: true */
'use strict';
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const ConfigCache = require('./config_cache.js');
const Events = require('./events.js');
@ -15,7 +15,7 @@ exports.getFullConfig = getFullConfig;
function getConfigPath(filePath) {
// |filePath| is assumed to be in the config path if it's only a file name
if('.' === paths.dirname(filePath)) {
filePath = paths.join(Config.paths.config, filePath);
filePath = paths.join(Config().paths.config, filePath);
}
return filePath;
}
@ -24,19 +24,20 @@ function init(cb) {
// pre-cache menu.hjson and prompt.hjson + establish events
const changed = ( { fileName, fileRoot } ) => {
const reCachedPath = paths.join(fileRoot, fileName);
if(reCachedPath === getConfigPath(Config.general.menuFile)) {
if(reCachedPath === getConfigPath(Config().general.menuFile)) {
Events.emit(Events.getSystemEvents().MenusChanged);
} else if(reCachedPath === getConfigPath(Config.general.promptFile)) {
} else if(reCachedPath === getConfigPath(Config().general.promptFile)) {
Events.emit(Events.getSystemEvents().PromptsChanged);
}
};
const config = Config();
async.series(
[
function menu(callback) {
return ConfigCache.getConfigWithOptions(
{
filePath : getConfigPath(Config.general.menuFile),
filePath : getConfigPath(config.general.menuFile),
callback : changed,
},
callback
@ -45,7 +46,7 @@ function init(cb) {
function prompt(callback) {
return ConfigCache.getConfigWithOptions(
{
filePath : getConfigPath(Config.general.promptFile),
filePath : getConfigPath(config.general.promptFile),
callback : changed,
},
callback

View File

@ -1,7 +1,7 @@
/* jslint node: true */
'use strict';
var Config = require('./config.js').config;
var Config = require('./config.js').get;
const StatLog = require('./stat_log.js');
var fs = require('graceful-fs');
@ -29,7 +29,7 @@ function DropFile(client, fileType) {
Object.defineProperty(this, 'fullPath', {
get : function() {
return paths.join(Config.paths.dropFiles, ('node' + self.client.node), self.fileName);
return paths.join(Config().paths.dropFiles, ('node' + self.client.node), self.fileName);
}
});
@ -157,7 +157,7 @@ function DropFile(client, fileType) {
// :TODO: Completely broken right now -- This need to be configurable & come from temp socket server most likely
'-1', // self.client.output._handle.fd.toString(), // :TODO: ALWAYS -1 on Windows!
'57600',
Config.general.boardName,
Config().general.boardName,
self.client.user.userId.toString(),
self.client.user.properties.real_name || self.client.user.username,
self.client.user.username,
@ -183,7 +183,7 @@ function DropFile(client, fileType) {
var secLevel = self.client.user.getLegacySecurityLevel().toString();
return iconv.encode( [
Config.general.boardName, // "The name of the system."
Config().general.boardName, // "The name of the system."
opUn, // "The sysop's name up to the first space."
opUn, // "The sysop's name following the first space."
'COM1', // "The serial port the modem is connected to, or 0 if logged in on console."

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Errors = require('./enig_error.js').Errors;
const Log = require('./logger.js').log;
@ -13,13 +13,14 @@ const nodeMailer = require('nodemailer');
exports.sendMail = sendMail;
function sendMail(message, cb) {
if(!_.has(Config, 'email.transport')) {
const config = Config();
if(!_.has(config, 'email.transport')) {
return cb(Errors.MissingConfig('Email "email::transport" configuration missing'));
}
message.from = message.from || Config.email.defaultFrom;
message.from = message.from || config.email.defaultFrom;
const transportOptions = Object.assign( {}, Config.email.transport, {
const transportOptions = Object.assign( {}, config.email.transport, {
logger : Log,
});

View File

@ -2,14 +2,14 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Log = require('./logger.js').log;
// deps
const assert = require('assert');
module.exports = function(condition, message) {
if(Config.debug.assertsEnabled) {
if(Config().debug.assertsEnabled) {
assert.apply(this, arguments);
} else if(!(condition)) {
const stack = new Error().stack;

View File

@ -3,7 +3,7 @@
// ENiGMA½
const PluginModule = require('./plugin_module.js').PluginModule;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Log = require('./logger.js').log;
const _ = require('lodash');
@ -155,8 +155,9 @@ class ScheduledEvent {
function EventSchedulerModule(options) {
PluginModule.call(this, options);
if(_.has(Config, 'eventScheduler')) {
this.moduleConfig = Config.eventScheduler;
const config = Config();
if(_.has(config, 'eventScheduler')) {
this.moduleConfig = config.eventScheduler;
}
const self = this;

View File

@ -4,7 +4,7 @@
// ENiGMA½
const MenuModule = require('./menu_module.js').MenuModule;
const resetScreen = require('./ansi_term.js').resetScreen;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Errors = require('./enig_error.js').Errors;
const Log = require('./logger.js').log;
const getEnigmaUserAgent = require('./misc_util.js').getEnigmaUserAgent;
@ -66,7 +66,7 @@ exports.getModule = class ExodusModule extends MenuModule {
this.config.sshHost = this.config.sshHost || this.config.ticketHost;
this.config.sshPort = this.config.sshPort || 22;
this.config.sshUser = this.config.sshUser || 'exodus_server';
this.config.sshKeyPem = this.config.sshKeyPem || joinPath(Config.paths.misc, 'exodus.id_rsa');
this.config.sshKeyPem = this.config.sshKeyPem || joinPath(Config().paths.misc, 'exodus.id_rsa');
}
initSequence() {

View File

@ -12,7 +12,7 @@ const FileArea = require('./file_base_area.js');
const Errors = require('./enig_error.js').Errors;
const ErrNotEnabled = require('./enig_error.js').ErrorReasons.NotEnabled;
const ArchiveUtil = require('./archive_util.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const DownloadQueue = require('./download_queue.js');
const FileAreaWeb = require('./file_area_web.js');
const FileBaseFilters = require('./file_base_filter.js');
@ -255,7 +255,7 @@ exports.getModule = class FileAreaList extends MenuModule {
const mimeType = resolveMimeType(entryInfo.archiveType);
let desc;
if(mimeType) {
let fileType = _.get(Config, [ 'fileTypes', mimeType ] );
let fileType = _.get(Config(), [ 'fileTypes', mimeType ] );
if(Array.isArray(fileType)) {
// further refine by extention
@ -264,7 +264,6 @@ exports.getModule = class FileAreaList extends MenuModule {
desc = fileType && fileType.desc;
}
entryInfo.archiveTypeDesc = desc || mimeType || entryInfo.archiveType;
//entryInfo.archiveTypeDesc = mimeType ? _.get(Config, [ 'fileTypes', mimeType, 'desc' ] ) || mimeType : entryInfo.archiveType;
} else {
entryInfo.archiveTypeDesc = 'N/A';
}
@ -510,7 +509,7 @@ exports.getModule = class FileAreaList extends MenuModule {
return callback(null);
}
const expireTime = moment().add(Config.fileBase.web.expireMinutes, 'minutes');
const expireTime = moment().add(Config().fileBase.web.expireMinutes, 'minutes');
FileAreaWeb.createAndServeTempDownload(
self.client,

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const FileDb = require('./database.js').dbs.file;
const getISOTimestampString = require('./database.js').getISOTimestampString;
const FileEntry = require('./file_entry.js');
@ -31,7 +31,7 @@ function notEnabledError() {
class FileAreaWebAccess {
constructor() {
this.hashids = new hashids(Config.general.boardName);
this.hashids = new hashids(Config().general.boardName);
this.expireTimers = {}; // hashId->timer
}
@ -52,7 +52,7 @@ class FileAreaWebAccess {
if(self.isEnabled()) {
const routeAdded = self.webServer.instance.addRoute({
method : 'GET',
path : Config.fileBase.web.routePath,
path : Config().fileBase.web.routePath,
handler : self.routeWebRequest.bind(self),
});
return callback(routeAdded ? null : Errors.General('Failed adding route'));
@ -184,11 +184,11 @@ class FileAreaWebAccess {
buildSingleFileTempDownloadLink(client, fileEntry, hashId) {
hashId = hashId || this.getSingleFileHashId(client, fileEntry);
return this.webServer.instance.buildUrl(`${Config.fileBase.web.path}${hashId}`);
return this.webServer.instance.buildUrl(`${Config().fileBase.web.path}${hashId}`);
}
buildBatchArchiveTempDownloadLink(client, hashId) {
return this.webServer.instance.buildUrl(`${Config.fileBase.web.path}${hashId}`);
return this.webServer.instance.buildUrl(`${Config().fileBase.web.path}${hashId}`);
}
getExistingTempDownloadServeItem(client, fileEntry, cb) {

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Errors = require('./enig_error.js').Errors;
const sortAreasOrConfs = require('./conf_area_util.js').sortAreasOrConfs;
const FileEntry = require('./file_entry.js');
@ -66,7 +66,7 @@ function getAvailableFileAreas(client, options) {
options = options || { };
// perform ACS check per conf & omit internal if desired
const allAreas = _.map(Config.fileBase.areas, (areaInfo, areaTag) => Object.assign(areaInfo, { areaTag : areaTag } ));
const allAreas = _.map(Config().fileBase.areas, (areaInfo, areaTag) => Object.assign(areaInfo, { areaTag : areaTag } ));
return _.omitBy(allAreas, areaInfo => {
if(!options.includeSystemInternal && isInternalArea(areaInfo.areaTag)) {
@ -96,16 +96,17 @@ function getSortedAvailableFileAreas(client, options) {
}
function getDefaultFileAreaTag(client, disableAcsCheck) {
let defaultArea = _.findKey(Config.fileBase, o => o.default);
const config = Config();
let defaultArea = _.findKey(config.fileBase, o => o.default);
if(defaultArea) {
const area = Config.fileBase.areas[defaultArea];
const area = config.fileBase.areas[defaultArea];
if(true === disableAcsCheck || client.acs.hasFileAreaRead(area)) {
return defaultArea;
}
}
// just use anything we can
defaultArea = _.findKey(Config.fileBase.areas, (area, areaTag) => {
defaultArea = _.findKey(config.fileBase.areas, (area, areaTag) => {
return WellKnownAreaTags.MessageAreaAttach !== areaTag && (true === disableAcsCheck || client.acs.hasFileAreaRead(area));
});
@ -113,7 +114,7 @@ function getDefaultFileAreaTag(client, disableAcsCheck) {
}
function getFileAreaByTag(areaTag) {
const areaInfo = Config.fileBase.areas[areaTag];
const areaInfo = Config().fileBase.areas[areaTag];
if(areaInfo) {
areaInfo.areaTag = areaTag; // convienence!
areaInfo.storage = getAreaStorageLocations(areaInfo);
@ -157,13 +158,14 @@ function changeFileAreaWithOptions(client, areaTag, options, cb) {
}
function isValidStorageTag(storageTag) {
return storageTag in Config.fileBase.storageTags;
return storageTag in Config().fileBase.storageTags;
}
function getAreaStorageDirectoryByTag(storageTag) {
const storageLocation = (storageTag && Config.fileBase.storageTags[storageTag]);
const config = Config();
const storageLocation = (storageTag && config.fileBase.storageTags[storageTag]);
return paths.resolve(Config.fileBase.areaStoragePrefix, storageLocation || '');
return paths.resolve(config.fileBase.areaStoragePrefix, storageLocation || '');
}
function getAreaDefaultStorageDirectory(areaInfo) {
@ -176,7 +178,7 @@ function getAreaStorageLocations(areaInfo) {
areaInfo.storageTags :
[ areaInfo.storageTags || '' ];
const avail = Config.fileBase.storageTags;
const avail = Config().fileBase.storageTags;
return _.compact(storageTags.map(storageTag => {
if(avail[storageTag]) {
@ -233,7 +235,7 @@ function sliceAtSauceMarker(data) {
function attemptSetEstimatedReleaseDate(fileEntry) {
// :TODO: yearEstPatterns RegExp's should be cached - we can do this @ Config (re)load time
const patterns = Config.fileBase.yearEstPatterns.map( p => new RegExp(p, 'gmi'));
const patterns = Config().fileBase.yearEstPatterns.map( p => new RegExp(p, 'gmi'));
function getMatch(input) {
if(input) {
@ -290,11 +292,11 @@ function extractAndProcessDescFiles(fileEntry, filePath, archiveEntries, cb) {
function extractDescFiles(callback) {
// :TODO: would be nice if these RegExp's were cached
// :TODO: this is long winded...
const config = Config();
const extractList = [];
const shortDescFile = archiveEntries.find( e => {
return Config.fileBase.fileNamePatterns.desc.find( pat => new RegExp(pat, 'i').test(e.fileName) );
return config.fileBase.fileNamePatterns.desc.find( pat => new RegExp(pat, 'i').test(e.fileName) );
});
if(shortDescFile) {
@ -302,7 +304,7 @@ function extractAndProcessDescFiles(fileEntry, filePath, archiveEntries, cb) {
}
const longDescFile = archiveEntries.find( e => {
return Config.fileBase.fileNamePatterns.descLong.find( pat => new RegExp(pat, 'i').test(e.fileName) );
return config.fileBase.fileNamePatterns.descLong.find( pat => new RegExp(pat, 'i').test(e.fileName) );
});
if(longDescFile) {
@ -334,6 +336,7 @@ function extractAndProcessDescFiles(fileEntry, filePath, archiveEntries, cb) {
});
},
function readDescFiles(descFiles, callback) {
const config = Config();
async.each(Object.keys(descFiles), (descType, next) => {
const path = descFiles[descType];
if(!path) {
@ -346,10 +349,9 @@ function extractAndProcessDescFiles(fileEntry, filePath, archiveEntries, cb) {
}
// skip entries that are too large
const maxFileSizeKey = `max${_.upperFirst(descType)}FileByteSize`;
if(Config.fileBase[maxFileSizeKey] && stats.size > Config.fileBase[maxFileSizeKey]) {
logDebug( { byteSize : stats.size, maxByteSize : Config.fileBase[maxFileSizeKey] }, `Skipping "${descType}"; Too large` );
const maxFileSizeKey = `max${_.upperFirst(descType)}FileByteSize`;
if(config.fileBase[maxFileSizeKey] && stats.size > config.fileBase[maxFileSizeKey]) {
logDebug( { byteSize : stats.size, maxByteSize : config.fileBase[maxFileSizeKey] }, `Skipping "${descType}"; Too large` );
return next(null);
}
@ -488,7 +490,8 @@ function populateFileEntryWithArchive(fileEntry, filePath, stepInfo, iterator, c
}
function getInfoExtractUtilForDesc(mimeType, filePath, descType) {
let fileType = _.get(Config, [ 'fileTypes', mimeType ] );
const config = Config();
let fileType = _.get(config, [ 'fileTypes', mimeType ] );
if(Array.isArray(fileType)) {
// further refine by extention
@ -504,7 +507,7 @@ function getInfoExtractUtilForDesc(mimeType, filePath, descType) {
return;
}
util = _.get(Config, [ 'infoExtractUtils', util ]);
util = _.get(config, [ 'infoExtractUtils', util ]);
if(!util || !_.isString(util.cmd)) {
return;
}

View File

@ -5,7 +5,7 @@
const stringFormat = require('./string_format.js');
const FileEntry = require('./file_entry.js');
const FileArea = require('./file_base_area.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const { Errors } = require('./enig_error.js');
const {
splitTextAtTerms,
@ -64,12 +64,14 @@ function exportFileList(filterCriteria, options, cb) {
{ name : options.headerTemplate, req : false },
{ name : options.entryTemplate, req : true }
];
const config = Config();
async.map(templateFiles, (template, nextTemplate) => {
if(!template.name && !template.req) {
return nextTemplate(null, Buffer.from([]));
}
template.name = paths.isAbsolute(template.name) ? template.name : paths.join(Config.paths.misc, template.name);
template.name = paths.isAbsolute(template.name) ? template.name : paths.join(config.paths.misc, template.name);
fs.readFile(template.name, (err, data) => {
return nextTemplate(err, data);
});
@ -221,7 +223,7 @@ function exportFileList(filterCriteria, options, cb) {
const headerFormatObj = {
nowTs : moment().format(options.tsFormat),
boardName : Config.general.boardName,
boardName : Config().general.boardName,
totalFileCount : totals.fileCount,
totalFileSize : totals.bytes,
filterAreaTag : filterCriteria.areaTag || '-ALL-',

View File

@ -11,7 +11,7 @@ const Errors = require('./enig_error.js').Errors;
const stringFormat = require('./string_format.js');
const FileAreaWeb = require('./file_area_web.js');
const ErrNotEnabled = require('./enig_error.js').ErrorReasons.NotEnabled;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
// deps
const async = require('async');
@ -139,7 +139,7 @@ exports.getModule = class FileBaseWebDownloadQueueManager extends MenuModule {
}
generateAndDisplayBatchLink(cb) {
const expireTime = moment().add(Config.fileBase.web.expireMinutes, 'minutes');
const expireTime = moment().add(Config().fileBase.web.expireMinutes, 'minutes');
FileAreaWeb.createAndServeTempBatchDownload(
this.client,
@ -183,6 +183,7 @@ exports.getModule = class FileBaseWebDownloadQueueManager extends MenuModule {
function prepareQueueDownloadLinks(callback) {
const webDlExpireTimeFormat = self.menuConfig.config.webDlExpireTimeFormat || 'YYYY-MMM-DD @ h:mm';
const config = Config();
async.each(self.dlQueue.items, (fileEntry, nextFileEntry) => {
FileAreaWeb.getExistingTempDownloadServeItem(self.client, fileEntry, (err, serveItem) => {
if(err) {
@ -190,7 +191,7 @@ exports.getModule = class FileBaseWebDownloadQueueManager extends MenuModule {
return nextFileEntry(err); // we should have caught this prior
}
const expireTime = moment().add(Config.fileBase.web.expireMinutes, 'minutes');
const expireTime = moment().add(config.fileBase.web.expireMinutes, 'minutes');
FileAreaWeb.createAndServeTempDownload(
self.client,

View File

@ -7,7 +7,7 @@ const {
getISOTimestampString,
sanatizeString
} = require('./database.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
// deps
const async = require('async');
@ -202,7 +202,8 @@ module.exports = class FileEntry {
}
static getAreaStorageDirectoryByTag(storageTag) {
const storageLocation = (storageTag && Config.fileBase.storageTags[storageTag]);
const config = Config();
const storageLocation = (storageTag && config.fileBase.storageTags[storageTag]);
// absolute paths as-is
if(storageLocation && '/' === storageLocation.charAt(0)) {
@ -210,7 +211,7 @@ module.exports = class FileEntry {
}
// relative to |areaStoragePrefix|
return paths.join(Config.fileBase.areaStoragePrefix, storageLocation || '');
return paths.join(config.fileBase.areaStoragePrefix, storageLocation || '');
}
get filePath() {

View File

@ -3,7 +3,7 @@
// enigma-bbs
const MenuModule = require('./menu_module.js').MenuModule;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const stringFormat = require('./string_format.js');
const Errors = require('./enig_error.js').Errors;
const DownloadQueue = require('./download_queue.js');
@ -56,9 +56,10 @@ exports.getModule = class TransferFileModule extends MenuModule {
//
// Most options can be set via extraArgs or config block
//
const config = Config();
if(options.extraArgs) {
if(options.extraArgs.protocol) {
this.protocolConfig = Config.fileTransferProtocols[options.extraArgs.protocol];
this.protocolConfig = config.fileTransferProtocols[options.extraArgs.protocol];
}
if(options.extraArgs.direction) {
@ -78,7 +79,7 @@ exports.getModule = class TransferFileModule extends MenuModule {
}
} else {
if(this.config.protocol) {
this.protocolConfig = Config.fileTransferProtocols[this.config.protocol];
this.protocolConfig = config.fileTransferProtocols[this.config.protocol];
}
if(this.config.direction) {
@ -98,7 +99,7 @@ exports.getModule = class TransferFileModule extends MenuModule {
}
}
this.protocolConfig = this.protocolConfig || Config.fileTransferProtocols.zmodem8kSz; // try for *something*
this.protocolConfig = this.protocolConfig || config.fileTransferProtocols.zmodem8kSz; // try for *something*
this.direction = this.direction || 'send';
this.sendQueue = this.sendQueue || [];

View File

@ -3,7 +3,7 @@
// enigma-bbs
const MenuModule = require('./menu_module.js').MenuModule;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const stringFormat = require('./string_format.js');
const ViewController = require('./view_controller.js').ViewController;
@ -129,7 +129,7 @@ exports.getModule = class FileTransferProtocolSelectModule extends MenuModule {
}
loadAvailProtocols() {
this.protocols = _.map(Config.fileTransferProtocols, (protInfo, protocol) => {
this.protocols = _.map(Config().fileTransferProtocols, (protInfo, protocol) => {
return {
protocol : protocol,
name : protInfo.name,

View File

@ -14,7 +14,7 @@ const StatLog = require('./stat_log.js');
const stringFormat = require('./string_format.js');
const MessageAreaConfTempSwitcher = require('./mod_mixins.js').MessageAreaConfTempSwitcher;
const { isAnsi, cleanControlCodes, insert } = require('./string_util.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const { getAddressedToInfo } = require('./mail_util.js');
// deps
@ -335,7 +335,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
// to packetAnsiMsgEncoding (generally cp437) as various boards
// really don't like ANSI messages in UTF-8 encoding (they should!)
//
msgOpts.meta = { System : { 'explicit_encoding' : Config.scannerTossers.ftn_bso.packetAnsiMsgEncoding || 'cp437' } };
msgOpts.meta = { System : { 'explicit_encoding' : _.get(Config(), 'scannerTossers.ftn_bso.packetAnsiMsgEncoding', 'cp437') } };
msgOpts.message = `${ansi.reset()}${ansi.eraseData(2)}${ansi.goto(1,1)}\r\n${ansi.up()}${msgOpts.message}`;
}
}

View File

@ -1,18 +1,17 @@
/* jslint node: true */
'use strict';
let Config = require('./config.js').config;
let Address = require('./ftn_address.js');
let FNV1a = require('./fnv1a.js');
const Config = require('./config.js').get;
const Address = require('./ftn_address.js');
const FNV1a = require('./fnv1a.js');
const getCleanEnigmaVersion = require('./misc_util.js').getCleanEnigmaVersion;
let _ = require('lodash');
let iconv = require('iconv-lite');
let moment = require('moment');
//let uuid = require('node-uuid');
let os = require('os');
const _ = require('lodash');
const iconv = require('iconv-lite');
const moment = require('moment');
const os = require('os');
let packageJson = require('../package.json');
const packageJson = require('../package.json');
// :TODO: Remove "Ftn" from most of these -- it's implied in the module
exports.stringToNullPaddedBuffer = stringToNullPaddedBuffer;
@ -199,9 +198,10 @@ function getQuotePrefix(name) {
// http://ftsc.org/docs/fts-0004.001
//
function getOrigin(address) {
const origin = _.has(Config, 'messageNetworks.originLine') ?
Config.messageNetworks.originLine :
Config.general.boardName;
const config = Config();
const origin = _.has(config, 'messageNetworks.originLine') ?
config.messageNetworks.originLine :
config.general.boardName;
const addrStr = new Address(address).toString('5D');
return ` * Origin: ${origin} (${addrStr})`;

View File

@ -10,7 +10,7 @@ const _ = require('lodash');
module.exports = class Log {
static init() {
const Config = require('./config.js').config;
const Config = require('./config.js').get();
const logPath = Config.paths.logs;
const err = this.checkLogPath(logPath);

View File

@ -6,7 +6,7 @@ const theme = require('./theme.js');
const ansi = require('./ansi_term.js');
const ViewController = require('./view_controller.js').ViewController;
const menuUtil = require('./menu_util.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const stringFormat = require('../core/string_format.js');
const MultiLineEditTextView = require('../core/multi_line_edit_text_view.js').MultiLineEditTextView;
const Errors = require('../core/enig_error.js').Errors;
@ -29,7 +29,7 @@ exports.MenuModule = class MenuModule extends PluginModule {
this.menuMethods = {}; // methods called from @method's
this.menuConfig.config = this.menuConfig.config || {};
this.cls = _.isBoolean(this.menuConfig.options.cls) ? this.menuConfig.options.cls : Config.menus.cls;
this.cls = _.isBoolean(this.menuConfig.options.cls) ? this.menuConfig.options.cls : Config().menus.cls;
this.viewControllers = {};
}

View File

@ -4,7 +4,7 @@
// ENiGMA½
var moduleUtil = require('./module_util.js');
var Log = require('./logger.js').log;
var Config = require('./config.js').config;
var Config = require('./config.js').get;
var asset = require('./asset.js');
var MCIViewFactory = require('./mci_view_factory.js').MCIViewFactory;
@ -75,7 +75,7 @@ function loadMenu(options, cb) {
const modLoadOpts = {
name : modSupplied ? modAsset.asset : 'standard_menu',
path : (!modSupplied || 'systemModule' === modAsset.type) ? __dirname : Config.paths.mods,
path : (!modSupplied || 'systemModule' === modAsset.type) ? __dirname : Config().paths.mods,
category : (!modSupplied || 'systemModule' === modAsset.type) ? null : 'mods',
};
@ -189,7 +189,7 @@ function handleAction(client, formData, conf, cb) {
return callModuleMenuMethod(
client,
actionAsset,
paths.join(Config.paths.mods, actionAsset.location),
paths.join(Config().paths.mods, actionAsset.location),
formData,
conf.extraArgs,
cb);
@ -234,7 +234,7 @@ function handleNext(client, nextSpec, conf, cb) {
case 'method' :
case 'systemMethod' :
if(_.isString(nextAsset.location)) {
return callModuleMenuMethod(client, nextAsset, paths.join(Config.paths.mods, nextAsset.location), {}, extraArgs, cb);
return callModuleMenuMethod(client, nextAsset, paths.join(Config().paths.mods, nextAsset.location), {}, extraArgs, cb);
} else if('systemMethod' === nextAsset.type) {
// :TODO: see other notes about system_menu_method.js here
return callModuleMenuMethod(client, nextAsset, paths.join(__dirname, 'system_menu_method.js'), {}, extraArgs, cb);

View File

@ -3,7 +3,7 @@
// ENiGMA½
const msgDb = require('./database.js').dbs.message;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Message = require('./message.js');
const Log = require('./logger.js').log;
const msgNetRecord = require('./msg_network.js').recordMessage;
@ -40,7 +40,7 @@ function getAvailableMessageConferences(client, options) {
assert(client || true === options.noClient);
// perform ACS check per conf & omit system_internal if desired
return _.omitBy(Config.messageConferences, (conf, confTag) => {
return _.omitBy(Config().messageConferences, (conf, confTag) => {
if(!options.includeSystemInternal && 'system_internal' === confTag) {
return true;
}
@ -68,8 +68,9 @@ function getAvailableMessageAreasByConfTag(confTag, options) {
// :TODO: confTag === "" then find default
if(_.has(Config.messageConferences, [ confTag, 'areas' ])) {
const areas = Config.messageConferences[confTag].areas;
const config = Config();
if(_.has(config.messageConferences, [ confTag, 'areas' ])) {
const areas = config.messageConferences[confTag].areas;
if(!options.client || true === options.noAcsCheck) {
// everything - no ACS checks
@ -109,16 +110,17 @@ function getDefaultMessageConferenceTag(client, disableAcsCheck) {
//
// Note that built in 'system_internal' is always ommited here
//
let defaultConf = _.findKey(Config.messageConferences, o => o.default);
const config = Config();
let defaultConf = _.findKey(config.messageConferences, o => o.default);
if(defaultConf) {
const conf = Config.messageConferences[defaultConf];
const conf = config.messageConferences[defaultConf];
if(true === disableAcsCheck || client.acs.hasMessageConfRead(conf)) {
return defaultConf;
}
}
// just use anything we can
defaultConf = _.findKey(Config.messageConferences, (conf, confTag) => {
defaultConf = _.findKey(config.messageConferences, (conf, confTag) => {
return 'system_internal' !== confTag && (true === disableAcsCheck || client.acs.hasMessageConfRead(conf));
});
@ -135,8 +137,9 @@ function getDefaultMessageAreaTagByConfTag(client, confTag, disableAcsCheck) {
//
confTag = confTag || getDefaultMessageConferenceTag(client);
if(confTag && _.has(Config.messageConferences, [ confTag, 'areas' ])) {
const areaPool = Config.messageConferences[confTag].areas;
const config = Config();
if(confTag && _.has(config.messageConferences, [ confTag, 'areas' ])) {
const areaPool = config.messageConferences[confTag].areas;
let defaultArea = _.findKey(areaPool, o => o.default);
if(defaultArea) {
const area = areaPool[defaultArea];
@ -154,18 +157,18 @@ function getDefaultMessageAreaTagByConfTag(client, confTag, disableAcsCheck) {
}
function getMessageConferenceByTag(confTag) {
return Config.messageConferences[confTag];
return Config().messageConferences[confTag];
}
function getMessageConfTagByAreaTag(areaTag) {
const confs = Config.messageConferences;
const confs = Config().messageConferences;
return Object.keys(confs).find( (confTag) => {
return _.has(confs, [ confTag, 'areas', areaTag]);
});
}
function getMessageAreaByTag(areaTag, optionalConfTag) {
const confs = Config.messageConferences;
const confs = Config().messageConferences;
// :TODO: this could be cached
if(_.isString(optionalConfTag)) {
@ -535,10 +538,11 @@ function trimMessageAreasScheduledEvent(args, cb) {
let areaInfos = [];
// determine maxMessages & maxAgeDays per area
const config = Config();
areaTags.forEach(areaTag => {
let maxMessages = Config.messageAreaDefaults.maxMessages;
let maxAgeDays = Config.messageAreaDefaults.maxAgeDays;
let maxMessages = config.messageAreaDefaults.maxMessages;
let maxAgeDays = config.messageAreaDefaults.maxAgeDays;
const area = getMessageAreaByTag(areaTag); // note: we don't know the conf here
if(area) {

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
// deps
const fs = require('graceful-fs');
@ -64,7 +64,7 @@ function loadModuleEx(options, cb) {
}
function loadModule(name, category, cb) {
const path = Config.paths[category];
const path = Config().paths[category];
if(!_.isString(path)) {
return cb(new Error(`Not sure where to look for "${name}" of category "${category}"`));
@ -77,7 +77,7 @@ function loadModule(name, category, cb) {
function loadModulesForCategory(category, iterator, complete) {
fs.readdir(Config.paths[category], (err, files) => {
fs.readdir(Config().paths[category], (err, files) => {
if(err) {
return iterator(err);
}
@ -100,10 +100,11 @@ function loadModulesForCategory(category, iterator, complete) {
}
function getModulePaths() {
const config = Config();
return [
Config.paths.mods,
Config.paths.loginServers,
Config.paths.contentServers,
Config.paths.scannerTossers,
config.paths.mods,
config.paths.loginServers,
config.paths.contentServers,
config.paths.scannerTossers,
];
}

View File

@ -6,7 +6,7 @@ const MenuModule = require('./menu_module.js').MenuModule;
const User = require('./user.js');
const theme = require('./theme.js');
const login = require('./system_menu_method.js').login;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const messageArea = require('./message_area.js');
exports.moduleInfo = {
@ -62,6 +62,7 @@ exports.getModule = class NewUserAppModule extends MenuModule {
//
submitApplication : function(formData, extraArgs, cb) {
const newUser = new User();
const config = Config();
newUser.username = formData.value.username;
@ -95,10 +96,10 @@ exports.getModule = class NewUserAppModule extends MenuModule {
// :TODO: should probably have a place to create defaults/etc.
};
if('*' === Config.defaults.theme) {
if('*' === config.defaults.theme) {
newUser.properties.theme_id = theme.getRandomTheme();
} else {
newUser.properties.theme_id = Config.defaults.theme;
newUser.properties.theme_id = config.defaults.theme;
}
// :TODO: User.create() should validate email uniqueness!
@ -118,7 +119,7 @@ exports.getModule = class NewUserAppModule extends MenuModule {
// Cache SysOp information now
// :TODO: Similar to bbs.js. DRY
if(newUser.isSysOp()) {
Config.general.sysOp = {
config.general.sysOp = {
username : formData.value.username,
properties : newUser.properties,
};

View File

@ -333,7 +333,7 @@ function importAreas() {
},
function validateAndCollectInput(callback) {
const msgArea = require('../../core/message_area.js');
const Config = require('../../core/config.js').config;
const sysConfig = require('../../core/config.js').get();
let msgConfs = msgArea.getSortedAvailMessageConferences(null, { noClient : true } );
if(!msgConfs) {
@ -355,8 +355,8 @@ function importAreas() {
}
let existingNetworkNames = [];
if(_.has(Config, 'messageNetworks.ftn.networks')) {
existingNetworkNames = Object.keys(Config.messageNetworks.ftn.networks);
if(_.has(sysConfig, 'messageNetworks.ftn.networks')) {
existingNetworkNames = Object.keys(sysConfig.messageNetworks.ftn.networks);
}
if(0 === existingNetworkNames.length) {
@ -366,7 +366,7 @@ function importAreas() {
if(networkName && !existingNetworkNames.find(net => networkName === net)) {
return callback(Errors.DoesNotExist(`FTN style Network "${networkName}" does not exist`));
}
getAnswers([
{
name : 'confTag',
@ -407,13 +407,13 @@ function importAreas() {
});
},
function confirmWithUser(callback) {
const Config = require('../../core/config.js').config;
const sysConfig = require('../../core/config.js').get();
console.info(`Importing the following for "${confTag}" - (${Config.messageConferences[confTag].name} - ${Config.messageConferences[confTag].desc})`);
console.info(`Importing the following for "${confTag}" - (${sysConfig.messageConferences[confTag].name} - ${sysConfig.messageConferences[confTag].desc})`);
importEntries.forEach(ie => {
console.info(` ${ie.ftnTag} - ${ie.name}`);
});
console.info('');
console.info('Importing will NOT create required FTN network configurations.');
console.info('If you have not yet done this, you will need to complete additional steps after importing.');

View File

@ -390,10 +390,10 @@ function displayFileAreaInfo() {
return initConfigAndDatabases(callback);
},
function dumpInfo(callback) {
const Config = require('../../core/config.js').config;
const sysConfig = require('../../core/config.js').get();
let suppliedAreas = argv._.slice(2);
if(!suppliedAreas || 0 === suppliedAreas.length) {
suppliedAreas = _.map(Config.fileBase.areas, (areaInfo, areaTag) => areaTag);
suppliedAreas = _.map(sysConfig.fileBase.areas, (areaInfo, areaTag) => areaTag);
}
const areaAndStorageInfo = getAreaAndStorage(suppliedAreas);

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Log = require('./logger.js').log;
const getMessageAreaByTag = require('./message_area.js').getMessageAreaByTag;
const getMessageConferenceByTag = require('./message_area.js').getMessageConferenceByTag;
@ -56,7 +56,7 @@ const PREDEFINED_MCI_GENERATORS = {
//
// Board
//
BN : function boardName() { return Config.general.boardName; },
BN : function boardName() { return Config().general.boardName; },
// ENiGMA
VL : function versionLabel() { return 'ENiGMA½ v' + packageJson.version; },

View File

@ -3,7 +3,7 @@
// ENiGMA½
const MessageScanTossModule = require('../msg_scan_toss_module.js').MessageScanTossModule;
const Config = require('../config.js').config;
const Config = require('../config.js').get;
const ftnMailPacket = require('../ftn_mail_packet.js');
const ftnUtil = require('../ftn_util.js');
const Address = require('../ftn_address.js');
@ -60,8 +60,9 @@ function FTNMessageScanTossModule() {
this.archUtil = ArchiveUtil.getInstance();
if(_.has(Config, 'scannerTossers.ftn_bso')) {
this.moduleConfig = Config.scannerTossers.ftn_bso;
const config = Config();
if(_.has(config, 'scannerTossers.ftn_bso')) {
this.moduleConfig = config.scannerTossers.ftn_bso;
}
this.getDefaultNetworkName = function() {
@ -69,19 +70,20 @@ function FTNMessageScanTossModule() {
return this.moduleConfig.defaultNetwork.toLowerCase();
}
const networkNames = Object.keys(Config.messageNetworks.ftn.networks);
const networkNames = Object.keys(config.messageNetworks.ftn.networks);
if(1 === networkNames.length) {
return networkNames[0].toLowerCase();
}
};
this.getDefaultZone = function(networkName) {
if(_.isNumber(Config.messageNetworks.ftn.networks[networkName].defaultZone)) {
return Config.messageNetworks.ftn.networks[networkName].defaultZone;
const config = Config();
if(_.isNumber(config.messageNetworks.ftn.networks[networkName].defaultZone)) {
return config.messageNetworks.ftn.networks[networkName].defaultZone;
}
// non-explicit: default to local address zone
const networkLocalAddress = Config.messageNetworks.ftn.networks[networkName].localAddress;
const networkLocalAddress = config.messageNetworks.ftn.networks[networkName].localAddress;
if(networkLocalAddress) {
const addr = Address.fromString(networkLocalAddress);
return addr.zone;
@ -96,14 +98,14 @@ function FTNMessageScanTossModule() {
*/
this.getNetworkNameByAddress = function(remoteAddress) {
return _.findKey(Config.messageNetworks.ftn.networks, network => {
return _.findKey(Config().messageNetworks.ftn.networks, network => {
const localAddress = Address.fromString(network.localAddress);
return !_.isUndefined(localAddress) && localAddress.isEqual(remoteAddress);
});
};
this.getNetworkNameByAddressPattern = function(remoteAddressPattern) {
return _.findKey(Config.messageNetworks.ftn.networks, network => {
return _.findKey(Config().messageNetworks.ftn.networks, network => {
const localAddress = Address.fromString(network.localAddress);
return !_.isUndefined(localAddress) && localAddress.isPatternMatch(remoteAddressPattern);
});
@ -111,7 +113,7 @@ function FTNMessageScanTossModule() {
this.getLocalAreaTagByFtnAreaTag = function(ftnAreaTag) {
ftnAreaTag = ftnAreaTag.toUpperCase(); // always compare upper
return _.findKey(Config.messageNetworks.ftn.areas, areaConf => {
return _.findKey(Config().messageNetworks.ftn.areas, areaConf => {
return areaConf.tag.toUpperCase() === ftnAreaTag;
});
};
@ -357,6 +359,7 @@ function FTNMessageScanTossModule() {
let ftnAttribute = ftnMailPacket.Packet.Attribute.Local; // message from our system
const config = Config();
if(self.isNetMailMessage(message)) {
//
// Set route and message destination properties -- they may differ
@ -405,14 +408,14 @@ function FTNMessageScanTossModule() {
//
// EchoMail requires some additional properties & kludges
//
message.meta.FtnProperty.ftn_area = Config.messageNetworks.ftn.areas[message.areaTag].tag;
message.meta.FtnProperty.ftn_area = config.messageNetworks.ftn.areas[message.areaTag].tag;
//
// When exporting messages, we should create/update SEEN-BY
// with remote address(s) we are exporting to.
//
const seenByAdditions =
[ `${localAddress.net}/${localAddress.node}` ].concat(Config.messageNetworks.ftn.areas[message.areaTag].uplinks);
[ `${localAddress.net}/${localAddress.node}` ].concat(config.messageNetworks.ftn.areas[message.areaTag].uplinks);
message.meta.FtnProperty.ftn_seen_by =
ftnUtil.getUpdatedSeenByEntries(message.meta.FtnProperty.ftn_seen_by, seenByAdditions);
@ -453,7 +456,7 @@ function FTNMessageScanTossModule() {
// Determine CHRS and actual internal encoding name. If the message has an
// explicit encoding set, use it. Otherwise, try to preserve any CHRS/encoding already set.
//
let encoding = options.nodeConfig.encoding || Config.scannerTossers.ftn_bso.packetMsgEncoding || 'utf8';
let encoding = options.nodeConfig.encoding || config.scannerTossers.ftn_bso.packetMsgEncoding || 'utf8';
const explicitEncoding = _.get(message.meta, 'System.explicit_encoding');
if(explicitEncoding) {
encoding = explicitEncoding;
@ -513,7 +516,7 @@ function FTNMessageScanTossModule() {
this.hasValidConfiguration = function() {
if(!_.has(this, 'moduleConfig.nodes') || !_.has(Config, 'messageNetworks.ftn.areas')) {
if(!_.has(this, 'moduleConfig.nodes') || !_.has(Config(), 'messageNetworks.ftn.areas')) {
return false;
}
@ -820,7 +823,7 @@ function FTNMessageScanTossModule() {
//
// Route full|wildcard -> full adddress/network lookup
//
const routes = _.get(Config, 'scannerTossers.ftn_bso.netMail.routes');
const routes = _.get(Config(), 'scannerTossers.ftn_bso.netMail.routes');
if(!routes) {
return;
}
@ -860,7 +863,7 @@ function FTNMessageScanTossModule() {
const config = _.find(this.moduleConfig.nodes, (node, nodeAddrWildcard) => {
return routeAddress.isPatternMatch(nodeAddrWildcard);
}) || { packetType : '2+', encoding : Config.scannerTossers.ftn_bso.packetMsgEncoding };
}) || { packetType : '2+', encoding : Config().scannerTossers.ftn_bso.packetMsgEncoding };
// we should never be failing here; we may just be using defaults.
return cb(
@ -899,7 +902,7 @@ function FTNMessageScanTossModule() {
exportOpts.destAddress = dstAddr;
exportOpts.routeAddress = routeInfo.routeAddress;
exportOpts.fileCase = routeInfo.config.fileCase || 'lower';
exportOpts.network = Config.messageNetworks.ftn.networks[routeInfo.networkName];
exportOpts.network = Config().messageNetworks.ftn.networks[routeInfo.networkName];
exportOpts.networkName = routeInfo.networkName;
exportOpts.outgoingDir = self.getOutgoingEchoMailPacketDir(exportOpts.networkName, exportOpts.destAddress);
exportOpts.exportType = self.getExportType(routeInfo.config);
@ -966,6 +969,7 @@ function FTNMessageScanTossModule() {
};
this.exportEchoMailMessagesToUplinks = function(messageUuids, areaConfig, cb) {
const config = Config();
async.each(areaConfig.uplinks, (uplink, nextUplink) => {
const nodeConfig = self.getNodeConfigByAddress(uplink);
if(!nodeConfig) {
@ -974,7 +978,7 @@ function FTNMessageScanTossModule() {
const exportOpts = {
nodeConfig,
network : Config.messageNetworks.ftn.networks[areaConfig.network],
network : config.messageNetworks.ftn.networks[areaConfig.network],
destAddress : Address.fromString(uplink),
networkName : areaConfig.network,
fileCase : nodeConfig.fileCase || 'lower',
@ -1119,7 +1123,7 @@ function FTNMessageScanTossModule() {
this.getLocalUserNameFromAlias = function(lookup) {
lookup = lookup.toLowerCase();
const aliases = _.get(Config, 'messageNetworks.ftn.netMail.aliases');
const aliases = _.get(Config(), 'messageNetworks.ftn.netMail.aliases');
if(!aliases) {
return lookup; // keep orig
}
@ -1195,7 +1199,7 @@ function FTNMessageScanTossModule() {
// a random UUID. Otherwise, don't assign the UUID just yet. It will be
// generated at persist() time and should be consistent across import/exports
//
if(true === _.get(Config, [ 'messageNetworks', 'ftn', 'areas', config.localAreaTag, 'allowDupes' ], false)) {
if(true === _.get(Config(), [ 'messageNetworks', 'ftn', 'areas', config.localAreaTag, 'allowDupes' ], false)) {
// just generate a UUID & therefor always allow for dupes
message.uuid = uuidV4();
}
@ -1650,7 +1654,8 @@ function FTNMessageScanTossModule() {
};
this.getLocalAreaTagsForTic = function() {
return _.union(Object.keys(Config.scannerTossers.ftn_bso.ticAreas || {} ), Object.keys(Config.fileBase.areas));
const config = Config();
return _.union(Object.keys(config.scannerTossers.ftn_bso.ticAreas || {} ), Object.keys(config.fileBase.areas));
};
this.processSingleTicFile = function(ticFileInfo, cb) {
@ -1659,9 +1664,10 @@ function FTNMessageScanTossModule() {
async.waterfall(
[
function generalValidation(callback) {
const sysConfig = Config();
const config = {
nodes : Config.scannerTossers.ftn_bso.nodes,
defaultPassword : Config.scannerTossers.ftn_bso.tic.password,
nodes : sysConfig.scannerTossers.ftn_bso.nodes,
defaultPassword : sysConfig.scannerTossers.ftn_bso.tic.password,
localAreaTags : self.getLocalAreaTagsForTic(),
};
@ -1672,7 +1678,7 @@ function FTNMessageScanTossModule() {
}
// We may need to map |localAreaTag| back to real areaTag if it's a mapping/alias
const mappedLocalAreaTag = _.get(Config.scannerTossers.ftn_bso, [ 'ticAreas', localInfo.areaTag ]);
const mappedLocalAreaTag = _.get(Config().scannerTossers.ftn_bso, [ 'ticAreas', localInfo.areaTag ]);
if(mappedLocalAreaTag) {
if(_.isString(mappedLocalAreaTag.areaTag)) {
@ -1699,7 +1705,7 @@ function FTNMessageScanTossModule() {
// Lastly, we will only replace if the item is in the same/specified area
// and that come from the same origin as a previous entry.
//
const allowReplace = _.get(Config.scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'allowReplace' ], Config.scannerTossers.ftn_bso.tic.allowReplace);
const allowReplace = _.get(Config().scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'allowReplace' ], Config().scannerTossers.ftn_bso.tic.allowReplace);
const replaces = ticFileInfo.getAsString('Replaces');
if(!allowReplace || !replaces) {
@ -1755,7 +1761,7 @@ function FTNMessageScanTossModule() {
short_file_name : ticFileInfo.getAsString('File').toUpperCase(), // upper to ensure no case issues later; this should be a DOS 8.3 name
tic_origin : ticFileInfo.getAsString('Origin'),
tic_desc : ticFileInfo.getAsString('Desc'),
upload_by_username : _.get(Config.scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'uploadBy' ], Config.scannerTossers.ftn_bso.tic.uploadBy),
upload_by_username : _.get(Config().scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'uploadBy' ], Config().scannerTossers.ftn_bso.tic.uploadBy),
}
};
@ -1769,7 +1775,7 @@ function FTNMessageScanTossModule() {
//
const hashTags =
localInfo.hashTags ||
_.get(Config.scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'hashTags' ] ); // catch-all*/
_.get(Config().scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'hashTags' ] ); // catch-all*/
if(hashTags) {
scanOpts.hashTags = new Set(hashTags.split(/[\s,]+/));
@ -1817,8 +1823,8 @@ function FTNMessageScanTossModule() {
// We will still fallback as needed from <priority1> -> <priority2> -> <fromFileName>
//
const descPriority = _.get(
Config.scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'descPriority' ],
Config.scannerTossers.ftn_bso.tic.descPriority
Config().scannerTossers.ftn_bso.nodes, [ localInfo.node, 'tic', 'descPriority' ],
Config().scannerTossers.ftn_bso.tic.descPriority
);
if('tic' === descPriority) {
@ -1926,11 +1932,12 @@ function FTNMessageScanTossModule() {
;
// we shouldn't, but be sure we don't try to pick up private mail here
const areaTags = Object.keys(Config.messageNetworks.ftn.areas)
const config = Config();
const areaTags = Object.keys(config.messageNetworks.ftn.areas)
.filter(areaTag => Message.WellKnownAreaTags.Private !== areaTag);
async.each(areaTags, (areaTag, nextArea) => {
const areaConfig = Config.messageNetworks.ftn.areas[areaTag];
const areaConfig = config.messageNetworks.ftn.areas[areaTag];
if(!this.isAreaConfigValid(areaConfig)) {
return nextArea();
}
@ -2336,7 +2343,7 @@ FTNMessageScanTossModule.prototype.record = function(message) {
} else if(message.areaTag) {
Object.assign(info, { type : 'EchoMail' } );
const areaConfig = Config.messageNetworks.ftn.areas[message.areaTag];
const areaConfig = Config().messageNetworks.ftn.areas[message.areaTag];
if(!this.isAreaConfigValid(areaConfig)) {
return;
}

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)' );

View File

@ -5,7 +5,7 @@
const MenuModule = require('./menu_module.js').MenuModule;
const Errors = require('../core/enig_error.js').Errors;
const ANSI = require('./ansi_term.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
// deps
const async = require('async');
@ -90,7 +90,7 @@ exports.getModule = class ShowArtModule extends MenuModule {
}
// further resolve key -> file base area art
const artSpec = _.get(Config, [ 'fileBase', 'areas', key, 'art' ]);
const artSpec = _.get(Config(), [ 'fileBase', 'areas', key, 'art' ]);
if(!artSpec) {
return cb(Errors.MissingConfig(`No art defined for file base area "${key}"`));
}

View File

@ -3,7 +3,7 @@
// ENiGMA½
const User = require('./user.js');
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Log = require('./logger.js').log;
const { getAddressedToInfo } = require('./mail_util.js');
const Message = require('./message.js');
@ -30,14 +30,15 @@ function validateMessageSubject(data, cb) {
}
function validateUserNameAvail(data, cb) {
if(!data || data.length < Config.users.usernameMin) {
const config = Config();
if(!data || data.length < config.users.usernameMin) {
cb(new Error('Username too short'));
} else if(data.length > Config.users.usernameMax) {
} else if(data.length > config.users.usernameMax) {
// generally should be unreached due to view restraints
return cb(new Error('Username too long'));
} else {
const usernameRegExp = new RegExp(Config.users.usernamePattern);
const invalidNames = Config.users.newUserNames + Config.users.badUserNames;
const usernameRegExp = new RegExp(config.users.usernamePattern);
const invalidNames = config.users.newUserNames + config.users.badUserNames;
if(!usernameRegExp.test(data)) {
return cb(new Error('Username contains invalid characters'));
@ -133,12 +134,13 @@ function validateBirthdate(data, cb) {
}
function validatePasswordSpec(data, cb) {
if(!data || data.length < Config.users.passwordMin) {
const config = Config();
if(!data || data.length < config.users.passwordMin) {
return cb(new Error('Password too short'));
}
// check badpass, if avail
fs.readFile(Config.users.badPassFile, 'utf8', (err, passwords) => {
fs.readFile(config.users.badPassFile, 'utf8', (err, passwords) => {
if(err) {
Log.warn( { error : err.message }, 'Cannot read bad pass file');
return cb(null);

View File

@ -1,7 +1,7 @@
/* jslint node: true */
'use strict';
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const art = require('./art.js');
const ansi = require('./ansi_term.js');
const Log = require('./logger.js').log;
@ -38,7 +38,7 @@ function refreshThemeHelpers(theme) {
let pwChar = _.get(
theme,
'customization.defaults.general.passwordChar',
Config.defaults.passwordChar
Config().defaults.passwordChar
);
if(_.isString(pwChar)) {
@ -50,22 +50,22 @@ function refreshThemeHelpers(theme) {
return pwChar;
},
getDateFormat : function(style = 'short') {
const format = Config.defaults.dateFormat[style] || 'MM/DD/YYYY';
const format = Config().defaults.dateFormat[style] || 'MM/DD/YYYY';
return _.get(theme, `customization.defaults.dateFormat.${style}`, format);
},
getTimeFormat : function(style = 'short') {
const format = Config.defaults.timeFormat[style] || 'h:mm a';
const format = Config().defaults.timeFormat[style] || 'h:mm a';
return _.get(theme, `customization.defaults.timeFormat.${style}`, format);
},
getDateTimeFormat : function(style = 'short') {
const format = Config.defaults.dateTimeFormat[style] || 'MM/DD/YYYY h:mm a';
const format = Config().defaults.dateTimeFormat[style] || 'MM/DD/YYYY h:mm a';
return _.get(theme, `customization.defaults.dateTimeFormat.${style}`, format);
}
};
}
function loadTheme(themeId, cb) {
const path = paths.join(Config.paths.themes, themeId, 'theme.hjson');
const path = paths.join(Config().paths.themes, themeId, 'theme.hjson');
const changed = ( { fileName, fileRoot } ) => {
const reCachedPath = paths.join(fileRoot, fileName);
@ -262,15 +262,16 @@ function getMergedTheme(menuConfig, promptConfig, theme) {
}
function reloadTheme(themeId) {
const config = Config();
async.waterfall(
[
function loadMenuConfig(callback) {
getFullConfig(Config.general.menuFile, (err, menuConfig) => {
getFullConfig(config.general.menuFile, (err, menuConfig) => {
return callback(err, menuConfig);
});
},
function loadPromptConfig(menuConfig, callback) {
getFullConfig(Config.general.promptFile, (err, promptConfig) => {
getFullConfig(config.general.promptFile, (err, promptConfig) => {
return callback(err, menuConfig, promptConfig);
});
},
@ -312,21 +313,21 @@ function reloadAllThemes()
}
function initAvailableThemes(cb) {
const config = Config();
async.waterfall(
[
function loadMenuConfig(callback) {
getFullConfig(Config.general.menuFile, (err, menuConfig) => {
getFullConfig(config.general.menuFile, (err, menuConfig) => {
return callback(err, menuConfig);
});
},
function loadPromptConfig(menuConfig, callback) {
getFullConfig(Config.general.promptFile, (err, promptConfig) => {
getFullConfig(config.general.promptFile, (err, promptConfig) => {
return callback(err, menuConfig, promptConfig);
});
},
function getThemeDirectories(menuConfig, promptConfig, callback) {
fs.readdir(Config.paths.themes, (err, files) => {
fs.readdir(config.paths.themes, (err, files) => {
if(err) {
return callback(err);
}
@ -337,7 +338,7 @@ function initAvailableThemes(cb) {
promptConfig,
files.filter( f => {
// sync normally not allowed -- initAvailableThemes() is a startup-only method, however
return fs.statSync(paths.join(Config.paths.themes, f)).isDirectory();
return fs.statSync(paths.join(config.paths.themes, f)).isDirectory();
})
);
});
@ -394,12 +395,13 @@ function setClientTheme(client, themeId) {
let msg;
let setThemeId;
const config = Config();
if(availThemes.has(themeId)) {
msg = 'Set client theme';
setThemeId = themeId;
} else if(availThemes.has(Config.defaults.theme)) {
} else if(availThemes.has(config.defaults.theme)) {
msg = 'Failed setting theme by supplied ID; Using default';
setThemeId = Config.defaults.theme;
setThemeId = config.defaults.theme;
} else {
msg = 'Failed setting theme by system default ID; Using the first one we can find';
setThemeId = availThemes.keys().next().value;
@ -421,10 +423,11 @@ function getThemeArt(options, cb) {
// readSauce
// random
//
const config = Config();
if(!options.themeId && _.has(options, 'client.user.properties.theme_id')) {
options.themeId = options.client.user.properties.theme_id;
} else {
options.themeId = Config.defaults.theme;
options.themeId = config.defaults.theme;
}
// :TODO: replace asAnsi stuff with something like retrieveAs = 'ansi' | 'pipe' | ...
@ -465,17 +468,17 @@ function getThemeArt(options, cb) {
return callback(null, artInfo);
}
options.basePath = paths.join(Config.paths.themes, options.themeId);
options.basePath = paths.join(config.paths.themes, options.themeId);
art.getArt(options.name, options, (err, artInfo) => {
return callback(null, artInfo);
});
},
function fromDefaultTheme(artInfo, callback) {
if(artInfo || Config.defaults.theme === options.themeId) {
if(artInfo || config.defaults.theme === options.themeId) {
return callback(null, artInfo);
}
options.basePath = paths.join(Config.paths.themes, Config.defaults.theme);
options.basePath = paths.join(config.paths.themes, config.defaults.theme);
art.getArt(options.name, options, (err, artInfo) => {
return callback(null, artInfo);
});
@ -485,7 +488,7 @@ function getThemeArt(options, cb) {
return callback(null, artInfo);
}
options.basePath = Config.paths.art;
options.basePath = config.paths.art;
art.getArt(options.name, options, (err, artInfo) => {
return callback(err, artInfo);
});

View File

@ -2,7 +2,7 @@
'use strict';
const userDb = require('./database.js').dbs.user;
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const userGroup = require('./user_group.js');
const Errors = require('./enig_error.js').Errors;
const Events = require('./events.js');
@ -56,7 +56,7 @@ module.exports = class User {
}
isValid() {
if(this.userId <= 0 || this.username.length < Config.users.usernameMin) {
if(this.userId <= 0 || this.username.length < Config().users.usernameMin) {
return false;
}
@ -181,15 +181,16 @@ module.exports = class User {
create(password, cb) {
assert(0 === this.userId);
const config = Config();
if(this.username.length < Config.users.usernameMin || this.username.length > Config.users.usernameMax) {
if(this.username.length < config.users.usernameMin || this.username.length > config.users.usernameMax) {
return cb(Errors.Invalid('Invalid username length'));
}
const self = this;
// :TODO: set various defaults, e.g. default activation status, etc.
self.properties.account_status = Config.users.requireActivation ? User.AccountStatus.inactive : User.AccountStatus.active;
self.properties.account_status = config.users.requireActivation ? User.AccountStatus.inactive : User.AccountStatus.active;
async.waterfall(
[
@ -229,7 +230,7 @@ module.exports = class User {
});
},
function setInitialGroupMembership(trans, callback) {
self.groups = Config.users.defaultGroups;
self.groups = config.users.defaultGroups;
if(User.RootUserID === self.userId) { // root/SysOp?
self.groups.push('sysops');

View File

@ -2,7 +2,7 @@
'use strict';
// ENiGMA½
const Config = require('./config.js').config;
const Config = require('./config.js').get;
const Errors = require('./enig_error.js').Errors;
const getServer = require('./listening_server.js').getServer;
const webServerPackageName = require('./servers/content/web.js').moduleInfo.packageName;
@ -89,12 +89,13 @@ class WebPasswordReset {
},
function getEmailTemplates(user, callback) {
fs.readFile(Config.contentServers.web.resetPassword.resetPassEmailText, 'utf8', (err, textTemplate) => {
const config = Config();
fs.readFile(config.contentServers.web.resetPassword.resetPassEmailText, 'utf8', (err, textTemplate) => {
if(err) {
textTemplate = PW_RESET_EMAIL_TEXT_TEMPLATE_DEFAULT;
}
fs.readFile(Config.contentServers.web.resetPassword.resetPassEmailHtml, 'utf8', (err, htmlTemplate) => {
fs.readFile(config.contentServers.web.resetPassword.resetPassEmailHtml, 'utf8', (err, htmlTemplate) => {
return callback(null, user, textTemplate, htmlTemplate);
});
});
@ -106,7 +107,7 @@ class WebPasswordReset {
function replaceTokens(s) {
return s
.replace(/%BOARDNAME%/g, Config.general.boardName)
.replace(/%BOARDNAME%/g, Config().general.boardName)
.replace(/%USERNAME%/g, user.username)
.replace(/%TOKEN%/g, user.properties.email_password_reset_token)
.replace(/%RESET_URL%/g, resetUrl)
@ -229,12 +230,13 @@ class WebPasswordReset {
const postResetUrl = webServer.instance.buildUrl('/reset_password');
const config = Config();
return webServer.instance.routeTemplateFilePage(
Config.contentServers.web.resetPassword.resetPageTemplate,
config.contentServers.web.resetPassword.resetPageTemplate,
(templateData, preprocessFinished) => {
const finalPage = templateData
.replace(/%BOARDNAME%/g, Config.general.boardName)
.replace(/%BOARDNAME%/g, config.general.boardName)
.replace(/%USERNAME%/g, user.username)
.replace(/%TOKEN%/g, token)
.replace(/%RESET_URL%/g, postResetUrl)
@ -262,9 +264,10 @@ class WebPasswordReset {
req.on('end', () => {
const formData = querystring.parse(bodyData);
const config = Config();
if(!formData.token || !formData.password || !formData.confirm_password ||
formData.password !== formData.confirm_password ||
formData.password.length < Config.users.passwordMin || formData.password.length > Config.users.passwordMax)
formData.password.length < config.users.passwordMin || formData.password.length > config.users.passwordMax)
{
return badRequest();
}