From e6f24582bdb0e601be800d98a75d63ee881b2f1f Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 22 Feb 2021 16:54:30 -0800 Subject: [PATCH] Improved Android push messaging token handling. --- db.js | 12 ++---------- meshagent.js | 7 ++++++- meshcentral.js | 1 + meshuser.js | 1 + views/default-mobile.handlebars | 1 + views/default.handlebars | 1 + webserver.js | 26 ++++++++++++++++++++++++++ 7 files changed, 38 insertions(+), 11 deletions(-) diff --git a/db.js b/db.js index 15f1fa44..eb084f90 100644 --- a/db.js +++ b/db.js @@ -1755,11 +1755,7 @@ module.exports.CreateDB = function (parent, func) { function dbNodeChange(nodeChange, added) { common.unEscapeLinksFieldName(nodeChange.fullDocument); const node = performTypedRecordDecrypt([nodeChange.fullDocument])[0]; - if (node.intelamt != null) { // Remove the Intel AMT password and MPS password before eventing this. - if (node.intelamt.pass != null) { node.intelamt.pass = 1; } - if (node.intelamt.mpspass != null) { node.intelamt.mpspass = 1; } - } - parent.DispatchEvent(['*', node.meshid], obj, { etype: 'node', action: (added ? 'addnode' : 'changenode'), node: node, nodeid: node._id, domain: node.domain, nolog: 1 }); + parent.DispatchEvent(['*', node.meshid], obj, { etype: 'node', action: (added ? 'addnode' : 'changenode'), node: parent.webserver.CloneSafeNode(node), nodeid: node._id, domain: node.domain, nolog: 1 }); } // Called when a device group has changed @@ -1779,11 +1775,7 @@ module.exports.CreateDB = function (parent, func) { mesh.nolog = 1; delete mesh.type; delete mesh._id; - if ((mesh.amt != null) && (mesh.amt.password != null)) { - mesh.amt = Object.assign({}, mesh.amt); // Shallow clone - if (mesh.amt.password != null) { mesh.amt.password = 1; } // Remove the Intel AMT password if present - } - parent.DispatchEvent(['*', mesh.meshid], obj, mesh); + parent.DispatchEvent(['*', mesh.meshid], obj, parent.webserver.CloneSafeMesh(mesh)); } // Called when a user account has changed diff --git a/meshagent.js b/meshagent.js index 1040ceea..a5069948 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1584,7 +1584,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { } // Push Messaging Token - if ((command.pmt != null) && (typeof command.pmt == 'string') && (device.pmt != command.pmt)) { device.pmt = command.pmt; change = 1; } // Don't save this as an event to the db. + if ((command.pmt != null) && (typeof command.pmt == 'string') && (device.pmt != command.pmt)) { + if (typeof device.pmt == 'string') { db.Remove('pmt_' + device.pmt); } + device.pmt = command.pmt; + change = 1; // Don't save this change as an event to the db, so no log=1. + parent.removePmtFromAllOtherNodes(device); // We need to make sure to remove this push messaging token from any other device on this server, all domains included. + } if ((command.users != null) && (Array.isArray(command.users)) && (device.users != command.users)) { device.users = command.users; change = 1; } // Don't save this to the db. if ((mesh.mtype == 2) && (!args.wanonly)) { diff --git a/meshcentral.js b/meshcentral.js index 6aa3b6a8..5ef6ccf6 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -821,6 +821,7 @@ function CreateMeshCentralServer(config, args) { if (db.RemoveSMBIOS) { db.RemoveSMBIOS(node._id); } // Remove SMBios data db.RemoveAllNodeEvents(node._id); // Remove all events for this node db.removeAllPowerEventsForNode(node._id); // Remove all power events for this node + if (typeof node.pmt == 'string') { db.Remove('pmt_' + node.pmt); } // Remove Push Messaging Token db.Get('ra' + node._id, function (err, nodes) { if ((nodes != null) && (nodes.length == 1)) { db.Remove('da' + nodes[0].daid); } // Remove diagnostic agent to real agent link db.Remove('ra' + node._id); // Remove real agent to diagnostic agent link diff --git a/meshuser.js b/meshuser.js index 5b640d33..ccaebda6 100644 --- a/meshuser.js +++ b/meshuser.js @@ -3683,6 +3683,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (db.RemoveSMBIOS) { db.RemoveSMBIOS(node._id); } // Remove SMBios data db.RemoveAllNodeEvents(node._id); // Remove all events for this node db.removeAllPowerEventsForNode(node._id); // Remove all power events for this node + if (typeof node.pmt == 'string') { db.Remove('pmt_' + node.pmt); } // Remove Push Messaging Token db.Get('ra' + node._id, function (err, nodes) { if ((nodes != null) && (nodes.length == 1)) { db.Remove('da' + nodes[0].daid); } // Remove diagnostic agent to real agent link db.Remove('ra' + node._id); // Remove real agent to diagnostic agent link diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index 2089ab76..6b4e0180 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -1764,6 +1764,7 @@ node.userloc = message.event.node.userloc; node.rdpport = message.event.node.rdpport; node.consent = message.event.node.consent; + node.pmt = message.event.node.pmt; if (message.event.node.agent != null) { if (node.agent == null) node.agent = {}; if (message.event.node.agent.ver != null) { node.agent.ver = message.event.node.agent.ver; } diff --git a/views/default.handlebars b/views/default.handlebars index 1309a16b..697d42b3 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2884,6 +2884,7 @@ node.rdpport = message.event.node.rdpport; node.rfbport = message.event.node.rfbport; node.consent = message.event.node.consent; + node.pmt = message.event.node.pmt; if (message.event.node.links != null) { node.links = message.event.node.links; } else { delete node.links; } if (message.event.node.agent != null) { if (node.agent == null) node.agent = {}; diff --git a/webserver.js b/webserver.js index 5339b0ed..aa5008f2 100644 --- a/webserver.js +++ b/webserver.js @@ -6754,6 +6754,32 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { } + // Insure exclusivity of a push messaging token for Android device + obj.removePmtFromAllOtherNodes = function (node) { + if (typeof node.pmt != 'string') return; + db.Get('pmt_' + node.pmt, function (err, docs) { + if ((err == null) && (docs.length == 1)) { + var oldNodeId = docs[0].nodeid; + db.Get(oldNodeId, function (nerr, ndocs) { + if ((nerr == null) && (ndocs.length == 1)) { + var oldNode = ndocs[0]; + if (oldNode.pmt == node.pmt) { + // Remove the push messaging token and save the node. + delete oldNode.pmt; + db.Set(oldNode); + + // Event the node change + var event = { etype: 'node', action: 'changenode', nodeid: oldNode._id, domain: oldNode.domain, node: obj.CloneSafeNode(oldNode) } + if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come. + parent.DispatchEvent(['*', oldNode.meshid, oldNode._id], obj, event); + } + } + }); + } + db.Set({ _id: 'pmt_' + node.pmt, type: 'pmt', domain: node.domain, time: Date.now(), nodeid: node._id }) + }); + } + // Return true if a mobile browser is detected. // This code comes from "http://detectmobilebrowsers.com/" and was modified, This is free and unencumbered software released into the public domain. For more information, please refer to the http://unlicense.org/ function isMobileBrowser(req) {