diff --git a/meshagent.js b/meshagent.js index a9f009fc..4a7b701b 100644 --- a/meshagent.js +++ b/meshagent.js @@ -72,7 +72,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node // Event node deletion - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 }); // Disconnect all connections if needed const state = parent.parent.GetConnectivityState(obj.dbNodeKey); @@ -555,12 +555,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (adminUser.links == null) adminUser.links = {}; adminUser.links[obj.dbMeshKey] = { rights: 0xFFFFFFFF }; db.SetUser(adminUser); - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [adminUser._id]), obj, { etype: 'mesh', username: adminUser.name, meshid: obj.dbMeshKey, name: meshname, mtype: 2, desc: '', action: 'createmesh', links: links, msg: 'Mesh created: ' + obj.meshid, domain: domain.id }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [adminUser._id, obj.dbNodeKey]), obj, { etype: 'mesh', username: adminUser.name, meshid: obj.dbMeshKey, name: meshname, mtype: 2, desc: '', action: 'createmesh', links: links, msg: 'Mesh created: ' + obj.meshid, domain: domain.id }); } } else { if ((mesh != null) && (mesh.deleted != null) && (mesh.links)) { // Must un-delete this mesh - var ids = parent.CreateMeshDispatchTargets(mesh._id); + var ids = parent.CreateMeshDispatchTargets(mesh._id, [obj.dbNodeKey]); // See if users still exists, if so, add links to the mesh for (var userid in mesh.links) { @@ -640,13 +640,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { mesh = { type: 'mesh', _id: obj.dbMeshKey, name: obj.meshid, mtype: 2, desc: '', domain: domain.id, links: links }; db.Set(common.escapeLinksFieldName(mesh)); parent.meshes[obj.meshid] = mesh; - parent.parent.AddEventDispatch(parent.CreateMeshDispatchTargets(obj.meshid), ws); + parent.parent.AddEventDispatch(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), ws); if (adminUser.links == null) user.links = {}; adminUser.links[obj.meshid] = { rights: 0xFFFFFFFF }; //adminUser.subscriptions = parent.subscribe(adminUser._id, ws); db.SetUser(user); - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(meshid, [user._id]), obj, { etype: 'mesh', username: user.name, meshid: obj.meshid, name: obj.meshid, mtype: 2, desc: '', action: 'createmesh', links: links, msg: 'Mesh created: ' + obj.meshid, domain: domain.id }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(meshid, [user._id, obj.dbNodeKey]), obj, { etype: 'mesh', username: user.name, meshid: obj.meshid, name: obj.meshid, mtype: 2, desc: '', action: 'createmesh', links: links, msg: 'Mesh created: ' + obj.meshid, domain: domain.id }); } } @@ -741,7 +741,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, node: parent.CloneSafeNode(device) }; if (log == 0) { event.nolog = 1; } else { event.msg = 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', '); } if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event); } } @@ -781,9 +781,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Event the new node if (obj.agentInfo.capabilities & 0x20) { // This is a temporary agent, don't log. - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, { etype: 'node', action: 'addnode', node: device, domain: domain.id, nolog: 1 }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, { etype: 'node', action: 'addnode', node: device, domain: domain.id, nolog: 1 }); } else { - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, { etype: 'node', action: 'addnode', node: device, msg: ('Added device ' + obj.agentInfo.computerName + ' to mesh ' + mesh.name), domain: domain.id }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, { etype: 'node', action: 'addnode', node: device, msg: ('Added device ' + obj.agentInfo.computerName + ' to mesh ' + mesh.name), domain: domain.id }); } completeAgentConnection3(device, mesh); @@ -1114,7 +1114,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { } catch (ex) { } // Event the node interface information change (This is a lot of traffic, probably don't need this). - //parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid), obj, { action: 'smBiosChange', nodeid: obj.dbNodeKey, domain: domain.id, smbios: command.value, nolog: 1 }); + //parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), obj, { action: 'smBiosChange', nodeid: obj.dbNodeKey, domain: domain.id, smbios: command.value, nolog: 1 }); break; } @@ -1128,7 +1128,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { db.Set(command); // Event the node interface information change - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid), obj, { action: 'ifchange', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), obj, { action: 'ifchange', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 }); break; } @@ -1167,7 +1167,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Event node deletion const change = 'Migrated device ' + node.name; - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid), obj, { etype: 'node', action: 'removenode', nodeid: node._id, msg: change, domain: node.domain }); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.dbNodeKey]), obj, { etype: 'node', action: 'removenode', nodeid: node._id, msg: change, domain: node.domain }); } }); break; @@ -1183,7 +1183,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Log a value in the event log if ((typeof command.msg == 'string') && (command.msg.length < 4096)) { var event = { etype: 'node', action: 'agentlog', nodeid: obj.dbNodeKey, domain: domain.id, msg: command.msg }; - var targets = parent.CreateMeshDispatchTargets(obj.dbMeshKey); + var targets = parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]); if (typeof command.userid == 'string') { var loguser = parent.users[command.userid]; if (loguser) { event.userid = command.userid; event.username = loguser.name; targets.push(command.userid); } @@ -1227,7 +1227,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Log this activation event var event = { etype: 'node', action: 'amtactivate', nodeid: obj.dbNodeKey, domain: domain.id, msg: 'Device requested Intel AMT ACM activation, FQDN: ' + command.fqdn, ip: obj.remoteaddrport }; if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event); // Update the device Intel AMT information ChangeAgentCoreInfo({ "intelamt": { user: 'admin', pass: amtpassword, uuid: command.uuid, realm: command.realm } }); @@ -1277,7 +1277,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (((obj.agentInfo.capabilities & 0x40) != 0) && (typeof command.value.value == 'string') && (command.value.value.length < 256)) { // If this is a diagnostic agent, log the event in the log of the main agent var event = { etype: 'node', action: 'diagnostic', nodeid: obj.realNodeKey, domain: domain.id, msg: command.value.value }; - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event); } break; } @@ -1295,7 +1295,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Event the new sysinfo hash, this will notify everyone that the sysinfo document was changed var event = { etype: 'node', action: 'sysinfohash', nodeid: obj.dbNodeKey, domain: domain.id, hash: command.data.hash, nolog: 1 }; - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event); } break; } @@ -1394,7 +1394,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { if (changes.length > 0) { event.msg = 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', '); } if ((log == 0) || ((obj.agentInfo) && (obj.agentInfo.capabilities) && (obj.agentInfo.capabilities & 0x20)) || (changes.length == 0)) { event.nolog = 1; } // If this is a temporary device, don't log changes if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event); } } }); @@ -1435,7 +1435,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, node: parent.CloneSafeNode(device), msg: 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', ') }; if (obj.agentInfo.capabilities & 0x20) { event.nolog = 1; } // If this is a temporary device, don't log changes if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event); } } }); @@ -1464,7 +1464,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Event the node change var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, node: parent.CloneSafeNode(device), nolog: 1 }; if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. - parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event); + parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event); } } }); diff --git a/meshuser.js b/meshuser.js index 0b9026a4..037079bb 100644 --- a/meshuser.js +++ b/meshuser.js @@ -1250,7 +1250,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use deluser = parent.users[deluserid]; if (deluser == null) { err = 'User does not exists'; } else if ((delusersplit.length != 3) || (delusersplit[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain - else if ((deluser.siteadmin != null) && (deluser.siteadmin > 0) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Permission denied'; } // Need full admin to remote another administrator + else if ((deluser.siteadmin == 0xFFFFFFFF) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Permission denied'; } // Need full admin to remote another administrator else if ((user.groups != null) && (user.groups.length > 0) && ((deluser.groups == null) || (findOne(deluser.groups, user.groups) == false))) { err = 'Invalid user group'; } // Can only perform this operation on other users of our group. } } catch (ex) { err = 'Validation exception: ' + ex; } @@ -2547,7 +2547,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use db.Set(device); // Event the new node - parent.parent.DispatchEvent(['*', command.meshid], obj, { etype: 'node', userid: user._id, username: user.name, action: 'addnode', node: parent.CloneSafeNode(device), msg: 'Added device ' + command.devicename + ' to mesh ' + mesh.name, domain: domain.id }); + parent.parent.DispatchEvent(['*', command.meshid, nodeid], obj, { etype: 'node', userid: user._id, username: user.name, action: 'addnode', node: parent.CloneSafeNode(device), msg: 'Added device ' + command.devicename + ' to mesh ' + mesh.name, domain: domain.id }); }); } break; @@ -2616,7 +2616,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use var newMesh = parent.meshes[command.meshid]; var event = { etype: 'node', userid: user._id, username: user.name, action: 'nodemeshchange', nodeid: node._id, node: node, oldMeshId: oldMeshId, newMeshId: command.meshid, msg: 'Moved device ' + node.name + ' to group ' + newMesh.name, 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(['*', oldMeshId, command.meshid], obj, event); + parent.parent.DispatchEvent(['*', oldMeshId, command.meshid, node._id], obj, event); }); } break; @@ -2648,7 +2648,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use var event = { etype: 'node', userid: user._id, username: user.name, action: 'removenode', nodeid: node._id, msg: 'Removed device ' + node.name + ' from group ' + parent.meshes[node.meshid].name, domain: domain.id }; // TODO: We can't use the changeStream for node delete because we will not know the meshid the device was in. //if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to remove the node. Another event will come. - parent.parent.DispatchEvent(['*', node.meshid], obj, event); + parent.parent.DispatchEvent(['*', node.meshid, node._id], obj, event); // Disconnect all connections if needed var state = parent.parent.GetConnectivityState(nodeid); @@ -2849,7 +2849,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use event.msg = 'Changed device ' + node.name + ' from group ' + mesh.name + ': ' + changes.join(', '); event.node = parent.CloneSafeNode(node); if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. - parent.parent.DispatchEvent(['*', node.meshid, user._id], obj, event); + parent.parent.DispatchEvent(['*', node.meshid, user._id, node._id], obj, event); } }); break; @@ -2970,7 +2970,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (rights == 0) return; // Add an event for this device - var targets = ['*', 'server-users', user._id, node.meshid]; + var targets = ['*', 'server-users', user._id, node.meshid, node._id]; var event = { etype: 'node', userid: user._id, username: user.name, nodeid: node._id, action: 'manual', msg: decodeURIComponent(command.msg), domain: domain.id }; parent.parent.DispatchEvent(targets, obj, event); }); diff --git a/package.json b/package.json index a3f7a095..fcc02751 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.5.0-i", + "version": "0.5.0-j", "keywords": [ "Remote Management", "Intel AMT", diff --git a/translate/translate.json b/translate/translate.json index 4e2e6b71..390ff556 100644 --- a/translate/translate.json +++ b/translate/translate.json @@ -542,7 +542,7 @@ "default-mobile.handlebars->9->246", "default-mobile.handlebars->9->70", "default.handlebars->27->1233", - "default.handlebars->27->1469", + "default.handlebars->27->1470", "default.handlebars->27->653" ] }, @@ -1851,7 +1851,7 @@ "default.handlebars->27->1169", "default.handlebars->27->1171", "default.handlebars->27->1369", - "default.handlebars->27->1446", + "default.handlebars->27->1447", "default.handlebars->27->187" ] }, @@ -1918,7 +1918,7 @@ "nl": "Lidmaatschap toevoegen", "ru": "Добавить участие", "xloc": [ - "default.handlebars->27->1465" + "default.handlebars->27->1466" ] }, { @@ -1964,7 +1964,7 @@ "xloc": [ "default.handlebars->27->1075", "default.handlebars->27->1170", - "default.handlebars->27->1455" + "default.handlebars->27->1456" ] }, { @@ -2304,7 +2304,7 @@ "nl": "Agent fout tellers", "ru": "Счетчик ошибок агента", "xloc": [ - "default.handlebars->27->1477" + "default.handlebars->27->1478" ] }, { @@ -2350,7 +2350,7 @@ "nl": "Agent Sessies", "ru": "Сессии агентов", "xloc": [ - "default.handlebars->27->1493" + "default.handlebars->27->1494" ] }, { @@ -2447,7 +2447,7 @@ "pt": "Agentes", "ru": "Агенты", "xloc": [ - "default.handlebars->27->1506" + "default.handlebars->27->1507" ] }, { @@ -3038,7 +3038,7 @@ "nl": "Weet u zeker dat u de plug-in {0} wilt gebruiken: {1}", "ru": "Вы уверенны, что {0} плагин: {1}", "xloc": [ - "default.handlebars->27->1542" + "default.handlebars->27->1543" ] }, { @@ -3359,7 +3359,7 @@ "nl": "Ongeldige handtening", "ru": "Плохой ключ", "xloc": [ - "default.handlebars->27->1484" + "default.handlebars->27->1485" ] }, { @@ -3370,7 +3370,7 @@ "nl": "Onjuist webcertificaat", "ru": "Плохой веб-сертификат", "xloc": [ - "default.handlebars->27->1483" + "default.handlebars->27->1484" ] }, { @@ -3563,7 +3563,7 @@ "pt": "Servidor CIRA", "ru": "CIRA Сервер", "xloc": [ - "default.handlebars->27->1533" + "default.handlebars->27->1534" ] }, { @@ -3577,7 +3577,7 @@ "pt": "Comandos do servidor CIRA", "ru": "CIRA Сервер команды", "xloc": [ - "default.handlebars->27->1534" + "default.handlebars->27->1535" ] }, { @@ -3588,7 +3588,7 @@ "nl": "CPU gebruik", "ru": "Загрузка CPU", "xloc": [ - "default.handlebars->27->1498" + "default.handlebars->27->1499" ] }, { @@ -3602,7 +3602,7 @@ "pt": "Carga da CPU nos últimos 15 minutos", "ru": "Загрузка CPU за последние 15 минут", "xloc": [ - "default.handlebars->27->1501" + "default.handlebars->27->1502" ] }, { @@ -3616,7 +3616,7 @@ "pt": "Carga da CPU nos últimos 5 minutos", "ru": "Загрузка CPU за последние 5 минут", "xloc": [ - "default.handlebars->27->1500" + "default.handlebars->27->1501" ] }, { @@ -3630,7 +3630,7 @@ "pt": "Carga da CPU no último minuto", "ru": "Загрузка CPU за последнюю минуту", "xloc": [ - "default.handlebars->27->1499" + "default.handlebars->27->1500" ] }, { @@ -3676,7 +3676,7 @@ "pt": "Erro de chamada", "ru": "Ошибка вызова", "xloc": [ - "default.handlebars->27->1543" + "default.handlebars->27->1544" ] }, { @@ -4018,7 +4018,7 @@ "pt": "Verificando ...", "ru": "Проверка...", "xloc": [ - "default.handlebars->27->1539", + "default.handlebars->27->1540", "default.handlebars->27->778" ] }, @@ -4322,7 +4322,7 @@ "ru": "Общие группы устройств", "xloc": [ "default.handlebars->27->1370", - "default.handlebars->27->1447" + "default.handlebars->27->1448" ] }, { @@ -4401,6 +4401,12 @@ "default.handlebars->27->380" ] }, + { + "en": "Confirm deletion of user {0}?", + "xloc": [ + "default.handlebars->27->1446" + ] + }, { "cs": "Potvrdit přesun jednoho záznamu do tohoto umístění?", "de": "Bestätigen Sie das Verschieben von 1 Eintrag an diesen Ort?", @@ -4466,7 +4472,7 @@ "ru": "Подтвердить удаление группы устройств {0}?", "xloc": [ "default.handlebars->27->1380", - "default.handlebars->27->1467" + "default.handlebars->27->1468" ] }, { @@ -4477,7 +4483,7 @@ "nl": "Bevestig het verwijderen van de groep {0}?", "ru": "Подтвердить удаление группы {0}?", "xloc": [ - "default.handlebars->27->1463" + "default.handlebars->27->1464" ] }, { @@ -4599,7 +4605,7 @@ "nl": "Verbonden Intel® AMT", "ru": "Подключено Intel® AMT", "xloc": [ - "default.handlebars->27->1489" + "default.handlebars->27->1490" ] }, { @@ -4610,7 +4616,7 @@ "nl": "Verbonden gebruikers", "ru": "Подключенные пользователи", "xloc": [ - "default.handlebars->27->1494" + "default.handlebars->27->1495" ] }, { @@ -4667,7 +4673,7 @@ "pt": "Contagem de conexões", "ru": "Подключений ", "xloc": [ - "default.handlebars->27->1505" + "default.handlebars->27->1506" ] }, { @@ -4681,7 +4687,7 @@ "pt": "Encaminhador de conexão", "ru": "Ретранслятор подключения", "xloc": [ - "default.handlebars->27->1532" + "default.handlebars->27->1533" ] }, { @@ -4768,7 +4774,7 @@ "pt": "Codificador de cookies", "ru": "Cookie-кодировщик", "xloc": [ - "default.handlebars->27->1519" + "default.handlebars->27->1520" ] }, { @@ -4977,7 +4983,7 @@ "pt": "Servidor Core", "ru": "Основной сервер", "xloc": [ - "default.handlebars->27->1518" + "default.handlebars->27->1519" ] }, { @@ -5844,8 +5850,8 @@ "default.handlebars->27->1145", "default.handlebars->27->1147", "default.handlebars->27->1376", - "default.handlebars->27->1453", - "default.handlebars->27->1459" + "default.handlebars->27->1454", + "default.handlebars->27->1460" ] }, { @@ -5878,7 +5884,7 @@ "default.handlebars->27->1348", "default.handlebars->27->1361", "default.handlebars->27->1416", - "default.handlebars->27->1492", + "default.handlebars->27->1493", "default.handlebars->container->column_l->p2->9" ] }, @@ -6681,7 +6687,7 @@ "nl": "Duplicaat Agent", "ru": "Скопировать агент", "xloc": [ - "default.handlebars->27->1488" + "default.handlebars->27->1489" ] }, { @@ -7578,7 +7584,7 @@ "nl": "Extern", "ru": "Внешний", "xloc": [ - "default.handlebars->27->1512" + "default.handlebars->27->1513" ] }, { @@ -7934,8 +7940,8 @@ "pt": "Livre", "ru": "Свободно", "xloc": [ - "default.handlebars->27->1473", - "default.handlebars->27->1475" + "default.handlebars->27->1474", + "default.handlebars->27->1476" ] }, { @@ -8114,7 +8120,7 @@ "xloc": [ "default.handlebars->27->1090", "default.handlebars->27->1373", - "default.handlebars->27->1450" + "default.handlebars->27->1451" ] }, { @@ -8610,7 +8616,7 @@ "es": "Heap Total", "nl": "Heap Totaal", "xloc": [ - "default.handlebars->27->1514" + "default.handlebars->27->1515" ] }, { @@ -8620,7 +8626,7 @@ "es": "Heap Used", "nl": "Heap gebruikt", "xloc": [ - "default.handlebars->27->1513" + "default.handlebars->27->1514" ] }, { @@ -9142,8 +9148,8 @@ "xloc": [ "default.handlebars->27->1222", "default.handlebars->27->1228", - "default.handlebars->27->1510", - "default.handlebars->27->1531" + "default.handlebars->27->1511", + "default.handlebars->27->1532" ] }, { @@ -9705,7 +9711,7 @@ "nl": "Ongeldige apparaatgroep type", "ru": "Некорректный тип группы устройств", "xloc": [ - "default.handlebars->27->1487" + "default.handlebars->27->1488" ] }, { @@ -9716,7 +9722,7 @@ "nl": "Onjuiste JSON", "ru": "Некорректный JSON", "xloc": [ - "default.handlebars->27->1481" + "default.handlebars->27->1482" ] }, { @@ -9756,7 +9762,7 @@ "nl": "Onjuiste PKCS handtekening", "ru": "Некорректная сигнатура PKCS", "xloc": [ - "default.handlebars->27->1479" + "default.handlebars->27->1480" ] }, { @@ -9767,7 +9773,7 @@ "nl": "Ongeldige RSA handtekening", "ru": "Некорректная сигнатура RSA", "xloc": [ - "default.handlebars->27->1480" + "default.handlebars->27->1481" ] }, { @@ -10589,7 +10595,7 @@ "pt": "Menos", "ru": "Меньше", "xloc": [ - "default.handlebars->27->1545" + "default.handlebars->27->1546" ] }, { @@ -11418,7 +11424,7 @@ "pt": "Mensagens do servidor principal", "ru": "Сообщения главного сервера", "xloc": [ - "default.handlebars->27->1521" + "default.handlebars->27->1522" ] }, { @@ -11715,7 +11721,7 @@ "nl": "Max Sessies bereikt", "ru": "Достигнуто максимальное число сессий", "xloc": [ - "default.handlebars->27->1485" + "default.handlebars->27->1486" ] }, { @@ -11760,7 +11766,7 @@ "pt": "Megabytes", "ru": "Мегабайт", "xloc": [ - "default.handlebars->27->1511" + "default.handlebars->27->1512" ] }, { @@ -11774,7 +11780,7 @@ "pt": "Memória", "ru": "ОЗУ", "xloc": [ - "default.handlebars->27->1502", + "default.handlebars->27->1503", "default.handlebars->27->743", "default.handlebars->container->column_l->p40->3->1->p40type->3" ] @@ -11884,7 +11890,7 @@ "nl": "MeshAgent verkeer", "ru": "Трафик MeshAgent", "xloc": [ - "default.handlebars->27->1523" + "default.handlebars->27->1524" ] }, { @@ -11897,7 +11903,7 @@ "nl": "MeshAgent update", "ru": "Обновление MeshAgent", "xloc": [ - "default.handlebars->27->1524" + "default.handlebars->27->1525" ] }, { @@ -11977,7 +11983,7 @@ "pt": "Peering do servidor MeshCentral", "ru": "Соединения сервера MeshCentral", "xloc": [ - "default.handlebars->27->1522" + "default.handlebars->27->1523" ] }, { @@ -12169,7 +12175,7 @@ "pt": "Despachante de mensagens", "ru": "Диспетчер сообщения", "xloc": [ - "default.handlebars->27->1520" + "default.handlebars->27->1521" ] }, { @@ -12251,7 +12257,7 @@ "pt": "Mais", "ru": "Еще", "xloc": [ - "default.handlebars->27->1544" + "default.handlebars->27->1545" ] }, { @@ -12804,7 +12810,7 @@ "ru": "События не найдены", "xloc": [ "default.handlebars->27->1269", - "default.handlebars->27->1468", + "default.handlebars->27->1469", "default.handlebars->27->691" ] }, @@ -12951,7 +12957,7 @@ "default.handlebars->27->1091", "default.handlebars->27->1192", "default.handlebars->27->1374", - "default.handlebars->27->1451" + "default.handlebars->27->1452" ] }, { @@ -13020,7 +13026,7 @@ "ru": "Нет общих групп устройств", "xloc": [ "default.handlebars->27->1377", - "default.handlebars->27->1454" + "default.handlebars->27->1455" ] }, { @@ -13229,7 +13235,7 @@ "nl": "Geen gebruikersgroep lidmaatschap", "ru": "Нет членства в группах пользователей", "xloc": [ - "default.handlebars->27->1460" + "default.handlebars->27->1461" ] }, { @@ -13622,7 +13628,7 @@ "pt": "Ocorreu em {0}", "ru": "Произошло в {0}", "xloc": [ - "default.handlebars->27->1471" + "default.handlebars->27->1472" ] }, { @@ -13943,7 +13949,7 @@ "xloc": [ "default.handlebars->27->1089", "default.handlebars->27->1371", - "default.handlebars->27->1448" + "default.handlebars->27->1449" ] }, { @@ -14435,7 +14441,7 @@ "nl": "Plugin Actie", "ru": "Действие плагина", "xloc": [ - "default.handlebars->27->1541", + "default.handlebars->27->1542", "default.handlebars->27->159" ] }, @@ -14978,7 +14984,7 @@ "pt": "RSS", "ru": "RSS", "xloc": [ - "default.handlebars->27->1515" + "default.handlebars->27->1516" ] }, { @@ -15121,7 +15127,7 @@ "nl": "Relay geteld", "ru": "Число ретрансляций", "xloc": [ - "default.handlebars->27->1497" + "default.handlebars->27->1498" ] }, { @@ -15132,7 +15138,7 @@ "nl": "Relay fouten", "ru": "Ошибки ретранслятора", "xloc": [ - "default.handlebars->27->1490" + "default.handlebars->27->1491" ] }, { @@ -15145,8 +15151,8 @@ "pt": "Retransmissão de sessão ", "ru": "Сессии ретранслятора", "xloc": [ - "default.handlebars->27->1496", - "default.handlebars->27->1509" + "default.handlebars->27->1497", + "default.handlebars->27->1510" ] }, { @@ -15358,7 +15364,7 @@ "ru": "Удалить группу устройств.", "xloc": [ "default.handlebars->27->1379", - "default.handlebars->27->1466" + "default.handlebars->27->1467" ] }, { @@ -15369,7 +15375,7 @@ "nl": "Verwijder gebruiker", "ru": "Удалить пользователя", "xloc": [ - "default.handlebars->27->1462" + "default.handlebars->27->1463" ] }, { @@ -15442,7 +15448,7 @@ "nl": "Verwijder de groepslidmaatschap", "ru": "Удалить членство пользователя в группе", "xloc": [ - "default.handlebars->27->1458" + "default.handlebars->27->1459" ] }, { @@ -15469,7 +15475,7 @@ "xloc": [ "default.handlebars->27->1092", "default.handlebars->27->1366", - "default.handlebars->27->1452" + "default.handlebars->27->1453" ] }, { @@ -16479,14 +16485,14 @@ "nl": "Server Certificaat", "ru": "Сертификат сервера", "xloc": [ - "default.handlebars->27->1525" + "default.handlebars->27->1526" ] }, { "en": "Server Database", "nl": "Server Database", "xloc": [ - "default.handlebars->27->1526" + "default.handlebars->27->1527" ] }, { @@ -16571,7 +16577,7 @@ "nl": "Server Status", "ru": "Состояние сервера", "xloc": [ - "default.handlebars->27->1476" + "default.handlebars->27->1477" ] }, { @@ -16599,7 +16605,7 @@ "pt": "Rastreamento de servidor", "ru": "Трассировка сервера", "xloc": [ - "default.handlebars->27->1535" + "default.handlebars->27->1536" ] }, { @@ -16707,7 +16713,7 @@ "pt": "ServerStats.csv", "ru": "ServerStats.csv", "xloc": [ - "default.handlebars->27->1517" + "default.handlebars->27->1518" ] }, { @@ -18291,7 +18297,7 @@ "pt": "Atualmente não há notificações", "ru": "На данный момент уведомлений нет", "xloc": [ - "default.handlebars->27->1470" + "default.handlebars->27->1471" ] }, { @@ -19176,7 +19182,7 @@ "default-mobile.handlebars->9->174", "default-mobile.handlebars->9->175", "default.handlebars->27->13", - "default.handlebars->27->1461", + "default.handlebars->27->1462", "default.handlebars->27->364", "default.handlebars->27->41", "default.handlebars->27->42", @@ -19209,7 +19215,7 @@ "nl": "Onbekende actie", "ru": "Неизвестное действие", "xloc": [ - "default.handlebars->27->1482" + "default.handlebars->27->1483" ] }, { @@ -19221,8 +19227,8 @@ "ru": "Неизвестная группа устройств", "xloc": [ "default.handlebars->27->1372", - "default.handlebars->27->1449", - "default.handlebars->27->1486" + "default.handlebars->27->1450", + "default.handlebars->27->1487" ] }, { @@ -19233,7 +19239,7 @@ "nl": "Onbekende groep", "ru": "Неизвестная группа", "xloc": [ - "default.handlebars->27->1478" + "default.handlebars->27->1479" ] }, { @@ -19259,7 +19265,7 @@ "nl": "Onbekende gebruikersgroep", "ru": "Неизвестная группа пользователей", "xloc": [ - "default.handlebars->27->1457" + "default.handlebars->27->1458" ] }, { @@ -19320,7 +19326,7 @@ "nl": "Bijgewerkt", "ru": "Актуально", "xloc": [ - "default.handlebars->27->1540" + "default.handlebars->27->1541" ] }, { @@ -19509,8 +19515,8 @@ "pt": "Usava", "ru": "Использовано", "xloc": [ - "default.handlebars->27->1472", - "default.handlebars->27->1474" + "default.handlebars->27->1473", + "default.handlebars->27->1475" ] }, { @@ -19568,7 +19574,7 @@ "nl": "Gebruikersaccounts", "ru": "Учетные записи пользователей", "xloc": [ - "default.handlebars->27->1491" + "default.handlebars->27->1492" ] }, { @@ -19609,7 +19615,7 @@ "xloc": [ "default.handlebars->27->1146", "default.handlebars->27->1350", - "default.handlebars->27->1464" + "default.handlebars->27->1465" ] }, { @@ -19631,7 +19637,7 @@ "nl": "Gebruikersgroeps lidmaatschap", "ru": "Членство в группах пользователей", "xloc": [ - "default.handlebars->27->1456" + "default.handlebars->27->1457" ] }, { @@ -19713,7 +19719,7 @@ "pt": "Sessões de Usuário", "ru": "Сессии пользователя", "xloc": [ - "default.handlebars->27->1508" + "default.handlebars->27->1509" ] }, { @@ -19841,7 +19847,7 @@ "xloc": [ "default.handlebars->27->1349", "default.handlebars->27->1360", - "default.handlebars->27->1507", + "default.handlebars->27->1508", "default.handlebars->container->topbar->1->1->UsersSubMenuSpan->UsersSubMenu->1->0->UsersGeneral" ] }, @@ -19853,7 +19859,7 @@ "nl": "gebruikers Sessies", "ru": "Сессии пользователей", "xloc": [ - "default.handlebars->27->1495" + "default.handlebars->27->1496" ] }, { @@ -20167,8 +20173,8 @@ "pt": "Servidor web", "ru": "Веб-сервер", "xloc": [ - "default.handlebars->27->1527", - "default.handlebars->27->1528" + "default.handlebars->27->1528", + "default.handlebars->27->1529" ] }, { @@ -20182,7 +20188,7 @@ "pt": "Solicitações de servidor Web", "ru": "Запросы веб-сервера", "xloc": [ - "default.handlebars->27->1529" + "default.handlebars->27->1530" ] }, { @@ -20196,7 +20202,7 @@ "pt": "Encaminhador de soquete da Web", "ru": "Ретранслятор Web Socket", "xloc": [ - "default.handlebars->27->1530" + "default.handlebars->27->1531" ] }, { @@ -20862,7 +20868,7 @@ "pt": "\\\\'", "ru": "\\\\'", "xloc": [ - "default.handlebars->27->1538" + "default.handlebars->27->1539" ] }, { @@ -21053,7 +21059,7 @@ "pt": "livre", "ru": "свободно", "xloc": [ - "default.handlebars->27->1503" + "default.handlebars->27->1504" ] }, { @@ -21287,7 +21293,7 @@ "pt": "servertrace.csv", "ru": "servertrace.csv", "xloc": [ - "default.handlebars->27->1537" + "default.handlebars->27->1538" ] }, { @@ -21324,7 +21330,7 @@ "pt": "tempo, conn.agente, conn.usuários.usersessions, conn.relaysession, conn.intelamt, mem.externo mem.amontoado, mem.heaptotal, mem.rss", "ru": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss", "xloc": [ - "default.handlebars->27->1516" + "default.handlebars->27->1517" ] }, { @@ -21336,7 +21342,7 @@ "pt": "hora, fonte, mensagem", "ru": "time, source, message", "xloc": [ - "default.handlebars->27->1536" + "default.handlebars->27->1537" ] }, { @@ -21359,7 +21365,7 @@ "pt": "total", "ru": "всего", "xloc": [ - "default.handlebars->27->1504" + "default.handlebars->27->1505" ] }, { @@ -22063,4 +22069,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index 86d0cfa8..5d87552b 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -3458,14 +3458,14 @@ if (typeof mesh == 'string') { mesh = meshes[mesh] } if ((mesh == null) || (mesh.links == null)) { return 0; } - // Check if user user + // Check if super user if (userinfo.manageAllDeviceGroups) return 0xFFFFFFFF; - // Check direct link permission + // Check device group link permission var rights = 0, r = mesh.links[userid]; if (r != null) { + if (rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device group link, stop here. rights = r.rights; - if (rights == 0xFFFFFFFF) { return rights; } // User has full rights thru a direct link, stop here. } // Check permissions thru user groups @@ -3476,7 +3476,7 @@ if (i.startsWith('ugrp/')) { r = mesh.links[i]; if (r != null) { - if (r.rights == 0xFFFFFFFF) { return r.rights; } // User has full rights thru a user group, stop here. + if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a user group, stop here. rights |= r.rights; // TODO: Deal with reverse permissions } } @@ -3514,7 +3514,19 @@ if (node == null) { return 0; } if (userid == null) { userid = userinfo._id; } if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } } - return GetMeshRights(node.meshid, userid); + var r = GetMeshRights(node.meshid, userid); + if (r != 0xFFFFFFFF) { + var user = null; + if (userid == userinfo._id) { user = userinfo; } else { if (users != null) { user = users[userid]; } } + if ((user != null) && (user.links != null)) { + var r2 = user.links[node._id]; + if (r2 != null) { + if (r2.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device link, stop here. + r |= r2; // TODO: Deal with reverse permissions + } + } + } + return r; } // diff --git a/views/default.handlebars b/views/default.handlebars index f5ebbd63..eef4f157 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2721,7 +2721,7 @@ go(parseInt('{{viewmode}}')); goBackStack.push(2); } else if (args.gotouser != null) { - if (users['user/' + domain + '/' + args.gotouser] == null) return; // This user is not loaded yet + if ((users == null) || (users['user/' + domain + '/' + args.gotouser] == null)) return; // This user is not loaded yet gotoUser('user/' + domain + '/' + args.gotouser); go(parseInt('{{viewmode}}')); goBackStack.push(4); @@ -3123,9 +3123,11 @@ // Display all empty device groups, we need to do this because users can add devices to these at any time. if ((sort == 0) && (Q('SearchInput').value == '') && (view < 3)) { - var deviceHeaderId2 = deviceHeaderId; - for (var i in meshes) { - var mesh = meshes[i], meshrights = GetMeshRights(mesh); + var deviceHeaderId2 = deviceHeaderId, sortedMeshes = []; + for (var i in meshes) { sortedMeshes.push(meshes[i]); } + sortedMeshes.sort(nameSort); + for (var i in sortedMeshes) { + var mesh = sortedMeshes[i], meshrights = GetMeshRights(mesh); if (displayedMeshes[mesh._id] == null) { if ((current != '') && (r != '')) { r += ''; } r += ''; } x += '
'; @@ -3141,8 +3143,7 @@ if (mesh.mtype == 1) { r += '
' + "No Intel® AMT devices in this mesh"; if ((meshrights & 4) != 0) { r += ', ' + "add one" + ''; } - } - if (mesh.mtype == 2) { + } else if (mesh.mtype == 2) { r += '
'; r += '
'; // Open collapse div r += '
' + "No devices in this group"; @@ -10055,16 +10056,14 @@ // Draw the user timeline drawUserPermissions(); - // Check if we can delete this user - var deletePossible = true; - if (user._id == userinfo._id) deletePossible = false; - if (user.siteadmin && user.siteadmin > 0 && userinfo.siteadmin != 0xFFFFFFFF) deletePossible = false; + // Check if we can change password / delete this user + var userAdminRights = (((userinfo.siteadmin != null) && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF)) || (userinfo.siteadmin == 0xFFFFFFFF)); // Show bottom buttons x = '
'; - if (deletePossible) x += '' + "Delete User" + ''; + if (userAdminRights) { x += '' + "Delete User" + ''; } x += '
'; - if (((userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF)) || (userinfo.siteadmin == 0xFFFFFFFF)) x += '' + "Change Password" + ''; + if (userAdminRights) { x += '' + "Change Password" + ''; } x += '

' QH('p30html3', x); @@ -10160,7 +10159,7 @@ function p30showDeleteUserDialog() { if (xxdialogMode) return; - setDialogMode(2, format("Delete User {0}", EscapeHtml(currentUser.name)), 3, p30showDeleteUserDialogEx, format('Confirm deletion of user {0}?', EscapeHtml(currentUser.name))); + setDialogMode(2, format("Delete User {0}", EscapeHtml(currentUser.name)), 3, p30showDeleteUserDialogEx, format("Confirm deletion of user {0}?", EscapeHtml(currentUser.name))); } function p30showDeleteUserDialogEx() { @@ -10170,6 +10169,29 @@ // Draw device power bars. The bars are 766px wide. function drawUserPermissions() { var count = 1, x = ''; + + if (urlargs.dp == 1) { // For testing only + // Display common devices + x += ' ' + "Add Device" + ''; + x += ''; + 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"; + 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):('' + "Unknown Device" + ''); + if (r == 0xFFFFFFFF) rights = "Full Device Rights"; else if (r == 0) rights = "No Rights"; + if ((currentUser._id != userinfo._id) && ((cr & 2) != 0)) { trash = ''; } + x += ''; + } + } + } + if (count == 1) { x += ''; } + x += '
' + "Common Devices" + '
 ' + nodename + '
' + trash + '
' + rights + '
 ' + "No devices in common" + '

'; + } + + // Display common device groups 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 += ' ' + "Add Device Group" + ''; } @@ -10190,6 +10212,7 @@ if (count == 1) { x += '
 ' + "No device groups in common" + '
'; + // Display user groups if (usergroups != null) { count = 1; x += '
'; @@ -11169,14 +11192,14 @@ if (typeof mesh == 'string') { mesh = meshes[mesh] } if ((mesh == null) || (mesh.links == null)) { return 0; } - // Check if user user + // Check if super user if (userinfo.manageAllDeviceGroups) return 0xFFFFFFFF; - // Check direct link permission + // Check device group link permission var rights = 0, r = mesh.links[userid]; if (r != null) { + if (rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device group link, stop here. rights = r.rights; - if (rights == 0xFFFFFFFF) { return rights; } // User has full rights thru a direct link, stop here. } // Check permissions thru user groups @@ -11187,7 +11210,7 @@ if (i.startsWith('ugrp/')) { r = mesh.links[i]; if (r != null) { - if (r.rights == 0xFFFFFFFF) { return r.rights; } // User has full rights thru a user group, stop here. + if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a user group, stop here. rights |= r.rights; // TODO: Deal with reverse permissions } } @@ -11219,13 +11242,25 @@ return false; } - + // Return the user rights for a given node function GetNodeRights(node, userid) { if (node == null) { return 0; } if (userid == null) { userid = userinfo._id; } if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } } - return GetMeshRights(node.meshid, userid); + var r = GetMeshRights(node.meshid, userid); + if (r != 0xFFFFFFFF) { + var user = null; + if (userid == userinfo._id) { user = userinfo; } else { if (users != null) { user = users[userid]; } } + if ((user != null) && (user.links != null)) { + var r2 = user.links[node._id]; + if (r2 != null) { + if (r2.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device link, stop here. + r |= r2; // TODO: Deal with reverse permissions + } + } + } + return r; } // diff --git a/webserver.js b/webserver.js index 7d6ad352..46509f41 100644 --- a/webserver.js +++ b/webserver.js @@ -4101,12 +4101,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { db.Get(nodeid, function (err, nodes) { if ((nodes == null) || (nodes.length != 1)) { func(null, 0, false); return; } // No such nodeid - // Check direct link - var rights = 0, visible = false, r = user.links[nodes[0].meshid]; + // Check device link + var rights = 0, visible = false, r = user.links[nodeid]; if (r != null) { - rights = r.rights; + if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a device link, stop here. + rights |= r.rights; + visible = true; + } + + // Check device group link + r = user.links[nodes[0].meshid]; + if (r != null) { + if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a device group link, stop here. + rights |= r.rights; visible = true; - if (rights == 0xFFFFFFFF) { func(nodes[0], rights, true); return; } // User has full rights thru a direct link, stop here. } // Check user group links @@ -4116,7 +4124,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { if (g && (g.links != null)) { r = g.links[nodes[0].meshid]; if (r != null) { - if (r.rights == 0xFFFFFFFF) { func(nodes[0], r.rights, true); return; } // User has full rights thru a user group link, stop here. + if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a user group link, stop here. rights |= r.rights; // TODO: Deal with reverse rights visible = true; } @@ -4202,7 +4210,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { return r; } - // Get the right of a user on a given device group + // Get the rights of a user on a given device group obj.GetMeshRights = function (user, mesh) { if ((user == null) || (mesh == null)) { return 0; } if (typeof user == 'string') { user = obj.users[user]; }