/* jslint node: true */ 'use strict'; var miscUtil = require('./misc_util.js'); var fs = require('fs'); var paths = require('path'); var async = require('async'); var _ = require('lodash'); var hjson = require('hjson'); exports.init = init; exports.getDefaultPath = getDefaultPath; function init(configPath, cb) { async.waterfall( [ function loadUserConfig(callback) { if(_.isString(configPath)) { fs.readFile(configPath, { encoding : 'utf8' }, function configData(err, data) { if(err) { callback(err); } else { try { var configJson = hjson.parse(data); callback(null, configJson); } catch(e) { callback(e); } } }); } else { callback(null, { } ); } }, function mergeWithDefaultConfig(configJson, callback) { var mergedConfig = _.merge(getDefaultConfig(), configJson, function mergeCustomizer(conf1, conf2) { // Arrays should always concat if(_.isArray(conf1)) { // :TODO: look for collisions & override dupes return conf1.concat(conf2); } }); callback(null, mergedConfig); }, function validate(mergedConfig, callback) { // // Various sections must now exist in config // if(!_.has(mergedConfig, 'messages.areas.') || !_.isArray(mergedConfig.messages.areas) || 0 === mergedConfig.messages.areas.length || !_.isString(mergedConfig.messages.areas[0].name)) { var msgAreasErr = new Error('Please create at least one message area'); msgAreasErr.code = 'EBADCONFIG'; callback(msgAreasErr); return; } callback(null, mergedConfig); } ], function complete(err, mergedConfig) { exports.config = mergedConfig; cb(err); } ); } function getDefaultPath() { var base = miscUtil.resolvePath('~/'); if(base) { // e.g. /home/users/joeuser/.config/enigma-bbs/config.hjson return paths.join(base, '.config', 'enigma-bbs', 'config.hjson'); } } function getDefaultConfig() { return { general : { boardName : 'Another Fine ENiGMA½ BBS', closedSystem : false, // is the system closed to new users? loginAttempts : 3, menuFile : 'menu.hjson', // Override to use something else, e.g. demo.hjson. Can be a full path (defaults to ./mods) promptFile : 'prompt.hjson', // Override to use soemthing else, e.g. myprompt.hjson. Can be a full path (defaults to ./mods) }, // :TODO: see notes below about 'theme' section - move this! preLoginTheme : 'luciano_blocktronics', users : { usernameMin : 2, usernameMax : 16, // Note that FidoNet wants 36 max usernamePattern : '^[A-Za-z0-9~!@#$%^&*()\\-\\_+]+$', passwordMin : 6, passwordMax : 128, realNameMax : 32, locationMax : 32, affilsMax : 32, emailMax : 255, webMax : 255, requireActivation : true, // require SysOp activation? invalidUsernames : [], groups : [ 'users', 'sysops' ], // built in groups defaultGroups : [ 'users' ], // default groups new users belong to newUserNames : [ 'new', 'apply' ], // Names reserved for applying // :TODO: Mystic uses TRASHCAN.DAT for this -- is there a reason to support something like that? badUserNames : [ 'sysop', 'admin', 'administrator', 'root', 'all' ], }, // :TODO: better name for "defaults"... which is redundant here! /* Concept "theme" : { "default" : "defaultThemeName", // or "*" "preLogin" : "*", "passwordChar" : "*", ... } */ defaults : { theme : 'luciano_blocktronics', passwordChar : '*', // TODO: move to user ? dateFormat : { short : 'MM/DD/YYYY', }, timeFormat : { short : 'h:mm a', }, dateTimeFormat : { short : 'MM/DD/YYYY h:mm a', } }, menus : { cls : true, // Clear screen before each menu by default? }, paths : { mods : paths.join(__dirname, './../mods/'), servers : paths.join(__dirname, './servers/'), art : paths.join(__dirname, './../mods/art/'), themes : paths.join(__dirname, './../mods/themes/'), logs : paths.join(__dirname, './../logs/'), // :TODO: set up based on system, e.g. /var/logs/enigmabbs or such db : paths.join(__dirname, './../db/'), dropFiles : paths.join(__dirname, './../dropfiles/'), // + "/node/ misc : paths.join(__dirname, './../misc/'), }, servers : { telnet : { port : 8888, enabled : true, firstMenu : 'telnetConnected', }, ssh : { port : 8889, enabled : true, // // Private key in PEM format // // Generating your PK: // > openssl genrsa -des3 -out ./misc/ssh_private_key.pem 2048 // // Then, set servers.ssh.privateKeyPass to the password you use above // in your config.hjson // privateKeyPem : paths.join(__dirname, './../misc/ssh_private_key.pem'), firstMenu : 'sshConnected', firstMenuNewUser : 'sshConnectedNewUser', } }, messages : { areas : [ { name : 'private_mail', desc : 'Private Email', groups : [ 'users' ] } ] }, networks : { /* networkName : { // e.g. fidoNet address : { zone : 0, net : 0, node : 0, point : 0, domain : 'l33t.codes' } } */ }, misc : { idleLogoutSeconds : 60 * 6, // 6m }, logging : { level : 'debug' } }; }