More work done on per-device permissions.

This commit is contained in:
Ylian Saint-Hilaire 2020-03-26 19:33:13 -07:00
parent b07a8bf3c5
commit 2314a58cd2
9 changed files with 595 additions and 129 deletions

View File

@ -147,6 +147,7 @@ module.exports.escapeFieldName = function (name) { if ((name.indexOf('%') == -1)
module.exports.unEscapeFieldName = function (name) { if (name.indexOf('%') == -1) return name; return name.split('%2E').join('.').split('%24').join('$').split('%25').join('%'); };
// Escape all links
module.exports.escapeLinksFieldNameEx = function (docx) { if (docx.links == null) { return docx; } var doc = Object.assign({}, docx); doc.links = Object.assign({}, doc.links); for (var i in doc.links) { var ue = module.exports.escapeFieldName(i); if (ue !== i) { doc.links[ue] = doc.links[i]; delete doc.links[i]; } } return doc; };
module.exports.escapeLinksFieldName = function (docx) { var doc = Object.assign({}, docx); if (doc.links != null) { doc.links = Object.assign({}, doc.links); for (var i in doc.links) { var ue = module.exports.escapeFieldName(i); if (ue !== i) { doc.links[ue] = doc.links[i]; delete doc.links[i]; } } } return doc; };
module.exports.unEscapeLinksFieldName = function (doc) { if (doc.links != null) { for (var j in doc.links) { var ue = module.exports.unEscapeFieldName(j); if (ue !== j) { doc.links[ue] = doc.links[j]; delete doc.links[j]; } } } return doc; };
//module.exports.escapeAllLinksFieldName = function (docs) { for (var i in docs) { module.exports.escapeLinksFieldName(docs[i]); } return docs; };

33
db.js
View File

@ -789,11 +789,17 @@ module.exports.CreateDB = function (parent, func) {
// Database actions on the main collection (MariaDB or MySQL)
obj.Set = function (value, func) {
var extra = null, extraex = null;
value = common.escapeLinksFieldNameEx(value);
if (value.meshid) { extra = value.meshid; } else if (value.email) { extra = 'email/' + value.email; }
if ((value.type == 'node') && (value.intelamt != null) && (value.intelamt.uuid != null)) { extraex = 'uuid/' + value.intelamt.uuid; }
sqlDbQuery('REPLACE INTO meshcentral.main VALUE (?, ?, ?, ?, ?, ?)', [value._id, (value.type ? value.type : null), ((value.domain != null) ? value.domain : null), extra, extraex, JSON.stringify(performTypedRecordEncrypt(value))], func);
}
obj.Get = function (_id, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [_id], func); }
obj.Get = function (_id, func) {
sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [_id], function (err, docs) {
if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
func(_id, func);
});
}
obj.GetAll = function (func) { sqlDbQuery('SELECT domain, doc FROM meshcentral.main', null, func); }
obj.GetHash = function (id, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ?', [id], func); }
obj.GetAllTypeNoTypeField = function (type, domain, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ?', [type, domain], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); }); };
@ -920,7 +926,7 @@ module.exports.CreateDB = function (parent, func) {
}
} else if (obj.databaseType == 3) {
// Database actions on the main collection (MongoDB)
obj.Set = function (data, func) { obj.file.replaceOne({ _id: data._id }, performTypedRecordEncrypt(data), { upsert: true }, func); };
obj.Set = function (data, func) { data = common.escapeLinksFieldNameEx(data); obj.file.replaceOne({ _id: data._id }, performTypedRecordEncrypt(data), { upsert: true }, func); };
obj.Get = function (id, func) {
if (arguments.length > 2) {
var parms = [func];
@ -932,9 +938,15 @@ module.exports.CreateDB = function (parent, func) {
userCallback.apply(obj, _func2.userArgs);
};
func2.userArgs = parms;
obj.file.find({ _id: id }).toArray(function (err, docs) { func2(err, performTypedRecordDecrypt(docs)); });
obj.file.find({ _id: id }).toArray(function (err, docs) {
if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
func2(err, performTypedRecordDecrypt(docs));
});
} else {
obj.file.find({ _id: id }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
obj.file.find({ _id: id }).toArray(function (err, docs) {
if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
func(err, performTypedRecordDecrypt(docs));
});
}
};
obj.GetAll = function (func) { obj.file.find({}).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
@ -1052,7 +1064,7 @@ module.exports.CreateDB = function (parent, func) {
} else {
// Database actions on the main collection (NeDB and MongoJS)
obj.Set = function (data, func) { var xdata = performTypedRecordEncrypt(data); obj.file.update({ _id: xdata._id }, xdata, { upsert: true }, func); };
obj.Set = function (data, func) { data = common.escapeLinksFieldNameEx(data); var xdata = performTypedRecordEncrypt(data); obj.file.update({ _id: xdata._id }, xdata, { upsert: true }, func); };
obj.Get = function (id, func) {
if (arguments.length > 2) {
var parms = [func];
@ -1064,9 +1076,15 @@ module.exports.CreateDB = function (parent, func) {
userCallback.apply(obj, _func2.userArgs);
};
func2.userArgs = parms;
obj.file.find({ _id: id }, function (err, docs) { func2(err, performTypedRecordDecrypt(docs)); });
obj.file.find({ _id: id }, function (err, docs) {
if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
func2(err, performTypedRecordDecrypt(docs));
});
} else {
obj.file.find({ _id: id }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
obj.file.find({ _id: id }, function (err, docs) {
if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
func(err, performTypedRecordDecrypt(docs));
});
}
};
obj.GetAll = function (func) { obj.file.find({}, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
@ -1323,6 +1341,7 @@ module.exports.CreateDB = function (parent, func) {
// Called when a node has changed
function dbNodeChange(nodeChange, added) {
common.unEscapeLinksFieldName(nodeChange.fullDocument);
const node = nodeChange.fullDocument;
if (node.intelamt && node.intelamt.pass) { delete node.intelamt.pass; } // Remove the Intel AMT password before eventing this.
parent.DispatchEvent(['*', node.meshid], obj, { etype: 'node', action: (added ? 'addnode' : 'changenode'), node: node, nodeid: node._id, domain: node.domain, nolog: 1 });

View File

@ -549,7 +549,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
const links = {};
links[adminUser._id] = { name: adminUser.name, rights: 0xFFFFFFFF };
mesh = { type: 'mesh', _id: obj.dbMeshKey, name: meshname, mtype: 2, desc: '', domain: domain.id, links: links };
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
parent.meshes[obj.dbMeshKey] = mesh;
if (adminUser.links == null) adminUser.links = {};
@ -580,7 +580,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
// Mark the mesh as active
delete mesh.deleted;
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
}
}
return mesh;
@ -638,7 +638,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
var links = {};
links[user._id] = { name: adminUser.name, rights: 0xFFFFFFFF };
mesh = { type: 'mesh', _id: obj.dbMeshKey, name: obj.meshid, mtype: 2, desc: '', domain: domain.id, links: links };
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
parent.meshes[obj.meshid] = mesh;
parent.parent.AddEventDispatch(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), ws);

View File

@ -815,8 +815,8 @@ function CreateMeshCentralServer(config, args) {
objectToAdd.push(newobj); // Add this user
}
} else if (newobj.type == 'mesh') {
// Add this object after escaping
objectToAdd.push(obj.common.escapeLinksFieldName(newobj));
// Add this object
objectToAdd.push(newobj);
} // Don't add nodes.
}
console.log('Importing ' + objectToAdd.length + ' object(s)...');

View File

@ -1268,7 +1268,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
mesh = parent.meshes[meshid];
if (mesh) {
// Remove user from the mesh
if (mesh.links[deluser._id] != null) { delete mesh.links[deluser._id]; parent.db.Set(common.escapeLinksFieldName(mesh)); }
if (mesh.links[deluser._id] != null) { delete mesh.links[deluser._id]; parent.db.Set(mesh); }
// Notify mesh change
change = 'Removed user ' + deluser.name + ' from group ' + mesh.name;
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id, invite: mesh.invite };
@ -1664,7 +1664,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (xmesh && xmesh.links) {
ugrp.links[i] = { rights: cgroup.links[i].rights };
xmesh.links[ugrpid] = { rights: cgroup.links[i].rights };
db.Set(common.escapeLinksFieldName(xmesh));
db.Set(xmesh);
// Notify mesh change
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: xmesh._id, name: xmesh.name, mtype: xmesh.mtype, desc: xmesh.desc, action: 'meshchange', links: xmesh.links, msg: 'Added group ' + ugrp.name + ' to mesh ' + xmesh.name, domain: domain.id, invite: mesh.invite };
@ -1678,7 +1678,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
// Save the new group
db.Set(common.escapeLinksFieldName(ugrp));
db.Set(ugrp);
if (db.changeStream == false) { parent.userGroups[ugrpid] = ugrp; }
// Event the device group creation
@ -1703,7 +1703,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
db.Get(command.ugrpid, function (err, groups) {
if ((err != null) || (groups.length != 1)) return;
var group = common.unEscapeLinksFieldName(groups[0]);
var group = groups[0];
// Unlink any user and meshes that have a link to this group
if (group.links) {
@ -1725,7 +1725,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
var xmesh = parent.meshes[i];
if (xmesh && xmesh.links) {
delete xmesh.links[group._id];
db.Set(common.escapeLinksFieldName(xmesh));
db.Set(xmesh);
// Notify mesh change
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: xmesh._id, name: xmesh.name, mtype: xmesh.mtype, desc: xmesh.desc, action: 'meshchange', links: xmesh.links, msg: 'Removed group ' + group.name + ' from mesh ' + xmesh.name, domain: domain.id, invite: mesh.invite };
@ -1762,7 +1762,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if ((common.validateString(command.name, 1, 64) == true) && (command.name != group.name) && (command.name.indexOf(' ') == -1)) { change = 'User group name changed from "' + group.name + '" to "' + command.name + '"'; group.name = command.name; }
if ((common.validateString(command.desc, 0, 1024) == true) && (command.desc != group.desc)) { if (change != '') change += ' and description changed'; else change += 'User group "' + group.name + '" description changed'; group.desc = command.desc; }
if (change != '') {
db.Set(common.escapeLinksFieldName(group));
db.Set(group);
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, name: group.name, desc: group.desc, action: 'usergroupchange', links: group.links, msg: change, domain: domain.id };
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.parent.DispatchEvent(['*', group._id, user._id], obj, event);
@ -1822,7 +1822,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (addedCount > 0) {
// Save the new group to the database
db.Set(common.escapeLinksFieldName(group));
db.Set(group);
// Notify user group change
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, name: group.name, desc: group.desc, action: 'usergroupchange', links: group.links, msg: 'Added user ' + chguser.name + ' to user group ' + group.name, domain: domain.id };
@ -1884,7 +1884,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if ((group.links != null) && (group.links[command.userid] != null)) {
change = true;
delete group.links[command.userid];
db.Set(common.escapeLinksFieldName(group));
db.Set(group);
// Notify user group change
if (change) {
@ -2158,7 +2158,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
var links = {};
links[user._id] = { name: user.name, rights: 4294967295 };
mesh = { type: 'mesh', _id: meshid, name: command.meshname, mtype: command.meshtype, desc: command.desc, domain: domain.id, links: links };
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
parent.meshes[meshid] = mesh;
parent.parent.AddEventDispatch([meshid], ws);
@ -2230,7 +2230,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
var xgroup = parent.userGroups[j];
if (xgroup && xgroup.links) {
delete xgroup.links[mesh._id];
db.Set(common.escapeLinksFieldName(xgroup));
db.Set(xgroup);
// Notify user group change
var targets = ['*', 'server-ugroups', user._id, xgroup._id];
@ -2251,7 +2251,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Mark the mesh as deleted
mesh.deleted = new Date(); // Mark the time this mesh was deleted, we can expire it at some point.
db.Set(common.escapeLinksFieldName(mesh)); // We don't really delete meshes because if a device connects to is again, we will un-delete it.
db.Set(mesh); // We don't really delete meshes because if a device connects to is again, we will un-delete it.
// Delete all devices attached to this mesh in the database
db.RemoveMeshDocuments(command.meshid);
@ -2304,7 +2304,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
if (change != '') {
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, flags: mesh.flags, consent: mesh.consent, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id, invite: mesh.invite };
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.parent.DispatchEvent(['*', mesh._id, user._id], obj, event);
@ -2356,7 +2356,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (newuser.links == null) { newuser.links = {}; }
if (newuser.links[command.meshid]) { newuser.links[command.meshid].rights = command.meshadmin; } else { newuser.links[command.meshid] = { rights: command.meshadmin }; }
if (newuserid.startsWith('user/')) { db.SetUser(newuser); }
else if (newuserid.startsWith('ugrp/')) { db.Set(common.escapeLinksFieldName(newuser)); }
else if (newuserid.startsWith('ugrp/')) { db.Set(newuser); }
parent.parent.DispatchEvent([newuser._id], obj, 'resubscribe');
if (newuserid.startsWith('user/')) {
@ -2375,7 +2375,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Add userid to the mesh
mesh.links[newuserid] = { name: newuser.name, rights: command.meshadmin };
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
// Notify mesh change
var event = { etype: 'mesh', username: newuser.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Added user ' + newuser.name + ' to mesh ' + mesh.name, domain: domain.id, invite: mesh.invite };
@ -2402,6 +2402,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
try {
if (common.validateString(command.nodeid, 1, 1024) == false) { err = 'Invalid nodeid'; } // Check the nodeid
else if (common.validateInt(command.rights) == false) { err = 'Invalid rights'; } // Device rights must be an integer
else if ((command.rights & 7) != 0) { err = 'Invalid rights'; } // EDITMESH, MANAGEUSERS or MANAGECOMPUTERS rights can't be assigned to a user to device link
else if ((common.validateStrArray(command.usernames, 1, 64) == false) && (common.validateStrArray(command.userids, 1, 128) == false)) { err = 'Invalid usernames'; } // Username is between 1 and 64 characters
else {
if (command.nodeid.indexOf('/') == -1) { command.nodeid = 'node/' + domain.id + '/' + command.meshid; }
@ -2421,8 +2422,70 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
for (var i in command.usernames) { command.userids.push('user/' + domain.id + '/' + command.usernames[i].toLowerCase()); }
}
// TODO
//console.log(command);
// Get the node and the rights for this node
parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
// Check if already in the right mesh
if ((node == null) || (node.meshid == command.meshid)) return;
var dispatchTargets = ['*', node.meshid, node._id];
// Check that we have rights to manage users on this device
if ((rights & MESHRIGHT_MANAGEUSERS) == 0) return;
// Add the new link to the users
var nodeChanged = false;
for (var i in command.userids) {
var newuserid = command.userids[i];
var newuser = parent.users[newuserid];
if (newuser != null) {
// Add this user to the dispatch target list
dispatchTargets.push(newuser._id);
if (command.rights == 0) {
// Remove link to this user
if (newuser.links != null) {
delete newuser.links[command.nodeid];
if (Object.keys(newuser.links).length == 0) { delete newuser.links; }
}
// Remove link to this device
if (node.links != null) {
delete node.links[newuserid];
nodeChanged = true;
if (Object.keys(node.links).length == 0) { delete node.links; }
}
} else {
// Add the new link to this user
if (newuser.links == null) { newuser.links = {}; }
newuser.links[command.nodeid] = { rights: command.rights };
// Add the new link to the device
if (node.links == null) { node.links = {}; }
node.links[newuserid] = { rights: command.rights }
nodeChanged = true;
}
// Save the user to the database
db.SetUser(newuser);
// Notify user change
var targets = ['*', 'server-users', newuserid._id];
var event = { etype: 'user', userid: newuserid._id, username: newuserid.name, action: 'accountchange', msg: (command.rights == 0) ? ('Removed user device rights for ' + user.name) : ('Changed user device rights for ' + user.name), domain: domain.id, account: parent.CloneSafeUser(newuser) };
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
parent.parent.DispatchEvent(targets, obj, event);
}
}
// Save the device
if (nodeChanged == true) {
// Save the node to the database
db.Set(node);
// Event the node change
var event = { etype: 'node', userid: user._id, username: user.name, action: 'changenode', nodeid: node._id, domain: domain.id, msg: (command.rights == 0) ? ('Removed user device rights for ' + node.name) : ('Changed user device rights for ' + node.name), node: parent.CloneSafeNode(node) }
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.parent.DispatchEvent(dispatchTargets, obj, event);
}
});
break;
}
@ -2461,7 +2524,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if ((delmeshrights == 0xFFFFFFFF) && (mesh.links[deluserid].rights != 0xFFFFFFFF)) return; // A non-admin can't kick out an admin
delete deluser.links[command.meshid];
if (deluserid.startsWith('user/')) { db.SetUser(deluser); }
else if (deluserid.startsWith('ugrp/')) { db.Set(common.escapeLinksFieldName(deluser)); }
else if (deluserid.startsWith('ugrp/')) { db.Set(deluser); }
parent.parent.DispatchEvent([deluser._id], obj, 'resubscribe');
if (deluserid.startsWith('user/')) {
@ -2483,7 +2546,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Remove user from the mesh
if (mesh.links[command.userid] != null) {
delete mesh.links[command.userid];
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
// Notify mesh change
var event;
@ -2528,7 +2591,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (command.amtpolicy.type === 2) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, badpass: command.amtpolicy.badpass, cirasetup: command.amtpolicy.cirasetup }; }
else if (command.amtpolicy.type === 3) { amtpolicy = { type: command.amtpolicy.type, password: command.amtpolicy.password, cirasetup: command.amtpolicy.cirasetup }; }
mesh.amt = amtpolicy;
db.Set(common.escapeLinksFieldName(mesh));
db.Set(mesh);
var amtpolicy2 = Object.assign({}, amtpolicy); // Shallow clone
delete amtpolicy2.password;
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, amt: amtpolicy2, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id, invite: mesh.invite };

View File

@ -653,7 +653,7 @@
"default-mobile.handlebars->9->246",
"default-mobile.handlebars->9->70",
"default.handlebars->27->1237",
"default.handlebars->27->1483",
"default.handlebars->27->1485",
"default.handlebars->27->653"
]
},
@ -2361,7 +2361,7 @@
"ru": "Добавить участие",
"zh-chs": "添加會員",
"xloc": [
"default.handlebars->27->1479"
"default.handlebars->27->1481"
]
},
{
@ -2847,7 +2847,7 @@
"ru": "Счетчик ошибок агента",
"zh-chs": "座席錯誤計數器",
"xloc": [
"default.handlebars->27->1492"
"default.handlebars->27->1494"
]
},
{
@ -2913,7 +2913,7 @@
"ru": "Сессии агентов",
"zh-chs": "座席會議",
"xloc": [
"default.handlebars->27->1508"
"default.handlebars->27->1510"
]
},
{
@ -3035,7 +3035,7 @@
"ru": "Агенты",
"zh-chs": "代理商",
"xloc": [
"default.handlebars->27->1521"
"default.handlebars->27->1523"
]
},
{
@ -3766,7 +3766,7 @@
"ru": "Вы уверенны, что {0} плагин: {1}",
"zh-chs": "您確定要{0}插件嗎:{1}",
"xloc": [
"default.handlebars->27->1558"
"default.handlebars->27->1560"
]
},
{
@ -4158,7 +4158,7 @@
"ru": "Плохой ключ",
"zh-chs": "錯誤的簽名",
"xloc": [
"default.handlebars->27->1499"
"default.handlebars->27->1501"
]
},
{
@ -4175,7 +4175,7 @@
"ru": "Плохой веб-сертификат",
"zh-chs": "錯誤的網絡證書",
"xloc": [
"default.handlebars->27->1498"
"default.handlebars->27->1500"
]
},
{
@ -4410,7 +4410,7 @@
"ru": "CIRA Сервер",
"zh-chs": "CIRA服務器",
"xloc": [
"default.handlebars->27->1549"
"default.handlebars->27->1551"
]
},
{
@ -4427,7 +4427,7 @@
"ru": "CIRA Сервер команды",
"zh-chs": "CIRA服務器命令",
"xloc": [
"default.handlebars->27->1550"
"default.handlebars->27->1552"
]
},
{
@ -4444,7 +4444,7 @@
"ru": "Загрузка CPU",
"zh-chs": "CPU負載",
"xloc": [
"default.handlebars->27->1513"
"default.handlebars->27->1515"
]
},
{
@ -4461,7 +4461,7 @@
"ru": "Загрузка CPU за последние 15 минут",
"zh-chs": "最近15分鐘的CPU負載",
"xloc": [
"default.handlebars->27->1516"
"default.handlebars->27->1518"
]
},
{
@ -4478,7 +4478,7 @@
"ru": "Загрузка CPU за последние 5 минут",
"zh-chs": "最近5分鐘的CPU負載",
"xloc": [
"default.handlebars->27->1515"
"default.handlebars->27->1517"
]
},
{
@ -4495,7 +4495,7 @@
"ru": "Загрузка CPU за последнюю минуту",
"zh-chs": "最後一分鐘的CPU負載",
"xloc": [
"default.handlebars->27->1514"
"default.handlebars->27->1516"
]
},
{
@ -4550,7 +4550,7 @@
"ru": "Ошибка вызова",
"zh-chs": "通話錯誤",
"xloc": [
"default.handlebars->27->1559"
"default.handlebars->27->1561"
]
},
{
@ -4968,7 +4968,7 @@
"ru": "Проверка...",
"zh-chs": "檢查...",
"xloc": [
"default.handlebars->27->1555",
"default.handlebars->27->1557",
"default.handlebars->27->778"
]
},
@ -5197,7 +5197,7 @@
"en": "Clear this notification",
"nl": "Wis deze melding",
"xloc": [
"default.handlebars->27->1486"
"default.handlebars->27->1488"
]
},
{
@ -5560,7 +5560,13 @@
"zh-chs": "確認刪除設備組{0}",
"xloc": [
"default.handlebars->27->1384",
"default.handlebars->27->1481"
"default.handlebars->27->1483"
]
},
{
"en": "Confirm removal of device {0}?",
"xloc": [
"default.handlebars->27->1476"
]
},
{
@ -5577,7 +5583,7 @@
"ru": "Подтвердить удаление группы {0}?",
"zh-chs": "確認刪除組{0}",
"xloc": [
"default.handlebars->27->1477"
"default.handlebars->27->1479"
]
},
{
@ -5728,7 +5734,7 @@
"ru": "Подключено Intel® AMT",
"zh-chs": "連接的英特爾®AMT",
"xloc": [
"default.handlebars->27->1504"
"default.handlebars->27->1506"
]
},
{
@ -5745,7 +5751,7 @@
"ru": "Подключенные пользователи",
"zh-chs": "關聯用戶",
"xloc": [
"default.handlebars->27->1509"
"default.handlebars->27->1511"
]
},
{
@ -5817,7 +5823,7 @@
"ru": "Подключений ",
"zh-chs": "連接數",
"xloc": [
"default.handlebars->27->1520"
"default.handlebars->27->1522"
]
},
{
@ -5834,7 +5840,7 @@
"ru": "Ретранслятор подключения",
"zh-chs": "連接繼電器",
"xloc": [
"default.handlebars->27->1548"
"default.handlebars->27->1550"
]
},
{
@ -5941,7 +5947,7 @@
"ru": "Cookie-кодировщик",
"zh-chs": "Cookie編碼器",
"xloc": [
"default.handlebars->27->1534"
"default.handlebars->27->1536"
]
},
{
@ -6201,7 +6207,7 @@
"ru": "Основной сервер",
"zh-chs": "核心服務器",
"xloc": [
"default.handlebars->27->1533"
"default.handlebars->27->1535"
]
},
{
@ -7235,6 +7241,7 @@
"zh-chs": "設備",
"xloc": [
"default.handlebars->27->1150",
"default.handlebars->27->1458",
"default.handlebars->container->column_l->p1->devListToolbarSpan->1->0->9->devListToolbarSort->sortselect->5"
]
},
@ -7273,7 +7280,6 @@
"default.handlebars->27->1148",
"default.handlebars->27->1149",
"default.handlebars->27->1380",
"default.handlebars->27->1458",
"default.handlebars->27->1467",
"default.handlebars->27->1473"
]
@ -7314,7 +7320,7 @@
"default.handlebars->27->1352",
"default.handlebars->27->1365",
"default.handlebars->27->1420",
"default.handlebars->27->1507",
"default.handlebars->27->1509",
"default.handlebars->container->column_l->p2->9"
]
},
@ -8309,7 +8315,7 @@
"ru": "Скопировать агент",
"zh-chs": "代理重複",
"xloc": [
"default.handlebars->27->1503"
"default.handlebars->27->1505"
]
},
{
@ -8738,7 +8744,7 @@
"en": "Email Traffic",
"nl": "E-mailverkeer",
"xloc": [
"default.handlebars->27->1542"
"default.handlebars->27->1544"
]
},
{
@ -9450,7 +9456,7 @@
"ru": "Внешний",
"zh-chs": "外部",
"xloc": [
"default.handlebars->27->1527"
"default.handlebars->27->1529"
]
},
{
@ -9882,8 +9888,8 @@
"ru": "Свободно",
"zh-chs": "自由",
"xloc": [
"default.handlebars->27->1488",
"default.handlebars->27->1490"
"default.handlebars->27->1490",
"default.handlebars->27->1492"
]
},
{
@ -10731,7 +10737,7 @@
"pt": "Total da pilha",
"zh-chs": "堆總數",
"xloc": [
"default.handlebars->27->1529"
"default.handlebars->27->1531"
]
},
{
@ -10746,7 +10752,7 @@
"pt": "Pilha usada",
"zh-chs": "堆使用",
"xloc": [
"default.handlebars->27->1528"
"default.handlebars->27->1530"
]
},
{
@ -11404,8 +11410,8 @@
"xloc": [
"default.handlebars->27->1226",
"default.handlebars->27->1232",
"default.handlebars->27->1525",
"default.handlebars->27->1547"
"default.handlebars->27->1527",
"default.handlebars->27->1549"
]
},
{
@ -12098,7 +12104,7 @@
"ru": "Некорректный тип группы устройств",
"zh-chs": "無效的設備組類型",
"xloc": [
"default.handlebars->27->1502"
"default.handlebars->27->1504"
]
},
{
@ -12115,7 +12121,7 @@
"ru": "Некорректный JSON",
"zh-chs": "無效的JSON",
"xloc": [
"default.handlebars->27->1496"
"default.handlebars->27->1498"
]
},
{
@ -12167,7 +12173,7 @@
"ru": "Некорректная сигнатура PKCS",
"zh-chs": "無效的PKCS簽名",
"xloc": [
"default.handlebars->27->1494"
"default.handlebars->27->1496"
]
},
{
@ -12184,7 +12190,7 @@
"ru": "Некорректная сигнатура RSA",
"zh-chs": "無效的RSA密碼",
"xloc": [
"default.handlebars->27->1495"
"default.handlebars->27->1497"
]
},
{
@ -13205,7 +13211,7 @@
"ru": "Меньше",
"zh-chs": "減",
"xloc": [
"default.handlebars->27->1561"
"default.handlebars->27->1563"
]
},
{
@ -14222,7 +14228,7 @@
"ru": "Сообщения главного сервера",
"zh-chs": "主服務器消息",
"xloc": [
"default.handlebars->27->1536"
"default.handlebars->27->1538"
]
},
{
@ -14596,7 +14602,7 @@
"ru": "Достигнуто максимальное число сессий",
"zh-chs": "達到的會話數上限",
"xloc": [
"default.handlebars->27->1500"
"default.handlebars->27->1502"
]
},
{
@ -14650,7 +14656,7 @@
"ru": "Мегабайт",
"zh-chs": "兆字節",
"xloc": [
"default.handlebars->27->1526"
"default.handlebars->27->1528"
]
},
{
@ -14667,7 +14673,7 @@
"ru": "ОЗУ",
"zh-chs": "記憶",
"xloc": [
"default.handlebars->27->1517",
"default.handlebars->27->1519",
"default.handlebars->27->743",
"default.handlebars->container->column_l->p40->3->1->p40type->3"
]
@ -14800,7 +14806,7 @@
"ru": "Трафик MeshAgent",
"zh-chs": "MeshAgent流量",
"xloc": [
"default.handlebars->27->1538"
"default.handlebars->27->1540"
]
},
{
@ -14817,7 +14823,7 @@
"ru": "Обновление MeshAgent",
"zh-chs": "MeshAgent更新",
"xloc": [
"default.handlebars->27->1539"
"default.handlebars->27->1541"
]
},
{
@ -14916,7 +14922,7 @@
"ru": "Соединения сервера MeshCentral",
"zh-chs": "MeshCentral服務器對等",
"xloc": [
"default.handlebars->27->1537"
"default.handlebars->27->1539"
]
},
{
@ -15170,7 +15176,7 @@
"ru": "Диспетчер сообщения",
"zh-chs": "郵件調度程序",
"xloc": [
"default.handlebars->27->1535"
"default.handlebars->27->1537"
]
},
{
@ -15271,7 +15277,7 @@
"ru": "Еще",
"zh-chs": "更多",
"xloc": [
"default.handlebars->27->1560"
"default.handlebars->27->1562"
]
},
{
@ -15956,7 +15962,7 @@
"zh-chs": "找不到活動",
"xloc": [
"default.handlebars->27->1273",
"default.handlebars->27->1482",
"default.handlebars->27->1484",
"default.handlebars->27->691"
]
},
@ -17000,7 +17006,7 @@
"ru": "Произошло в {0}",
"zh-chs": "發生在{0}",
"xloc": [
"default.handlebars->27->1485"
"default.handlebars->27->1487"
]
},
{
@ -18015,7 +18021,7 @@
"ru": "Действие плагина",
"zh-chs": "插件動作",
"xloc": [
"default.handlebars->27->1557",
"default.handlebars->27->1559",
"default.handlebars->27->159"
]
},
@ -18707,7 +18713,7 @@
"ru": "RSS",
"zh-chs": "的RSS",
"xloc": [
"default.handlebars->27->1530"
"default.handlebars->27->1532"
]
},
{
@ -18886,7 +18892,7 @@
"ru": "Число ретрансляций",
"zh-chs": "中繼計數",
"xloc": [
"default.handlebars->27->1512"
"default.handlebars->27->1514"
]
},
{
@ -18902,7 +18908,7 @@
"ru": "Ошибки ретранслятора",
"zh-chs": "中繼錯誤",
"xloc": [
"default.handlebars->27->1505"
"default.handlebars->27->1507"
]
},
{
@ -18918,8 +18924,8 @@
"ru": "Сессии ретранслятора",
"zh-chs": "接力會議",
"xloc": [
"default.handlebars->27->1511",
"default.handlebars->27->1524"
"default.handlebars->27->1513",
"default.handlebars->27->1526"
]
},
{
@ -19193,7 +19199,7 @@
"zh-chs": "刪除設備組",
"xloc": [
"default.handlebars->27->1383",
"default.handlebars->27->1480"
"default.handlebars->27->1482"
]
},
{
@ -19210,7 +19216,8 @@
"ru": "Удалить пользователя",
"zh-chs": "刪除用戶",
"xloc": [
"default.handlebars->27->1476"
"default.handlebars->27->1475",
"default.handlebars->27->1478"
]
},
{
@ -20603,7 +20610,7 @@
"ru": "Сертификат сервера",
"zh-chs": "服務器證書",
"xloc": [
"default.handlebars->27->1540"
"default.handlebars->27->1542"
]
},
{
@ -20616,7 +20623,7 @@
"pt": "Banco de Dados do Servidor",
"zh-chs": "服務器數據庫",
"xloc": [
"default.handlebars->27->1541"
"default.handlebars->27->1543"
]
},
{
@ -20723,7 +20730,7 @@
"ru": "Состояние сервера",
"zh-chs": "服務器狀態",
"xloc": [
"default.handlebars->27->1491"
"default.handlebars->27->1493"
]
},
{
@ -20757,7 +20764,7 @@
"ru": "Трассировка сервера",
"zh-chs": "服務器跟踪",
"xloc": [
"default.handlebars->27->1551"
"default.handlebars->27->1553"
]
},
{
@ -20893,7 +20900,7 @@
"ru": "ServerStats.csv",
"zh-chs": "ServerStats.csv",
"xloc": [
"default.handlebars->27->1532"
"default.handlebars->27->1534"
]
},
{
@ -22869,7 +22876,7 @@
"ru": "На данный момент уведомлений нет",
"zh-chs": "目前沒有任何通知",
"xloc": [
"default.handlebars->27->1484"
"default.handlebars->27->1486"
]
},
{
@ -23995,7 +24002,7 @@
"default-mobile.handlebars->9->174",
"default-mobile.handlebars->9->175",
"default.handlebars->27->13",
"default.handlebars->27->1475",
"default.handlebars->27->1477",
"default.handlebars->27->364",
"default.handlebars->27->41",
"default.handlebars->27->42",
@ -24037,7 +24044,7 @@
"ru": "Неизвестное действие",
"zh-chs": "未知動作",
"xloc": [
"default.handlebars->27->1497"
"default.handlebars->27->1499"
]
},
{
@ -24069,7 +24076,7 @@
"xloc": [
"default.handlebars->27->1376",
"default.handlebars->27->1463",
"default.handlebars->27->1501"
"default.handlebars->27->1503"
]
},
{
@ -24086,7 +24093,7 @@
"ru": "Неизвестная группа",
"zh-chs": "未知群組",
"xloc": [
"default.handlebars->27->1493"
"default.handlebars->27->1495"
]
},
{
@ -24196,7 +24203,7 @@
"ru": "Актуально",
"zh-chs": "最新",
"xloc": [
"default.handlebars->27->1556"
"default.handlebars->27->1558"
]
},
{
@ -24436,8 +24443,8 @@
"ru": "Использовано",
"zh-chs": "用過的",
"xloc": [
"default.handlebars->27->1487",
"default.handlebars->27->1489"
"default.handlebars->27->1489",
"default.handlebars->27->1491"
]
},
{
@ -24511,7 +24518,7 @@
"ru": "Учетные записи пользователей",
"zh-chs": "用戶帳號",
"xloc": [
"default.handlebars->27->1506"
"default.handlebars->27->1508"
]
},
{
@ -24565,7 +24572,7 @@
"xloc": [
"default.handlebars->27->1147",
"default.handlebars->27->1354",
"default.handlebars->27->1478"
"default.handlebars->27->1480"
]
},
{
@ -24703,7 +24710,7 @@
"ru": "Сессии пользователя",
"zh-chs": "用戶會話",
"xloc": [
"default.handlebars->27->1523"
"default.handlebars->27->1525"
]
},
{
@ -24858,7 +24865,7 @@
"xloc": [
"default.handlebars->27->1353",
"default.handlebars->27->1364",
"default.handlebars->27->1522",
"default.handlebars->27->1524",
"default.handlebars->container->topbar->1->1->UsersSubMenuSpan->UsersSubMenu->1->0->UsersGeneral"
]
},
@ -24876,7 +24883,7 @@
"ru": "Сессии пользователей",
"zh-chs": "用戶會話",
"xloc": [
"default.handlebars->27->1510"
"default.handlebars->27->1512"
]
},
{
@ -25270,8 +25277,8 @@
"ru": "Веб-сервер",
"zh-chs": "網絡服務器",
"xloc": [
"default.handlebars->27->1543",
"default.handlebars->27->1544"
"default.handlebars->27->1545",
"default.handlebars->27->1546"
]
},
{
@ -25288,7 +25295,7 @@
"ru": "Запросы веб-сервера",
"zh-chs": "Web服務器請求",
"xloc": [
"default.handlebars->27->1545"
"default.handlebars->27->1547"
]
},
{
@ -25305,7 +25312,7 @@
"ru": "Ретранслятор Web Socket",
"zh-chs": "Web套接字中繼",
"xloc": [
"default.handlebars->27->1546"
"default.handlebars->27->1548"
]
},
{
@ -26142,7 +26149,7 @@
"ru": "\\\\'",
"zh-chs": "\\\\'",
"xloc": [
"default.handlebars->27->1554"
"default.handlebars->27->1556"
]
},
{
@ -26381,7 +26388,7 @@
"ru": "свободно",
"zh-chs": "自由",
"xloc": [
"default.handlebars->27->1518"
"default.handlebars->27->1520"
]
},
{
@ -26675,7 +26682,7 @@
"ru": "servertrace.csv",
"zh-chs": "servertrace.csv",
"xloc": [
"default.handlebars->27->1553"
"default.handlebars->27->1555"
]
},
{
@ -26725,7 +26732,7 @@
"ru": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss",
"zh-chs": "時間conn.agentconn.usersconn.usersessionsconn.relaysessionconn.intelamtmem.externalmem.heapusedmem.heaptotalmem.rss",
"xloc": [
"default.handlebars->27->1531"
"default.handlebars->27->1533"
]
},
{
@ -26741,7 +26748,7 @@
"ru": "time, source, message",
"zh-chs": "時間,來源,訊息",
"xloc": [
"default.handlebars->27->1552"
"default.handlebars->27->1554"
]
},
{
@ -26771,7 +26778,7 @@
"ru": "всего",
"zh-chs": "總",
"xloc": [
"default.handlebars->27->1519"
"default.handlebars->27->1521"
]
},
{

View File

@ -2419,6 +2419,7 @@
node.tags = message.event.node.tags;
node.userloc = message.event.node.userloc;
node.rdpport = message.event.node.rdpport;
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 = {};
if (message.event.node.agent.ver != null) { node.agent.ver = message.event.node.agent.ver; }
@ -8433,10 +8434,10 @@
} else if (userid === 4) {
var y = '', firstMeshId = null;
for (var i in meshes) { y += '<option value=' + encodeURIComponent(meshes[i]._id) + '>' + EscapeHtml(meshes[i].name) + '</option>'; if (firstMeshId == null) { firstMeshId = meshes[i]._id; } }
x += addHtmlValue("Device Group", '<div style=width:230px;margin:0;padding:0><select onchange=p20changeMeshAddMeshUserDialog() id=dp2meshid style=width:100%>' + y + '</select></div>');
x += addHtmlValue("Device Group", '<div style=width:230px;margin:0;padding:0><select onchange=p20changeMeshAddMeshUserDialog(4) id=dp2meshid style=width:100%>' + y + '</select></div>');
y = '';
for (var i in nodes) { if (nodes[i].meshid == firstMeshId) { y += '<option value=' + encodeURIComponent(nodes[i]._id) + '>' + EscapeHtml(nodes[i].name) + '</option>'; } }
x += addHtmlValue("Device", '<div style=width:230px;margin:0;padding:0><select onchange=p20validateAddMeshUserDialog() id=dp2nodeid style=width:100%>' + y + '</select></div>');
x += addHtmlValue("Device", '<div style=width:230px;margin:0;padding:0><select onchange=p20validateAddMeshUserDialog(4) id=dp2nodeid style=width:100%>' + y + '</select></div>');
} else {
userid = decodeURIComponent(userid);
var uname = userid.split('/')[2];
@ -8513,7 +8514,7 @@
if (meshrights & 32768) { Q('p20uninstall').checked = true; }
}
}
p20validateAddMeshUserDialog();
p20validateAddMeshUserDialog(userid);
return false;
}
@ -8521,6 +8522,7 @@
var y = '', meshid = decodeURIComponent(Q('dp2meshid').value);
for (var i in nodes) { if (nodes[i].meshid == meshid) { y += '<option value=' + encodeURIComponent(nodes[i]._id) + '>' + EscapeHtml(nodes[i].name) + '</option>'; } }
QH('dp2nodeid', y);
p20validateAddMeshUserDialog(4);
}
function p20setname(name) {
@ -8533,14 +8535,36 @@
return false;
}
function p20validateAddMeshUserDialog() {
function p20validateAddMeshUserDialog(updateId) {
var ok = true;
if (updateId === 4) {
// Update user device rights
var devrights = 0, nodeid = decodeURIComponent(Q('dp2nodeid').value);
if ((nodeid != '') && (currentUser.links != null) && (currentUser.links[nodeid] != null)) { devrights = currentUser.links[nodeid].rights; }
Q('p20remotecontrol').checked = ((devrights & 8) != 0);
Q('p20meshagentconsole').checked = ((devrights & 16) != 0);
Q('p20meshserverfiles').checked = ((devrights & 32) != 0);
Q('p20wakedevices').checked = ((devrights & 64) != 0);
Q('p20editnotes').checked = ((devrights & 128) != 0);
Q('p20remoteview').checked = ((devrights & 256) != 0);
Q('p20noterminal').checked = ((devrights & 512) != 0);
Q('p20nofiles').checked = ((devrights & 1024) != 0);
Q('p20noamt').checked = ((devrights & 2048) != 0);
Q('p20remotelimitedinput').checked = ((devrights & 4096) != 0);
Q('p20limitevents').checked = ((devrights & 8192) != 0);
Q('p20chatnotify').checked = ((devrights & 16384) != 0);
Q('p20uninstall').checked = ((devrights & 32768) != 0);
Q('p20nodesktop').checked = ((devrights & 65536) != 0);
ok = (nodeid != '');
}
var meshrights = null;
if ((xxdialogTag === 1) || (xxdialogTag === 3)) {
meshrights = GetMeshRights(decodeURIComponent(Q('dp2groupid').value));
} else {
meshrights = GetMeshRights(currentMesh);
}
var ok = true;
if (Q('dp20username')) {
var xusers = Q('dp20username').value.split(',');
for (var i in xusers) {
@ -8569,14 +8593,15 @@
}
QE('idx_dlgOkButton', ok);
var nc;
if (Q('p20fulladmin') != null) {
var nc = !Q('p20fulladmin').checked;
nc = !Q('p20fulladmin').checked;
QE('p20fulladmin', meshrights == 0xFFFFFFFF);
QE('p20editmesh', nc && (meshrights == 0xFFFFFFFF));
QE('p20manageusers', nc);
QE('p20managecomputers', nc);
} else {
nc = true;
nc = (nodeid != '');
}
QE('p20remotecontrol', nc);
QE('p20meshagentconsole', nc);
@ -10205,13 +10230,13 @@
if (currentUser.links) {
for (var i in currentUser.links) {
if (i.startsWith('node/')) {
var cr = 0, r = currentUser.links[i].rights, node = getNodeFromId(i), trash = '', rights = "Partial Device Rights";
var r = currentUser.links[i].rights, node = getNodeFromId(i), trash = '', rights = "Partial Device Rights", cr = GetNodeRights(node);
if (node == null) { continue; }
if ((userinfo.links) && (userinfo.links[i] != null) && (userinfo.links[i].rights != null)) { cr = userinfo.links[i].rights; }
var nodename = node?EscapeHtml(node.name):('<i>' + "Unknown Device" + '</i>');
if (r == 0xFFFFFFFF) rights = "Full Device Rights"; else if (r == 0) rights = "No Rights";
if ((currentUser._id != userinfo._id) && ((cr & 2) != 0)) { trash = '<a href=# onclick=\'return p30removeNodeFromUser(event,"' + encodeURIComponent(node._id) + '")\' title=\"' + "Remove user rights to this device group" + '\" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
x += '<tr ' + (((++count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title=\"' + "Device Group" + '\" class=m99></div><div>&nbsp;' + nodename + '<div></div></div></td><td><div style=float:right>' + trash + '</div><div>' + rights + '</div></td></tr>';
x += '<tr ' + (((++count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title=\"' + "Device" + '\" class=si' + node.icon + '></div><div>&nbsp;' + nodename + '<div></div></div></td><td><div style=float:right>' + trash + '</div><div>' + rights + '</div></td></tr>';
}
}
}
@ -10220,6 +10245,7 @@
}
// Display common device groups
count = 1;
var deviceGroupCount = 0, newDeviceGroup = false;
for (var i in meshes) { deviceGroupCount++; if ((currentUser.links == null) || (currentUser.links[i] == null)) { newDeviceGroup = true; } }
if ((deviceGroupCount > 0) && (newDeviceGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(1)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device Group" + '</a>'; }
@ -10267,6 +10293,16 @@
QH('p30html2', x);
}
function p30removeNodeFromUser(event, nodeid) {
if (xxdialogMode) return;
var node = getNodeFromId(decodeURIComponent(nodeid))
setDialogMode(2, "Remove User", 3, p30removeNodeFromUserEx, format("Confirm removal of device {0}?", node.name), node);
}
function p30removeNodeFromUserEx(b, node) {
meshserver.send({ action: 'adddeviceuser', nodeid: node._id, nodename: node.name, userids: [ currentUser._id ], rights: 0 });
}
function p30RemoveUserGroup(button, ugrpid) {
if (xxdialogMode || (usergroups == null)) return;
var groupid = decodeURIComponent(ugrpid), group = usergroups[groupid];

View File

@ -203,6 +203,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
//function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
// Fetch all users from the database, keep this in memory
obj.db.GetAllType('user', function (err, docs) {
obj.common.unEscapeAllLinksFieldName(docs);
var domainUserCount = {}, i = 0;
for (i in parent.config.domains) { domainUserCount[i] = 0; }
for (i in docs) { var u = obj.users[docs[i]._id] = docs[i]; domainUserCount[u.domain]++; }
@ -1354,7 +1355,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var mesh = obj.meshes[meshid];
if (mesh) {
// Remove user from the mesh
if (mesh.links[userid] != null) { delete mesh.links[userid]; obj.db.Set(obj.common.escapeLinksFieldName(mesh)); }
if (mesh.links[userid] != null) { delete mesh.links[userid]; obj.db.Set(mesh); }
// Notify mesh change
var change = 'Removed user ' + user.name + ' from group ' + mesh.name;
obj.parent.DispatchEvent(['*', mesh._id, user._id, userid], obj, { etype: 'mesh', userid: user._id, username: user.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id });

339
x.txt Normal file
View File

@ -0,0 +1,339 @@
[ { _id: 'user//544849534953415445535453494431',
type: 'user',
name: 'LDAP User1',
creation: 1555361291,
login: 1555365153,
domain: '',
links: { 'mesh//2odhtyJSNw0$wApTgsGPZoF1h5XovNbN9KbetvIzMkAhXsPyFXFfW@Dnwp6BMhis': [Object] },
siteadmin: 0,
email: 'aa@bb.com' },
{ _id: 'user//a@a.com',
creation: 1562625646,
domain: '',
email: 'a@a.com',
emailVerified: true,
hash: 'm9/LFPJ2HI/bXQdjBC1jGUF6ymLv3Zc0TClv34pEimRpWWtaslTu40qUXcBDRW4ImT8PCc+EMMsMen5VKfyDlk9hMIsERKVn06EMtT4XJZwqXStk2Pyx5qZy/wmE99bKsGOuXRaq3FXecEf+LK+fxfY4wEnCSQuKfSQll10cKcA=',
name: 'a@a.com',
passchange: 1562625646,
salt: 'OOfnPUaVYtJ7vYGGitFpyMySKdJq8AVspq87B1JoKfrGnMcEGtXlrs7OXbpLDOeYrOcaWQcgjSjNlYLBR4pYTFn71aC2GqDrAUSETPQlBtsxxxT+FA0VJic+q8Fds7Ef1ku+1A//UsK3/smqVEC8qNCzw8CI6OkNLBSU/bMDsZY=',
type: 'user',
login: 1562625674 },
{ type: 'user',
_id: 'user//aa',
name: 'aa',
creation: 1585276083,
domain: '',
email: 'aa@aa.com',
passchange: 1585276083,
salt: 'AU9ir/d/tuEgGPn3noRhdsjF3BCAKpVHrG0nEE0/U6x0Sqa+Z9Mf4yRHhn1XYw0tRyX3TVDAD6iNmDGHgxukXRuCfPgog1YIkU+8xKrxy0MF97gkJA+4s9zWpXBUbrTCyo4UQkV2fpQ4SkyTi84cU7lP46nNUIu4kJoUiTHlZLw=',
hash: 'V95ikU9NKh8jLxQJzc3qv1gOM4yK/cOasalrdTsoW2RUvrrWlt81UAy1NKrRFZx9zknYI1HbFtPuyZZyfFsDKtM7JuB4YL5nJeqqpFrPaqMsNw3GZ8tn2au+X4JxHlYeRF1Rrx90lbi7hrxfHHecBSU10reXiEMTLYg8uxpZILY=',
links:
{ 'mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c': [Object],
'ugrp//BXQUCOnHMBI14nGBhfTkvMlmb2K3FcP09Bu@3jpffr3nn@hxsm5RlpNLWheqQqYJ': [Object],
'ugrp//mKkqX0gLZ30jhPOs4cYdeCi5E@1P3OpypcAj1CKK14n04upXON36@5VE9BIez9h3': [Object],
'node//8wGlXgB8y@@Pe24vbVYUMoOxE2Si9eupK0gJ8wJW6GQCabaTYFmlHMjCyO3p0VEv': [Object] } },
{ _id: 'user//admin',
type: 'user',
name: 'admin',
domain: '',
creation: 1417814230,
salt: '5cTXOdvnH0G5ThP0A2clL8+1zmdhhONqEo2t6cYBtLp27eRKCx6eEnONculOtTRd+bCO5795A2aDvWlFLhnxutNONmEc8aTDju+CiAq5f6gCzuZnIY3CA9Oc9fqOM4AZ8l7Bg/IT/7MKYMB0djeBTvJkJ1wkAAUh3nCRbfo2PC8=',
hash: 'Pg7Hb/nA0S3HsacfuGbgRpxHsFchrMy1/XntdCwmqcwh/MvFecqggzZcDEmxhQ+mwjH2rnm+X2nbTxI9vDKgLndAjIDxY5eWN58lfRobniBV3I8zMmC/oQHf4YEPVTHMBxwU/s8MjbR38YjIICJdtkEAXHr4+NoAj8tsVIbQzWg=',
siteadmin: 4294967295,
links:
{ 'mesh//1bc82505ef750af28b19292eaf2260eae83bc2939a367f1a885efe865b729193': [Object],
'mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c': [Object],
'mesh//93c713c5cda428bb06777a7e7cd8075527f8a2f305945ac241852b37b1f30739': [Object],
'mesh//acf0460d17df45ff977d2ceb3fcc84ced94a68bc67ef513bbdb1fc59a591bd5d': [Object],
'mesh//sjN2rO85LGJCEXxW50TUI1vOCr@9zVpE4A@9jrAcPjA7n531RHZVMGpksK1yWY4O': [Object],
'mesh//5LNNn8cM9vKaUFs91inT2SNpTXgp0mlmI6Q29kCFEmoypqxYDfjY5N7Ae3QxwIVO': [Object],
'ugrp//BXQUCOnHMBI14nGBhfTkvMlmb2K3FcP09Bu@3jpffr3nn@hxsm5RlpNLWheqQqYJ': [Object] },
login: 1584903356,
email: 'ysainthilaire@hotmail.com',
emailVerified: true,
passchange: 1584914891,
pastlogin: 1584903334 },
{ type: 'user',
_id: 'user//bb',
name: 'bb',
creation: 1584487582,
domain: '',
email: 'bb@bb.com',
passchange: 1584487582,
salt: 'mccoD17PKETFJ26DUPBpaMdBxQ64WpYgEnUFcHkkFY8E6+J3q74i6Eaj/DrAOwBlXcS0hzbjb1XbCTugoOrUQb2zB32H0Fv5VJjoRUwSu3kO7gYlRTX6V6Gw8vLgcZ6PcSAelL7+Km6Zd1pAx/aiG4iZ816q6L2R7rsg2p7n82A=',
hash: 'CEBlvxFURwI9rGX6n5ucBi+Ukec2waPe++2khiLR1il7SXcUd+XnLVcY34w2t2rFrP0i8RCoC/tLgACko1h/SfIgFf4DWtnQSZ0x4U7YDm9o7go7yhmmbUMaNm+tGNGDTVDeVFBvoiTleE949sIJuOZ6iYHYVdW6VwkUTmy5/Hg=' },
{ _id: 'user//bob',
type: 'user',
name: 'bob',
creation: 1523394756,
domain: '',
email: 'bob@bob.com',
salt: '53GmyHZq0DyCEqX8ndsU8gnv/2QfmRb3F/a03Rorl+X/wH7mG5GvvYtXL4aS+NWsr43Mm4jFx38qTmQi961ufGy8RWEKjo3FsAPFq3fnYJvBpmWCDPz8svPe5UtU6yGi8SPUWQD3d5fb4FZ4Qub49agVG52lMAoI7+XPee1aodw=',
hash: 'CtvD7IX3ytdJXmlbYEMRhSq0GuHVmis/a6qKGeJpb6MDvcB1MOPVuR3KMguPHxC2VQci0nkYosft/0V4RFxB1Y0OBCEo480Lprpce/TbJ1OvbUGxTpt0EJ3W8GFDrHW2MEyJlG0DTqrz5fM4cNS4zgYoM6XltEN4YYOcDvoeYFc=',
login: 1578349086,
links: { 'ugrp//BXQUCOnHMBI14nGBhfTkvMlmb2K3FcP09Bu@3jpffr3nn@hxsm5RlpNLWheqQqYJ': [Object] },
siteadmin: 0,
pastlogin: 1578349086 },
{ _id: 'user//bryan',
type: 'user',
name: 'Bryan',
domain: '',
creation: 1373413118,
passtype: 1,
salt: 'GoMdgNplNW5Tq1LI38Fi0Q==',
hash: 'HSelSEKY8BJWdAV6D0PD4Gwiazg=',
links: { 'mesh//542dea438e6065bffa9318c149e9982440dba4ce6ba3ba2b577e0e127b6a7f24': [Object] },
siteadmin: 0,
login: null,
groups: [ 'test' ] },
{ type: 'user',
_id: 'user//cc',
name: 'cc',
email: 'cc@cc.com',
creation: 1580415619,
login: 1580415619,
domain: '',
salt: 'JKaqzhk6DQDmhPejyA8F60DZ/XuCAY6nHX+jDvIwHVuYOrZU45uYf1R1VJI0UXKGpt/uin3xfdWw/dtfhDyJETKlOb3xdHg52UVJnpkUBrxlumgI/KitDqhmZ7skoKwJmJ8lRn7aN8+j1DJlbhBN9OuhyU8gttzrzbMWhStOHRo=',
hash: '6JpuKMQHg8FwS5PDA7yVqh2/NOlStVc7TGjLkP3ZO2ZqO4jFU8780UgdtEEGaRw8fHiby6gLqxLQZhzGb1cF5ormiH2HSI+n6TDET0GuTYYHnYNrSWXG+EZOEn/sOybqL1I7hXKUeI2bnewUtxRcml9oOifgDVuBbNRDoPrl7I8=',
links: { 'mesh//qbu74CK7bX8AYu9gqZNGSad1poraKWlyay0yCLrx8jPZ@d6$ZQX0XcwMThPWqqRQ': [Object] } },
{ _id: 'user//dd',
type: 'user',
name: 'dd',
email: 'dd@dd.com',
creation: 1551389245,
login: 1551389245,
domain: '',
passhint: '',
salt: 'HiFDC9cDOxGKHIohkudzflVT8kNMD8Uy60Qt6/LIahJuBCIxcH3rPIqu/kEdo/+YyrMuHs83mudkvLHrsgCJXz4khqbI4owsJrAJ5UGuGaLbh08coGgzpMDjoDlSoxL3nF09+/ZsL3kPIn3jVxKQeepBgN+Vd5paOOGEy0n3z8o=',
hash: '/ak7hzgp4zbPEjYTe7bvOtamDNsccm/oV1wdZ7DUc4M7AVpXSIiKKNfBCLXgfi5T4FcHs75VEvnCwYeZCbKAFYeN/d4TYOdnPM6fWgAGk//MCScdawbJrnB9fiVXOA6GYU/SyXbHxX2TaRprjKfhk+Zc0vPCauDpg3xzTzISMXo=' },
{ _id: 'user//demo',
type: 'user',
name: 'demo',
domain: '',
creation: 1428090949,
salt: 'sGIIlqmi5YN8+BEBOYI2Ub+TGV0nAcE7UdM7itv80HGriQKtAeajer18WdJIsfEvXwEMjqftvEmNE1QLafb7edZ4LVTSe90+mluRxQ6na+GauoXIazTHCola+Ke3ySpedWuHvnKPrwQEWtTFDAp6UjppfwFtd8W6yAPyzYJwpfM=',
hash: '0YfvLDm9NIMOHcbK9lQon+dH70vlQRnTW+b1BdQCBIcx4HyM6NpPeEs+nU6wqDk6nXwBp50OpBNmPLlCslpZAFg6R4sQzIJEcirb8GZnRaABDus8kq3Gq23DWp45j/uwQMAA6Z4orqXmr0OHEMB9Cr+p2jg+c01QTM2FU+TUvBc=',
links: {},
login: 1513299316,
siteadmin: 0 },
{ _id: 'user//devbox\\default',
type: 'user',
name: 'DEVBOX\\Default',
domain: '',
sid: 'S-1-5-21-3031010259-3226202738-568380285-1001',
creation: 1548377831,
login: 1548377831 },
{ _id: 'user//eee',
creation: 1561833844,
domain: '',
email: 'eee@eee.com',
hash: 'ya2sbB16v1yiYcA/zS8glcrFZoB1uPpzu8kx5G0iELB87KDzMYr1M9WgecvYyhpYL27Qu+G1lM6w+cX1iHigUSB9stZRlBNy4r6go3IiZQqxIPQOwn5eWswgKqRXglAXfCp52b9WwcFLU31KklUZOadkSdGKk4b23ERhd8lMRkI=',
name: 'eee',
passchange: -1,
salt: 'ispJqptip9UX3yaSL7911MCAf577tXC4BF3h2PPGYIQPY4qw4QCMUwPvpo1bnKQUgKBuHVnZRtuyC/1dk87aEnmOgyoZVIhb4KSV8lzTDS1JkgT29ukxwngqbEaDnkzbc9vxQVboWTqveK+FMHqy6qzIVHOirqgfjv6PF26wWeE=',
type: 'user' },
{ _id: 'user//joe',
type: 'user',
name: 'joe',
email: 'joe@intel.com',
creation: 1551138573,
login: 1551138573,
domain: '',
passhint: '',
salt: 'z8lIYIkrHboKGo62rF5cyCfvHCrT2IQYpU6uufW5lMO0GWte+p8q9FEHct+xItY96azQmti8Cy/mczr5j53WPRtxnMtnf7DxI65GLJYrGqoQJ/InyNSYd0O4/r2tZlwn5hK8+/E8hi1MxuFBAGlC4guKAoS+W2x996POjgbqsu8=',
hash: 'q0UZypM0R2sk+VKDSXR7ouCMR/EYnaESJtNApE7ZxhHAjhDCxQQdnmTrSTvhPtp2seM9IOCK9YFjMR52sNxBfqtD1F+E4GcyaCxTC6NntEIMizVz1kw+hPmweo6u7Lu1EliDymHtrkmFvpqhfIb9b7ISpb7wL6LPsn7sfN1/R1o=',
groups: [ 'test' ] },
{ _id: 'user//joe.bob',
type: 'user',
name: 'joe.bob',
email: 'bob@bob.com',
creation: 1531530565,
login: 1531534497,
domain: '',
passhint: 'bob',
salt: '6P9m1LSHS+S1L7+HJO23pDBHn6eiZmAKXVckawjGNFPz8Py0zu6jDCcbP89lgnqLN8KjyWc7NO4dOPyL26QEkKOA2PghljDwjaWaCnX1EYkYDiJV3b4muHrQ0hVsdbYP/52gtRZAE5f0qM3xZjxfHz2dVyrRCFb+iNvCB/OiikQ=',
hash: 'yMsV9ATYiOcVOAjaH8Gxc6+jM28JwxsK0+GaA6b6Y8kL871sENd8/5nqi0QWYRKKahkpFe+xAaTdze/+/7vXt3Ly/WJsU7q8asZgORxqxWU0wsekFP2tnAjdiC/Grhj5euAXqft84p5aQHQt2PE/CoT+FOIVvUiM5gD/Iq1ev1M=',
links:
{ 'mesh//1fHXfQIiCOOOFw8lkIlUnXSQ3A75kFrKw2PvGQFkaAsGCM7mz@3$Mrr5NbPNTmxy': [Object],
'mesh//PleIaEpGvRNLCx6rLcsKOogtaKfEDI7Tm2YSPGUurBLqNzRgLPd4ZurifZonL$7X': [Object],
'mesh//8kWnSpFr$cIj2YvibBdMkBxBlcuNZp0yBZQSoWV12DTZV2f@34wJi5CIPMSUoOou': [Object],
'mesh//CWsMAU4u63zNLLvdmoZP8uPcg$lzLnVcC25buVmqI05r1Wxk3ngk1OEgyHoFg7Oa': [Object],
'mesh//Gt0Eo1GNpJmQ1WRwvKeIhibHBQ2j@XOV@omqmvsf8ZY6k3oKswvDdjzPn1KA4IQf': [Object],
'mesh//GXbvFkWNsVKJCBbTvhBHCgFAY5fayzcStTJeZ5TdDfLC0sDL5TDs1ALFm8hMFoQ9': [Object],
'mesh//7z0GW8pppHVGDw@Rz$fb1E29GnA9yExEKASjAf$r$hyBMP0$BSH$rVqWKCwxQ7D6': [Object],
'mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c': [Object] } },
{ _id: 'user//mytestuser',
type: 'user',
name: 'MyTestUser',
email: 'a@a.com',
creation: 1541494376,
login: 1541494376,
domain: '',
passhint: 'a',
salt: '3bURHy0OVDLNGJrEyQGs2UBhktEoJao9p4dIPS+uZwWdzPCcCZr4r7/dWlsjFGyKqCoWoStR6XzIFGElAAW5eUq2dM7lG9GXvrp59TzizKwTUAJWyCTfCmoP2jbTBjFLr5umBNsapiBY1HXXJxoRpJJJDGCt0ysETgIYjJfWUN8=',
hash: 'VzMdJ9paS12tH3KM3yUsVJXYt6tB/LJ8jX3665otE4AmQgaxBOXiEVr5Ff8oYd6MPonr6D93ACUems0R0NiX4EjGcOveT1zNijjaVYxFRu2PzkKayxqeupZQvniz6HdrtptEa96GpWXqXJ0dzsVbMcpfEKz1Tjk5cFku3swfZYw=' },
{ _id: 'user//null',
type: 'user',
name: 'Test User',
creation: 1555017483,
login: 1555017682,
domain: '',
links: { 'mesh//k0nAuG45xS5TSYR3s1kT1XGUonCM48sGbuf6D8dDlYFSbbHcxqGk2daZrVC4D@dg': [Object] } },
{ _id: 'user//ppp',
type: 'user',
name: 'ppp',
creation: 1557712716,
domain: '',
siteadmin: 192,
email: 'ppp@ppp.com',
passchange: 1557712716,
salt: 'M83AO69eUNCOUlHAoMMf9PoYits3d2+G5ml76VxS8Fve46TOwCK5pwHhCur3iKNDDOOz0/OrzrF1axyiB2kzQUQvs1DZgZlO+1F9DpTI7avibLYljRlrs1KBm7Bb910VYjQNNvKKLI+h7ls45s1wUFgWF2EngpECv9tq05UoX4M=',
hash: 'RDR75KY2bypDWxJEgYznG+HjyCPR3GSJVI4bGtAu4C8XMvnB+4+2g47TKVb8nM9MpWj4/M4XWQ87VhJIMXoCQ5qg6SeWdIXL3ab1UpXSzn7fAeFspqrQ8A9ZcnfN+OARL2gLL8qSchonebVfL3BdDqTgc64pn1MhctQUvylsRYE=' },
{ _id: 'user//qqq',
type: 'user',
name: 'qqq',
email: 'qqq@qqq.com',
creation: 1549852967,
login: 1549853132,
domain: '',
passhint: 'allq',
salt: '+pzWoML4DMmYZ3y9DFMEwkJz/sal3qDKHKnhmVu352zzZPzXC+mL/hbmHOSi1Quw65tMMLtcjXn5cquMFToX1DlsURnuDbxaINuzZ9pec6dxIn26EJ8urZ00bVXTSusv2xhcJuYKEabC/gKWpe6E0VR8xctEUjjqAgP1BCOAifo=',
hash: 'n7gXwzoFS9UkTHQbbuuabGjCJmRadzWENmkjwMBnNrhQwG2qLeD5f/A1EPKIwr2P39J0cClFHPt25kX0PtItEyJO5wcnVrbESfc3Jsm6nG+Kze0ayW3Na+iEmnwWMDZYNgFe3k95ubOXzKl/CCUjuW4RAEwj5f631XoTS6ygW1Y=',
siteadmin: 32 },
{ _id: 'user//robert',
type: 'user',
name: 'Robert',
email: 'robert@bob.com',
creation: 1543864529,
login: 1543864529,
domain: '',
passhint: 'robert',
salt: '/brZFf8ljdG2eZAFgBl3CaMnY5FGYPB93S3Y97wym/kUAVkF5NHlDVVNfmghC97VzZuHnlIoFlt4IUHbZHSc4/KAOc4pX/ZcyicsacMXyW+4CtDgSllnXeejK0nkVV/AdJSwKMQZ3K5+77TvydXbwLFuGoZ0NVOzCto/CgaWtsQ=',
hash: 'X7OlXcp514ay/HXV2qDsAQVerr2jWGdCUAVnl6FVsvw4XN+jgBsq8E7f0RnuAZp/BFIlqkLaj8TqYtpFPR87LCJdcg8LZ3Y7ygyiZp0rdpztyxBAJ3YyiFRrSvJB/u4JM0GJ88WPCRK6CbHwBlhg4i+VRSMPetn1XiemubK1Qv8=',
links: {} },
{ _id: 'user//rrr',
creation: 1561919781,
domain: '',
email: 'rrr@rrrt.com',
hash: 'o85W/QlWhRXHrIeyw+L2TXWnW5MDr+Dc+66MeH58iCxKIh/aMuLdOD9on3ViNbW9Wqt4f7wKxjletFVhJYwmd/3VvPLBxdvZ4r3c4El9I49vGavCngqlaHc69ohh30KVEXUYy3zzxyOFn7HukSSkCMmnsq/IKIpA6ZVR95GNQ54=',
name: 'rrr',
passchange: 1561919781,
salt: '1crF6xIQlbO2GYPRPksF7HUu1ytB9zJrDl6zd09OYFdDEQRuK+DhCLPJq5CTJU5Tg7GjVmIq/rXqGKQFlvTZ2/cLmELwN9l9UQeBsiyb7lxSusU3SRTCbYAZV4aPy97xHw+F1JlLtEaXSJ0TM1WwcBECW/qJ4ZeIDpQfNUw6HAY=',
type: 'user' },
{ _id: 'user//sampleuser',
creation: 1562012207,
domain: '',
hash: 'clVpJBetcpCd20KcvCJ4K1cCdodNIHSZW11tR/PzKnZDek0XjLCINucUK1wbXbsmqvE36AXPFDy0URSmJB3ohjkP02TDl3mDUGg+tmM+0Gh9CGTzImRG0xnPLoUtBo5QpRBItLUEz2wzzHn3Pds4fecAUSZUGH2K+icFBWG/2BU=',
name: 'SampleUser',
passchange: 1562012207,
salt: 'XQ9F2M9E2kumUFxqxFv48UxDyhHQroBS46ud7e1iaDH1cGZ+V78YQ3fo58NjTn0XkiJmS1usxlu+qXQEbGSM5e8EAS3qK9rXdZ78CMm7+NEz8AoxkzpmAeICuIXikOP488eseXJYItZzbr3jOMjvKra+nw1kpeVRbW3R0XHVVtc=',
type: 'user' },
{ _id: 'user//test',
creation: 1562534252,
domain: '',
email: 'test@test.com',
hash: 'FYtXnIWEW7fIrZSNwGx/Rl5Blsvqpl1LGs8exXWYrNJc3X6UzS7+qziti+i5M1m4yjiQLp5JzGuJkfdVDexua6y5Ixh15dEsoLSndE0QOSa+7Yo01FEy5LGuwGd6Rbs1yRsH4P4pGyMZhj5DsaYGLeNKiXgcMqjTKAhF0VGXxVs=',
login: 1562534252,
name: 'test',
salt: 'Kj1I+Xf9Bh+3uMNpH/LNzmonk/+kOjaW2rRKEFAolqQ1ngELtkqeEipBESGUNvNDblx8kTiNIIFda9e4fdAxZlHuX/AAIiBpw2saS5zYUPtmFnoBom2PTIzurHNYYXBz8vS3VCcTFv3ZbW3tg38jYX8z5h6blNzgwI51GkgDOP4=',
type: 'user' },
{ _id: 'user//test.user',
creation: 1558462786,
domain: '',
email: 'test.user@user.com',
hash: 'RVL0gdctx/WMMlrRkflAMURL7UxN4c1jos6/ZzVSAcTXbOozfWJeE5JzCZQFNnze0OTSltq1WQtRk5dJFhum8KhKkUGe/dVvC+u4qPs27RmzNdc3rNLKDLPXKyPqe0008e0pkjPiEYBZAVj9Cy8r4Aew5mrgpx4/fBIhzGz/6bo=',
login: 1558462857,
name: 'test.user',
salt: 'hH8ABQQ0srookeRbjIcl5uDz7tDYZYotaPTgTQVaoPuXNwBdXJanrfPtIfPSuruZTUeEP5/2kWgEakfMO/on09iZgcuLCSvS4nySNZZuZ7VbApgmsqfNAtPOULrHMuZchsBtCvUwiyTAOKyXmUNDD8txnmlfZmyCnqF49nc0DnU=',
siteadmin: 0,
type: 'user',
links: { 'mesh//MAIhngk0XrQaFqDWpvBBrLnGwQWUTKQ6Aa8UMNFVJ9dmtZoAEkZF1DAMKsTHQbXt': [Object] },
otphkeys: [ [Object] ],
otpkeys: { keys: [Object] },
passchange: 1558473367 },
{ _id: 'user//testuser',
type: 'user',
name: 'TestUser',
creation: 1523658499,
domain: '',
email: 'testuser@meshcentral.com',
salt: 'KsM9DOWsz3Ub8Q1m5ex/Ge7XP6fBJ+MMA8LqjXmSRhLE0HWfv4uWAarWjZYYYM4/kWKZZSjkQWMMzCeZul3krBTogZRqMUar+VgKgZbjW0vX6NvMFn32Y2m+K/YSyl0XQoN09nmU5EN/RA95bkTz3RK/pXsOYVNdCcojs1uISj0=',
hash: 'uMO6etn7jwT1BBFqIY+DSqozcMIlpIAu9d4ruhxNmu/5smo/8M7Pvwa42tCza0bNsBNybPB6xOEYa4z+2W30WQ2dnN1AaHvRltdllxrPjmW0PjuD/4cNG+Z6Lb3v6R6QIUxYpUwo7gC87rM4+KyGiMFUq83VG67T4AcBxtKhzm4=',
siteadmin: 32,
login: null,
links: {} },
{ _id: 'user//x1',
type: 'user',
name: 'x1',
creation: 1557869247,
domain: '',
siteadmin: 192,
email: 'x1@x',
passchange: 1557869247,
salt: 'X3E7xiTou1fRcRr+Rf5xBnCd6M7RtKishIjZyu+dm5KayLm6D/CCFkR9zuTyxqzuw4NZlp994jCvegryqBow0Db8sstcs/Vp8A2l4WUGcaNW6Yy9zVomJZE9xHuqRlUUU1J8SIlnrBrpcu3nXp4LRI3UOLroGSLbO9ojzYHnn/g=',
hash: 'sc3wb1cP/R4lngyKmI4rqK1nXM4RCa+ZQmhbF48E6D8GejAynmR1kgTTGAqS22CPcTMdHmsxy+nZh0Pncmv5Z9HbxyGhrgFwkeIUYxrq7AO6A0w1dEIG99Qk/Pa3AZO0w917kUFSS7Dz94ZAouskm/F84lynUqSSolTqgpVCkJE=' },
{ _id: 'user//x2',
type: 'user',
name: 'x2',
creation: 1557869247,
domain: '',
siteadmin: 192,
email: 'x2@x',
passchange: -1,
salt: 'DFp2VFHhVfSpaqglMTLNpcsbARAqAx4uVb4j9V6az3tSrArGd7MSwQHpA69Jq91PZtw/dkqci3lkq9u74u7PSAttsA5z9IenGiTNGDBCSv5eDqGVHZdTWfcNw7CJM86shJ9NL1OEJR3owLnZFPir3f4ZeOV+GmuRhBLv5NFvBEA=',
hash: 'bQLaZ36j4QuUJnvtbs84qdfTHWn40sL3Qndv3Pn8GtAUy2zgJdx6LGEhPKOyfizONibD2D2kH9SFqFGUDoZX+tQWwao4HRqY9spp6DtvqZu8rza2JR0Kyx0WbfjRtR6yW5TnvQC+xHd/aaSFmefPK/lxViUrGyzvbBM4e455xts=' },
{ type: 'user',
_id: 'user//zz',
name: 'zz',
creation: 1577396990,
domain: '',
email: 'zz@zz.vcom',
passchange: 1577396990,
salt: 'KHt8U1w8t/50xXo+9zk5Hra8ypSIuR7fntQRfyg5dvq8TWohl7NP5fYQX+AEvnrsP9lhbYghBV6c68UgiIdUOje0rZh6XA/oHiHmfUzANALZeNp16Czrhb5k8bAFKI7is4A5Hw1sViA3cOgnNO4GhZqM1vmNgE0YuJPnVL1+y9Q=',
hash: 'Ng6aEiTYGuPXG+BfJ2mt3cSJzM3iZslOo/hoX5w/CdRux3gqFkQTzwyHagJCozWHi0hq2omV+O9hzJlPZUU1Er9n7s9Yn0ssVJbT7un93n33gqaKwf2PivMMHMMKNZb7gtkgFwOIiQOSKHPN/eNs29rTixWPqr6JyMByXygvOZ8=' },
{ _id: 'user/customer1/admin',
type: 'user',
name: 'admin',
email: 'admin@admin.com',
creation: 1554414308,
login: 1559319199,
domain: 'customer1',
siteadmin: 4294967295,
salt: 'qqjKAHNRtdwcGlRUmlb67dXL8cjR8kur5Mu5j0i0HPqVkCO/oDpyl/xHFMDRt2U4VRT8v5XaD/GDeqYDpA+h6Wy3cJiENpElQx49WKRFlfgyO6t26wSUXFQd5jDjr/XijnktR5LALXRbwCkozbFoyot4uRneXu44OxrSdDDRHaI=',
hash: '32JbzlVq9ge7o/6Qn4ii/a/oYWJRaXmDi/pVtRjPCZAFiR8bBu3gkY2JrimyMAOvkfwQJkrBNZRrDjB2BjvzWofy6BdCMzkhdnYpJ2kbeL16Nz3qqI3IauXI9E5SbYyG5DCo5ERCA75CGGexLH9vaVl8hT5K0N6sgDS/dAGT7u4=',
links: { 'mesh/customer1/EaSw1hJBKjf1QApmilFSAIo1KhA@R@dgRHIDAUUZBaMBGEYJw9qlhOa7p0xfWZvN': [Object] } },
{ _id: 'user/devtest/a',
type: 'user',
name: 'a',
email: 'ylian.saint-hilaire@intel.com',
creation: 1514930104,
login: 1515724646,
domain: 'devtest',
passhint: 'a',
siteadmin: 4294967295,
salt: 'g4aZeKUV0aPjzW8YpALfO7SYcyY03vdJVGNSowLqOlWZrFmnActIo+AvDb7ydC+DpSCWBq5fTHBj4Eol++PXeqyjcbVAKfMoZzGA6gdqNJ+UgabpzcddGm3oYEWcuEbvIzlLXSkZA+2LeXwRM9LbiRwH/dY0TrHVO2pwg8Hc3NU=',
hash: '1+l9Wi2xEmoKNEH1jNkQGfI+F1gSId/SL7qAjxfe/lu5QvoFE4X9d3kajaC2GtWn73ilB5qmThOFqbL3nqut84EgHDmGWlxEJfGFytZwN0JlJSrid9OSKbfvS1E4P6jPWnbOLyiiKMWYktFwX2aNHRJZktrwcx07xpNuK7T5zFw=',
links: { 'mesh/devtest/8CvC1wI7ivS289DcIUcMwXivGD2nKuj5jpUQ0qBd5Xd@R@jGkKSAA24A6UA9YRTe': [Object] },
emailVerified: true },
{ _id: 'user/devtest/aa',
type: 'user',
name: 'aa',
email: 'aa@aa.com',
creation: 1552685405,
login: 1552685405,
domain: 'devtest',
salt: '7NX9z7hNOFXcVXGccbcyEs1en/dVf6SskT0wGMW46yR7sMWVPOGiCT9AdlaN6huYSbhCprFCu7YIqw4MYFboyq0bhGGAnovFSIVs+XcEjfIG7I7D00HDsRS7Cf5SO2SU8XEzjIr+RirYqZhEzRUQvnHEPNkJg8JT8GI1I+fYWLM=',
hash: 'wgh86y3OwRe+rcygmIYXuZGtetxoNuFKt2gBVClwxuS7tjYGLQu8Q9Hb4M7NWxCUFLUgq4JHmnvh0AMADGT+7NquDny6alTU5Yz8XUa0+qgiuUUX4LA5kuCoxxaqLIB/rsLoEMEMhFI9yRe0j3d1uAItVuHfyejl7+QvShkv26o=' },
{ _id: 'user/devtest/admin',
type: 'user',
name: 'admin',
email: 'admin@admin.com',
creation: 1552591371,
login: 1552692388,
domain: 'devtest',
salt: 'MOQqzm7q32/fk27Z00lPwGW1GTASDczli6lDt/7yb8eNhU6d1Wo5sF5Pl/TZcxmNrBzTiVOnqBQbAfwXTYj8fPazyUDarYQ5wYs7I2rVmH5IQAotBUaANwkFv5OBJ+JrlOqiJvoQLiB6yJwk9enQpbZw+2LJOLysPgNkXzAFtCg=',
hash: 'PXWMPJ6xNGlb9iUudI3uptVqZo5tz+fgK5/apDEaEr0W73pJAxekwpeiZy+gFkvdl7eSecYgnN6Krq5xoHbPC4cDNisLZYQNapBeVe5pjzHc7X3/kI364l/jiI2OVKT+GzfzS4sJYVaBvd+tledOFwn1PSzQ7UT4IP3YRywbI74=',
siteadmin: 4294967295,
links:
{ 'mesh/devtest/vqbVBqGofP8h3l9Wxgk$$Dh3NgpvGCmaiNiMZLvuHdolSbF3W7@qvwpKbJP4i2Bd': [Object],
'mesh/devtest/XJEZ5L3trxPBkZc@6E4CAXmzk2D@JvhAKf20RRMutxxE@H$dLW1Eo5PUVYb$k9UK': [Object] } } ]