Added chat to device support, more fixes.
Ylian Saint-Hilaire committed
Dec 7, 2018 at 16:36 UTC
e236fae42e767be65a85c0abf7c25044b4b70ad5
16 files changed
+157
-68
agents/MeshCmd-signed.exe
Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ
agents/MeshCmd64-signed.exe
Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ
agents/MeshService-signed.exe
Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64-signed.exe
Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshcore.js
+44
-5
@@ -436,14 +436,23 @@ function createMeshCore(agent) {
436
break;
437
}
438
case 'ps': {
439
+ // Return the list of running processes
440
if (data.sessionid) {
441
processManager.getProcesses(function (plist) { mesh.SendCommand({ "action": "msg", "type": "ps", "value": JSON.stringify(plist), "sessionid": data.sessionid }); });
442
}
443
break;
444
}
445
case 'pskill': {
445
- //sendConsoleText(JSON.stringify(data));
446
- try { process.kill(data.value); } catch (e) { sendConsoleText(JSON.stringify(e)); }
446
+ // Kill a process
447
+ if (data.value) {
448
+ try { process.kill(data.value); } catch (e) { sendConsoleText(JSON.stringify(e)); }
449
+ }
450
+ break;
451
+ }
452
+ case 'openUrl': {
453
+ // Open a local web browser and return success/fail
454
+ sendConsoleText('OpenURL: ' + data.url);
455
+ if (data.url) { mesh.SendCommand({ "action": "msg", "type":"openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
456
break;
457
}
458
}
@@ -477,6 +486,12 @@ function createMeshCore(agent) {
486
if (data.title && data.msg) { require('toaster').Toast(data.title, data.msg); }
487
break;
488
}
489
+ case 'openUrl': {
490
+ // Open a local web browser and return success/fail
491
+ sendConsoleText('OpenURL: ' + data.url);
492
+ if (data.url) { mesh.SendCommand({ "action": "openUrl", "url": data.url, "sessionid": data.sessionid, "success": (openUserDesktopUrl(data.url) != null) }); }
493
+ break;
494
+ }
495
}
496
}
497
}
@@ -964,13 +979,32 @@ function createMeshCore(agent) {
979
response.close = function () { sendConsoleText('httprequest.response.close', this.sessionid); consoleHttpRequest = null; }
980
};
981
982
+ // Open a web browser to a specified URL on current user's desktop
983
+ function openUserDesktopUrl(url) {
984
+ var child = null;
985
+ try {
986
+ switch (process.platform) {
987
+ case 'win32':
988
+ child = require('child_process').execFile(process.env['windir'] + '\\system32\\cmd.exe', ["/c", "start", url], { type: childProcess.SpawnTypes.USER });
989
+ break;
990
+ case 'linux':
991
+ child = require('child_process').execFile('/usr/bin/xdg-open', ['xdg-open', url], { type: require('child_process').SpawnTypes.DETACHED, uid: require('user-sessions').consoleUid() });
992
+ break;
993
+ case 'darwin':
994
+ child = require('child_process').execFile('/usr/bin/open', ['open', url], { uid: require('user-sessions').consoleUid() });
995
+ break;
996
+ }
997
+ } catch (ex) { }
998
+ return child;
999
+ }
1000
+
1001
// Process a mesh agent console command
1002
function processConsoleCommand(cmd, args, rights, sessionid) {
1003
try {
1004
var response = null;
1005
switch (cmd) {
1006
case 'help': { // Displays available commands
973
- response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps.';
1007
+ response = 'Available commands: help, info, osinfo,args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps, openurl.';
1008
break;
1009
}
1010
/*
@@ -992,6 +1026,11 @@ function createMeshCore(agent) {
1026
}
1027
break;
1028
*/
1029
+ case 'openurl': {
1030
+ if (args['_'].length != 1) { response = 'Proper usage: openurl (url)'; } // Display usage
1031
+ else { if (openUserDesktopUrl(args['_'][0]) == null) { response = 'Failed.'; } else { response = 'Success.'; } }
1032
+ break;
1033
+ }
1034
case 'users': {
1035
if (meshCoreObj.users == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + meshCoreObj.users.join(', ') + '.'; }
1036
break;
@@ -1520,7 +1559,7 @@ function createMeshCore(agent) {
1559
//amtLms.on('bind', function (map) { });
1560
amtLms.on('notify', function (data, options, str, code) {
1561
if (code == 'iAMT0052-3') {
1523
- kvmGetData();
1562
+ obj.kvmGetData();
1563
} else {
1564
//if (str != null) { sendConsoleText('Intel AMT LMS: ' + str); }
1565
handleAmtNotification(data);
@@ -1597,7 +1636,7 @@ function createMeshCore(agent) {
1636
});
1637
}
1638
1600
- obj.kvmGetData = function(tag) {
1639
+ obj.kvmGetData = function (tag) {
1640
obj.osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(obj.kvmDataGetResponse, tag);
1641
}
1642
agents/modules_meshcore/amt-wsman-duk.js
+3
@@ -88,8 +88,10 @@ function CreateWsmanComm(/*host, port, user, pass, tls, extra*/)
88
obj.digest.http = require('http');
89
}
90
var request = { protocol: (obj.tls == 1 ? 'https:' : 'http:'), method: 'POST', host: obj.host, path: '/wsman', port: obj.port, rejectUnauthorized: false, checkServerIdentity: function (cert) { console.log('checkServerIdentity', JSON.stringify(cert)); } };
91
+
92
var req = obj.digest.request(request);
93
//console.log('Request ' + (obj.RequestCount++));
94
+
95
req.on('error', function (e) { obj.gotNextMessagesError({ status: 600 }, 'error', null, [postdata, callback, tag]); });
96
req.on('response', function (response) {
97
//console.log('Response: ' + response.statusCode);
@@ -105,6 +107,7 @@ function CreateWsmanComm(/*host, port, user, pass, tls, extra*/)
107
108
// Send POST body, this work with binary.
109
req.end(postdata);
110
+
111
obj.ActiveAjaxCount++;
112
return req;
113
}
meshrelay.js
+8
-1
@@ -98,7 +98,14 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
98
if (obj.id.startsWith('meshmessenger/')) {
99
if (obj.user == null) { try { obj.close(); } catch (e) { } return null; }
100
var x = obj.id.split('/'), user1 = x[1] + '/' + x[2] + '/' + x[3], user2 = x[4] + '/' + x[5] + '/' + x[6];
101
- if ((obj.user._id != user1) && (obj.user._id != user2)) { try { obj.close(); } catch (e) { } return null; }
101
+ if ((x[1] != 'user') && (x[4] != 'user')) { try { obj.close(); } catch (e) { } return null; } // MeshMessenger session must have at least one authenticated user
102
+ if ((x[1] == 'user') && (x[4] == 'user')) {
103
+ // If this is a user-to-user session, you must be authenticated to join.
104
+ if ((obj.user._id != user1) && (obj.user._id != user2)) { try { obj.close(); } catch (e) { } return null; }
105
+ } else {
106
+ // If only one side of the session is a user
107
+ // !!!!! TODO: Need to make sure that one of the two sides is the correct user. !!!!!
108
+ }
109
}
110
111
// Validate that the id is valid, we only need to do this on non-authenticated sessions.
meshuser.js
+64
-40
@@ -76,6 +76,40 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
76
ds.on('close', function () { /*delete this.ss.fs._copyStreams[this.ss.id];*/ func(tag); });
77
}
78
79
+ // Route a command to a target node
80
+ function routeCommandToNode(command) {
81
+ if (obj.common.validateString(command.nodeid, 8, 128) == false) return false;
82
+ var splitnodeid = command.nodeid.split('/');
83
+ // Check that we are in the same domain and the user has rights over this node.
84
+ if ((splitnodeid[0] == 'node') && (splitnodeid[1] == domain.id)) {
85
+ // See if the node is connected
86
+ var agent = obj.parent.wsagents[command.nodeid];
87
+ if (agent != null) {
88
+ // Check if we have permission to send a message to that node
89
+ var rights = user.links[agent.dbMeshKey];
90
+ if ((rights != null) && ((rights.rights & 8) || (rights.rights & 256))) { // 8 is remote control permission, 256 is desktop read only
91
+ command.sessionid = ws.sessionId; // Set the session id, required for responses.
92
+ command.rights = rights.rights; // Add user rights flags to the message
93
+ delete command.nodeid; // Remove the nodeid since it's implyed.
94
+ try { agent.send(JSON.stringify(command)); } catch (ex) { }
95
+ }
96
+ } else {
97
+ // Check if a peer server is connected to this agent
98
+ var routing = obj.parent.parent.GetRoutingServerId(command.nodeid, 1); // 1 = MeshAgent routing type
99
+ if (routing != null) {
100
+ // Check if we have permission to send a message to that node
101
+ var rights = user.links[routing.meshid];
102
+ if ((rights != null) && ((rights.rights & 8) || (rights.rights & 256))) { // 8 is remote control permission
103
+ command.fromSessionid = ws.sessionId; // Set the session id, required for responses.
104
+ command.rights = rights.rights; // Add user rights flags to the message
105
+ obj.parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
106
+ }
107
+ }
108
+ }
109
+ }
110
+ return true;
111
+ }
112
+
113
try {
114
// Check if the user is logged in
115
if (user == null) { try { obj.ws.close(); } catch (e) { } return; }
@@ -303,37 +337,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
337
}
338
case 'msg':
339
{
306
- // Route a message.
307
- // This this command has a nodeid, that is the target.
308
- if (obj.common.validateString(command.nodeid, 8, 128) == false) return;
309
- var splitnodeid = command.nodeid.split('/');
310
- // Check that we are in the same domain and the user has rights over this node.
311
- if ((splitnodeid[0] == 'node') && (splitnodeid[1] == domain.id)) {
312
- // See if the node is connected
313
- var agent = obj.parent.wsagents[command.nodeid];
314
- if (agent != null) {
315
- // Check if we have permission to send a message to that node
316
- var rights = user.links[agent.dbMeshKey];
317
- if ((rights != null) && ((rights.rights & 8) || (rights.rights & 256))) { // 8 is remote control permission, 256 is desktop read only
318
- command.sessionid = ws.sessionId; // Set the session id, required for responses.
319
- command.rights = rights.rights; // Add user rights flags to the message
320
- delete command.nodeid; // Remove the nodeid since it's implyed.
321
- try { agent.send(JSON.stringify(command)); } catch (ex) { }
322
- }
323
- } else {
324
- // Check if a peer server is connected to this agent
325
- var routing = obj.parent.parent.GetRoutingServerId(command.nodeid, 1); // 1 = MeshAgent routing type
326
- if (routing != null) {
327
- // Check if we have permission to send a message to that node
328
- var rights = user.links[routing.meshid];
329
- if ((rights != null) && ((rights.rights & 8) || (rights.rights & 256))) { // 8 is remote control permission
330
- command.fromSessionid = ws.sessionId; // Set the session id, required for responses.
331
- command.rights = rights.rights; // Add user rights flags to the message
332
- obj.parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
333
- }
334
- }
335
- }
336
- }
340
+ // Route this command to a target node
341
+ routeCommandToNode(command);
342
break;
343
}
344
case 'events':
@@ -601,19 +606,38 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
606
{
607
// Send a notification message to a user
608
if ((user.siteadmin & 2) == 0) break;
604
- if (obj.common.validateString(command.userid, 1, 2048) == false) break;
609
606
- // Create the notification message
607
- var notification = {
608
- "action": "msg", "type": "notify", "value": "<b>" + user.name + "</b>: Chat Request, Click here to accept.", "userid": user._id, "username": user.name, "tag": 'meshmessenger/' + encodeURIComponent(command.userid) + '/' + encodeURIComponent(user._id) };
610
+ // Setup a user-to-user session
611
+ if (obj.common.validateString(command.userid, 1, 2048)) {
612
610
- // Get the list of sessions for this user
611
- var sessions = obj.parent.wssessions[command.userid];
612
- if (sessions != null) { for (i in sessions) { try { sessions[i].send(JSON.stringify(notification)); } catch (ex) { } } }
613
+ // Create the notification message
614
+ var notification = {
615
+ "action": "msg", "type": "notify", "value": "<b>" + user.name + "</b>: Chat Request, Click here to accept.", "userid": user._id, "username": user.name, "tag": 'meshmessenger/' + encodeURIComponent(command.userid) + '/' + encodeURIComponent(user._id)
616
+ };
617
614
- if (obj.parent.parent.multiServer != null) {
615
- // TODO: Add multi-server support
618
+ // Get the list of sessions for this user
619
+ var sessions = obj.parent.wssessions[command.userid];
620
+ if (sessions != null) { for (i in sessions) { try { sessions[i].send(JSON.stringify(notification)); } catch (ex) { } } }
621
+
622
+ if (obj.parent.parent.multiServer != null) {
623
+ // TODO: Add multi-server support
624
+ }
625
+ }
626
+
627
+ // Setup a user-to-node session
628
+ if (obj.common.validateString(command.nodeid, 1, 2048)) {
629
+ if (obj.args.lanonly == true) { return; } // User-to-device chat is not support in LAN-only mode yet. We need the agent to replace the IP address of the server??
630
+
631
+ // Create the server url
632
+ var httpsPort = ((obj.parent.args.aliasport == null) ? obj.parent.args.port : obj.parent.args.aliasport); // Use HTTPS alias port is specified
633
+ var xdomain = (domain.dns == null) ? domain.id : '';
634
+ if (xdomain != '') xdomain += "/";
635
+ var url = "http" + (obj.args.notls ? '' : 's') + "://" + obj.parent.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "messenger.htm?id=meshmessenger/" + encodeURIComponent(command.nodeid) + "/" + encodeURIComponent(user._id) + "&title=" + encodeURIComponent(user.name);
636
+
637
+ // Create the notification message
638
+ routeCommandToNode({ "action": "openUrl", "nodeid": command.nodeid, "userid": user._id, "username": user.name, "url": url });
639
}
640
+
641
break;
642
}
643
case 'serverversion':
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.2.4-b",
3
+ "version": "0.2.4-e",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
public/images/icon-notify.png
Binary files /dev/null and b/public/images/icon-notify.png differ
public/images/icon-url.png
Binary files /dev/null and b/public/images/icon-url.png differ
public/images/icon-url2.png
Binary files /dev/null and b/public/images/icon-url2.png differ
views/default.handlebars
+22
-6
@@ -447,8 +447,11 @@
447
<td style=padding-top:2px;padding-bottom:2px;background:#C0C0C0>
448
<div style=float:right;text-align:right>
449
<select id=termdisplays style=display:none onchange=deskSetDisplay(event) onclick=deskGetDisplayNumbers(event)></select>
450
- <input id=DeskToastButton type=button value=Toast title="Display a notification message on the remote computer" onkeypress="return false" onkeydown="return false" onclick="deviceToastFunction()">
450
+ <!--<input id=DeskToastButton type=button value=Toast title="Display a notification message on the remote computer" onkeypress="return false" onkeydown="return false" onclick="deviceToastFunction()"> -->
451
<input id=DeskToolsButton type=button value=Tools title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()">
452
+ <span style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open chat window to this computer"><a onclick=deviceChat()><img src='images/icon-chat.png' height=16 width=16 style=padding-top:2px /></a></span>
453
+ <span style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Display a notification on the remote computer"><a onclick=deviceToastFunction()><img src='images/icon-notify.png' height=16 width=16 style=padding-top:2px /></a></span>
454
+ <span style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open a web address on remote computer"><a onclick=deviceUrlFunction()><img src='images/icon-url2.png' height=16 width=16 style=padding-top:2px /></a></span>
455
</div>
456
<div>
457
<select style="margin-left:6px" id="deskkeys">
@@ -3229,7 +3232,6 @@
3232
if (((meshrights & 8) != 0) && (mesh.mtype == 2)) x += '<a style=cursor:pointer onclick=p10showMeshCmdDialog(1,"' + node._id + '") title="Traffic router used to connect to a device thru this server.">Router</a> ';
3233
3234
// RDP link, show this link only of the remote machine is Windows.
3232
- console.log(((connectivity & 1) != 0), (clickOnce == true), (mesh.mtype == 2), ((meshrights & 8) != 0));
3235
if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
3236
if ((node.agent.id > 0) && (node.agent.id < 5)) { x += '<a style=cursor:pointer onclick=p10clickOnce("' + node._id + '","RDP2",3389) title="Requires Microsoft ClickOnce support in your browser.">RDP</a> '; }
3237
if (node.agent.id > 4) {
@@ -3312,9 +3314,24 @@
3314
3315
function showNotesEx(buttons, tag) { meshserver.send({ action: 'setNotes', id: decodeURIComponent(tag), notes: encodeURIComponent(Q('d2devNotes').value) }); }
3316
3317
+ function deviceChat() {
3318
+ if (xxdialogMode) return;
3319
+ window.open('/messenger.htm?id=meshmessenger/' + encodeURIComponent(currentNode._id) + '/' + encodeURIComponent(userinfo._id) + '&title=' + currentNode.name, 'meshmessenger:' + currentNode._id);
3320
+ meshserver.send({ action: 'meshmessenger', nodeid: decodeURIComponent(currentNode._id) });
3321
+ }
3322
+
3323
+ function deviceUrlFunction() {
3324
+ if (xxdialogMode) return;
3325
+ setDialogMode(2, "Open Page on Device", 3, deviceUrlFunctionEx, '<input id=d2devurl placeholder="http://server.com" style=width:100%;overflow-y:scroll></input>');
3326
+ }
3327
+
3328
+ function deviceUrlFunctionEx() {
3329
+ meshserver.send({ action: 'msg', type: 'openUrl', nodeid: currentNode._id, url: Q('d2devurl').value });
3330
+ }
3331
+
3332
function deviceToastFunction() {
3333
if (xxdialogMode) return;
3317
- setDialogMode(2, "Device Toast", 3, deviceToastFunctionEx, '<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>');
3334
+ setDialogMode(2, "Device Notification", 3, deviceToastFunctionEx, '<textarea id=d2devToast style=width:100%;height:80px;resize:none;overflow-y:scroll></textarea>');
3335
}
3336
3337
function deviceToastFunctionEx() {
@@ -5727,11 +5744,10 @@
5744
if (sessions != null) {
5745
gray = '';
5746
if (self) {
5730
- msg2 = "<span style=float:right;margin-top:1px;margin-left:4px;margin-right:4px title=Chat><a onclick=userChat(event,\"" + encodeURIComponent(user._id) + "\",\"" + encodeURIComponent(user.name) + "\")><img src='images/icon-chat.png' height=16 width=16 style=padding-top:2px /></a></span>";
5731
- msg += "<a onclick=showUserAlertDialog(event,\"" + encodeURIComponent(user._id) + "\")>";
5747
+ msg2 = "<span style=float:right;margin-top:1px;margin-right:4px title=Chat><a onclick=userChat(event,\"" + encodeURIComponent(user._id) + "\",\"" + encodeURIComponent(user.name) + "\")><img src='images/icon-chat.png' height=16 width=16 style=padding-top:2px /></a></span>";
5748
+ msg2 += "<span style=float:right;margin-top:1px;margin-left:4px;margin-right:4px title=Notify><a onclick=showUserAlertDialog(event,\"" + encodeURIComponent(user._id) + "\")><img src='images/icon-notify.png' height=16 width=16 style=padding-top:2px /></a></span>";
5749
}
5750
if (sessions == 1) { msg += '1 active session'; } else { msg += sessions + ' active sessions'; }
5734
- if (self) { msg += "</a>"; }
5751
} else {
5752
if (user.login) { msg += '<span title="Last login: ' + new Date(user.login).toLocaleString() + '">' + new Date(user.login).toLocaleDateString() + '</span>'; }
5753
}
webserver.js
+15
-15
@@ -755,14 +755,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
755
if (obj.args.minify && !req.query.nominify) {
756
// Try to server the minified version if we can.
757
try {
758
- res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/default-mobile-min' : 'views/default-min'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, webcerthash: new Buffer(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer });
758
+ res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/default-mobile-min' : 'views/default-min'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, webcerthash: new Buffer(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer });
759
} catch (ex) {
760
// In case of an exception, serve the non-minified version.
761
- res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/default-mobile' : 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, webcerthash: new Buffer(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer });
761
+ res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/default-mobile' : 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, webcerthash: new Buffer(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer });
762
}
763
} else {
764
// Serve non-minified version of web pages.
765
- res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/default-mobile' : 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, webcerthash: new Buffer(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer });
765
+ res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/default-mobile' : 'views/default'), { viewmode: viewmode, currentNode: currentNode, logoutControl: logoutcontrol, title: domain.title, title2: domain.title2, domainurl: domain.url, domain: domain.id, debuglevel: parent.debugLevel, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, noServerBackup: (args.noserverbackup == 1 ? 1 : 0), features: features, sessiontime: args.sessiontime, mpspass: args.mpspass, webcerthash: new Buffer(obj.webCertificateFullHashs[domain.id], 'binary').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'), footer: (domain.footer == null) ? '' : domain.footer });
766
}
767
} else {
768
// Send back the login application
@@ -775,18 +775,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
775
if (obj.args.minify && !req.query.nominify) {
776
// Try to server the minified version if we can.
777
try {
778
- res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile-min' : 'views/login-min'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, sessiontime: args.sessiontime, footer: (domain.footer == null) ? '' : domain.footer });
778
+ res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile-min' : 'views/login-min'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, sessiontime: args.sessiontime, footer: (domain.footer == null) ? '' : domain.footer });
779
} catch (ex) {
780
// In case of an exception, serve the non-minified version.
781
- res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, sessiontime: args.sessiontime, footer: (domain.footer == null) ? '' : domain.footer });
781
+ res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, sessiontime: args.sessiontime, footer: (domain.footer == null) ? '' : domain.footer });
782
}
783
} else {
784
// Serve non-minified version of web pages.
785
- res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, sessiontime: args.sessiontime, footer: (domain.footer == null) ? '' : domain.footer });
785
+ res.render(obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, sessiontime: args.sessiontime, footer: (domain.footer == null) ? '' : domain.footer });
786
}
787
788
/*
789
- var xoptions = { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, footer: (domain.footer == null) ? '' : domain.footer };
789
+ var xoptions = { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, footer: (domain.footer == null) ? '' : domain.footer };
790
var xpath = obj.path.join(__dirname, isMobileBrowser(req) ? 'views/login-mobile' : 'views/login');
791
console.log('Render...');
792
res.render(xpath, xoptions, function (err, html) {
@@ -1272,8 +1272,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1272
ws.on('error', function (err) { console.log('WEBSERVER WSERR2: ' + err); });
1273
1274
// If the web socket is closed, close the associated TCP connection.
1275
- ws.on('close', function (req) {
1276
- Debug(1, 'Closing relay web socket connection to ' + ws.upgradeReq.query.host + '.');
1275
+ ws.on('close', function () {
1276
+ Debug(1, 'Closing relay web socket connection to ' + req.query.host + '.');
1277
if (ws.forwardclient) { try { ws.forwardclient.destroy(); } catch (e) { } }
1278
});
1279
@@ -1550,7 +1550,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1550
var xdomain = (domain.dns == null) ? domain.id : '';
1551
if (xdomain != '') xdomain += "/";
1552
var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + meshidhex + "\r\nServerID=" + serveridhex + "\r\n";
1553
- if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
1553
+ if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
1554
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
1555
if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; }
1556
@@ -1612,7 +1612,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1612
};
1613
if (user != null) { meshaction.username = user.name; }
1614
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
1615
- if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
1615
+ if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + obj.getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
1616
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename=meshaction.txt' });
1617
res.send(JSON.stringify(meshaction, null, ' '));
1618
});
@@ -1627,7 +1627,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1627
};
1628
if (user != null) { meshaction.username = user.name; }
1629
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
1630
- if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
1630
+ if (obj.args.lanonly != true) { meshaction.serverUrl = ((obj.args.notls == true) ? 'ws://' : 'wss://') + obj.getWebServerName(domain) + ':' + httpsPort + '/' + ((domain.id == '') ? '' : ('/' + domain.id)) + 'meshrelay.ashx'; }
1631
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/plain', 'Content-Disposition': 'attachment; filename=meshaction.txt' });
1632
res.send(JSON.stringify(meshaction, null, ' '));
1633
} else {
@@ -1650,7 +1650,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1650
};
1651
1652
// Get the web server hostname. This may change if using a domain with a DNS name.
1653
- function getWebServerName(domain) {
1653
+ obj.getWebServerName = function(domain) {
1654
if (domain.dns != null) return domain.dns;
1655
return obj.certificates.CommonName;
1656
}
@@ -1688,7 +1688,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1688
var xdomain = (domain.dns == null) ? domain.id : '';
1689
if (xdomain != '') xdomain += "/";
1690
var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + meshidhex + "\r\nServerID=" + serveridhex + "\r\n";
1691
- if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
1691
+ if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
1692
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
1693
if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; }
1694
@@ -1769,7 +1769,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1769
if (xdomain != '') xdomain += "/";
1770
var meshsettings = "MeshName=" + mesh.name + "\r\nMeshType=" + mesh.mtype + "\r\nMeshID=0x" + meshidhex + "\r\nServerID=" + serveridhex + "\r\n";
1771
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
1772
- if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
1772
+ if (obj.args.lanonly != true) { meshsettings += "MeshServer=ws" + (obj.args.notls ? '' : 's') + "://" + obj.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "agent.ashx\r\n"; } else { meshsettings += "MeshServer=local"; }
1773
if (req.query.tag != null) { meshsettings += "Tag=" + req.query.tag + "\r\n"; }
1774
if ((req.query.installflags != null) && (req.query.installflags != 0)) { meshsettings += "InstallFlags=" + req.query.installflags + "\r\n"; }
1775