From 2b4336e2224c8bf8020d192c1cfdf646ec885318 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Tue, 12 May 2020 00:01:42 -0700 Subject: [PATCH] Improved device session notification. --- agents/meshcore.js | 27 +++++++++++++++++++++++++++ meshagent.js | 2 ++ meshcentral.js | 2 +- views/default.handlebars | 11 ++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/agents/meshcore.js b/agents/meshcore.js index 7f66fd55..e291e630 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -304,6 +304,7 @@ function createMeshCore(agent) { var nextTunnelIndex = 1; var amtPolicy = null; var apftunnel = null; + var tunnelUserCount = { terminal: {}, files: {} }; // List of userid->count sessions for terminal and files. // Add to the server event log function MeshServerLog(msg, state) { @@ -1154,6 +1155,12 @@ function createMeshCore(agent) { this.httprequest.tpromise = new prom(function (res, rej) { this._res = res; this._rej = rej; }); this.end = function () { + // Remove the terminal session to the count to update the server + if (this.httprequest.userid != null) { + if (tunnelUserCount.terminal[this.httprequest.userid] != null) { tunnelUserCount.terminal[this.httprequest.userid]--; if (tunnelUserCount.terminal[this.httprequest.userid] <= 0) { delete tunnelUserCount.terminal[this.httprequest.userid]; } } + try { mesh.SendCommand({ action: 'sessions', type: 'terminal', value: tunnelUserCount.terminal }); } catch (ex) { } + } + if (process.platform == 'win32') { // Unpipe the web socket this.unpipe(this.httprequest._term); @@ -1315,6 +1322,12 @@ function createMeshCore(agent) { this.httprequest.tpromise._res(); } + // Add the terminal session to the count to update the server + if (this.httprequest.userid != null) { + if (tunnelUserCount.terminal[this.httprequest.userid] == null) { tunnelUserCount.terminal[this.httprequest.userid] = 1; } else { tunnelUserCount.terminal[this.httprequest.userid]++; } + try { mesh.SendCommand({ action: 'sessions', type: 'terminal', value: tunnelUserCount.terminal }); } catch (ex) { } + } + this.httprequest.tpromise.that = this; this.httprequest.tpromise.then(function () { @@ -1664,6 +1677,20 @@ function createMeshCore(agent) { if (cmd.action == undefined) { return; } //sendConsoleText('CMD: ' + JSON.stringify(cmd)); + // Add the files session to the count to update the server + if (this.httprequest.userid != null) { + if (tunnelUserCount.files[this.httprequest.userid] == null) { tunnelUserCount.files[this.httprequest.userid] = 1; } else { tunnelUserCount.files[this.httprequest.userid]++; } + try { mesh.SendCommand({ action: 'sessions', type: 'files', value: tunnelUserCount.files }); } catch (ex) { } + } + + this.end = function () { + // Remove the files session from the count to update the server + if (this.httprequest.userid != null) { + if (tunnelUserCount.files[this.httprequest.userid] != null) { tunnelUserCount.files[this.httprequest.userid]--; if (tunnelUserCount.files[this.httprequest.userid] <= 0) { delete tunnelUserCount.files[this.httprequest.userid]; } } + try { mesh.SendCommand({ action: 'sessions', type: 'files', value: tunnelUserCount.files }); } catch (ex) { } + } + }; + if ((cmd.path != null) && (process.platform != 'win32') && (cmd.path[0] != '/')) { cmd.path = '/' + cmd.path; } // Add '/' to paths on non-windows //console.log(objToString(cmd, 0, ' ')); switch (cmd.action) { diff --git a/meshagent.js b/meshagent.js index a0bc98e7..6d971542 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1331,6 +1331,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // This is a list of sessions provided by the agent if (obj.sessions == null) { obj.sessions = {}; } if (command.type == 'kvm') { obj.sessions.kvm = command.value; } + else if (command.type == 'terminal') { obj.sessions.terminal = command.value; } + else if (command.type == 'files') { obj.sessions.files = command.value; } obj.updateSessions(); break; } diff --git a/meshcentral.js b/meshcentral.js index 683c092d..309b7d0d 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -129,7 +129,7 @@ function CreateMeshCentralServer(config, args) { try { require('./pass').hash('test', function () { }, 0); } catch (e) { console.log('Old version of node, must upgrade.'); return; } // TODO: Not sure if this test works or not. // Check for invalid arguments - var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'rediraliasport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'listuserids', 'showusergroups', 'shownodes', 'showmeshes', 'showevents', 'showsmbios', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'xinstall', 'xuninstall', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbexportmin', 'dbimport', 'dbmerge', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', 'fastcert', 'swarmport', 'logintoken', 'logintokenkey', 'logintokengen', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore', 'dblistconfigfiles', 'dbshowconfigfile', 'dbpushconfigfiles', 'dbpullconfigfiles', 'dbdeleteconfigfiles', 'vaultpushconfigfiles', 'vaultpullconfigfiles', 'vaultdeleteconfigfiles', 'configkey', 'loadconfigfromdb', 'npmpath', 'memorytracking', 'serverid', 'recordencryptionrecode', 'vault', 'token', 'unsealkey', 'name', 'log', 'dbstats', 'translate', 'createaccount', 'resetaccount', 'pass', 'adminaccount', 'domain', 'email']; + var validArguments = ['_', 'notls', 'user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'rediraliasport', 'cert', 'mpscert', 'deletedomain', 'deletedefaultdomain', 'showall', 'showusers', 'listuserids', 'showusergroups', 'shownodes', 'showmeshes', 'showevents', 'showsmbios', 'showpower', 'clearpower', 'showiplocations', 'help', 'exactports', 'xinstall', 'xuninstall', 'install', 'uninstall', 'start', 'stop', 'restart', 'debug', 'filespath', 'datapath', 'noagentupdate', 'launch', 'noserverbackup', 'mongodb', 'mongodbcol', 'wanonly', 'lanonly', 'nousers', 'mpspass', 'ciralocalfqdn', 'dbexport', 'dbexportmin', 'dbimport', 'dbmerge', 'dbencryptkey', 'selfupdate', 'tlsoffload', 'userallowedip', 'userblockedip', 'swarmallowedip', 'agentallowedip', 'agentblockedip', 'fastcert', 'swarmport', 'logintoken', 'logintokenkey', 'logintokengen', 'mailtokengen', 'admin', 'unadmin', 'sessionkey', 'sessiontime', 'minify', 'minifycore', 'dblistconfigfiles', 'dbshowconfigfile', 'dbpushconfigfiles', 'dbpullconfigfiles', 'dbdeleteconfigfiles', 'vaultpushconfigfiles', 'vaultpullconfigfiles', 'vaultdeleteconfigfiles', 'configkey', 'loadconfigfromdb', 'npmpath', 'memorytracking', 'serverid', 'recordencryptionrecode', 'vault', 'token', 'unsealkey', 'name', 'log', 'dbstats', 'translate', 'createaccount', 'resetaccount', 'pass', 'adminaccount', 'domain', 'email']; for (var arg in obj.args) { obj.args[arg.toLocaleLowerCase()] = obj.args[arg]; if (validArguments.indexOf(arg.toLocaleLowerCase()) == -1) { console.log('Invalid argument "' + arg + '", use --help.'); return; } } if (obj.args.mongodb == true) { console.log('Must specify: --mongodb [connectionstring] \r\nSee https://docs.mongodb.com/manual/reference/connection-string/ for MongoDB connection string.'); return; } for (i in obj.config.settings) { obj.args[i] = obj.config.settings[i]; } // Place all settings into arguments, arguments have already been placed into settings so arguments take precedence. diff --git a/views/default.handlebars b/views/default.handlebars index 10ca0230..1d71e46e 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2643,6 +2643,9 @@ node.pwr = message.event.pwr; node.lastconnect = Date.now(); + // Clear sesssion information if needed + if ((node.conn & 1) == 0) { delete node.sessions; } + // Web page update masterUpdate(1 | 4 | 16); refreshDevice(node._id); @@ -3434,9 +3437,15 @@ } else if (i == 'multidesk') { x += '' + "Remote Desktop" + ''; for (var j in node.sessions.multidesk) { x += addHtmlValue4(getUserName(j), ((node.sessions.multidesk[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.multidesk[j])))); } + } else if (i == 'terminal') { + x += '' + "Terminal" + ''; + for (var j in node.sessions.terminal) { x += addHtmlValue4(getUserName(j), ((node.sessions.terminal[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.terminal[j])))); } + } else if (i == 'files') { + x += '' + "Files" + ''; + for (var j in node.sessions.files) { x += addHtmlValue4(getUserName(j), ((node.sessions.files[j] == 1)?"1 session":nobreak(format("{0} sessions", node.sessions.files[j])))); } } } - if (x != '') setDialogMode(2, "Sessions - " + EscapeHtml(node.name), 1, null, x, 'SESSIONS-' + node._id); + if (x != '') setDialogMode(2, "Sessions" + ' - ' + EscapeHtml(node.name), 1, null, x, 'SESSIONS-' + node._id); } function toggleCollapseGroup(id, id2, type) {