diff --git a/WHATSNEW.md b/WHATSNEW.md index de8b6383..90b9e374 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -19,6 +19,9 @@ This document attempts to track **major** changes and additions in ENiGMA½. For * Any module may now register for a system startup intiialization via the `initializeModules(initInfo, cb)` export. * User event log is now functional. Various events a user performs will be persisted to the `system.db` `user_event_log` table for up to 90 days. An example usage can be found in the updated `last_callers` module where events are turned into Ami/X style actions. Please see `UPGRADE.md`! * New MCI codes including general purpose movement codes. See [MCI codes](docs/art/mci.md) +* `install.sh` will now attempt to use NPM's `--build-from-source` option when ARM is detected. +* `oputil.js config new` will now generate a much more complete configuration file with comments, examples, etc. `oputil.js config cat` dumps your current config to stdout. + ## 0.0.8-alpha diff --git a/core/config.js b/core/config.js index bc6be381..f6adaa35 100644 --- a/core/config.js +++ b/core/config.js @@ -346,6 +346,19 @@ function getDefaultConfig() { certPem : paths.join(__dirname, './../config/https_cert.pem'), keyPem : paths.join(__dirname, './../config/https_cert_key.pem'), } + }, + + gopher : { + enabled : false, + port : 8070, + publicHostname : 'another-fine-enigma-bbs.org', + publicPort : 8080, // adjust if behind NAT/etc. + bannerFile : 'gopher_banner.asc', + + // + // Set messageConferences{} to maps of confTag -> [ areaTag1, areaTag2, ... ] + // to export message confs/areas + // } }, diff --git a/core/oputil/oputil_config.js b/core/oputil/oputil_config.js index eade918b..b25441d8 100644 --- a/core/oputil/oputil_config.js +++ b/core/oputil/oputil_config.js @@ -4,12 +4,14 @@ // ENiGMA½ const resolvePath = require('../../core/misc_util.js').resolvePath; -const printUsageAndSetExitCode = require('./oputil_common.js').printUsageAndSetExitCode; -const ExitCodes = require('./oputil_common.js').ExitCodes; -const argv = require('./oputil_common.js').argv; -const getConfigPath = require('./oputil_common.js').getConfigPath; +const { + printUsageAndSetExitCode, + getConfigPath, + argv, + ExitCodes, + initConfigAndDatabases +} = require('./oputil_common.js'); const getHelpFor = require('./oputil_help.js').getHelpFor; -const initConfigAndDatabases = require('./oputil_common.js').initConfigAndDatabases; const Errors = require('../../core/enig_error.js').Errors; // deps @@ -21,6 +23,8 @@ const hjson = require('hjson'); const paths = require('path'); const _ = require('lodash'); +const packageJson = require('../../package.json'); + exports.handleConfigCommand = handleConfigCommand; @@ -37,6 +41,15 @@ const ConfigIncludeKeys = [ 'fileBase.areaStoragePrefix', ]; +const HJSONStringifyComonOpts = { + emitRootBraces : true, + bracesSameLine : true, + space : 4, + keepWsc : true, + quotes : 'min', + eol : '\n', +}; + const QUESTIONS = { Intro : [ { @@ -214,7 +227,10 @@ function askNewConfigQuestions(cb) { } function writeConfig(config, path) { - config = hjson.stringify(config, { bracesSameLine : true, space : '\t', keepWsc : true, quotes : 'strings' } ); + config = hjson.stringify(config, HJSONStringifyComonOpts) + .replace(/%ENIG_VERSION%/g, packageJson.version) + .replace(/%HJSON_VERSION%/g, hjson.version) + ; try { fs.writeFileSync(path, config, 'utf8'); @@ -522,6 +538,24 @@ function getImportEntries(importType, importData) { return importEntries; } +function catCurrentConfig() { + try { + const config = hjson.rt.parse(fs.readFileSync(getConfigPath(), 'utf8')); + const hjsonOpts = Object.assign({}, HJSONStringifyComonOpts, { + colors : false === argv.colors ? false : true, + keepWsc : false === argv.comments ? false : true, + }); + + console.log(hjson.stringify(config, hjsonOpts)); + } catch(e) { + if('ENOENT' == e.code) { + console.error(`File not found: ${getConfigPath()}`); + } else { + console.error(e); + } + } +} + function handleConfigCommand() { if(true === argv.help) { return printUsageAndSetExitCode(getHelpFor('Config'), ExitCodes.ERROR); @@ -532,6 +566,7 @@ function handleConfigCommand() { switch(action) { case 'new' : return buildNewConfig(); case 'import-areas' : return importAreas(); + case 'cat' : return catCurrentConfig(); default : return printUsageAndSetExitCode(getHelpFor('Config'), ExitCodes.ERROR); } diff --git a/core/oputil/oputil_help.js b/core/oputil/oputil_help.js index 4981f922..7c96d171 100644 --- a/core/oputil/oputil_help.js +++ b/core/oputil/oputil_help.js @@ -39,12 +39,17 @@ actions: actions: new generate a new/initial configuration import-areas PATH import areas using fidonet *.NA or AREAS.BBS file from PATH + cat cat current configuration to stdout import-areas args: --conf CONF_TAG specify conference tag in which to import areas --network NETWORK specify network name/key to associate FTN areas --uplinks UL1,UL2,... specify one or more comma separated uplinks --type TYPE specifies area import type. valid options are "bbs" and "na" + +cat args: + --no-color disable color + --no-comments strip any comments `, FileBase : `usage: oputil.js fb [] diff --git a/misc/config_template.in.hjson b/misc/config_template.in.hjson index c8c9bebb..b05fa057 100644 --- a/misc/config_template.in.hjson +++ b/misc/config_template.in.hjson @@ -1,281 +1,308 @@ { - /* - ./\/\.' ENiGMA½ System Configuration -/--/-------- - -- - + /* + ./\/\.' ENiGMA½ System Configuration -/--/-------- - -- - - _____________________ _____ ____________________ __________\_ / - \__ ____/\_ ____ \ /____/ / _____ __ \ / ______/ // /___jp! - // __|___// | \// |// | \// | | \// \ /___ /_____ - /____ _____| __________ ___|__| ____| \ / _____ \ - ---- \______\ -- |______\ ------ /______/ ---- |______\ - |______\ /__/ // ___/ - /__ _\ - <*> ENiGMA½ // HTTPS://GITHUB.COM/NUSKOOLER/ENIGMA-BBS <*> /__/ + _____________________ _____ ____________________ __________\_ / + \__ ____/\_ ____ \ /____/ / _____ __ \ / ______/ // /___jp! + // __|___// | \// |// | \// | | \// \ /___ /_____ + /____ _____| __________ ___|__| ____| \ / _____ \ + ---- \______\ -- |______\ ------ /______/ ---- |______\ - |______\ /__/ // ___/ + /__ _\ + <*> ENiGMA½ // HTTPS://GITHUB.COM/NUSKOOLER/ENIGMA-BBS <*> /__/ - ------------------------------------------------------------------------------- + *-----------------------------------------------------------------------------* + Generated by ENiGMA½ v%ENIG_VERSION% / hjson v%HJSON_VERSION% + *-----------------------------------------------------------------------------* - General Information - ------------------------------- - This configuration is in HJSON (http://hjson.org/) format. Strict to-spec - JSON is also perfectly valid. Use 'hjson' from npm to convert to/from JSON. - - See http://hjson.org/ for more information and syntax. - Various editors and IDEs have plugins for the HJSON format which can be - very useful. + ------------------------------- -- - - + General Information + ------------------------------- - - + This configuration is in HJSON (http://hjson.org/) format. Strict to-spec + JSON is also perfectly valid. Use 'hjson' from npm to convert to/from JSON. - Available Configuration - ------------------------------- - ENiGMA½ is highly configurable! By default, this file contains common - configuration elements, examples, etc. To see a full list of settings - available to this file, don't be afraid to open up core/config.js and - look around. Do not make changes there however, you may override any - of the configuration from within this file! + See http://hjson.org/ for more information and syntax. - See the documentation for more information, and don't be shy to ask - for help! - */ + Various editors and IDEs such as Sublime Text 3, Visual Studio Code, and so + on have syntax highlighting for the HJSON format which are highly recommended. - general: { - // Your BBS Name! - boardName: XXXXX - } - logging: { - // - // By default, the system will rotate logs. - // Remember you can pipe logs through bunyan to pretty-print: - // > tail -F enigma/logs/enigma-bbs.log | enigma/node_modules/bunyan/bin/bunyan - // - rotatingFile: { - // If you're having trouble, try setting this to "trace" - level: XXXXX - } - } + ------------------------------- -- - - + Configuration + ------------------------------- - - + ENiGMA½ is *highly* configurable, and thus can be overwhelming at first! - theme: { - // Default theme applied to new users. "*" indicates random. - default: XXXXX + By default, this file contains common configuration elements, examples, etc. + To see a more complete view of settings available to the system, don't be + afraid to open up core/config.js and look around. Do not make changes there + however! All system configuration can be extended and defaults overridden + via this file! - // Theme applied before a user has logged in. "*" indicates random. - preLogin: XXXXX + Please see RTFM ...er, uh... see the documentation for more information, and + don't be shy to ask for help: - // - // dateFormat, timeFormat, and dateTimeFormat blocks configure - // moment.js (https://momentjs.com/docs/#/displaying/) style formats - // for dates and times. Short and long versions are available. - // Note that themes may override these settings. - // - } + BBS : Xibalba @ xibalba.l33t.codes + FTN : BBS Discussion on fsxNet + IRC : #enigma-bbs / FreeNode + Email : bryan@leet.codes + */ - // - // Login servers represent available servers (or protocols) in which - // users are permitted to access your system. - // - loginServers: { - // Remember kids, Telnet is insecure! - telnet: { - // It's best to use non-privileged ports and NAT/foward to them - port: XXXXX - } + general: { + // Your BBS Name! + boardName: XXXXX + } - // ...but SSH *is* secure! - ssh: { - port: XXXXX + logging: { + // + // By default, the system will rotate logs. + // Remember you can pipe logs through bunyan to pretty-print: + // > tail -F enigma/logs/enigma-bbs.log | enigma/node_modules/bunyan/bin/bunyan + // + rotatingFile: { + // If you're having trouble, try setting this to "trace" + level: XXXXX + } + } - // - // To enable SSH: - // 1) Generate a Private Key (PK): - // > openssl genrsa -des3 -out ./config/ssh_private_key.pem 2048 - // 2) Set "privateKeyPass" below - // - enabled: XXXXX + theme: { + // Default theme applied to new users. "*" indicates random. + default: XXXXX + // Theme applied before a user has logged in. "*" indicates random. + preLogin: XXXXX - // set this to your PK's password, generated in step #1 above - privateKeyPass: SuperSecretPasswordChangeMe! + // + // dateFormat, timeFormat, and dateTimeFormat blocks configure + // moment.js (https://momentjs.com/docs/#/displaying/) style formats + // for dates and times. Short and long versions are available. + // Note that themes may override these settings. + // + } - // - // It's possible to lock down various algorithms available to - // SSH, but be aware this may limit the clients that can connect! - // - algorithms: {} - } + // + // Login servers represent available servers (or protocols) in which + // users are permitted to access your system. + // + loginServers: { + // Remember kids, Telnet is insecure! + telnet: { + // It's best to use non-privileged ports and NAT/foward to them + port: XXXXX + } - webSocket: { - // - // Setting "proxied" to true allows non-secure (ws://) WebSockets - // to be considered secure when the X-Fowarded-Proto HTTP header - // is set to "https". This is helpful when ENiGMA is running behind - // another web server doing SSL/TLS termination. - // - proxied: false + // ...but SSH *is* secure! + ssh: { + port: XXXXX - // Non-secure WebSockets, or ws:// - ws: { - port: XXXXX - } + // + // To enable SSH: + // 1) Generate a Private Key (PK): + // > openssl genrsa -des3 -out ./config/ssh_private_key.pem 2048 + // 2) Set "privateKeyPass" below + // + enabled: XXXXX - // Secure WebSockets, or wss:// - wss: { - port: XXXXX - enabled: XXXXX + // set this to your PK's password, generated in step #1 above + privateKeyPass: SuperSecretPasswordChangeMe! - // - // Certificate and Key in PEM format. - // Note that web browsers will not trust self-signed certs. Look - // into Let's Encrypt and perhaps running ENiGMA behind another - // web server such as Caddy. - // - certPem: XXXXX - keyPem: XXXXX - } - } - } + // + // It's possible to lock down various algorithms available to + // SSH, but be aware this may limit the clients that can connect! + // + algorithms: {} + } - // - // Content Servers expose content from the system - // - contentServers: { - // - // The Web Content Server can expose content over HTTP (http://) and - // HTTPS (https://) for (but not limited to) the following purposes: - // * Static content - // * Web downloads from the file base - // * Password reset forms (sent to users in PW reset emails; see - // "email" block below) - // - web: { - // Set to your public FQDN - domain: XXXXX - } - } + webSocket: { + // + // Setting "proxied" to true allows non-secure (ws://) WebSockets + // to be considered secure when the X-Fowarded-Proto HTTP header + // is set to "https". This is helpful when ENiGMA is running behind + // another web server doing SSL/TLS termination. + // + proxied: false - // - // Currently, ENiGMA½ can use external email to mail - // users for password resets. Additional functionality will - // be added in the future. - // - email: { - // - // Set the following keys to configure: - // * "defaultFrom" to the reply address - // * "transport" to a configuration block that meets the - // requirements of Nodemailer (https://nodemailer.com/) - // - // Example: - // transport: { - // service: Zoho - // auth: { - // user: myuser@myhost.com - // pass: supersecretpassword - // } - // } - // - } + // Non-secure WebSockets, or ws:// + ws: { + port: XXXXX + } - // Message conferences and areas are within this block - messageConferences: { - // An entry here prepresents a conference taka aka confTag - another_sample_conf: { - name: "Another Sample Conference" - desc: "Another conf sample. Change me!" - areas: { - // Similar to confTags, this is a areaTag - another_sample_area: { - name: "Another Sample Area" - desc: "Another area example. Change me!" - // The 'sort' key can override natural sort order and can live at the conference and area levels - sort: 2 - } - } - } - } + // Secure WebSockets, or wss:// + wss: { + port: XXXXX + enabled: XXXXX - // - // ENiGMA½ comes with a very powerful File Base, but may be a bit strange - // until you get used to it. Please see the documentation! - // - fileBase: { - // - // Storage tags with relative paths (that is, paths that do not start - // with a "/") are relative to the following path: - // - areaStoragePrefix: XXXXX + // + // Certificate and Key in PEM format. + // Note that web browsers will not trust self-signed certs. Look + // into Let's Encrypt and perhaps running ENiGMA behind another + // web server such as Caddy. + // + certPem: XXXXX + keyPem: XXXXX + } + } + } - // - // Storage tags create a tag -> directory (relative or full path) - // that can be used in areas. - // - storageTags: { - // - // Example storage tag: "super_l33t_warez": - // super_l33t_warez: "/path/to/super/l33t/warez" - // - } + // + // Content Servers expose content from the system + // + contentServers: { + // + // The Web Content Server can expose content over HTTP (http://) and + // HTTPS (https://) for (but not limited to) the following purposes: + // * Static content + // * Web downloads from the file base + // * Password reset forms (sent to users in PW reset emails; see + // "email" block below) + // + web: { + // Set to your public FQDN + domain: XXXXX + } - areas: { - // - // Example area with the areaTag of "an_example_area": - // an_example_area: { - // name: "Example File Area" - // desc: "It's just an example, yo!" - // storageTags: [ - // "super_l33t_warez" - // ] - // } - // - // File Base Areas are read-only (ie: download only) by default. - // To make a uploadable area, set ACS as you like. For example, - // to allow all users to upload to an area: - // - // an_example_area: { - // // ... - // acs: { - // write: GM[users] - // } - // } - } - } + // Ladies and gentlemen, a Gopher server! + gopher: { + port: XXXXX + enabled: false - // General user configuration - users: { - // - // ENiGMA½ utilizes user groups similar to Windows and *nix. Built in groups - // include "users" (for regular users) and "sysops" for +ops. You can add other - // groups to the system as well by adding a 'groups' key in this section: - // groups: [ "leet", "lamerz" ] - // + // + // The Gopher Content Server can export message base + // conferences and areas via the "messageConferences" key. + // + // Example: + // messageConferences: { + // some_conf: [ "area_tag1", "area_tag2" ] + // } + } + } - // Set default group(s) new users should automatically be assigned to - // defaultGroups : [ "lamerz" ] + // + // Currently, ENiGMA½ can use external email to mail + // users for password resets. Additional functionality will + // be added in the future. + // + email: { + // + // Set the following keys to configure: + // * "defaultFrom" to the reply address + // * "transport" to a configuration block that meets the + // requirements of Nodemailer (https://nodemailer.com/) + // + // Example: + // transport: { + // service: Zoho + // auth: { + // user: myuser@myhost.com + // pass: supersecretpassword + // } + // } + // + } - // Should new users require +op activation? - requireActivation: false, - } + // Message conferences and areas are within this block + messageConferences: { + // An entry here prepresents a conference taka aka confTag + another_sample_conf: { + name: "Another Sample Conference" + desc: "Another conf sample. Change me!" + areas: { + // Similar to confTags, this is a areaTag + another_sample_area: { + name: "Another Sample Area" + desc: "Another area example. Change me!" + // The 'sort' key can override natural sort order and can live at the conference and area levels + sort: 2 + } + } + } + } - // Archive files and related - archives: { - archivers: { - // - // Each key in the "archivers" configuration block represents a specific - // external archive utility. ENiGMA½ has sane configuration by default - // for many archivers, but the tools themselves are likely not yet installed - // on your system! - // - // You'll want to have archivers configured for the many old-school archive - // formats that a BBS may encounter! Please consult the documentation on - // information as to where to find and install these utilities! - // - } - } + // + // ENiGMA½ comes with a very powerful File Base, but may be a bit strange + // until you get used to it. Please see the documentation! + // + fileBase: { + // + // Storage tags with relative paths (that is, paths that do not start + // with a "/") are relative to the following path: + // + areaStoragePrefix: XXXXX - fileTransferProtocols: { - // - // Each key in the "fileTransferProtocols" configuration block defines - // an external file transfer utility for legacy protocols such as - // X, Y, and Z-Modem. - // - // You will want to ensure your system has these external utilities - // installed and/or define new or additional protocols. Please - // see the documentation for more information! - // - } + // + // Storage tags create a tag -> directory (relative or full path) + // that can be used in areas. + // + storageTags: { + // + // Example storage tag: "super_l33t_warez": + // super_l33t_warez: "/path/to/super/l33t/warez" + // + } + + areas: { + // + // Example area with the areaTag of "an_example_area": + // an_example_area: { + // name: "Example File Area" + // desc: "It's just an example, yo!" + // storageTags: [ + // "super_l33t_warez" + // ] + // } + // + // File Base Areas are read-only (ie: download only) by default. + // To make a uploadable area, set ACS as you like. For example, + // to allow all users to upload to an area: + // + // an_example_area: { + // // ... + // acs: { + // write: GM[users] + // } + // } + } + } + + // General user configuration + users: { + // + // ENiGMA½ utilizes user groups similar to Windows and *nix. Built in groups + // include "users" (for regular users) and "sysops" for +ops. You can add other + // groups to the system as well by adding a 'groups' key in this section: + // groups: [ "leet", "lamerz" ] + // + + // Set default group(s) new users should automatically be assigned to + // defaultGroups : [ "lamerz" ] + + // Should new users require +op activation? + requireActivation: false, + } + + // Archive files and related + archives: { + archivers: { + // + // Each key in the "archivers" configuration block represents a specific + // external archive utility. ENiGMA½ has sane configuration by default + // for many archivers, but the tools themselves are likely not yet installed + // on your system! + // + // You'll want to have archivers configured for the many old-school archive + // formats that a BBS may encounter! Please consult the documentation on + // information as to where to find and install these utilities! + // + } + } + + fileTransferProtocols: { + // + // Each key in the "fileTransferProtocols" configuration block defines + // an external file transfer utility for legacy protocols such as + // X, Y, and Z-Modem. + // + // You will want to ensure your system has these external utilities + // installed and/or define new or additional protocols. Please + // see the documentation for more information! + // + } } \ No newline at end of file