Database fixes for new MongoDB driver.

This commit is contained in:
Ylian Saint-Hilaire 2019-05-20 18:03:14 -07:00
parent 4520b7c6a1
commit 084a6bab57
7 changed files with 56 additions and 50 deletions

21
db.js
View File

@ -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); };

View File

@ -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) {

View File

@ -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

View File

@ -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: <b>' + EscapeHtml(command.email) + '</b>.' })); } 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) { }
});

View File

@ -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

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.3.4-v",
"version": "0.3.4-y",
"keywords": [
"Remote Management",
"Intel AMT",

View File

@ -468,7 +468,7 @@
<div id="DeskToolsProcesses" style=""></div>
</div>
</div>
<div id=p11DeskConsoleMsg style="display:none;cursor:pointer;position:absolute;right:30px;bottom:30px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p11clearConsoleMsg()></div>
<div id=p11DeskConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:17px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p11clearConsoleMsg()></div>
</div>
<div id=deskarea4 class="areaFoot">
<div class="toright2">
@ -557,7 +557,7 @@
</td>
</tr>
</table>
<div id=p12TermConsoleMsg style="display:none;cursor:pointer;position:absolute;right:30px;bottom:45px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p12clearConsoleMsg()></div>
<div id=p12TermConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:45px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p12clearConsoleMsg()></div>
</div>
</div>
<div id=p13 style="display:none">
@ -611,7 +611,7 @@
</td>
</tr>
</table>
<div id=p13FilesConsoleMsg style="display:none;cursor:pointer;position:absolute;right:30px;bottom:55px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p13clearConsoleMsg()></div>
<div id=p13FilesConsoleMsg style="display:none;cursor:pointer;position:absolute;left:30px;top:165px;color:yellow;background-color:rgba(0,0,0,0.6);padding:10px;border-radius:5px" onclick=p13clearConsoleMsg()></div>
<div id="p13filetable" style="">
<div id="p13bigok" style="display:none"><b>&checkmark;</b></div>
<div id="p13bigfail" style="display:none"><b>&#10007;</b></div>