Alternate messaging system improvements (#4274)

Ylian Saint-Hilaire committed Jul 15, 2022 at 14:23 UTC ea977d8c0d67ec83f524f780f53cbf2f27fe7304
4 files changed +91 -47
meshcentral-config-schema.json
+12 -8
@@ -395,14 +395,18 @@
395 }
396 }
397 },
398 - "altMessenging": {
399 - "type": "object",
400 - "properties": {
401 - "name": { "type": "string", "description": "Name of the alternative messaging service, for example: \"Jitsi\" " },
402 - "url": { "type": "string", "description": "URL to the alternative messaging services, for example: \"https://meet.jit.si/myserver-{0}\"" },
403 - "localurl": { "type": "string", "description": "If specified, this is the URL that is used on the administrator side, for example: \"https://meet.jit.si/myserver-{0}\"" }
404 - },
405 - "required": [ "name", "url" ]
398 + "altMessenging": {
399 + "type": "array",
400 + "items": {
401 + "type": "object",
402 + "properties": {
403 + "name": { "type": "string", "description": "Name of the alternative messaging service, for example: \"Jitsi\" " },
404 + "url": { "type": "string", "description": "URL to the alternative messaging services, for example: \"https://meet.jit.si/myserver-{0}\", for a device {0}, {1}, {2}, {3} is the device id. For a user, {0} is the userid, {1} is full userid with dashes, {2} is real name with no spaces, {3} is real name with dash instead of spaces." },
405 + "localurl": { "type": "string", "description": "If specified, this is the URL that is used on the administrator side, for example: \"https://meet.jit.si/myserver-{0}\", for a device {0}, {1}, {2}, {3} is the device id. For a user, {0} is the userid, {1} is full userid with dashes, {2} is real name with no spaces, {3} is real name with dash instead of spaces." },
406 + "type": { "type": "string", "enum": [null, "user", "device"], "default": null, "description": "Indicate if this button should be shown in the user or device type. If obmitted, it will be displayed in both." }
407 + },
408 + "required": [ "name", "url" ]
409 + }
410 },
411 "deviceMeshRouterLinks": {
412 "rdp": { "type": "boolean", "default": true, "description": "Display a RDP link in the device tab when supported." },
meshuser.js
+2 -2
@@ -554,9 +554,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
554 }
555 if (matchingDomains.length > 0) { serverinfo.amtAcmFqdn = matchingDomains; }
556 }
557 - if ((typeof domain.altmessenging == 'object') && (typeof domain.altmessenging.name == 'string') && (typeof domain.altmessenging.url == 'string')) { serverinfo.altmessenging = [{ name: domain.altmessenging.name, url: domain.altmessenging.url, localurl: domain.altmessenging.localurl }]; }
557 if (typeof domain.devicemeshrouterlinks == 'object') { serverinfo.devicemeshrouterlinks = domain.devicemeshrouterlinks; }
559 - if (Array.isArray(domain.altmessenging)) { serverinfo.altmessenging = []; for (var i in domain.altmessenging) { if ((typeof domain.altmessenging[i] == 'object') && (typeof domain.altmessenging[i].name == 'string') && (typeof domain.altmessenging[i].url == 'string')) { serverinfo.altmessenging.push({ name: domain.altmessenging[i].name, url: domain.altmessenging[i].url }); } } }
558 + if ((typeof domain.altmessenging == 'object') && (typeof domain.altmessenging.name == 'string') && (typeof domain.altmessenging.url == 'string')) { serverinfo.altmessenging = [{ name: domain.altmessenging.name, url: domain.altmessenging.url, localurl: domain.altmessenging.localurl, type: domain.altmessenging.type }]; }
559 + if (Array.isArray(domain.altmessenging)) { serverinfo.altmessenging = []; for (var i in domain.altmessenging) { if ((typeof domain.altmessenging[i] == 'object') && (typeof domain.altmessenging[i].name == 'string') && (typeof domain.altmessenging[i].url == 'string')) { serverinfo.altmessenging.push({ name: domain.altmessenging[i].name, url: domain.altmessenging[i].url, type: domain.altmessenging[i].type }); } } }
560 serverinfo.https = true;
561 serverinfo.redirport = args.redirport;
562 if (parent.parent.webpush != null) { serverinfo.vapidpublickey = parent.parent.webpush.vapidPublicKey; } // Web push public key
sample-config-advanced.json
+50 -32
@@ -10,7 +10,7 @@
10 "_WANonly": true,
11 "_LANonly": true,
12 "_maintenanceMode": true,
13 - "_certificatePrivateKeyPassword": ["password1", "password2"],
13 + "_certificatePrivateKeyPassword": [ "password1", "password2" ],
14 "_sessionTime": 60,
15 "_sessionKey": "MyReallySecretPassword1",
16 "_sessionSameSite": "strict",
@@ -83,9 +83,9 @@
83 "_agentAllowedIP": "192.168.0.100/24",
84 "_agentBlockedIP": "127.0.0.1,::1",
85 "_authLog": "c:\\temp\\auth.log",
86 - "_InterUserMessaging": ["user//admin"],
87 - "_manageAllDeviceGroups": ["user//admin"],
88 - "_manageCrossDomain": ["user//admin"],
86 + "_InterUserMessaging": [ "user//admin" ],
87 + "_manageAllDeviceGroups": [ "user//admin" ],
88 + "_manageCrossDomain": [ "user//admin" ],
89 "_localDiscovery": {
90 "name": "Local server name",
91 "info": "Information about this server"
@@ -146,7 +146,10 @@
146 "count": 10,
147 "coolofftime": 10
148 },
149 - "watchDog": { "interval": 100, "timeout": 400 },
149 + "watchDog": {
150 + "interval": 100,
151 + "timeout": 400
152 + },
153 "_AmtProvisioningServer": {
154 "port": 9971,
155 "deviceGroup": "mesh//xxxxxxxxxxxxxxxxxxxxx",
@@ -179,15 +182,15 @@
182 "_nightMode": 1,
183 "_userQuota": 1048576,
184 "_meshQuota": 248576,
182 - "_loginKey": ["abc", "123"],
183 - "_agentKey": ["abc", "123"],
185 + "_loginKey": [ "abc", "123" ],
186 + "_agentKey": [ "abc", "123" ],
187 "_ipkvm": false,
188 "minify": true,
189 "_newAccounts": true,
187 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
190 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
191 "_userNameIsEmail": true,
189 - "_newAccountEmailDomains": ["sample.com"],
190 - "_newAccountsRights": ["nonewgroups", "notools"],
192 + "_newAccountEmailDomains": [ "sample.com" ],
193 + "_newAccountsRights": [ "nonewgroups", "notools" ],
194 "_welcomeText": "Sample Text on Login Page.",
195 "_welcomePicture": "mainwelcome.jpg",
196 "_welcomePictureFullScreen": false,
@@ -202,13 +205,23 @@
205 "_AutoRemoveInactiveDevices": 37,
206 "_DeviceSearchBarServerAndClientName": false,
207 "_agentSelfGuestSharing": {
205 - "expire": 120
206 - },
207 - "_certUrl": "https://192.168.2.106:443/",
208 - "_altMessenging": {
209 - "name": "Jitsi",
210 - "url": "https://meet.jit.si/myserver-{0}"
208 + "expire": 120
209 },
210 + "_certUrl": "https://192.168.2.106:443/",
211 + "_altMessenging": [
212 + {
213 + "name": "Jitsi",
214 + "url": "https://meet.jit.si/myserver-{0}",
215 + "localurl": "https://meet.jit.si/myserver-local-{0}",
216 + "type": "device"
217 + },
218 + {
219 + "name": "Jitsi",
220 + "url": "https://meet.jit.si/myserver-{0}-{1}-{2}-{3}",
221 + "localurl": "https://meet.jit.si/myserver-local-{0}-{1}-{2}-{3}",
222 + "type": "user"
223 + }
224 + ],
225 "_deviceMeshRouterLinks": {
226 "rdp": true,
227 "ssh": true,
@@ -219,7 +232,7 @@
232 "protocol": "http",
233 "port": 80,
234 "_ip": "192.168.1.100",
222 - "_filter": ["mesh/(domainid)/(meshid)", "node/(domainid)/(nodeid)"]
235 + "_filter": [ "mesh/(domainid)/(meshid)", "node/(domainid)/(nodeid)" ]
236 },
237 {
238 "name": "HTTPS",
@@ -364,7 +377,12 @@
377 }
378 },
379 "_amtManager": {
367 - "adminAccounts": [{ "user": "admin", "pass": "MyP@ssw0rd" }],
380 + "adminAccounts": [
381 + {
382 + "user": "admin",
383 + "pass": "MyP@ssw0rd"
384 + }
385 + ],
386 "environmentDetection": [
387 "domain1.com",
388 "domain2.com",
@@ -393,8 +411,8 @@
411 "Strict-Transport-Security": "max-age=360000",
412 "x-frame-options": "SAMEORIGIN"
413 },
396 - "_agentConfig": ["webSocketMaskOverride=1", "coreDumpEnabled=1"],
397 - "_assistantConfig": ["disableUpdate=1"],
414 + "_agentConfig": [ "webSocketMaskOverride=1", "coreDumpEnabled=1" ],
415 + "_assistantConfig": [ "disableUpdate=1" ],
416 "_sessionRecording": {
417 "_onlySelectedUsers": true,
418 "_onlySelectedUserGroups": true,
@@ -405,42 +423,42 @@
423 "_maxRecordingDays": 15,
424 "_maxRecordingSizeMegabytes": 3,
425 "__protocols__": "Is an array: 1 = Terminal, 2 = Desktop, 5 = Files, 100 = Intel AMT WSMAN, 101 = Intel AMT Redirection, 200 = Messenger",
408 - "protocols": [1, 2, 101]
426 + "protocols": [ 1, 2, 101 ]
427 },
428 "_authStrategies": {
429 "__comment__": "This section is used to allow users to login using other accounts. You will need to get an API key from the services and register callback URL's",
430 "twitter": {
431 "_callbackurl": "https://server/auth-twitter-callback",
432 "newAccounts": true,
415 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
433 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
434 "clientid": "xxxxxxxxxxxxxxxxxxxxxxx",
435 "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
436 },
437 "google": {
438 "_callbackurl": "https://server/auth-google-callback",
439 "newAccounts": true,
422 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
440 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
441 "clientid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com",
442 "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxx"
443 },
444 "github": {
445 "_callbackurl": "https://server/auth-github-callback",
446 "newAccounts": true,
429 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
447 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
448 "clientid": "xxxxxxxxxxxxxxxxxxxxxxx",
449 "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
450 },
451 "reddit": {
452 "_callbackurl": "https://server/auth-reddit-callback",
453 "newAccounts": true,
436 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
454 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
455 "clientid": "xxxxxxxxxxxxxxxxxxxxxxx",
456 "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
457 },
458 "azure": {
459 "_callbackurl": "https://server/auth-azure-callback",
460 "newAccounts": true,
443 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
461 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
462 "clientid": "00000000-0000-0000-0000-000000000000",
463 "clientsecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
464 "tenantid": "00000000-0000-0000-0000-000000000000"
@@ -448,7 +466,7 @@
466 "jumpcloud": {
467 "_callbackurl": "https://server/auth-jumpcloud-callback",
468 "newAccounts": true,
451 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
469 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
470 "entityid": "meshcentral",
471 "idpurl": "https://sso.jumpcloud.com/saml2/saml2",
472 "cert": "jumpcloud-saml.pem"
@@ -457,8 +475,8 @@
475 "_callbackurl": "https://server/auth-saml-callback",
476 "_disableRequestedAuthnContext": true,
477 "newAccounts": true,
460 - "_newAccountsUserGroups": ["ugrp//xxxxxxxxxxxxxxxxx"],
461 - "_newAccountsRights": ["nonewgroups", "notools"],
478 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
479 + "_newAccountsRights": [ "nonewgroups", "notools" ],
480 "entityid": "meshcentral",
481 "idpurl": "https://server/saml2",
482 "cert": "saml.pem"
@@ -494,7 +512,7 @@
512 "uid": "anneonyme",
513 "mail": "anneonyme@example.com",
514 "email": "anneonyme@example.com",
497 - "otherMail": ["other.anneonyme@example.com", "anneonyme@example.com"]
515 + "otherMail": [ "other.anneonyme@example.com", "anneonyme@example.com" ]
516 },
517 "so": {
518 "displayName": "Sticker Sophie",
@@ -502,7 +520,7 @@
520 "uid": "ssticker",
521 "mail": "ssticker@example.com",
522 "email": "ssticker@example.com",
505 - "otherMail": ["other.ssticker@example.com", "ssticker@example.com"]
523 + "otherMail": [ "other.ssticker@example.com", "ssticker@example.com" ]
524 }
525 },
526 "__LDAPOptions": {
@@ -551,7 +569,7 @@
569 "_sendmail": {
570 "newline": "unix",
571 "path": "/usr/sbin/sendmail",
554 - "_args": ["-f", "foo@example.com"]
572 + "_args": [ "-f", "foo@example.com" ]
573 },
574 "_sms": {
575 "provider": "twilio",
views/default.handlebars
+27 -5
@@ -7144,7 +7144,12 @@
7144 //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += '<input type=button value=Toast title="' + "Display a text message of the remote device" + '" onclick=deviceToastFunction() />'; }
7145 if ((meshrights & 8) && (connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0))) { x += '<input type=button value="' + "Chat" + '" title="' + "Open chat window to this computer" + '" onclick=deviceChat(event) />'; }
7146 if ((serverinfo != null) && (serverinfo.altmessenging != null) && (meshrights & 8) && (connectivity & 1)) {
7147 - for (var i in serverinfo.altmessenging) { x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altDeviceChat(event,' + i + ') />'; }
7147 + for (var i in serverinfo.altmessenging) {
7148 + var am = serverinfo.altmessenging[i];
7149 + if ((am.type == null) || (am.type == 'device')) {
7150 + x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altDeviceChat(event,' + i + ') />';
7151 + }
7152 + }
7153 }
7154 if ((serverinfo.guestdevicesharing !== false) && (node.agent != null) && (node.agent.caps & 3) && (connectivity & 1) && ((meshrights & 0x80008) == 0x80008) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 0x1000) == 0))) {
7155 x += '<input type=button value="' + "Share" + '" title="' + "Create a link to share this device with a guest" + '" onclick=showShareDevice() />';
@@ -7633,9 +7638,9 @@
7638
7639 function altDeviceChat(e, i) {
7640 if (xxdialogMode) return;
7636 - var url = serverinfo.altmessenging[i].url.split('{0}').join(currentNode._id.split('/').join('-'));
7641 + var url = serverinfo.altmessenging[i].url.split('{0}').join(currentNode._id.split('/')[2]).split('{1}').join(currentNode._id.split('/')[2]).split('{2}').join(currentNode._id.split('/')[2]).split('{3}').join(currentNode._id.split('/')[2]);
7642 var localurl = url;
7638 - if (typeof serverinfo.altmessenging[i].localurl == 'string') { localurl = serverinfo.altmessenging[i].localurl.split('{0}').join(currentNode._id.split('/').join('-')); }
7643 + if (typeof serverinfo.altmessenging[i].localurl == 'string') { localurl = serverinfo.altmessenging[i].localurl.split('{0}').join(currentNode._id.split('/')[2]).split('{1}').join(currentNode._id.split('/')[2]).split('{2}').join(currentNode._id.split('/')[2]).split('{3}').join(currentNode._id.split('/')[2]); }
7644 if (url != '') { meshserver.send({ action: 'msg', type: 'openUrl', nodeid: currentNode._id, url: url }); }
7645 if (localurl != '') { safeNewWindow(localurl, 'altmessenger:' + currentNode._id, 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=400,height=560'); }
7646 }
@@ -14429,7 +14434,17 @@
14434 function altUserChat(e, userid, name, i) {
14435 if (xxdialogMode) return;
14436 haltEvent(e);
14432 - var url = serverinfo.altmessenging[i].url.split('{0}').join(userid.split('/').join('-'));
14437 + var url = serverinfo.altmessenging[i].url;
14438 + var ruserid = decodeURIComponent(userid);
14439 + var userid1 = encodeURIComponentEx(ruserid.split('/')[2]); // userid
14440 + var userid2 = encodeURIComponentEx(ruserid.split('/').join('-')); // user-domain-userid
14441 + var userid3 = userid1, userid4 = userid2;
14442 + var ruser = users[ruserid];
14443 + if ((ruser != null) && (ruser.realname != null)) {
14444 + userid3 = encodeURIComponentEx(ruser.realname.split(' ').join('')); // real name with no empty spaces
14445 + userid4 = encodeURIComponentEx(ruser.realname.split(' ').join('-')); // real name with - instead of spaces
14446 + }
14447 + url = url.split('{0}').join(userid1).split('{1}').join(userid2).split('{2}').join(userid3).split('{3}').join(userid4);
14448 if (urlargs.key) { url += '&key=' + urlargs.key; }
14449 safeNewWindow(url, 'altmessenger:' + userid);
14450 meshserver.send({ action: 'notifyuser', userid: decodeURIComponent(userid), msg: serverinfo.altmessenging[i].name, msgid: 11, url: url });
@@ -15429,7 +15444,14 @@
15444 if (!self && ((activeSessions > 0) || ((features2 & 8) && (user.webpush)))) {
15445 x += '<input type=button value="' + "Notify" + '" title="' + "Send user notification" + '" onclick=showUserAlertDialog(event,"' + encodeURIComponentEx(user._id) + '") />';
15446 x += '<input type=button value="' + "Chat" + '" title="' + "Chat" + '" onclick=userChat(event,"' + encodeURIComponentEx(user._id) + '","' + encodeURIComponentEx(user.name) + '") />';
15432 - if ((activeSessions > 0) && (serverinfo != null) && (serverinfo.altmessenging != null)) { for (var i in serverinfo.altmessenging) { x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altUserChat(event,"' + encodeURIComponentEx(user._id) + '","' + encodeURIComponentEx(user.name) + '",' + i + ') />'; } }
15447 + if ((activeSessions > 0) && (serverinfo != null) && (serverinfo.altmessenging != null)) {
15448 + for (var i in serverinfo.altmessenging) {
15449 + var am = serverinfo.altmessenging[i];
15450 + if ((am.type == null) || (am.type == 'user')) {
15451 + x += '<input type=button value="' + EscapeHtml(am.name) + '" onclick=altUserChat(event,"' + encodeURIComponentEx(user._id) + '","' + encodeURIComponentEx(user.name) + '",' + i + ') />';
15452 + }
15453 + }
15454 + }
15455 }
15456
15457 // Setup the panel