mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-02-12 11:01:52 +00:00
Partial support for device paging support on the server side, allows a user to view only a subset of the devices.
This commit is contained in:
parent
d4d1f7d454
commit
15c882f24e
2 changed files with 139 additions and 44 deletions
51
db.js
51
db.js
|
@ -1329,20 +1329,21 @@ module.exports.CreateDB = function (parent, func) {
|
||||||
func(err, performTypedRecordDecrypt(docs));
|
func(err, performTypedRecordDecrypt(docs));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
|
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, skip, limit, func) {
|
||||||
|
if (limit == 0) { limit = -1; } // In SQLite, no limit is -1
|
||||||
if (id && (id != '')) {
|
if (id && (id != '')) {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra IN (' + dbMergeSqlArray(meshes) + '))', [id, type, domain], function (err, docs) {
|
sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra IN (' + dbMergeSqlArray(meshes) + ')) LIMIT $4 OFFSET $5', [id, type, domain, limit, skip], function (err, docs) {
|
||||||
if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
|
if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
|
||||||
func(err, performTypedRecordDecrypt(docs));
|
func(err, performTypedRecordDecrypt(docs));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (extrasids == null) {
|
if (extrasids == null) {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra IN (' + dbMergeSqlArray(meshes) + '))', [type, domain], function (err, docs) {
|
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra IN (' + dbMergeSqlArray(meshes) + ')) LIMIT $3 OFFSET $4', [type, domain, limit, skip], function (err, docs) {
|
||||||
if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
|
if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
|
||||||
func(err, performTypedRecordDecrypt(docs));
|
func(err, performTypedRecordDecrypt(docs));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra IN (' + dbMergeSqlArray(meshes) + ')) OR (id IN (' + dbMergeSqlArray(extrasids) + ')))', [type, domain], function (err, docs) {
|
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra IN (' + dbMergeSqlArray(meshes) + ')) OR (id IN (' + dbMergeSqlArray(extrasids) + '))) LIMIT $3 OFFSET $4', [type, domain, limit, skip], function (err, docs) {
|
||||||
if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
|
if (docs != null) { for (var i in docs) { delete docs[i].type; if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); } } }
|
||||||
func(err, performTypedRecordDecrypt(docs));
|
func(err, performTypedRecordDecrypt(docs));
|
||||||
});
|
});
|
||||||
|
@ -1550,7 +1551,7 @@ module.exports.CreateDB = function (parent, func) {
|
||||||
func(null, common.aceUnEscapeAllFieldNames(docs));
|
func(null, common.aceUnEscapeAllFieldNames(docs));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
|
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, skip, limit, func) {
|
||||||
if (meshes.length == 0) { func(null, []); return; }
|
if (meshes.length == 0) { func(null, []); return; }
|
||||||
var query = obj.file.query('meshcentral').take(999999).filter('type', '==', type).filter('domain', '==', domain);
|
var query = obj.file.query('meshcentral').take(999999).filter('type', '==', type).filter('domain', '==', domain);
|
||||||
if (id) { query = query.filter('_id', '==', id); }
|
if (id) { query = query.filter('_id', '==', id); }
|
||||||
|
@ -1780,14 +1781,15 @@ module.exports.CreateDB = function (parent, func) {
|
||||||
obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM main', null, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM main', null, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
||||||
obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM main WHERE id = $1', [id], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM main WHERE id = $1', [id], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
||||||
obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM main WHERE type = $1 AND domain = $2', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM main WHERE type = $1 AND domain = $2', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
|
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, skip, limit, func) {
|
||||||
|
if (limit == 0) { limit = 0xFFFFFFFF; }
|
||||||
if (id && (id != '')) {
|
if (id && (id != '')) {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra = ANY ($4))', [id, type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
sqlDbQuery('SELECT doc FROM main WHERE (id = $1) AND (type = $2) AND (domain = $3) AND (extra = ANY ($4)) LIMIT $5 OFFSET $6', [id, type, domain, meshes, limit, skip], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
||||||
} else {
|
} else {
|
||||||
if (extrasids == null) {
|
if (extrasids == null) {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra = ANY ($3))', [type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }, true);
|
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND (extra = ANY ($3)) LIMIT $4 OFFSET $5', [type, domain, meshes, limit, skip], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }, true);
|
||||||
} else {
|
} else {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra = ANY ($3)) OR (id = ANY ($4)))', [type, domain, meshes, extrasids], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
sqlDbQuery('SELECT doc FROM main WHERE (type = $1) AND (domain = $2) AND ((extra = ANY ($3)) OR (id = ANY ($4))) LIMIT $5 OFFSET $6', [type, domain, meshes, extrasids, limit, skip], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1947,13 +1949,14 @@ module.exports.CreateDB = function (parent, func) {
|
||||||
obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM main', null, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM main', null, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
||||||
obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM main WHERE id = ?', [id], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM main WHERE id = ?', [id], function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); }
|
||||||
obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
|
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, skip, limit, func) {
|
||||||
|
if (limit == 0) { limit = 0xFFFFFFFF; }
|
||||||
if ((meshes == null) || (meshes.length == 0)) { meshes = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead.
|
if ((meshes == null) || (meshes.length == 0)) { meshes = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead.
|
||||||
if ((extrasids == null) || (extrasids.length == 0)) { extrasids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead.
|
if ((extrasids == null) || (extrasids.length == 0)) { extrasids = ''; } // MySQL can't handle a query with IN() on an empty array, we have to use an empty string instead.
|
||||||
if (id && (id != '')) {
|
if (id && (id != '')) {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE id = ? AND type = ? AND domain = ? AND extra IN (?)', [id, type, domain, meshes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
sqlDbQuery('SELECT doc FROM main WHERE id = ? AND type = ? AND domain = ? AND extra IN (?) LIMIT ? OFFSET ?', [id, type, domain, meshes, limit, skip], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
||||||
} else {
|
} else {
|
||||||
sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ? AND (extra IN (?) OR id IN (?))', [type, domain, meshes, extrasids], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
sqlDbQuery('SELECT doc FROM main WHERE type = ? AND domain = ? AND (extra IN (?) OR id IN (?)) LIMIT ? OFFSET ?', [type, domain, meshes, extrasids, limit, skip], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, performTypedRecordDecrypt(docs)); });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
||||||
|
@ -2177,15 +2180,21 @@ module.exports.CreateDB = function (parent, func) {
|
||||||
obj.GetAll = function (func) { obj.file.find({}).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAll = function (func) { obj.file.find({}).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetHash = function (id, func) { obj.file.find({ _id: id }).project({ _id: 0, hash: 1 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetHash = function (id, func) { obj.file.find({ _id: id }).project({ _id: 0, hash: 1 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }).project({ type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }).project({ type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
|
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, skip, limit, func) {
|
||||||
if (extrasids == null) {
|
if (extrasids == null) {
|
||||||
var x = { type: type, domain: domain, meshid: { $in: meshes } };
|
const x = { type: type, domain: domain, meshid: { $in: meshes } };
|
||||||
if (id) { x._id = id; }
|
if (id) { x._id = id; }
|
||||||
obj.file.find(x, { type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
var f = obj.file.find(x, { type: 0 });
|
||||||
|
if (skip > 0) f = f.skip(skip); // Skip records
|
||||||
|
if (limit > 0) f = f.limit(limit); // Limit records
|
||||||
|
f.toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||||
} else {
|
} else {
|
||||||
var x = { type: type, domain: domain, $or: [ { meshid: { $in: meshes } }, { _id: { $in: extrasids } } ] };
|
const x = { type: type, domain: domain, $or: [ { meshid: { $in: meshes } }, { _id: { $in: extrasids } } ] };
|
||||||
if (id) { x._id = id; }
|
if (id) { x._id = id; }
|
||||||
obj.file.find(x, { type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
var f = obj.file.find(x, { type: 0 });
|
||||||
|
if (skip > 0) f = f.skip(skip); // Skip records
|
||||||
|
if (limit > 0) f = f.limit(limit); // Limit records
|
||||||
|
f.toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
||||||
|
@ -2409,18 +2418,18 @@ module.exports.CreateDB = function (parent, func) {
|
||||||
obj.GetAll = function (func) { obj.file.find({}, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAll = function (func) { obj.file.find({}, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
obj.GetHash = function (id, func) { obj.file.find({ _id: id }, { _id: 0, hash: 1 }, func); };
|
obj.GetHash = function (id, func) { obj.file.find({ _id: id }, { _id: 0, hash: 1 }, func); };
|
||||||
obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||||
//obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, func) {
|
//obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, domain, type, id, skip, limit, func) {
|
||||||
//var x = { type: type, domain: domain, meshid: { $in: meshes } };
|
//var x = { type: type, domain: domain, meshid: { $in: meshes } };
|
||||||
//if (id) { x._id = id; }
|
//if (id) { x._id = id; }
|
||||||
//obj.file.find(x, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
//obj.file.find(x, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||||
//};
|
//};
|
||||||
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, func) {
|
obj.GetAllTypeNoTypeFieldMeshFiltered = function (meshes, extrasids, domain, type, id, skip, limit, func) {
|
||||||
if (extrasids == null) {
|
if (extrasids == null) {
|
||||||
var x = { type: type, domain: domain, meshid: { $in: meshes } };
|
const x = { type: type, domain: domain, meshid: { $in: meshes } };
|
||||||
if (id) { x._id = id; }
|
if (id) { x._id = id; }
|
||||||
obj.file.find(x, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
obj.file.find(x, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||||
} else {
|
} else {
|
||||||
var x = { type: type, domain: domain, $or: [{ meshid: { $in: meshes } }, { _id: { $in: extrasids } }] };
|
const x = { type: type, domain: domain, $or: [{ meshid: { $in: meshes } }, { _id: { $in: extrasids } }] };
|
||||||
if (id) { x._id = id; }
|
if (id) { x._id = id; }
|
||||||
obj.file.find(x, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
obj.file.find(x, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||||
}
|
}
|
||||||
|
|
132
meshuser.js
132
meshuser.js
|
@ -105,6 +105,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
obj.domain = domain;
|
obj.domain = domain;
|
||||||
obj.ws = ws;
|
obj.ws = ws;
|
||||||
|
|
||||||
|
// Information related to the current page the user is looking at
|
||||||
|
obj.deviceSkip = 0; // How many devices to skip
|
||||||
|
obj.deviceLimit = 0; // How many devices to view
|
||||||
|
obj.visibleDevices = null; // An object of visible nodeid's if the user is in paging mode
|
||||||
|
|
||||||
// Check if we are a cross-domain administrator
|
// Check if we are a cross-domain administrator
|
||||||
if (parent.parent.config.settings.managecrossdomain && (parent.parent.config.settings.managecrossdomain.indexOf(user._id) >= 0)) { obj.crossDomain = true; }
|
if (parent.parent.config.settings.managecrossdomain && (parent.parent.config.settings.managecrossdomain.indexOf(user._id) >= 0)) { obj.crossDomain = true; }
|
||||||
|
|
||||||
|
@ -414,6 +419,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
// If this session is logged in using a loginToken and the token is removed, disconnect.
|
// If this session is logged in using a loginToken and the token is removed, disconnect.
|
||||||
if ((req.session.loginToken != null) && (typeof event == 'object') && (event.action == 'loginTokenChanged') && (event.removed != null) && (event.removed.indexOf(req.session.loginToken) >= 0)) { delete req.session; obj.close(); return; }
|
if ((req.session.loginToken != null) && (typeof event == 'object') && (event.action == 'loginTokenChanged') && (event.removed != null) && (event.removed.indexOf(req.session.loginToken) >= 0)) { delete req.session; obj.close(); return; }
|
||||||
|
|
||||||
|
// If this user is not viewing all devices and paging, check if this event is in the current page
|
||||||
|
if (isEventWithinPage(ids) == false) return;
|
||||||
|
|
||||||
// Normally, only allow this user to receive messages from it's own domain.
|
// Normally, only allow this user to receive messages from it's own domain.
|
||||||
// If the user is a cross domain administrator, allow some select messages from different domains.
|
// If the user is a cross domain administrator, allow some select messages from different domains.
|
||||||
if ((event.domain == null) || (event.domain == domain.id) || ((obj.crossDomain === true) && (allowedCrossDomainMessages.indexOf(event.action) >= 0))) {
|
if ((event.domain == null) || (event.domain == domain.id) || ((obj.crossDomain === true) && (allowedCrossDomainMessages.indexOf(event.action) >= 0))) {
|
||||||
|
@ -706,7 +714,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request a list of all nodes
|
// Request a list of all nodes
|
||||||
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', command.id, function (err, docs) {
|
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', command.id, obj.deviceSkip, obj.deviceLimit, function (err, docs) {
|
||||||
|
|
||||||
//console.log(err, docs, links, extraids, domain.id, 'node', command.id);
|
//console.log(err, docs, links, extraids, domain.id, 'node', command.id);
|
||||||
|
|
||||||
|
@ -714,10 +722,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
parent.common.unEscapeAllLinksFieldName(docs);
|
parent.common.unEscapeAllLinksFieldName(docs);
|
||||||
|
|
||||||
var r = {};
|
var r = {};
|
||||||
|
if (obj.visibleDevices != null) { obj.visibleDevices = {}; }
|
||||||
for (i in docs) {
|
for (i in docs) {
|
||||||
// Check device links, if a link points to an unknown user, remove it.
|
// Check device links, if a link points to an unknown user, remove it.
|
||||||
parent.cleanDevice(docs[i]);
|
parent.cleanDevice(docs[i]);
|
||||||
|
|
||||||
|
// If we are paging, add the device to the page here
|
||||||
|
if (obj.visibleDevices != null) { obj.visibleDevices[docs[i]._id] = 1; }
|
||||||
|
|
||||||
// Remove any connectivity and power state information, that should not be in the database anyway.
|
// Remove any connectivity and power state information, that should not be in the database anyway.
|
||||||
// TODO: Find why these are sometimes saved in the db.
|
// TODO: Find why these are sometimes saved in the db.
|
||||||
if (docs[i].conn != null) { delete docs[i].conn; }
|
if (docs[i].conn != null) { delete docs[i].conn; }
|
||||||
|
@ -788,7 +800,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
|
|
||||||
r[meshid].push(docs[i]);
|
r[meshid].push(docs[i]);
|
||||||
}
|
}
|
||||||
try { ws.send(JSON.stringify({ action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag })); } catch (ex) { }
|
const response = { action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag };
|
||||||
|
if (obj.visibleDevices != null) {
|
||||||
|
// If in paging mode, report back the skip and limit values
|
||||||
|
response.skip = obj.deviceSkip;
|
||||||
|
response.limit = obj.deviceLimit;
|
||||||
|
// TODO: Add total device count
|
||||||
|
}
|
||||||
|
try { ws.send(JSON.stringify(response)); } catch (ex) { }
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6128,14 +6147,30 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
}
|
}
|
||||||
|
|
||||||
function serverCommandLastConnects(command) {
|
function serverCommandLastConnects(command) {
|
||||||
const links = parent.GetAllMeshIdWithRights(user);
|
if (obj.visibleDevices == null) {
|
||||||
const extraids = getUserExtraIds();
|
// If we are not paging, get all devices visible to this user
|
||||||
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) {
|
const links = parent.GetAllMeshIdWithRights(user);
|
||||||
if (docs == null) return;
|
const extraids = getUserExtraIds();
|
||||||
|
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, obj.deviceSkip, obj.deviceLimit, function (err, docs) {
|
||||||
|
if (docs == null) return;
|
||||||
|
|
||||||
|
// Create a list of node ids for this user and query them for last device connection time
|
||||||
|
const ids = []
|
||||||
|
for (var i in docs) { ids.push('lc' + docs[i]._id); }
|
||||||
|
|
||||||
|
// Pull list of last connections only for device owned by this user
|
||||||
|
db.GetAllIdsOfType(ids, domain.id, 'lastconnect', function (err, docs) {
|
||||||
|
if (docs == null) return;
|
||||||
|
const response = {};
|
||||||
|
for (var j in docs) { response[docs[j]._id.substring(2)] = docs[j].time; }
|
||||||
|
obj.send({ action: 'lastconnects', lastconnects: response, tag: command.tag });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If we are paging, we know what devices the user is look at
|
||||||
// Create a list of node ids for this user and query them for last device connection time
|
// Create a list of node ids for this user and query them for last device connection time
|
||||||
const ids = []
|
const ids = []
|
||||||
for (var i in docs) { ids.push('lc' + docs[i]._id); }
|
for (var i in obj.visibleDevices) { ids.push('lc' + i); }
|
||||||
|
|
||||||
// Pull list of last connections only for device owned by this user
|
// Pull list of last connections only for device owned by this user
|
||||||
db.GetAllIdsOfType(ids, domain.id, 'lastconnect', function (err, docs) {
|
db.GetAllIdsOfType(ids, domain.id, 'lastconnect', function (err, docs) {
|
||||||
|
@ -6144,7 +6179,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
for (var j in docs) { response[docs[j]._id.substring(2)] = docs[j].time; }
|
for (var j in docs) { response[docs[j]._id.substring(2)] = docs[j].time; }
|
||||||
obj.send({ action: 'lastconnects', lastconnects: response, tag: command.tag });
|
obj.send({ action: 'lastconnects', lastconnects: response, tag: command.tag });
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function serverCommandLoginCookie(command) {
|
function serverCommandLoginCookie(command) {
|
||||||
|
@ -7505,22 +7540,62 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
|
|
||||||
// Return detailed information about all nodes this user has access to
|
// Return detailed information about all nodes this user has access to
|
||||||
function getAllDeviceDetailedInfo(type, func) {
|
function getAllDeviceDetailedInfo(type, func) {
|
||||||
// Get all device groups this user has access to
|
// If we are not paging, get all devices visible to this user
|
||||||
var links = parent.GetAllMeshIdWithRights(user);
|
if (obj.visibleDevices == null) {
|
||||||
|
|
||||||
// Add any nodes with direct rights or any nodes with user group direct rights
|
// Get all device groups this user has access to
|
||||||
var extraids = getUserExtraIds();
|
var links = parent.GetAllMeshIdWithRights(user);
|
||||||
|
|
||||||
// Request a list of all nodes
|
// Add any nodes with direct rights or any nodes with user group direct rights
|
||||||
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) {
|
var extraids = getUserExtraIds();
|
||||||
if (docs == null) { docs = []; }
|
|
||||||
parent.common.unEscapeAllLinksFieldName(docs);
|
|
||||||
|
|
||||||
var results = [], resultPendingCount = 0;
|
// Request a list of all nodes
|
||||||
for (i in docs) {
|
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, obj.deviceSkip, obj.deviceLimit, function (err, docs) {
|
||||||
// Check device links, if a link points to an unknown user, remove it.
|
if (docs == null) { docs = []; }
|
||||||
parent.cleanDevice(docs[i]);
|
parent.common.unEscapeAllLinksFieldName(docs);
|
||||||
|
|
||||||
|
var results = [], resultPendingCount = 0;
|
||||||
|
for (i in docs) {
|
||||||
|
// Check device links, if a link points to an unknown user, remove it.
|
||||||
|
parent.cleanDevice(docs[i]);
|
||||||
|
|
||||||
|
// Fetch the node from the database
|
||||||
|
resultPendingCount++;
|
||||||
|
const getNodeFunc = function (node, rights, visible) {
|
||||||
|
if ((node != null) && (visible == true)) {
|
||||||
|
const getNodeSysInfoFunc = function (err, docs) {
|
||||||
|
const getNodeNetInfoFunc = function (err, docs) {
|
||||||
|
var netinfo = null;
|
||||||
|
if ((err == null) && (docs != null) && (docs.length == 1)) { netinfo = docs[0]; }
|
||||||
|
resultPendingCount--;
|
||||||
|
getNodeNetInfoFunc.results.push({ node: parent.CloneSafeNode(getNodeNetInfoFunc.node), sys: getNodeNetInfoFunc.sysinfo, net: netinfo });
|
||||||
|
if (resultPendingCount == 0) { func(getNodeFunc.results, type); }
|
||||||
|
}
|
||||||
|
getNodeNetInfoFunc.results = getNodeSysInfoFunc.results;
|
||||||
|
getNodeNetInfoFunc.nodeid = getNodeSysInfoFunc.nodeid;
|
||||||
|
getNodeNetInfoFunc.node = getNodeSysInfoFunc.node;
|
||||||
|
if ((err == null) && (docs != null) && (docs.length == 1)) { getNodeNetInfoFunc.sysinfo = docs[0]; }
|
||||||
|
|
||||||
|
// Query the database for network information
|
||||||
|
db.Get('if' + getNodeSysInfoFunc.nodeid, getNodeNetInfoFunc);
|
||||||
|
}
|
||||||
|
getNodeSysInfoFunc.results = getNodeFunc.results;
|
||||||
|
getNodeSysInfoFunc.nodeid = getNodeFunc.nodeid;
|
||||||
|
getNodeSysInfoFunc.node = node;
|
||||||
|
|
||||||
|
// Query the database for system information
|
||||||
|
db.Get('si' + getNodeFunc.nodeid, getNodeSysInfoFunc);
|
||||||
|
} else { resultPendingCount--; }
|
||||||
|
if (resultPendingCount == 0) { func(getNodeFunc.results.join('\r\n'), type); }
|
||||||
|
}
|
||||||
|
getNodeFunc.results = results;
|
||||||
|
getNodeFunc.nodeid = docs[i]._id;
|
||||||
|
parent.GetNodeWithRights(domain, user, docs[i]._id, getNodeFunc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// If we are paging, we know what devices the user is look at
|
||||||
|
for (var id in obj.visibleDevices) {
|
||||||
// Fetch the node from the database
|
// Fetch the node from the database
|
||||||
resultPendingCount++;
|
resultPendingCount++;
|
||||||
const getNodeFunc = function (node, rights, visible) {
|
const getNodeFunc = function (node, rights, visible) {
|
||||||
|
@ -7551,10 +7626,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
if (resultPendingCount == 0) { func(getNodeFunc.results.join('\r\n'), type); }
|
if (resultPendingCount == 0) { func(getNodeFunc.results.join('\r\n'), type); }
|
||||||
}
|
}
|
||||||
getNodeFunc.results = results;
|
getNodeFunc.results = results;
|
||||||
getNodeFunc.nodeid = docs[i]._id;
|
getNodeFunc.nodeid = id;
|
||||||
parent.GetNodeWithRights(domain, user, docs[i]._id, getNodeFunc);
|
parent.GetNodeWithRights(domain, user, id, getNodeFunc);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display a notification message for this session only.
|
// Display a notification message for this session only.
|
||||||
|
@ -7721,5 +7796,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
return authFactorCount;
|
return authFactorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if the event is for a device that is part of the currently visible page
|
||||||
|
function isEventWithinPage(ids) {
|
||||||
|
if (obj.visibleDevices == null) return true; // Add devices are visible
|
||||||
|
var r = true;
|
||||||
|
for (var i in ids) {
|
||||||
|
// If the event is for a visible device, return true
|
||||||
|
if (ids[i].startsWith('node/')) { r = false; if (obj.visibleDevices[ids[i]] != null) return true; }
|
||||||
|
}
|
||||||
|
return r; // If this event is not for any specific device, return true
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue