From e7483569e721d754dd369d7ea7c0eb4ae155c1f9 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Mon, 9 Nov 2020 19:40:55 -0700 Subject: [PATCH] Merge --- core/client_connections.js | 3 ++ core/stat_log.js | 6 +++- core/wfc.js | 67 ++++++++++++++++++++++++++++++++++++-- docs/servers/web-server.md | 19 ++++++----- 4 files changed, 82 insertions(+), 13 deletions(-) diff --git a/core/client_connections.js b/core/client_connections.js index d1a6be6e..744f1f2a 100644 --- a/core/client_connections.js +++ b/core/client_connections.js @@ -41,12 +41,15 @@ function getActiveConnectionList(authUsersOnly) { authenticated : ac.user.isAuthenticated(), userId : ac.user.userId, action : _.get(ac, 'currentMenuModule.menuConfig.desc', 'Unknown'), + serverName : ac.session.serverName, + isSecure : ac.session.isSecure, }; // // There may be a connection, but not a logged in user as of yet // if(ac.user.isAuthenticated()) { + entry.text = ac.user.username; entry.userName = ac.user.username; entry.realName = ac.user.properties[UserProps.RealName]; entry.location = ac.user.properties[UserProps.Location]; diff --git a/core/stat_log.js b/core/stat_log.js index af88ff57..5355f0c1 100644 --- a/core/stat_log.js +++ b/core/stat_log.js @@ -109,6 +109,10 @@ class StatLog { getSystemStat(statName) { return this.systemStats[statName]; } + getFriendlySystemStat(statName, defaultValue) { + return (this.getSystemStat(statName) || defaultValue).toLocaleString(); + } + getSystemStatNum(statName) { return parseInt(this.getSystemStat(statName)) || 0; } @@ -220,7 +224,7 @@ class StatLog { sysDb.run( `DELETE FROM system_event_log WHERE id IN( - SELECT id + SELECT id FROM system_event_log WHERE log_name = ? ORDER BY id DESC diff --git a/core/wfc.js b/core/wfc.js index c08b9ffa..6bc066cd 100644 --- a/core/wfc.js +++ b/core/wfc.js @@ -1,6 +1,13 @@ // ENiGMA½ const { MenuModule } = require('./menu_module'); +const { getActiveConnectionList } = require('./client_connections'); +const StatLog = require('./stat_log'); +const SysProps = require('./system_property'); +const { + formatByteSize, formatByteSizeAbbr, +} = require('./string_util'); + // deps const async = require('async'); const _ = require('lodash'); @@ -17,8 +24,8 @@ const FormIds = { const MciViewIds = { main : { - nodeStatus : 0, - quickLogView : 1, + nodeStatus : 1, + quickLogView : 2, customRangeStart : 10, } @@ -35,7 +42,7 @@ exports.getModule = class WaitingForCallerModule extends MenuModule { this.config.acs = this.config.acs || DefaultACS; if (!this.config.acs.includes('SC')) { - this.config.acs = 'SC' + this.config.acs; // secure connection at the very, very least + this.config.acs = 'SC' + this.config.acs; // secure connection at the very least } } @@ -56,6 +63,9 @@ exports.getModule = class WaitingForCallerModule extends MenuModule { // return this.validateMCIByViewIds('main', requiredCodes, callback); return callback(null); }, + (callback) => { + return this._refreshNodeStatus(callback); + } ], err => { return cb(err); @@ -63,5 +73,56 @@ exports.getModule = class WaitingForCallerModule extends MenuModule { ); }); } + + _refreshStats(cb) { + const fileAreaStats = StatLog.getSystemStat(SysProps.FileBaseAreaStats); + const totalFiles = fileAreaStats.totalFiles || 0; + const totalFileBytes = fileAreaStats.totalBytes || 0; + + this.stats = { + // Totals + totalCalls : StatLog.getFriendlySystemStat(SysProps.LoginCount, 0), + totalPosts : StatLog.getFriendlySystemStat(SysProps.MessageTotalCount, 0), + //totalUsers : + totalFiles : totalFiles.toLocaleString(), + totalFileBytes : formatByteSize(totalFileBytes, false), + totalFileBytesAbbr : formatByteSizeAbbr(totalFileBytes), + // :TODO: date, time - formatted as per config.dateTimeFormat and such + // :TODO: Most/All current user status should be predefined MCI + // :TODO: lastCaller + // :TODO: totalMemoryBytes, freeMemoryBytes + // :TODO: CPU info/averages/load + // :TODO: processUptime + // :TODO: 24 HOUR stats - + // calls24Hour, posts24Hour, uploadBytes24Hour, downloadBytes24Hour, ... + // :TODO: totals - most avail from MCI + }; + + return cb(null); + } + + _refreshNodeStatus(cb) { + const nodeStatusView = this.getView('main', MciViewIds.main.nodeStatus); + if (!nodeStatusView) { + return cb(null); + } + + const nodeStatusItems = getActiveConnectionList(false).slice(0, nodeStatusView.height).map(ac => { + // Handle pre-authenticated + if (!ac.authenticated) { + ac.text = ac.username = 'Pre Auth'; + ac.action = 'Logging In'; + } + + return Object.assign(ac, { + timeOn : _.upperFirst(ac.timeOn.humanize()), // make friendly + }); + }); + + nodeStatusView.setItems(nodeStatusItems); + nodeStatusView.redraw(); + + return cb(null); + } }; diff --git a/docs/servers/web-server.md b/docs/servers/web-server.md index 216efb6c..75c7ea18 100644 --- a/docs/servers/web-server.md +++ b/docs/servers/web-server.md @@ -10,18 +10,19 @@ By default the web server is not enabled. To enable it, you will need to at a mi ```hjson contentServers: { - web: { - domain: bbs.yourdomain.com + web: { + domain: bbs.yourdomain.com - http: { - enabled: true - port: 8080 - } - } + http: { + enabled: true + port: 8080 + } + } } ``` The following is a table of all configuration keys available under `contentServers.web`: + | Key | Required | Description | |------|----------|-------------| | `domain` | :+1: | Sets the domain, e.g. `bbs.yourdomain.com`. | @@ -52,9 +53,9 @@ Entries available under `contentServers.web.https`: #### Certificates -If you don't have a TLS certificate for your domain, a good source for a certificate can be [LetsEncrypt](https://letsencrypt.org/) who supplies free and trusted TLS certificates. +If you don't have a TLS certificate for your domain, a good source for a certificate can be [Let's Encrypt](https://letsencrypt.org/) who supplies free and trusted TLS certificates. A common strategy is to place another web server such as [Caddy](https://caddyserver.com/) in front of ENiGMA½ acting as a transparent proxy and TLS termination point. -Keep in mind that the SSL certificate provided by Let's Encrypt's Certbot is by default stored in a privileged location; if your ENIGMA instance is not running as root (which it should not be!), you'll need to copy the SSL certificate somewhere else in order for ENIGMA to use it. +:information_source: Keep in mind that the SSL certificate provided by Let's Encrypt's Certbot is by default stored in a privileged location; if your ENIGMA instance is not running as root (which it should not be!), you'll need to copy the SSL certificate somewhere else in order for ENIGMA to use it. ## Static Routes