Fixed user account delete with user manager.
Ylian Saint-Hilaire committed
Mar 17, 2020 at 17:17 UTC
b72f43c119611122dc85410ef19cd0ae5f5bab89
7 files changed
+217
-156
meshagent.js
+18
-18
@@ -72,7 +72,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
72
db.removeAllPowerEventsForNode(obj.dbNodeKey); // Remove all power events for this node
73
74
// Event node deletion
75
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
75
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, { etype: 'node', action: 'removenode', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
76
77
// Disconnect all connections if needed
78
const state = parent.parent.GetConnectivityState(obj.dbNodeKey);
@@ -555,12 +555,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
555
if (adminUser.links == null) adminUser.links = {};
556
adminUser.links[obj.dbMeshKey] = { rights: 0xFFFFFFFF };
557
db.SetUser(adminUser);
558
- 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 });
558
+ 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 });
559
}
560
} else {
561
if ((mesh != null) && (mesh.deleted != null) && (mesh.links)) {
562
// Must un-delete this mesh
563
- var ids = parent.CreateMeshDispatchTargets(mesh._id);
563
+ var ids = parent.CreateMeshDispatchTargets(mesh._id, [obj.dbNodeKey]);
564
565
// See if users still exists, if so, add links to the mesh
566
for (var userid in mesh.links) {
@@ -640,13 +640,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
640
mesh = { type: 'mesh', _id: obj.dbMeshKey, name: obj.meshid, mtype: 2, desc: '', domain: domain.id, links: links };
641
db.Set(common.escapeLinksFieldName(mesh));
642
parent.meshes[obj.meshid] = mesh;
643
- parent.parent.AddEventDispatch(parent.CreateMeshDispatchTargets(obj.meshid), ws);
643
+ parent.parent.AddEventDispatch(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), ws);
644
645
if (adminUser.links == null) user.links = {};
646
adminUser.links[obj.meshid] = { rights: 0xFFFFFFFF };
647
//adminUser.subscriptions = parent.subscribe(adminUser._id, ws);
648
db.SetUser(user);
649
- 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 });
649
+ 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 });
650
}
651
}
652
@@ -741,7 +741,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
741
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, node: parent.CloneSafeNode(device) };
742
if (log == 0) { event.nolog = 1; } else { event.msg = 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', '); }
743
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.
744
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event);
744
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event);
745
}
746
}
747
@@ -781,9 +781,9 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
781
// Event the new node
782
if (obj.agentInfo.capabilities & 0x20) {
783
// This is a temporary agent, don't log.
784
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, { etype: 'node', action: 'addnode', node: device, domain: domain.id, nolog: 1 });
784
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, { etype: 'node', action: 'addnode', node: device, domain: domain.id, nolog: 1 });
785
} else {
786
- 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 });
786
+ 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 });
787
}
788
789
completeAgentConnection3(device, mesh);
@@ -1114,7 +1114,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1114
} catch (ex) { }
1115
1116
// Event the node interface information change (This is a lot of traffic, probably don't need this).
1117
- //parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid), obj, { action: 'smBiosChange', nodeid: obj.dbNodeKey, domain: domain.id, smbios: command.value, nolog: 1 });
1117
+ //parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), obj, { action: 'smBiosChange', nodeid: obj.dbNodeKey, domain: domain.id, smbios: command.value, nolog: 1 });
1118
1119
break;
1120
}
@@ -1128,7 +1128,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1128
db.Set(command);
1129
1130
// Event the node interface information change
1131
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid), obj, { action: 'ifchange', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
1131
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.meshid, [obj.dbNodeKey]), obj, { action: 'ifchange', nodeid: obj.dbNodeKey, domain: domain.id, nolog: 1 });
1132
1133
break;
1134
}
@@ -1167,7 +1167,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1167
1168
// Event node deletion
1169
const change = 'Migrated device ' + node.name;
1170
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid), obj, { etype: 'node', action: 'removenode', nodeid: node._id, msg: change, domain: node.domain });
1170
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.dbNodeKey]), obj, { etype: 'node', action: 'removenode', nodeid: node._id, msg: change, domain: node.domain });
1171
}
1172
});
1173
break;
@@ -1183,7 +1183,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1183
// Log a value in the event log
1184
if ((typeof command.msg == 'string') && (command.msg.length < 4096)) {
1185
var event = { etype: 'node', action: 'agentlog', nodeid: obj.dbNodeKey, domain: domain.id, msg: command.msg };
1186
- var targets = parent.CreateMeshDispatchTargets(obj.dbMeshKey);
1186
+ var targets = parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]);
1187
if (typeof command.userid == 'string') {
1188
var loguser = parent.users[command.userid];
1189
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) {
1227
// Log this activation event
1228
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 };
1229
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.
1230
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, event);
1230
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event);
1231
1232
// Update the device Intel AMT information
1233
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) {
1277
if (((obj.agentInfo.capabilities & 0x40) != 0) && (typeof command.value.value == 'string') && (command.value.value.length < 256)) {
1278
// If this is a diagnostic agent, log the event in the log of the main agent
1279
var event = { etype: 'node', action: 'diagnostic', nodeid: obj.realNodeKey, domain: domain.id, msg: command.value.value };
1280
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, event);
1280
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event);
1281
}
1282
break;
1283
}
@@ -1295,7 +1295,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1295
1296
// Event the new sysinfo hash, this will notify everyone that the sysinfo document was changed
1297
var event = { etype: 'node', action: 'sysinfohash', nodeid: obj.dbNodeKey, domain: domain.id, hash: command.data.hash, nolog: 1 };
1298
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey), obj, event);
1298
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(obj.dbMeshKey, [obj.dbNodeKey]), obj, event);
1299
}
1300
break;
1301
}
@@ -1394,7 +1394,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1394
if (changes.length > 0) { event.msg = 'Changed device ' + device.name + ' from group ' + mesh.name + ': ' + changes.join(', '); }
1395
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
1396
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.
1397
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event);
1397
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event);
1398
}
1399
}
1400
});
@@ -1435,7 +1435,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1435
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(', ') };
1436
if (obj.agentInfo.capabilities & 0x20) { event.nolog = 1; } // If this is a temporary device, don't log changes
1437
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.
1438
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event);
1438
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event);
1439
}
1440
}
1441
});
@@ -1464,7 +1464,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
1464
// Event the node change
1465
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, node: parent.CloneSafeNode(device), nolog: 1 };
1466
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.
1467
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid), obj, event);
1467
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(device.meshid, [obj.dbNodeKey]), obj, event);
1468
}
1469
}
1470
});
meshuser.js
+6
-6
@@ -1250,7 +1250,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1250
deluser = parent.users[deluserid];
1251
if (deluser == null) { err = 'User does not exists'; }
1252
else if ((delusersplit.length != 3) || (delusersplit[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
1253
- else if ((deluser.siteadmin != null) && (deluser.siteadmin > 0) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Permission denied'; } // Need full admin to remote another administrator
1253
+ else if ((deluser.siteadmin == 0xFFFFFFFF) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Permission denied'; } // Need full admin to remote another administrator
1254
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.
1255
}
1256
} catch (ex) { err = 'Validation exception: ' + ex; }
@@ -2547,7 +2547,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2547
db.Set(device);
2548
2549
// Event the new node
2550
- 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 });
2550
+ 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 });
2551
});
2552
}
2553
break;
@@ -2616,7 +2616,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2616
var newMesh = parent.meshes[command.meshid];
2617
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 };
2618
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.
2619
- parent.parent.DispatchEvent(['*', oldMeshId, command.meshid], obj, event);
2619
+ parent.parent.DispatchEvent(['*', oldMeshId, command.meshid, node._id], obj, event);
2620
});
2621
}
2622
break;
@@ -2648,7 +2648,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2648
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 };
2649
// TODO: We can't use the changeStream for node delete because we will not know the meshid the device was in.
2650
//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.
2651
- parent.parent.DispatchEvent(['*', node.meshid], obj, event);
2651
+ parent.parent.DispatchEvent(['*', node.meshid, node._id], obj, event);
2652
2653
// Disconnect all connections if needed
2654
var state = parent.parent.GetConnectivityState(nodeid);
@@ -2849,7 +2849,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2849
event.msg = 'Changed device ' + node.name + ' from group ' + mesh.name + ': ' + changes.join(', ');
2850
event.node = parent.CloneSafeNode(node);
2851
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.
2852
- parent.parent.DispatchEvent(['*', node.meshid, user._id], obj, event);
2852
+ parent.parent.DispatchEvent(['*', node.meshid, user._id, node._id], obj, event);
2853
}
2854
});
2855
break;
@@ -2970,7 +2970,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2970
if (rights == 0) return;
2971
2972
// Add an event for this device
2973
- var targets = ['*', 'server-users', user._id, node.meshid];
2973
+ var targets = ['*', 'server-users', user._id, node.meshid, node._id];
2974
var event = { etype: 'node', userid: user._id, username: user.name, nodeid: node._id, action: 'manual', msg: decodeURIComponent(command.msg), domain: domain.id };
2975
parent.parent.DispatchEvent(targets, obj, event);
2976
});
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.5.0-i",
3
+ "version": "0.5.0-j",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
translate/translate.json
+107
-101
@@ -542,7 +542,7 @@
542
"default-mobile.handlebars->9->246",
543
"default-mobile.handlebars->9->70",
544
"default.handlebars->27->1233",
545
- "default.handlebars->27->1469",
545
+ "default.handlebars->27->1470",
546
"default.handlebars->27->653"
547
]
548
},
@@ -1851,7 +1851,7 @@
1851
"default.handlebars->27->1169",
1852
"default.handlebars->27->1171",
1853
"default.handlebars->27->1369",
1854
- "default.handlebars->27->1446",
1854
+ "default.handlebars->27->1447",
1855
"default.handlebars->27->187"
1856
]
1857
},
@@ -1918,7 +1918,7 @@
1918
"nl": "Lidmaatschap toevoegen",
1919
"ru": "Добавить участие",
1920
"xloc": [
1921
- "default.handlebars->27->1465"
1921
+ "default.handlebars->27->1466"
1922
]
1923
},
1924
{
@@ -1964,7 +1964,7 @@
1964
"xloc": [
1965
"default.handlebars->27->1075",
1966
"default.handlebars->27->1170",
1967
- "default.handlebars->27->1455"
1967
+ "default.handlebars->27->1456"
1968
]
1969
},
1970
{
@@ -2304,7 +2304,7 @@
2304
"nl": "Agent fout tellers",
2305
"ru": "Счетчик ошибок агента",
2306
"xloc": [
2307
- "default.handlebars->27->1477"
2307
+ "default.handlebars->27->1478"
2308
]
2309
},
2310
{
@@ -2350,7 +2350,7 @@
2350
"nl": "Agent Sessies",
2351
"ru": "Сессии агентов",
2352
"xloc": [
2353
- "default.handlebars->27->1493"
2353
+ "default.handlebars->27->1494"
2354
]
2355
},
2356
{
@@ -2447,7 +2447,7 @@
2447
"pt": "Agentes",
2448
"ru": "Агенты",
2449
"xloc": [
2450
- "default.handlebars->27->1506"
2450
+ "default.handlebars->27->1507"
2451
]
2452
},
2453
{
@@ -3038,7 +3038,7 @@
3038
"nl": "Weet u zeker dat u de plug-in {0} wilt gebruiken: {1}",
3039
"ru": "Вы уверенны, что {0} плагин: {1}",
3040
"xloc": [
3041
- "default.handlebars->27->1542"
3041
+ "default.handlebars->27->1543"
3042
]
3043
},
3044
{
@@ -3359,7 +3359,7 @@
3359
"nl": "Ongeldige handtening",
3360
"ru": "Плохой ключ",
3361
"xloc": [
3362
- "default.handlebars->27->1484"
3362
+ "default.handlebars->27->1485"
3363
]
3364
},
3365
{
@@ -3370,7 +3370,7 @@
3370
"nl": "Onjuist webcertificaat",
3371
"ru": "Плохой веб-сертификат",
3372
"xloc": [
3373
- "default.handlebars->27->1483"
3373
+ "default.handlebars->27->1484"
3374
]
3375
},
3376
{
@@ -3563,7 +3563,7 @@
3563
"pt": "Servidor CIRA",
3564
"ru": "CIRA Сервер",
3565
"xloc": [
3566
- "default.handlebars->27->1533"
3566
+ "default.handlebars->27->1534"
3567
]
3568
},
3569
{
@@ -3577,7 +3577,7 @@
3577
"pt": "Comandos do servidor CIRA",
3578
"ru": "CIRA Сервер команды",
3579
"xloc": [
3580
- "default.handlebars->27->1534"
3580
+ "default.handlebars->27->1535"
3581
]
3582
},
3583
{
@@ -3588,7 +3588,7 @@
3588
"nl": "CPU gebruik",
3589
"ru": "Загрузка CPU",
3590
"xloc": [
3591
- "default.handlebars->27->1498"
3591
+ "default.handlebars->27->1499"
3592
]
3593
},
3594
{
@@ -3602,7 +3602,7 @@
3602
"pt": "Carga da CPU nos últimos 15 minutos",
3603
"ru": "Загрузка CPU за последние 15 минут",
3604
"xloc": [
3605
- "default.handlebars->27->1501"
3605
+ "default.handlebars->27->1502"
3606
]
3607
},
3608
{
@@ -3616,7 +3616,7 @@
3616
"pt": "Carga da CPU nos últimos 5 minutos",
3617
"ru": "Загрузка CPU за последние 5 минут",
3618
"xloc": [
3619
- "default.handlebars->27->1500"
3619
+ "default.handlebars->27->1501"
3620
]
3621
},
3622
{
@@ -3630,7 +3630,7 @@
3630
"pt": "Carga da CPU no último minuto",
3631
"ru": "Загрузка CPU за последнюю минуту",
3632
"xloc": [
3633
- "default.handlebars->27->1499"
3633
+ "default.handlebars->27->1500"
3634
]
3635
},
3636
{
@@ -3676,7 +3676,7 @@
3676
"pt": "Erro de chamada",
3677
"ru": "Ошибка вызова",
3678
"xloc": [
3679
- "default.handlebars->27->1543"
3679
+ "default.handlebars->27->1544"
3680
]
3681
},
3682
{
@@ -4018,7 +4018,7 @@
4018
"pt": "Verificando ...",
4019
"ru": "Проверка...",
4020
"xloc": [
4021
- "default.handlebars->27->1539",
4021
+ "default.handlebars->27->1540",
4022
"default.handlebars->27->778"
4023
]
4024
},
@@ -4322,7 +4322,7 @@
4322
"ru": "Общие группы устройств",
4323
"xloc": [
4324
"default.handlebars->27->1370",
4325
- "default.handlebars->27->1447"
4325
+ "default.handlebars->27->1448"
4326
]
4327
},
4328
{
@@ -4401,6 +4401,12 @@
4401
"default.handlebars->27->380"
4402
]
4403
},
4404
+ {
4405
+ "en": "Confirm deletion of user {0}?",
4406
+ "xloc": [
4407
+ "default.handlebars->27->1446"
4408
+ ]
4409
+ },
4410
{
4411
"cs": "Potvrdit přesun jednoho záznamu do tohoto umístění?",
4412
"de": "Bestätigen Sie das Verschieben von 1 Eintrag an diesen Ort?",
@@ -4466,7 +4472,7 @@
4472
"ru": "Подтвердить удаление группы устройств {0}?",
4473
"xloc": [
4474
"default.handlebars->27->1380",
4469
- "default.handlebars->27->1467"
4475
+ "default.handlebars->27->1468"
4476
]
4477
},
4478
{
@@ -4477,7 +4483,7 @@
4483
"nl": "Bevestig het verwijderen van de groep {0}?",
4484
"ru": "Подтвердить удаление группы {0}?",
4485
"xloc": [
4480
- "default.handlebars->27->1463"
4486
+ "default.handlebars->27->1464"
4487
]
4488
},
4489
{
@@ -4599,7 +4605,7 @@
4605
"nl": "Verbonden Intel® AMT",
4606
"ru": "Подключено Intel® AMT",
4607
"xloc": [
4602
- "default.handlebars->27->1489"
4608
+ "default.handlebars->27->1490"
4609
]
4610
},
4611
{
@@ -4610,7 +4616,7 @@
4616
"nl": "Verbonden gebruikers",
4617
"ru": "Подключенные пользователи",
4618
"xloc": [
4613
- "default.handlebars->27->1494"
4619
+ "default.handlebars->27->1495"
4620
]
4621
},
4622
{
@@ -4667,7 +4673,7 @@
4673
"pt": "Contagem de conexões",
4674
"ru": "Подключений ",
4675
"xloc": [
4670
- "default.handlebars->27->1505"
4676
+ "default.handlebars->27->1506"
4677
]
4678
},
4679
{
@@ -4681,7 +4687,7 @@
4687
"pt": "Encaminhador de conexão",
4688
"ru": "Ретранслятор подключения",
4689
"xloc": [
4684
- "default.handlebars->27->1532"
4690
+ "default.handlebars->27->1533"
4691
]
4692
},
4693
{
@@ -4768,7 +4774,7 @@
4774
"pt": "Codificador de cookies",
4775
"ru": "Cookie-кодировщик",
4776
"xloc": [
4771
- "default.handlebars->27->1519"
4777
+ "default.handlebars->27->1520"
4778
]
4779
},
4780
{
@@ -4977,7 +4983,7 @@
4983
"pt": "Servidor Core",
4984
"ru": "Основной сервер",
4985
"xloc": [
4980
- "default.handlebars->27->1518"
4986
+ "default.handlebars->27->1519"
4987
]
4988
},
4989
{
@@ -5844,8 +5850,8 @@
5850
"default.handlebars->27->1145",
5851
"default.handlebars->27->1147",
5852
"default.handlebars->27->1376",
5847
- "default.handlebars->27->1453",
5848
- "default.handlebars->27->1459"
5853
+ "default.handlebars->27->1454",
5854
+ "default.handlebars->27->1460"
5855
]
5856
},
5857
{
@@ -5878,7 +5884,7 @@
5884
"default.handlebars->27->1348",
5885
"default.handlebars->27->1361",
5886
"default.handlebars->27->1416",
5881
- "default.handlebars->27->1492",
5887
+ "default.handlebars->27->1493",
5888
"default.handlebars->container->column_l->p2->9"
5889
]
5890
},
@@ -6681,7 +6687,7 @@
6687
"nl": "Duplicaat Agent",
6688
"ru": "Скопировать агент",
6689
"xloc": [
6684
- "default.handlebars->27->1488"
6690
+ "default.handlebars->27->1489"
6691
]
6692
},
6693
{
@@ -7578,7 +7584,7 @@
7584
"nl": "Extern",
7585
"ru": "Внешний",
7586
"xloc": [
7581
- "default.handlebars->27->1512"
7587
+ "default.handlebars->27->1513"
7588
]
7589
},
7590
{
@@ -7934,8 +7940,8 @@
7940
"pt": "Livre",
7941
"ru": "Свободно",
7942
"xloc": [
7937
- "default.handlebars->27->1473",
7938
- "default.handlebars->27->1475"
7943
+ "default.handlebars->27->1474",
7944
+ "default.handlebars->27->1476"
7945
]
7946
},
7947
{
@@ -8114,7 +8120,7 @@
8120
"xloc": [
8121
"default.handlebars->27->1090",
8122
"default.handlebars->27->1373",
8117
- "default.handlebars->27->1450"
8123
+ "default.handlebars->27->1451"
8124
]
8125
},
8126
{
@@ -8610,7 +8616,7 @@
8616
"es": "Heap Total",
8617
"nl": "Heap Totaal",
8618
"xloc": [
8613
- "default.handlebars->27->1514"
8619
+ "default.handlebars->27->1515"
8620
]
8621
},
8622
{
@@ -8620,7 +8626,7 @@
8626
"es": "Heap Used",
8627
"nl": "Heap gebruikt",
8628
"xloc": [
8623
- "default.handlebars->27->1513"
8629
+ "default.handlebars->27->1514"
8630
]
8631
},
8632
{
@@ -9142,8 +9148,8 @@
9148
"xloc": [
9149
"default.handlebars->27->1222",
9150
"default.handlebars->27->1228",
9145
- "default.handlebars->27->1510",
9146
- "default.handlebars->27->1531"
9151
+ "default.handlebars->27->1511",
9152
+ "default.handlebars->27->1532"
9153
]
9154
},
9155
{
@@ -9705,7 +9711,7 @@
9711
"nl": "Ongeldige apparaatgroep type",
9712
"ru": "Некорректный тип группы устройств",
9713
"xloc": [
9708
- "default.handlebars->27->1487"
9714
+ "default.handlebars->27->1488"
9715
]
9716
},
9717
{
@@ -9716,7 +9722,7 @@
9722
"nl": "Onjuiste JSON",
9723
"ru": "Некорректный JSON",
9724
"xloc": [
9719
- "default.handlebars->27->1481"
9725
+ "default.handlebars->27->1482"
9726
]
9727
},
9728
{
@@ -9756,7 +9762,7 @@
9762
"nl": "Onjuiste PKCS handtekening",
9763
"ru": "Некорректная сигнатура PKCS",
9764
"xloc": [
9759
- "default.handlebars->27->1479"
9765
+ "default.handlebars->27->1480"
9766
]
9767
},
9768
{
@@ -9767,7 +9773,7 @@
9773
"nl": "Ongeldige RSA handtekening",
9774
"ru": "Некорректная сигнатура RSA",
9775
"xloc": [
9770
- "default.handlebars->27->1480"
9776
+ "default.handlebars->27->1481"
9777
]
9778
},
9779
{
@@ -10589,7 +10595,7 @@
10595
"pt": "Menos",
10596
"ru": "Меньше",
10597
"xloc": [
10592
- "default.handlebars->27->1545"
10598
+ "default.handlebars->27->1546"
10599
]
10600
},
10601
{
@@ -11418,7 +11424,7 @@
11424
"pt": "Mensagens do servidor principal",
11425
"ru": "Сообщения главного сервера",
11426
"xloc": [
11421
- "default.handlebars->27->1521"
11427
+ "default.handlebars->27->1522"
11428
]
11429
},
11430
{
@@ -11715,7 +11721,7 @@
11721
"nl": "Max Sessies bereikt",
11722
"ru": "Достигнуто максимальное число сессий",
11723
"xloc": [
11718
- "default.handlebars->27->1485"
11724
+ "default.handlebars->27->1486"
11725
]
11726
},
11727
{
@@ -11760,7 +11766,7 @@
11766
"pt": "Megabytes",
11767
"ru": "Мегабайт",
11768
"xloc": [
11763
- "default.handlebars->27->1511"
11769
+ "default.handlebars->27->1512"
11770
]
11771
},
11772
{
@@ -11774,7 +11780,7 @@
11780
"pt": "Memória",
11781
"ru": "ОЗУ",
11782
"xloc": [
11777
- "default.handlebars->27->1502",
11783
+ "default.handlebars->27->1503",
11784
"default.handlebars->27->743",
11785
"default.handlebars->container->column_l->p40->3->1->p40type->3"
11786
]
@@ -11884,7 +11890,7 @@
11890
"nl": "MeshAgent verkeer",
11891
"ru": "Трафик MeshAgent",
11892
"xloc": [
11887
- "default.handlebars->27->1523"
11893
+ "default.handlebars->27->1524"
11894
]
11895
},
11896
{
@@ -11897,7 +11903,7 @@
11903
"nl": "MeshAgent update",
11904
"ru": "Обновление MeshAgent",
11905
"xloc": [
11900
- "default.handlebars->27->1524"
11906
+ "default.handlebars->27->1525"
11907
]
11908
},
11909
{
@@ -11977,7 +11983,7 @@
11983
"pt": "Peering do servidor MeshCentral",
11984
"ru": "Соединения сервера MeshCentral",
11985
"xloc": [
11980
- "default.handlebars->27->1522"
11986
+ "default.handlebars->27->1523"
11987
]
11988
},
11989
{
@@ -12169,7 +12175,7 @@
12175
"pt": "Despachante de mensagens",
12176
"ru": "Диспетчер сообщения",
12177
"xloc": [
12172
- "default.handlebars->27->1520"
12178
+ "default.handlebars->27->1521"
12179
]
12180
},
12181
{
@@ -12251,7 +12257,7 @@
12257
"pt": "Mais",
12258
"ru": "Еще",
12259
"xloc": [
12254
- "default.handlebars->27->1544"
12260
+ "default.handlebars->27->1545"
12261
]
12262
},
12263
{
@@ -12804,7 +12810,7 @@
12810
"ru": "События не найдены",
12811
"xloc": [
12812
"default.handlebars->27->1269",
12807
- "default.handlebars->27->1468",
12813
+ "default.handlebars->27->1469",
12814
"default.handlebars->27->691"
12815
]
12816
},
@@ -12951,7 +12957,7 @@
12957
"default.handlebars->27->1091",
12958
"default.handlebars->27->1192",
12959
"default.handlebars->27->1374",
12954
- "default.handlebars->27->1451"
12960
+ "default.handlebars->27->1452"
12961
]
12962
},
12963
{
@@ -13020,7 +13026,7 @@
13026
"ru": "Нет общих групп устройств",
13027
"xloc": [
13028
"default.handlebars->27->1377",
13023
- "default.handlebars->27->1454"
13029
+ "default.handlebars->27->1455"
13030
]
13031
},
13032
{
@@ -13229,7 +13235,7 @@
13235
"nl": "Geen gebruikersgroep lidmaatschap",
13236
"ru": "Нет членства в группах пользователей",
13237
"xloc": [
13232
- "default.handlebars->27->1460"
13238
+ "default.handlebars->27->1461"
13239
]
13240
},
13241
{
@@ -13622,7 +13628,7 @@
13628
"pt": "Ocorreu em {0}",
13629
"ru": "Произошло в {0}",
13630
"xloc": [
13625
- "default.handlebars->27->1471"
13631
+ "default.handlebars->27->1472"
13632
]
13633
},
13634
{
@@ -13943,7 +13949,7 @@
13949
"xloc": [
13950
"default.handlebars->27->1089",
13951
"default.handlebars->27->1371",
13946
- "default.handlebars->27->1448"
13952
+ "default.handlebars->27->1449"
13953
]
13954
},
13955
{
@@ -14435,7 +14441,7 @@
14441
"nl": "Plugin Actie",
14442
"ru": "Действие плагина",
14443
"xloc": [
14438
- "default.handlebars->27->1541",
14444
+ "default.handlebars->27->1542",
14445
"default.handlebars->27->159"
14446
]
14447
},
@@ -14978,7 +14984,7 @@
14984
"pt": "RSS",
14985
"ru": "RSS",
14986
"xloc": [
14981
- "default.handlebars->27->1515"
14987
+ "default.handlebars->27->1516"
14988
]
14989
},
14990
{
@@ -15121,7 +15127,7 @@
15127
"nl": "Relay geteld",
15128
"ru": "Число ретрансляций",
15129
"xloc": [
15124
- "default.handlebars->27->1497"
15130
+ "default.handlebars->27->1498"
15131
]
15132
},
15133
{
@@ -15132,7 +15138,7 @@
15138
"nl": "Relay fouten",
15139
"ru": "Ошибки ретранслятора",
15140
"xloc": [
15135
- "default.handlebars->27->1490"
15141
+ "default.handlebars->27->1491"
15142
]
15143
},
15144
{
@@ -15145,8 +15151,8 @@
15151
"pt": "Retransmissão de sessão ",
15152
"ru": "Сессии ретранслятора",
15153
"xloc": [
15148
- "default.handlebars->27->1496",
15149
- "default.handlebars->27->1509"
15154
+ "default.handlebars->27->1497",
15155
+ "default.handlebars->27->1510"
15156
]
15157
},
15158
{
@@ -15358,7 +15364,7 @@
15364
"ru": "Удалить группу устройств.",
15365
"xloc": [
15366
"default.handlebars->27->1379",
15361
- "default.handlebars->27->1466"
15367
+ "default.handlebars->27->1467"
15368
]
15369
},
15370
{
@@ -15369,7 +15375,7 @@
15375
"nl": "Verwijder gebruiker",
15376
"ru": "Удалить пользователя",
15377
"xloc": [
15372
- "default.handlebars->27->1462"
15378
+ "default.handlebars->27->1463"
15379
]
15380
},
15381
{
@@ -15442,7 +15448,7 @@
15448
"nl": "Verwijder de groepslidmaatschap",
15449
"ru": "Удалить членство пользователя в группе",
15450
"xloc": [
15445
- "default.handlebars->27->1458"
15451
+ "default.handlebars->27->1459"
15452
]
15453
},
15454
{
@@ -15469,7 +15475,7 @@
15475
"xloc": [
15476
"default.handlebars->27->1092",
15477
"default.handlebars->27->1366",
15472
- "default.handlebars->27->1452"
15478
+ "default.handlebars->27->1453"
15479
]
15480
},
15481
{
@@ -16479,14 +16485,14 @@
16485
"nl": "Server Certificaat",
16486
"ru": "Сертификат сервера",
16487
"xloc": [
16482
- "default.handlebars->27->1525"
16488
+ "default.handlebars->27->1526"
16489
]
16490
},
16491
{
16492
"en": "Server Database",
16493
"nl": "Server Database",
16494
"xloc": [
16489
- "default.handlebars->27->1526"
16495
+ "default.handlebars->27->1527"
16496
]
16497
},
16498
{
@@ -16571,7 +16577,7 @@
16577
"nl": "Server Status",
16578
"ru": "Состояние сервера",
16579
"xloc": [
16574
- "default.handlebars->27->1476"
16580
+ "default.handlebars->27->1477"
16581
]
16582
},
16583
{
@@ -16599,7 +16605,7 @@
16605
"pt": "Rastreamento de servidor",
16606
"ru": "Трассировка сервера",
16607
"xloc": [
16602
- "default.handlebars->27->1535"
16608
+ "default.handlebars->27->1536"
16609
]
16610
},
16611
{
@@ -16707,7 +16713,7 @@
16713
"pt": "ServerStats.csv",
16714
"ru": "ServerStats.csv",
16715
"xloc": [
16710
- "default.handlebars->27->1517"
16716
+ "default.handlebars->27->1518"
16717
]
16718
},
16719
{
@@ -18291,7 +18297,7 @@
18297
"pt": "Atualmente não há notificações",
18298
"ru": "На данный момент уведомлений нет",
18299
"xloc": [
18294
- "default.handlebars->27->1470"
18300
+ "default.handlebars->27->1471"
18301
]
18302
},
18303
{
@@ -19176,7 +19182,7 @@
19182
"default-mobile.handlebars->9->174",
19183
"default-mobile.handlebars->9->175",
19184
"default.handlebars->27->13",
19179
- "default.handlebars->27->1461",
19185
+ "default.handlebars->27->1462",
19186
"default.handlebars->27->364",
19187
"default.handlebars->27->41",
19188
"default.handlebars->27->42",
@@ -19209,7 +19215,7 @@
19215
"nl": "Onbekende actie",
19216
"ru": "Неизвестное действие",
19217
"xloc": [
19212
- "default.handlebars->27->1482"
19218
+ "default.handlebars->27->1483"
19219
]
19220
},
19221
{
@@ -19221,8 +19227,8 @@
19227
"ru": "Неизвестная группа устройств",
19228
"xloc": [
19229
"default.handlebars->27->1372",
19224
- "default.handlebars->27->1449",
19225
- "default.handlebars->27->1486"
19230
+ "default.handlebars->27->1450",
19231
+ "default.handlebars->27->1487"
19232
]
19233
},
19234
{
@@ -19233,7 +19239,7 @@
19239
"nl": "Onbekende groep",
19240
"ru": "Неизвестная группа",
19241
"xloc": [
19236
- "default.handlebars->27->1478"
19242
+ "default.handlebars->27->1479"
19243
]
19244
},
19245
{
@@ -19259,7 +19265,7 @@
19265
"nl": "Onbekende gebruikersgroep",
19266
"ru": "Неизвестная группа пользователей",
19267
"xloc": [
19262
- "default.handlebars->27->1457"
19268
+ "default.handlebars->27->1458"
19269
]
19270
},
19271
{
@@ -19320,7 +19326,7 @@
19326
"nl": "Bijgewerkt",
19327
"ru": "Актуально",
19328
"xloc": [
19323
- "default.handlebars->27->1540"
19329
+ "default.handlebars->27->1541"
19330
]
19331
},
19332
{
@@ -19509,8 +19515,8 @@
19515
"pt": "Usava",
19516
"ru": "Использовано",
19517
"xloc": [
19512
- "default.handlebars->27->1472",
19513
- "default.handlebars->27->1474"
19518
+ "default.handlebars->27->1473",
19519
+ "default.handlebars->27->1475"
19520
]
19521
},
19522
{
@@ -19568,7 +19574,7 @@
19574
"nl": "Gebruikersaccounts",
19575
"ru": "Учетные записи пользователей",
19576
"xloc": [
19571
- "default.handlebars->27->1491"
19577
+ "default.handlebars->27->1492"
19578
]
19579
},
19580
{
@@ -19609,7 +19615,7 @@
19615
"xloc": [
19616
"default.handlebars->27->1146",
19617
"default.handlebars->27->1350",
19612
- "default.handlebars->27->1464"
19618
+ "default.handlebars->27->1465"
19619
]
19620
},
19621
{
@@ -19631,7 +19637,7 @@
19637
"nl": "Gebruikersgroeps lidmaatschap",
19638
"ru": "Членство в группах пользователей",
19639
"xloc": [
19634
- "default.handlebars->27->1456"
19640
+ "default.handlebars->27->1457"
19641
]
19642
},
19643
{
@@ -19713,7 +19719,7 @@
19719
"pt": "Sessões de Usuário",
19720
"ru": "Сессии пользователя",
19721
"xloc": [
19716
- "default.handlebars->27->1508"
19722
+ "default.handlebars->27->1509"
19723
]
19724
},
19725
{
@@ -19841,7 +19847,7 @@
19847
"xloc": [
19848
"default.handlebars->27->1349",
19849
"default.handlebars->27->1360",
19844
- "default.handlebars->27->1507",
19850
+ "default.handlebars->27->1508",
19851
"default.handlebars->container->topbar->1->1->UsersSubMenuSpan->UsersSubMenu->1->0->UsersGeneral"
19852
]
19853
},
@@ -19853,7 +19859,7 @@
19859
"nl": "gebruikers Sessies",
19860
"ru": "Сессии пользователей",
19861
"xloc": [
19856
- "default.handlebars->27->1495"
19862
+ "default.handlebars->27->1496"
19863
]
19864
},
19865
{
@@ -20167,8 +20173,8 @@
20173
"pt": "Servidor web",
20174
"ru": "Веб-сервер",
20175
"xloc": [
20170
- "default.handlebars->27->1527",
20171
- "default.handlebars->27->1528"
20176
+ "default.handlebars->27->1528",
20177
+ "default.handlebars->27->1529"
20178
]
20179
},
20180
{
@@ -20182,7 +20188,7 @@
20188
"pt": "Solicitações de servidor Web",
20189
"ru": "Запросы веб-сервера",
20190
"xloc": [
20185
- "default.handlebars->27->1529"
20191
+ "default.handlebars->27->1530"
20192
]
20193
},
20194
{
@@ -20196,7 +20202,7 @@
20202
"pt": "Encaminhador de soquete da Web",
20203
"ru": "Ретранслятор Web Socket",
20204
"xloc": [
20199
- "default.handlebars->27->1530"
20205
+ "default.handlebars->27->1531"
20206
]
20207
},
20208
{
@@ -20862,7 +20868,7 @@
20868
"pt": "\\\\'",
20869
"ru": "\\\\'",
20870
"xloc": [
20865
- "default.handlebars->27->1538"
20871
+ "default.handlebars->27->1539"
20872
]
20873
},
20874
{
@@ -21053,7 +21059,7 @@
21059
"pt": "livre",
21060
"ru": "свободно",
21061
"xloc": [
21056
- "default.handlebars->27->1503"
21062
+ "default.handlebars->27->1504"
21063
]
21064
},
21065
{
@@ -21287,7 +21293,7 @@
21293
"pt": "servertrace.csv",
21294
"ru": "servertrace.csv",
21295
"xloc": [
21290
- "default.handlebars->27->1537"
21296
+ "default.handlebars->27->1538"
21297
]
21298
},
21299
{
@@ -21324,7 +21330,7 @@
21330
"pt": "tempo, conn.agente, conn.usuários.usersessions, conn.relaysession, conn.intelamt, mem.externo mem.amontoado, mem.heaptotal, mem.rss",
21331
"ru": "time, conn.agent, conn.users, conn.usersessions, conn.relaysession, conn.intelamt, mem.external, mem.heapused, mem.heaptotal, mem.rss",
21332
"xloc": [
21327
- "default.handlebars->27->1516"
21333
+ "default.handlebars->27->1517"
21334
]
21335
},
21336
{
@@ -21336,7 +21342,7 @@
21342
"pt": "hora, fonte, mensagem",
21343
"ru": "time, source, message",
21344
"xloc": [
21339
- "default.handlebars->27->1536"
21345
+ "default.handlebars->27->1537"
21346
]
21347
},
21348
{
@@ -21359,7 +21365,7 @@
21365
"pt": "total",
21366
"ru": "всего",
21367
"xloc": [
21362
- "default.handlebars->27->1504"
21368
+ "default.handlebars->27->1505"
21369
]
21370
},
21371
{
@@ -22063,4 +22069,4 @@
22069
]
22070
}
22071
]
22066
-}
22072
+}
\ No newline at end of file
views/default-mobile.handlebars
+17
-5
@@ -3458,14 +3458,14 @@
3458
if (typeof mesh == 'string') { mesh = meshes[mesh] }
3459
if ((mesh == null) || (mesh.links == null)) { return 0; }
3460
3461
- // Check if user user
3461
+ // Check if super user
3462
if (userinfo.manageAllDeviceGroups) return 0xFFFFFFFF;
3463
3464
- // Check direct link permission
3464
+ // Check device group link permission
3465
var rights = 0, r = mesh.links[userid];
3466
if (r != null) {
3467
+ if (rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device group link, stop here.
3468
rights = r.rights;
3468
- if (rights == 0xFFFFFFFF) { return rights; } // User has full rights thru a direct link, stop here.
3469
}
3470
3471
// Check permissions thru user groups
@@ -3476,7 +3476,7 @@
3476
if (i.startsWith('ugrp/')) {
3477
r = mesh.links[i];
3478
if (r != null) {
3479
- if (r.rights == 0xFFFFFFFF) { return r.rights; } // User has full rights thru a user group, stop here.
3479
+ if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a user group, stop here.
3480
rights |= r.rights; // TODO: Deal with reverse permissions
3481
}
3482
}
@@ -3514,7 +3514,19 @@
3514
if (node == null) { return 0; }
3515
if (userid == null) { userid = userinfo._id; }
3516
if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } }
3517
- return GetMeshRights(node.meshid, userid);
3517
+ var r = GetMeshRights(node.meshid, userid);
3518
+ if (r != 0xFFFFFFFF) {
3519
+ var user = null;
3520
+ if (userid == userinfo._id) { user = userinfo; } else { if (users != null) { user = users[userid]; } }
3521
+ if ((user != null) && (user.links != null)) {
3522
+ var r2 = user.links[node._id];
3523
+ if (r2 != null) {
3524
+ if (r2.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device link, stop here.
3525
+ r |= r2; // TODO: Deal with reverse permissions
3526
+ }
3527
+ }
3528
+ }
3529
+ return r;
3530
}
3531
3532
//
views/default.handlebars
+54
-19
@@ -2721,7 +2721,7 @@
2721
go(parseInt('{{viewmode}}'));
2722
goBackStack.push(2);
2723
} else if (args.gotouser != null) {
2724
- if (users['user/' + domain + '/' + args.gotouser] == null) return; // This user is not loaded yet
2724
+ if ((users == null) || (users['user/' + domain + '/' + args.gotouser] == null)) return; // This user is not loaded yet
2725
gotoUser('user/' + domain + '/' + args.gotouser);
2726
go(parseInt('{{viewmode}}'));
2727
goBackStack.push(4);
@@ -3123,9 +3123,11 @@
3123
3124
// Display all empty device groups, we need to do this because users can add devices to these at any time.
3125
if ((sort == 0) && (Q('SearchInput').value == '') && (view < 3)) {
3126
- var deviceHeaderId2 = deviceHeaderId;
3127
- for (var i in meshes) {
3128
- var mesh = meshes[i], meshrights = GetMeshRights(mesh);
3126
+ var deviceHeaderId2 = deviceHeaderId, sortedMeshes = [];
3127
+ for (var i in meshes) { sortedMeshes.push(meshes[i]); }
3128
+ sortedMeshes.sort(nameSort);
3129
+ for (var i in sortedMeshes) {
3130
+ var mesh = sortedMeshes[i], meshrights = GetMeshRights(mesh);
3131
if (displayedMeshes[mesh._id] == null) {
3132
if ((current != '') && (r != '')) { r += '</tr></table>'; }
3133
r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt>';
@@ -3141,8 +3143,7 @@
3143
if (mesh.mtype == 1) {
3144
r += '<td><div style=padding:10px><i>' + "No Intel® AMT devices in this mesh";
3145
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
3144
- }
3145
- if (mesh.mtype == 2) {
3146
+ } else if (mesh.mtype == 2) {
3147
r += '<td>';
3148
r += '<div id=DevxCol' + deviceHeaderId2 + ((collapsed === true)?' style=display:none':'') + '>'; // Open collapse div
3149
r += '<div style=padding:10px><i>' + "No devices in this group";
@@ -10055,16 +10056,14 @@
10056
// Draw the user timeline
10057
drawUserPermissions();
10058
10058
- // Check if we can delete this user
10059
- var deletePossible = true;
10060
- if (user._id == userinfo._id) deletePossible = false;
10061
- if (user.siteadmin && user.siteadmin > 0 && userinfo.siteadmin != 0xFFFFFFFF) deletePossible = false;
10059
+ // Check if we can change password / delete this user
10060
+ var userAdminRights = (((userinfo.siteadmin != null) && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF)) || (userinfo.siteadmin == 0xFFFFFFFF));
10061
10062
// Show bottom buttons
10063
x = '<div style=float:right;font-size:x-small>';
10065
- if (deletePossible) x += '<a href=# style=cursor:pointer onclick=\'return p30showDeleteUserDialog()\' title="Remove this user">' + "Delete User" + '</a>';
10064
+ if (userAdminRights) { x += '<a href=# style=cursor:pointer onclick=\'return p30showDeleteUserDialog()\' title="Remove this user">' + "Delete User" + '</a>'; }
10065
x += '</div><div style=font-size:x-small>';
10067
- if (((userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF)) || (userinfo.siteadmin == 0xFFFFFFFF)) x += '<a href=# style=cursor:pointer onclick=\'return p30showUserChangePassDialog(' + multiFactor + ')\' title="' + "Change the password for this user" + '">' + "Change Password" + '</a>';
10066
+ if (userAdminRights) { x += '<a href=# style=cursor:pointer onclick=\'return p30showUserChangePassDialog(' + multiFactor + ')\' title="' + "Change the password for this user" + '">' + "Change Password" + '</a>'; }
10067
x += '</div><br>'
10068
QH('p30html3', x);
10069
@@ -10160,7 +10159,7 @@
10159
10160
function p30showDeleteUserDialog() {
10161
if (xxdialogMode) return;
10163
- setDialogMode(2, format("Delete User {0}", EscapeHtml(currentUser.name)), 3, p30showDeleteUserDialogEx, format('Confirm deletion of user {0}?', EscapeHtml(currentUser.name)));
10162
+ setDialogMode(2, format("Delete User {0}", EscapeHtml(currentUser.name)), 3, p30showDeleteUserDialogEx, format("Confirm deletion of user {0}?", EscapeHtml(currentUser.name)));
10163
}
10164
10165
function p30showDeleteUserDialogEx() {
@@ -10170,6 +10169,29 @@
10169
// Draw device power bars. The bars are 766px wide.
10170
function drawUserPermissions() {
10171
var count = 1, x = '';
10172
+
10173
+ if (urlargs.dp == 1) { // For testing only
10174
+ // Display common devices
10175
+ 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" + '</a>';
10176
+ x += '<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>' + "Common Devices" + '</th><th scope=col style=text-align:left></th></tr>';
10177
+ if (currentUser.links) {
10178
+ for (var i in currentUser.links) {
10179
+ if (i.startsWith('node/')) {
10180
+ var cr = 0, r = currentUser.links[i].rights, node = getNodeFromId(i), trash = '', rights = "Partial Device Rights";
10181
+ if (node == null) { continue; }
10182
+ if ((userinfo.links) && (userinfo.links[i] != null) && (userinfo.links[i].rights != null)) { cr = userinfo.links[i].rights; }
10183
+ var nodename = node?EscapeHtml(node.name):('<i>' + "Unknown Device" + '</i>');
10184
+ if (r == 0xFFFFFFFF) rights = "Full Device Rights"; else if (r == 0) rights = "No Rights";
10185
+ 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>'; }
10186
+ x += '<tr ' + (((++count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title=\"' + "Device Group" + '\" class=m99></div><div> ' + nodename + '<div></div></div></td><td><div style=float:right>' + trash + '</div><div>' + rights + '</div></td></tr>';
10187
+ }
10188
+ }
10189
+ }
10190
+ if (count == 1) { x += '<tr><td><div style=padding:6px> <i>' + "No devices in common" + '</i><div></div></div></td><td></td></tr>'; }
10191
+ x += '</tbody></table><br />';
10192
+ }
10193
+
10194
+ // Display common device groups
10195
var deviceGroupCount = 0, newDeviceGroup = false;
10196
for (var i in meshes) { deviceGroupCount++; if ((currentUser.links == null) || (currentUser.links[i] == null)) { newDeviceGroup = true; } }
10197
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>'; }
@@ -10190,6 +10212,7 @@
10212
if (count == 1) { x += '<tr><td><div style=padding:6px> <i>' + "No device groups in common" + '</i><div></div></div></td><td></td></tr>'; }
10213
x += '</tbody></table>';
10214
10215
+ // Display user groups
10216
if (usergroups != null) {
10217
count = 1;
10218
x += '<br />';
@@ -11169,14 +11192,14 @@
11192
if (typeof mesh == 'string') { mesh = meshes[mesh] }
11193
if ((mesh == null) || (mesh.links == null)) { return 0; }
11194
11172
- // Check if user user
11195
+ // Check if super user
11196
if (userinfo.manageAllDeviceGroups) return 0xFFFFFFFF;
11197
11175
- // Check direct link permission
11198
+ // Check device group link permission
11199
var rights = 0, r = mesh.links[userid];
11200
if (r != null) {
11201
+ if (rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device group link, stop here.
11202
rights = r.rights;
11179
- if (rights == 0xFFFFFFFF) { return rights; } // User has full rights thru a direct link, stop here.
11203
}
11204
11205
// Check permissions thru user groups
@@ -11187,7 +11210,7 @@
11210
if (i.startsWith('ugrp/')) {
11211
r = mesh.links[i];
11212
if (r != null) {
11190
- if (r.rights == 0xFFFFFFFF) { return r.rights; } // User has full rights thru a user group, stop here.
11213
+ if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a user group, stop here.
11214
rights |= r.rights; // TODO: Deal with reverse permissions
11215
}
11216
}
@@ -11219,13 +11242,25 @@
11242
11243
return false;
11244
}
11222
-
11245
+
11246
// Return the user rights for a given node
11247
function GetNodeRights(node, userid) {
11248
if (node == null) { return 0; }
11249
if (userid == null) { userid = userinfo._id; }
11250
if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } }
11228
- return GetMeshRights(node.meshid, userid);
11251
+ var r = GetMeshRights(node.meshid, userid);
11252
+ if (r != 0xFFFFFFFF) {
11253
+ var user = null;
11254
+ if (userid == userinfo._id) { user = userinfo; } else { if (users != null) { user = users[userid]; } }
11255
+ if ((user != null) && (user.links != null)) {
11256
+ var r2 = user.links[node._id];
11257
+ if (r2 != null) {
11258
+ if (r2.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device link, stop here.
11259
+ r |= r2; // TODO: Deal with reverse permissions
11260
+ }
11261
+ }
11262
+ }
11263
+ return r;
11264
}
11265
11266
//
webserver.js
+14
-6
@@ -4101,12 +4101,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4101
db.Get(nodeid, function (err, nodes) {
4102
if ((nodes == null) || (nodes.length != 1)) { func(null, 0, false); return; } // No such nodeid
4103
4104
- // Check direct link
4105
- var rights = 0, visible = false, r = user.links[nodes[0].meshid];
4104
+ // Check device link
4105
+ var rights = 0, visible = false, r = user.links[nodeid];
4106
if (r != null) {
4107
- rights = r.rights;
4107
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a device link, stop here.
4108
+ rights |= r.rights;
4109
+ visible = true;
4110
+ }
4111
+
4112
+ // Check device group link
4113
+ r = user.links[nodes[0].meshid];
4114
+ if (r != null) {
4115
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a device group link, stop here.
4116
+ rights |= r.rights;
4117
visible = true;
4109
- if (rights == 0xFFFFFFFF) { func(nodes[0], rights, true); return; } // User has full rights thru a direct link, stop here.
4118
}
4119
4120
// Check user group links
@@ -4116,7 +4124,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4124
if (g && (g.links != null)) {
4125
r = g.links[nodes[0].meshid];
4126
if (r != null) {
4119
- if (r.rights == 0xFFFFFFFF) { func(nodes[0], r.rights, true); return; } // User has full rights thru a user group link, stop here.
4127
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a user group link, stop here.
4128
rights |= r.rights; // TODO: Deal with reverse rights
4129
visible = true;
4130
}
@@ -4202,7 +4210,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4210
return r;
4211
}
4212
4205
- // Get the right of a user on a given device group
4213
+ // Get the rights of a user on a given device group
4214
obj.GetMeshRights = function (user, mesh) {
4215
if ((user == null) || (mesh == null)) { return 0; }
4216
if (typeof user == 'string') { user = obj.users[user]; }