From b53867ef93ceec184afbba949df3269c15d44a22 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Thu, 4 Feb 2021 18:37:38 -0800 Subject: [PATCH] Added support for alternative messenging service. --- firebase.js | 6 +++++- meshcentral-config-schema.json | 9 +++++++++ meshuser.js | 3 +++ sample-config-advanced.json | 4 ++++ views/default-mobile.handlebars | 6 ++++++ views/default.handlebars | 27 +++++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) diff --git a/firebase.js b/firebase.js index 08a98341..8c22fb3c 100644 --- a/firebase.js +++ b/firebase.js @@ -197,7 +197,10 @@ module.exports.CreateFirebaseRelay = function (parent, url, key) { obj.connectWebSocket = function () { if (obj.wsclient != null) return; obj.wsclient = new WebSocket(relayUrl.href + (key ? ('?key=' + key) : ''), { rejectUnauthorized: false }) - obj.wsclient.on('open', function () { obj.wsopen = true; }); + obj.wsclient.on('open', function () { + parent.debug('email', 'FBWS-Connected'); + obj.wsopen = true; + }); obj.wsclient.on('message', function (msg) { parent.debug('email', 'FBWS-Data(' + msg.length + '): ' + msg); var data = null; @@ -214,6 +217,7 @@ module.exports.CreateFirebaseRelay = function (parent, url, key) { setTimeout(obj.connectWebSocket, 2000); }); obj.wsclient.on('close', function () { + parent.debug('email', 'FBWS-Disconnected'); obj.wsclient = null; obj.wsopen = false; setTimeout(obj.connectWebSocket, 2000); diff --git a/meshcentral-config-schema.json b/meshcentral-config-schema.json index e7b815e4..107ab8cc 100644 --- a/meshcentral-config-schema.json +++ b/meshcentral-config-schema.json @@ -205,6 +205,15 @@ "footer": { "type": "string", "default": null, "description": "This is a HTML string displayed at the bottom of the web page when a user is logged in." }, "loginfooter": { "type": "string", "default": null, "description": "This is a HTML string displayed at the bottom of the web page when a user is not logged in." }, "guestDeviceSharing": { "type": "boolean", "default": true, "description": "When set to false, the desktop/terminal sharing link feature is not available." }, + "altMessenging": { + "type": "object", + "properties": { + "name": { "type": "string", "description": "Name of the alternative messaging service, for example: \"Jitsi\" " }, + "url": { "type": "string", "description": "URL to the alternative messaging services, for example: \"https://meet.jit.si/myserver-{0}\"" } + }, + "additionalProperties": false, + "required": [ "name", "url" ] + }, "certUrl": { "type": "string", "format": "uri", diff --git a/meshuser.js b/meshuser.js index 39009686..9d01743f 100644 --- a/meshuser.js +++ b/meshuser.js @@ -459,6 +459,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } if (matchingDomains.length > 0) { serverinfo.amtAcmFqdn = matchingDomains; } } + 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 }; } serverinfo.https = true; serverinfo.redirport = args.redirport; @@ -2716,7 +2717,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Create the notification message var notification = { action: 'msg', type: 'notify', id: Math.random(), value: command.msg, title: user.name, icon: 8, userid: user._id, username: user.name }; + if (typeof command.url == 'string') { notification.url = command.url; } if ((typeof command.maxtime == 'number') && (command.maxtime > 0)) { notification.maxtime = command.maxtime; } + if (command.msgid == 11) { notification.value = "Chat Request, Click here to accept."; notification.msgid = 11; } // Chat request // Get the list of sessions for this user var sessions = parent.wssessions[command.userid]; diff --git a/sample-config-advanced.json b/sample-config-advanced.json index 20aaa3b4..80fc6ae1 100644 --- a/sample-config-advanced.json +++ b/sample-config-advanced.json @@ -143,6 +143,10 @@ "_footer": "Twitter", "_loginfooter": "This is a private server.", "_certUrl": "https://192.168.2.106:443/", + "_altMessenging": { + "name": "Jitsi", + "url": "https://meet.jit.si/myserver-{0}" + }, "myServer": { "Backup": false, "Restore": false, diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index c6a72bac..c427eb73 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -1358,6 +1358,7 @@ if (message.id != null) { n.id = message.id; } if (message.nodeid != null) { n.nodeid = message.nodeid; } if (message.tag != null) { n.tag = message.tag; } + if (message.url != null) { n.url = message.url; } if (message.username != null) { n.username = message.username; } if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); @@ -1384,6 +1385,7 @@ var n = { text: message.value, title: message.title, icon: message.icon, titleid: message.titleid, msgid: message.msgid, args: message.args }; if (message.id != null) { n.id = message.id; } if (message.tag != null) { n.tag = message.tag; } + if (message.url != null) { n.url = message.url; } if (message.username != null) { n.username = message.username; } if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); @@ -5171,6 +5173,9 @@ if ((n.tag != null) && n.tag.startsWith('meshmessenger/')) { safeNewWindow('/messenger?id=' + n.tag + '&title=' + encodeURIComponentEx(n.username), n.tag.split('/')[2]); notificationDelete(id); + } else if (n.url != null) { + safeNewWindow(n.url); + notificationDelete(id); } } } @@ -5273,6 +5278,7 @@ } notification.id = n.id; notification.xtag = n.tag; + notification.url = n.url; notification.nodeid = n.nodeid; notification.username = n.username; notification.onclick = function (e) { notificationSelected(e.target.id, true); } diff --git a/views/default.handlebars b/views/default.handlebars index e598b68d..a66e2e76 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2199,6 +2199,7 @@ if (message.id != null) { n.id = message.id; } if (message.nodeid != null) { n.nodeid = message.nodeid; } if (message.tag != null) { n.tag = message.tag; } + if (message.url != null) { n.url = message.url; } if (message.username != null) { n.username = message.username; } if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); @@ -2239,6 +2240,7 @@ var n = { text: message.value, title: message.title, icon: message.icon, titleid: message.titleid, msgid: message.msgid, args: message.args }; if (message.id != null) { n.id = message.id; } if (message.tag != null) { n.tag = message.tag; } + if (message.url != null) { n.url = message.url; } if (message.username != null) { n.username = message.username; } if (typeof message.maxtime == 'number') { n.maxtime = message.maxtime; } addNotification(n); @@ -5978,6 +5980,7 @@ if ((meshrights & 8) && ((connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0)))) { x += ''; } //if ((connectivity & 1) && (meshrights & 8) && (node.agent.id < 5)) { x += ''; } if ((meshrights & 8) && (connectivity & 1) || ((node.pmt == 1) && ((features2 & 2) != 0))) { x += ''; } + if ((serverinfo != null) && (serverinfo.altmessenging != null) && (meshrights & 8) && (connectivity & 1)) { x += ''; } if ((serverinfo.guestdevicesharing !== false) && (node.agent != null) && (node.agent.caps & 3) && (connectivity & 1) && ((meshrights & 0x80008) == 0x80008) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 0x1000) == 0))) { x += ''; } // Custom UI @@ -6312,6 +6315,13 @@ meshserver.send({ action: 'meshmessenger', nodeid: decodeURIComponent(currentNode._id) }); } + function altDeviceChat(e) { + if (xxdialogMode) return; + var url = serverinfo.altmessenging.url.split('{0}').join(currentNode._id.split('/').join('-')); + meshserver.send({ action: 'msg', type: 'openUrl', nodeid: currentNode._id, url: url }); + safeNewWindow(url, 'altmessenger:' + currentNode._id, 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,width=400,height=560'); + } + function deviceToggleBackground() { if (xxdialogMode) return; meshserver.send({ action: 'msg', type: 'deskBackground', nodeid: currentNode._id, op: 1 }); // Toggle desktop background image @@ -11800,6 +11810,7 @@ } function userChat(e, userid, name) { + if (xxdialogMode) return; haltEvent(e); var url = '/messenger?id=meshmessenger/' + userid + '/' + encodeURIComponentEx(userinfo._id) + '&title=' + name; if ((authCookie != null) && (authCookie != '')) { url += '&auth=' + authCookie; } @@ -11808,6 +11819,15 @@ return false; } + function altUserChat(e, userid, name) { + if (xxdialogMode) return; + haltEvent(e); + var url = serverinfo.altmessenging.url.split('{0}').join(userid.split('/').join('-')); + safeNewWindow(url, 'altmessenger:' + userid); + meshserver.send({ action: 'notifyuser', userid: decodeURIComponent(userid), msg: serverinfo.altmessenging.name, msgid: 11, url: url }); + return false; + } + function showSendSMS(userid) { if (xxdialogMode) return; setDialogMode(2, "Send SMS", 3, showSendSMSEx, '', userid); @@ -12712,6 +12732,7 @@ if (!self && (activeSessions > 0)) { x += ''; x += ''; + if ((serverinfo != null) && (serverinfo.altmessenging != null)) { x += ''; } } // Setup the panel @@ -13351,6 +13372,7 @@ } function notificationSelectedEx(n, id) { + console.log(n); if (n.nodeid != null) { if (n.tag == 'desktop') gotoDevice(n.nodeid, 12); // Desktop else if (n.tag == 'terminal') gotoDevice(n.nodeid, 11); // Terminal @@ -13362,6 +13384,9 @@ if ((n.tag != null) && n.tag.startsWith('meshmessenger/')) { safeNewWindow('/messenger?id=' + n.tag + '&title=' + encodeURIComponentEx(n.username), n.tag.split('/')[2]); notificationDelete(id); + } else if (n.url != null) { + safeNewWindow(n.url); + notificationDelete(id); } } } @@ -13389,6 +13414,7 @@ // Add a new notification and play the notification sound function addNotification(n) { + console.log('addNotification', n); // Perform message translation var translatedTitles = [ null, @@ -13464,6 +13490,7 @@ } notification.id = n.id; notification.xtag = n.tag; + notification.url = n.url; notification.nodeid = n.nodeid; notification.username = n.username; notification.onclick = function (e) { notificationSelected(e.target.id, true); }