diff --git a/core/client_connections.js b/core/client_connections.js index 2e838e77..f74ba49b 100644 --- a/core/client_connections.js +++ b/core/client_connections.js @@ -3,7 +3,11 @@ var logger = require('./logger.js'); +var _ = require('lodash'); +var moment = require('moment'); + exports.getActiveConnections = getActiveConnections; +exports.getActiveNodeList = getActiveNodeList; exports.addNewClient = addNewClient; exports.removeClient = removeClient; @@ -14,6 +18,33 @@ function getActiveConnections() { return clientConnections; } +function getActiveNodeList() { + const now = moment(); + + return _.map(getActiveConnections(), ac => { + let entry = { + node : ac.node, + authenticated : ac.user.isAuthenticated(), + userId : ac.user.userId, + action : _.has(ac, 'currentMenuModule.menuConfig.desc') ? ac.currentMenuModule.menuConfig.desc : 'Unknown', + }; + + // + // There may be a connection, but not a logged in user as of yet + // + if(ac.user.isAuthenticated()) { + entry.userName = ac.user.username; + entry.realName = ac.user.properties.real_name; + entry.location = ac.user.properties.location; + entry.affils = ac.user.properties.affiliation; + + const diff = now.diff(moment(ac.user.properties.last_login_timestamp), 'minutes'); + entry.timeOn = moment.duration(diff, 'minutes'); + } + return entry; + }); +} + function addNewClient(client, clientSock) { var id = client.session.id = clientConnections.push(client) - 1; diff --git a/core/theme.js b/core/theme.js index b87a1ce8..29498434 100644 --- a/core/theme.js +++ b/core/theme.js @@ -209,12 +209,7 @@ function getMergedTheme(menuConfig, promptConfig, theme) { var mergedThemeMenu = mergedTheme[areaName][menuName]; if(_.has(theme, [ 'customization', areaName, menuName ])) { - - if('telnetConnected' === menuName || 'mainMenuLastCallers' === menuName) { - console.log('break me') - } - - var menuTheme = theme.customization[areaName][menuName]; + var menuTheme = theme.customization[areaName][menuName]; // config block is direct assign/overwrite // :TODO: should probably be _.merge() diff --git a/docs/index.md b/docs/index.md index 51e85ffe..c88fd5ea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,9 +8,21 @@ TL;DR? This should get you started... * [Node.js](https://nodejs.org/) version **v0.12.2 or higher** (v4.2+ is recommended) * [io.js](https://iojs.org/) should also work, though I have not yet tested this. * :information_source: It is suggested to use [nvm](https://github.com/creationix/nvm) to manage your Node/io.js installs -* Windows users will need additional dependencies installed for the `npm install` step in order to compile native binaries: - * A recent copy of Visual Studio (Express editions OK) - * Python 2.7.x +* **Windows users will need additional dependencies installed** for the `npm install` step in order to compile native binaries: + * A recent copy of Visual Studio ([Visual Studio Express](https://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx) editions OK) + * [Python](https://www.python.org/downloads/) 2.7.x + +## New to Node +If you're new to Node.js and/or do not care about Node itself and just want to get ENiGMA½ running these steps should get you going on most \*nix type enviornments: + +```bash +curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash +nvm install 4.2.4 +nvm use 4.2.4 +``` + + +If the above completed without errors, you should now have `nvm`, `node`, and `npm` installed and in your environment. ## Clone ```bash @@ -19,6 +31,7 @@ git clone https://github.com/NuSkooler/enigma-bbs.git ## Install Node Modules ```bash +cd enigma-bbs npm install ``` @@ -53,12 +66,15 @@ messages: { ./main.js ``` +ENiGMA½ does not produce much to standard out. See below for tailing the log file to see what's going on. + +### Points of Interest +* Default ports are 8888 (Telnet) and 8889 (SSH) + * Note that on *nix systems port such as telnet/23 are privileged (e.g. require root). See [this SO article](http://stackoverflow.com/questions/16573668/best-practices-when-running-node-js-with-port-80-ubuntu-linode) for some tips on using these ports on your system if desired. +* The first user you create via applying is the SysOp (aka root) +* You may want to tail the logfile with Bunyan: `tail -F ./logs/enigma-bbs.log | ./node_modules/bunyan/bin/bunyan` + # Advanced Installation If you've become convinced you would like a "production" BBS running ENiGMA½ a more advanced installation may be in order. [PM2](https://github.com/Unitech/pm2) is an excellent choice for managing your running ENiGMA½ instances. Additionally, it is suggested that you run as a specific more locked down user (e.g. 'enigma'). - -Some points of interest: -* Default ports are 8888 (Telnet) and 8889 (SSH) -* The first user you create via applying is the SysOp (aka root) -* You may want to tail the logfile with Bunyan: `tail -F ./logs/enigma-bbs.log | ./node_modules/bunyan/bin/bunyan` \ No newline at end of file diff --git a/mods/whos_online.js b/mods/whos_online.js index ad0219d8..6b0ef4c1 100644 --- a/mods/whos_online.js +++ b/mods/whos_online.js @@ -3,7 +3,7 @@ var MenuModule = require('../core/menu_module.js').MenuModule; var ViewController = require('../core/view_controller.js').ViewController; -var getActiveConnections = require('../core/client_connections.js').getActiveConnections; +var getActiveNodeList = require('../core/client_connections.js').getActiveNodeList; var moment = require('moment'); var async = require('async'); @@ -67,60 +67,21 @@ WhosOnlineModule.prototype.mciReady = function(mciData, cb) { function populateList(callback) { var onlineListView = vc.getView(MciCodeIds.OnlineList); - var onlineList = getActiveConnections().slice(0, onlineListView.height); - - var listFormat = self.menuConfig.config.listFormat || '{node} - {username} - {action} - {timeOn}'; - - var now = moment(); - - onlineListView.setItems(_.map(onlineList, function formatOnlineEntry(oe) { - var fmtObj = { - node : oe.node, - userId : oe.user.userId, - userName : oe.user.username, - realName : oe.user.properties.real_name, - timeOn : function getTimeOn() { - var diff = now.diff(moment(oe.user.properties.last_login_timestamp), 'minutes'); - return _.capitalize(moment.duration(diff, 'minutes').humanize()); - }, - action : function getCurrentAction() { - var cmm = oe.currentMenuModule; - if(cmm) { - return cmm.menuConfig.desc || 'Unknown'; - } - return 'Unknown'; - //oe.currentMenuModule.menuConfig.desc || 'Unknown', - }, - location : oe.user.properties.location, - affils : oe.user.properties.affiliation, - }; - try { - return listFormat.format(fmtObj); - } catch(e) { - console.log('Exception caught formatting: ' + e.toString() + ':\n' + JSON.stringify(fmtObj)); + const listFormat = self.menuConfig.config.listFormat || '{node} - {userName} - {action} - {timeOn}'; + const nonAuthUser = self.menuConfig.config.nonAuthUser || 'Logging In'; + const otherUnknown = self.menuConfig.config.otherUnknown || 'N/A'; + const onlineList = getActiveNodeList().slice(0, onlineListView.height); + + onlineListView.setItems(_.map(onlineList, oe => { + if(oe.authenticated) { + oe.timeOn = _.capitalize(oe.timeOn.humanize()); + } else { + [ 'realName', 'location', 'affils', 'timeOn' ].forEach(m => { + oe[m] = otherUnknown; + }); + oe.userName = nonAuthUser; } - /* - return listFormat.format({ - node : oe.node, - userId : oe.user.userId, - userName : oe.user.username, - realName : oe.user.properties.real_name, - timeOn : function getTimeOn() { - var diff = now.diff(moment(oe.user.properties.last_login_timestamp), 'minutes'); - return _.capitalize(moment.duration(diff, 'minutes').humanize()); - }, - action : function getCurrentAction() { - var cmm = oe.currentMenuModule; - if(cmm) { - return cmm.menuConfig.desc || 'Unknown'; - } - return 'Unknown'; - //oe.currentMenuModule.menuConfig.desc || 'Unknown', - }, - location : oe.user.properties.location, - affils : oe.user.properties.affiliation, - }); - */ + return listFormat.format(oe); })); // :TODO: This is a hack until pipe codes are better implemented