From 084a6bab5789beaab16c4c30fc5010b84e91843e Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 20 May 2019 18:03:14 -0700 Subject: [PATCH] Database fixes for new MongoDB driver. --- db.js | 21 ++++++++++++-------- meshagent.js | 18 ++++++++--------- meshcentral.js | 4 ++-- meshuser.js | 43 ++++++++++++++++++++-------------------- mpsserver.js | 12 +++++------ package.json | 2 +- views/default.handlebars | 6 +++--- 7 files changed, 56 insertions(+), 50 deletions(-) diff --git a/db.js b/db.js index 3d6cdf7e..0f87684f 100644 --- a/db.js +++ b/db.js @@ -198,14 +198,19 @@ module.exports.CreateDB = function (parent, func) { if (typeof obj.parent.args.dbexpire.statsevents == 'number') { expireServerStatsSeconds = obj.parent.args.dbexpire.statsevents; } } - if (obj.parent.args.xmongodb) { + if (obj.parent.args.mongodb) { // Use MongoDB obj.databaseType = 3; - require('mongodb').MongoClient.connect(obj.parent.args.xmongodb, { useNewUrlParser: true }, function (err, client) { + require('mongodb').MongoClient.connect(obj.parent.args.mongodb, { useNewUrlParser: true }, function (err, client) { if (err != null) { console.log("Unable to connect to database: " + err); process.exit(); return; } - Datastore = client; - const dbname = (obj.parent.args.mongodbname) ? (obj.parent.args.mongodbname) : 'meshcentral'; + + // Get the database name and setup the database client + var dbNamefromUrl = null; + try { dbNamefromUrl = require('url').parse(obj.parent.args.mongodb).path.split('/')[1]; } catch (ex) { } + var dbname = 'meshcentral'; + if (dbNamefromUrl) { dbname = dbNamefromUrl; } + if (obj.parent.args.mongodbname) { dbname = obj.parent.args.mongodbname; } const dbcollectionname = (obj.parent.args.mongodbcol) ? (obj.parent.args.mongodbcol) : 'meshcentral'; const db = client.db(dbname); @@ -311,11 +316,11 @@ module.exports.CreateDB = function (parent, func) { setupFunctions(func); // Completed setup of MongoDB }); - } else if (obj.parent.args.mongodb) { - // Use MongoJS + } else if (obj.parent.args.xmongodb) { + // Use MongoJS, this is the old system. obj.databaseType = 2; Datastore = require('mongojs'); - var db = Datastore(obj.parent.args.mongodb); + var db = Datastore(obj.parent.args.xmongodb); var dbcollection = 'meshcentral'; if (obj.parent.args.mongodbcol) { dbcollection = obj.parent.args.mongodbcol; } @@ -504,7 +509,7 @@ module.exports.CreateDB = function (parent, func) { obj.RemoveAll = function (func) { obj.file.deleteMany({}, { multi: true }, func); }; obj.RemoveAllOfType = function (type, func) { obj.file.deleteMany({ type: type }, { multi: true }, func); }; obj.InsertMany = function (data, func) { obj.file.insertMany(data, func); }; - obj.RemoveMeshDocuments = function (id) { obj.file.deleteMany({ meshid: id }, { multi: true }); obj.file.remove({ _id: 'nt' + id }); }; + obj.RemoveMeshDocuments = function (id) { obj.file.deleteMany({ meshid: id }, { multi: true }); obj.file.deleteOne({ _id: 'nt' + id }); }; obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); }; obj.DeleteDomain = function (domain, func) { obj.file.deleteMany({ domain: domain }, { multi: true }, func); }; obj.SetUser = function (user) { var u = Clone(user); if (u.subscriptions) { delete u.subscriptions; } obj.Set(u); }; diff --git a/meshagent.js b/meshagent.js index ae95f1a3..a6b5b3bb 100644 --- a/meshagent.js +++ b/meshagent.js @@ -600,7 +600,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { var device; // See if this node exists in the database - if (nodes.length == 0) { + if ((nodes == null) || (nodes.length == 0)) { // This device does not exist, use the meshid given by the device // See if this mesh exists, if it does not we may want to create it. @@ -798,7 +798,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Fetch the the real agent nodeid db.Get('da' + obj.dbNodeKey, function (err, nodes, self) { - if (nodes.length == 1) + if ((nodes != null) && (nodes.length == 1)) { self.realNodeKey = nodes[0].raid; @@ -834,7 +834,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Fetch the the diagnostic agent nodeid db.Get('ra' + obj.dbNodeKey, function (err, nodes) { - if (nodes.length == 1) { + if ((nodes != null) && (nodes.length == 1)) { obj.diagnosticNodeKey = nodes[0].daid; obj.send(JSON.stringify({ action: 'diagnostic', value: { command: 'query', value: obj.diagnosticNodeKey } })); } @@ -849,7 +849,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (domain.iplocation == true) { // Check if we already have IP location information for this node db.Get('iploc_' + obj.remoteaddr, function (err, iplocs) { - if (iplocs.length == 1) { + if ((iplocs != null) && (iplocs.length == 1)) { // We have a location in the database for this remote IP const iploc = nodes[0], x = {}; if ((iploc != null) && (iploc.ip != null) && (iploc.loc != null)) { @@ -876,7 +876,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // If we need to ask for IP location, see if we have the quota to do it. if (doIpLocation > 0) { db.getValueOfTheDay('ipLocationRequestLimitor', 10, function (ipLocationLimitor) { - if (ipLocationLimitor.value > 0) { + if ((ipLocationLimitor != null) && (ipLocationLimitor.value > 0)) { ipLocationLimitor.value--; db.Set(ipLocationLimitor); obj.send(JSON.stringify({ action: 'iplocation' })); @@ -1103,7 +1103,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (command.oldnodeid.length != 64) break; const oldNodeKey = 'node//' + command.oldnodeid.toLowerCase(); db.Get(oldNodeKey, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes != null) && (nodes.length != 1)) return; const node = nodes[0]; if (node.meshid == obj.dbMeshKey) { // Update the device name & host @@ -1212,7 +1212,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Get the node and change it if needed db.Get(obj.dbNodeKey, function (err, nodes) { // TODO: THIS IS A BIG RACE CONDITION HERE, WE NEED TO FIX THAT. If this call is made twice at the same time on the same device, data will be missed. - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; const device = nodes[0]; if (device.agent) { var changes = [], change = 0, log = 0; @@ -1280,7 +1280,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Get the node and change it if needed db.Get(obj.dbNodeKey, function (err, nodes) { - if (nodes.length != 1) { return; } + if ((nodes == null) || (nodes.length != 1)) { return; } const device = nodes[0]; if (device.agent) { var changes = [], change = 0; @@ -1318,7 +1318,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (tag.length == 0) { tag = null; } // Get the node and change it if needed db.Get(obj.dbNodeKey, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; const device = nodes[0]; if (device.agent) { if (device.agent.tag != tag) { diff --git a/meshcentral.js b/meshcentral.js index f0006f85..a579c17d 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1745,8 +1745,8 @@ function mainStart() { if (require('os').platform() == 'win32') { modules.push('node-windows'); if (sspi == true) { modules.push('node-sspi'); } } // Add Windows modules if (ldap == true) { modules.push('ldapauth-fork'); } if (config.letsencrypt != null) { modules.push('greenlock'); modules.push('le-store-certbot'); modules.push('le-challenge-fs'); modules.push('le-acme-core'); } // Add Greenlock Modules - if (config.settings.mongodb != null) { modules.push('mongojs'); } // Add MongoJS - else if (config.settings.xmongodb != null) { modules.push('mongodb'); } // Add MongoDB + if (config.settings.mongodb != null) { modules.push('mongodb'); } // Add MongoDB, official driver. + else if (config.settings.xmongodb != null) { modules.push('mongojs'); } // Add MongoJS, old driver. if (config.smtp != null) { modules.push('nodemailer'); } // Add SMTP support // Get the current node version diff --git a/meshuser.js b/meshuser.js index fd4c9622..57c42402 100644 --- a/meshuser.js +++ b/meshuser.js @@ -369,6 +369,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Request a list of all nodes db.GetAllTypeNoTypeFieldMeshFiltered(links, domain.id, 'node', command.id, function (err, docs) { + if (docs == null) { docs = []; } var r = {}; for (i in docs) { // Remove any connectivity and power state information, that should not be in the database anyway. @@ -415,7 +416,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // The result is a compacted array: [ startPowerState, startTimeUTC, powerState ] + many[ deltaTime, powerState ] if (common.validateString(command.nodeid, 0, 128) == false) return; db.getPowerTimeline(command.nodeid, function (err, docs) { - if (err == null && docs.length > 0) { + if ((err == null) && (docs != null) && (docs.length > 0)) { var timeline = [], time = null, previousPower; for (i in docs) { var doc = docs[i]; @@ -826,7 +827,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (parent.users[req.session.userid].email != command.email) { // Check if this email is already validated on a different account db.GetUserWithVerifiedEmail(domain.id, command.email, function (err, docs) { - if (docs.length > 0) { + if ((docs != null) && (docs.length > 0)) { // Notify the duplicate email error try { ws.send(JSON.stringify({ action: 'msg', type: 'notify', title: 'Account Settings', tag: 'ServerNotify', value: 'Failed to change email address, another account already using: ' + EscapeHtml(command.email) + '.' })); } catch (ex) { } } else { @@ -1677,7 +1678,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the device db.Get(nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -1695,7 +1696,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use db.RemoveAllNodeEvents(node._id); // Remove all events for this node db.removeAllPowerEventsForNode(node._id); // Remove all power events for this node db.Get('ra' + obj.dbNodeKey, function (err, nodes) { - if (nodes.length == 1) { db.Remove('da' + nodes[0].daid); } // Remove diagnostic agent to real agent link + 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 }); @@ -1727,7 +1728,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if ((nodeid.split('/').length == 3) && (nodeid.split('/')[1] == domain.id)) { // Validate the domain, operation only valid for current domain // Get the device db.Get(nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -1739,7 +1740,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the device interface information db.Get('if' + node._id, function (err, nodeifs) { - if (nodeifs.length == 1) { + if ((nodeifs != null) && (nodeifs.length == 1)) { var nodeif = nodeifs[0]; var macs = []; for (var i in nodeif.netif) { if (nodeif.netif[i].mac) { macs.push(nodeif.netif[i].mac); } } @@ -1783,7 +1784,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if ((nodeid.split('/').length == 3) && (nodeid.split('/')[1] == domain.id)) { // Validate the domain, operation only valid for current domain // Get the device db.Get(nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -1821,7 +1822,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if ((nodeid.split('/').length == 3) && (nodeid.split('/')[1] == domain.id)) { // Validate the domain, operation only valid for current domain // Get the device db.Get(nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -1852,7 +1853,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the device db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) { try { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, netif: null })); } catch (ex) { } return; } + if ((nodes == null) || (nodes.length != 1)) { try { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, netif: null })); } catch (ex) { } return; } var node = nodes[0]; // Get the mesh for this device @@ -1863,7 +1864,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get network information about this node db.Get('if' + command.nodeid, function (err, netinfos) { - if (netinfos.length != 1) { try { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, netif: null })); } catch (ex) { } return; } + if ((netinfos == null) || (netinfos.length != 1)) { try { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, netif: null })); } catch (ex) { } return; } var netinfo = netinfos[0]; try { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, updateTime: netinfo.updateTime, netif: netinfo.netif })); } catch (ex) { } }); @@ -1880,7 +1881,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Change the device db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -1947,7 +1948,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Change the device db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -1988,7 +1989,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Change the device db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -2015,7 +2016,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Check if this user has rights on this nodeid if (common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid db.Get(command.nodeid, function (err, nodes) { // TODO: Make a NodeRights(user) method that also does not do a db call if agent is connected (???) - if (nodes.length == 1) { + if ((nodes == null) || (nodes.length == 1)) { meshlinks = user.links[nodes[0].meshid]; if ((meshlinks) && (meshlinks.rights) && ((meshlinks.rights & MESHRIGHT_REMOTECONTROL) != 0)) { // Add a user authentication cookie to a url @@ -2062,7 +2063,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (idtype == 'node') { // Check if this user has rights on this id to set notes db.Get(command.id, function (err, nodes) { // TODO: Make a NodeRights(user) method that also does not do a db call if agent is connected (???) - if (nodes.length == 1) { + if ((nodes == null) || (nodes.length == 1)) { meshlinks = user.links[nodes[0].meshid]; if ((meshlinks) && (meshlinks.rights) && (meshlinks.rights & parent.MESHRIGHT_SETNOTES != 0)) { // Set the id's notes @@ -2340,7 +2341,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the device db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -2362,7 +2363,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the device db.Get(command.nodeid, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -2396,7 +2397,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (idtype == 'node') { // Get the device db.Get(command.id, function (err, nodes) { - if (nodes.length != 1) return; + if ((nodes == null) || (nodes.length != 1)) return; var node = nodes[0]; // Get the mesh for this device @@ -2408,7 +2409,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the notes about this node db.Get('nt' + command.id, function (err, notes) { try { - if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } + if ((notes == null) || (notes.length != 1)) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value })); } catch (ex) { } }); @@ -2424,7 +2425,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the notes about this node db.Get('nt' + command.id, function (err, notes) { try { - if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } + if ((notes == null) || (notes.length != 1)) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value })); } catch (ex) { } }); @@ -2433,7 +2434,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use // Get the notes about this node db.Get('nt' + command.id, function (err, notes) { try { - if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } + if ((notes == null) || (notes.length != 1)) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; } ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value })); } catch (ex) { } }); diff --git a/mpsserver.js b/mpsserver.js index a07f4d78..40061e85 100644 --- a/mpsserver.js +++ b/mpsserver.js @@ -198,10 +198,10 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Fetch the mesh obj.db.Get(socket.tag.meshid, function (err, meshes) { - if (meshes.length === 1) { + if ((meshes != null) && (meshes.length === 1)) { var mesh = meshes[0]; obj.db.Get(socket.tag.nodeid, function (err, nodes) { - if (nodes.length !== 1) { + if ((nodes == null) || (nodes.length !== 1)) { if (mesh.mtype == 1) { // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, host: null, domain: domainid, intelamt: { user: '', pass: '', tls: 0, state: 2 } }; @@ -318,7 +318,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { socket.tag.connectTime = Date.now(); obj.db.Get(socket.tag.nodeid, function (err, nodes) { - if (nodes.length !== 1) { + if ((nodes == null) || (nodes.length !== 1)) { // Node is not in the database, add it. Credentials will be empty until added by the user. var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, host: null, domain: mesh.domain, intelamt: { user: '', pass: '', tls: 0, state: 2 } }; obj.db.Set(device); @@ -343,7 +343,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { } else if (mesh.mtype == 2) { // If this is a agent mesh, search the mesh for this device UUID // Intel AMT GUID (socket.tag.SystemId) will be used to search the node obj.db.getAmtUuidNode(mesh._id, socket.tag.SystemId, function (err, nodes) { // TODO: May need to optimize this request with indexes - if (nodes.length !== 1) { + if ((nodes == null) || (nodes.length !== 1)) { // New CIRA connection for unknown node, disconnect. unknownNodeCount++; console.log('CIRA connection for unknown node. groupid: ' + mesh._id + ', uuid: ' + socket.tag.SystemId); @@ -748,7 +748,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Change the device obj.db.Get(socket.tag.nodeid, function (err, nodes) { - if (nodes.length !== 1) return; + if ((nodes == null) || (nodes.length !== 1)) return; var node = nodes[0]; // See if any changes need to be made @@ -756,7 +756,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) { // Get the mesh for this device obj.db.Get(node.meshid, function (err, meshes) { - if (meshes.length !== 1) return; + if ((meshes == null) || (meshes.length !== 1)) return; var mesh = meshes[0]; // Ready the node change event diff --git a/package.json b/package.json index 4f6c1036..7e152532 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.3.4-v", + "version": "0.3.4-y", "keywords": [ "Remote Management", "Intel AMT", diff --git a/views/default.handlebars b/views/default.handlebars index 9eea1183..f6d25fbb 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -468,7 +468,7 @@
- +
@@ -557,7 +557,7 @@ - +