Fixed mobile application for user groups.
Ylian Saint-Hilaire committed
Jan 4, 2020 at 11:37 UTC
8a31f38241b209ae3d4236daef660251a95286c4
4 files changed
+75
-9
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.4.6-w",
3
+ "version": "0.4.6-x",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
sample-config.json
+1
-1
@@ -65,7 +65,7 @@
65
},
66
"__MaxInvalidLogin": "Time in minutes, max amount of bad logins from a source IP in the time before logins are rejected.",
67
"MaxInvalidLogin": { "time": 10, "count": 10, "coolofftime": 10 },
68
- "_plugins": {
68
+ "_Plugins": {
69
"enabled": true
70
}
71
},
views/default-mobile.handlebars
+72
-6
@@ -117,6 +117,14 @@
117
float: left;
118
}
119
120
+ .m4 {
121
+ background: url(../images/images16.png) -128px 0px;
122
+ height: 16px;
123
+ width: 16px;
124
+ border: none;
125
+ float: left;
126
+ }
127
+
128
.gray {
129
/*filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");*/ /* Firefox 10+, Firefox on Android */
130
filter: gray; /* IE6-9 */
@@ -614,6 +622,7 @@
622
var authCookieRenewTimer = null;
623
var meshserver = null;
624
var xdr = null;
625
+ var usergroups = null;
626
var serverinfo = null;
627
var nodes = [];
628
var meshes = {};
@@ -670,6 +679,7 @@
679
if (authCookieRenewTimer != null) { clearInterval(authCookieRenewTimer); authCookieRenewTimer = null; }
680
} else if (state == 2) {
681
// Fetch list of meshes, nodes, files
682
+ meshserver.send({ action: 'usergroups' });
683
meshserver.send({ action: 'meshes' });
684
meshserver.send({ action: 'nodes' });
685
meshserver.send({ action: 'files' });
@@ -755,6 +765,20 @@
765
updateDevices();
766
break;
767
}
768
+ case 'usergroups': {
769
+ var groupCount = 0;
770
+ if (Array.isArray(message.ugroups)) {
771
+ usergroups = {};
772
+ for (var i in message.ugroups) { groupCount++; usergroups[message.ugroups[i]._id] = message.ugroups[i]; }
773
+ if (groupCount == 0) { usergroups = null; }
774
+ } else {
775
+ usergroups = message.ugroups;
776
+ for (var i in message.ugroups) { groupCount++; }
777
+ if (groupCount == 0) { usergroups = null; }
778
+ }
779
+ //masterUpdate(8192);
780
+ break;
781
+ }
782
case 'files': {
783
filetree = setupBackPointers(message.filetree);
784
updateFiles();
@@ -876,6 +900,34 @@
900
}
901
break;
902
}
903
+ case 'createusergroup':
904
+ case 'usergroupchange': {
905
+ // User group changed
906
+ if (usergroups == null) { usergroups = {}; }
907
+ var ugroup = usergroups[message.event.ugrpid];
908
+ if (ugroup == null) {
909
+ // This is a new user group for us
910
+ usergroups[message.event.ugrpid] = { _id: message.event.ugrpid, name: message.event.name, desc: message.event.desc, domain: message.event.domain, links: message.event.links };
911
+ } else {
912
+ // This is an existing user group
913
+ ugroup.name = message.event.name;
914
+ ugroup.desc = message.event.desc;
915
+ ugroup.links = message.event.links;
916
+ }
917
+ //masterUpdate(8192 + 16384);
918
+ break;
919
+ }
920
+ case 'deleteusergroup': {
921
+ // User group removed
922
+ if ((usergroups != null) && (usergroups[message.event.ugrpid] != null)) {
923
+ delete usergroups[message.event.ugrpid];
924
+ var c = 0;
925
+ for (var i in usergroups) { c++; }
926
+ if (c == 0) { usergroups = null; } // If user groups is empty, set it to null.
927
+ //masterUpdate(8192 + 16384);
928
+ }
929
+ break;
930
+ }
931
case 'createmesh': {
932
// A new mesh was created
933
if (message.event.links[userinfo._id] != null) { // Check if this is a mesh create for a mesh we own. If site administrator, we get all messages so need to ignore some.
@@ -1724,11 +1776,11 @@
1776
if (typeof deviceHeaderCount[nodes[i].state] == 'undefined') { deviceHeaderCount[nodes[i].state] = 1; } else { deviceHeaderCount[nodes[i].state]++; }
1777
}
1778
1727
- // Display all empty meshes, we need to do this because users can add devices to these at any time.
1779
+ // Display all empty device groups, we need to do this because users can add devices to these at any time.
1780
if (sort == 0) {
1781
for (var i in meshes) {
1782
var mesh = meshes[i];
1731
- if (IsMeshViewable(mesh)) {
1783
+ if ((displayedMeshes[mesh._id] == null) && (IsMeshViewable(mesh))) {
1784
if ((current != '') && (r != '')) { r += '</tr></table>'; }
1785
r += '<div><div colspan=3 class=DevSt><span style=float:right>';
1786
//r += getMeshActions(mesh, meshrights);
@@ -3135,16 +3187,23 @@
3187
3188
// Sort the users for this mesh
3189
var count = 1, sortedusers = [];
3138
- for (var i in currentMesh.links) { sortedusers.push({ id: i, name: i.split('/')[2], rights: currentMesh.links[i].rights }); }
3190
+ for (var i in currentMesh.links) {
3191
+ var uname = i.split('/')[2];
3192
+ if (currentMesh.links[i].name) { uname = currentMesh.links[i].name; }
3193
+ if (i == userinfo._id) { uname = userinfo.name; }
3194
+ if ((usergroups != null) && (usergroups[i] != null)) { uname = usergroups[i].name; }
3195
+ sortedusers.push({ id: i, name: uname, rights: currentMesh.links[i].rights });
3196
+ }
3197
sortedusers.sort(function (a, b) { if (a.name > b.name) return 1; if (a.name < b.name) return -1; return 0; });
3198
3199
// Display all users for this mesh
3200
for (var i in sortedusers) {
3143
- var trash = '', rights = "Partial Rights", r = sortedusers[i].rights;
3201
+ var trash = '', rights = "Partial Rights", r = sortedusers[i].rights, icon = 2;
3202
if (r == 0xFFFFFFFF) rights = "Full Administrator"; else if (r == 0) rights = "No Rights";
3203
if ((i != userinfo._id) && (meshrights == 0xFFFFFFFF || (((meshrights & 2) != 0)))) { trash = '<a onclick=p20deleteUser(event,"' + encodeURIComponent(sortedusers[i].id) + '") style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
3204
+ if (sortedusers[i].id.startsWith('ugrp/')) { icon = 4; }
3205
x += '<tr onclick=p20viewuser("' + encodeURIComponent(sortedusers[i].id) + '") style=height:32px;cursor:pointer' + (((count % 2) == 0) ? ';background-color:#DDD' : '') + '><td>';
3147
- x += '<div style=float:right>' + trash + '</div><div style=float:right;padding-right:4px>' + rights + '</div><div class=m2></div><div> ' + EscapeHtml(decodeURIComponent(sortedusers[i].name)) + '<div></div></div>';
3206
+ x += '<div style=float:right>' + trash + '</div><div style=float:right;padding-right:4px>' + rights + '</div><div class=m' + icon + '></div><div> ' + EscapeHtml(decodeURIComponent(sortedusers[i].name)) + '<div></div></div>';
3207
x += '</td></tr>';
3208
++count;
3209
}
@@ -3296,7 +3355,14 @@
3355
setDialogMode(2, "Device Group User", buttons, p20viewuserEx, x, userid);
3356
}
3357
3299
- function p20viewuserEx(button, userid) { if (button != 2) return; setDialogMode(2, "Remote Mesh User", 3, p20viewuserEx2, format("Confirm removal of user {0}?", userid.split('/')[2]), userid); }
3358
+ function p20viewuserEx(button, userid) {
3359
+ if (button != 2) return;
3360
+ var uname = userid.split('/')[2];
3361
+ if (users && users[userid]) { uname = users[userid].name; }
3362
+ if (usergroups && usergroups[userid]) { uname = usergroups[userid].name; }
3363
+ if (userinfo._id == userid) { uname = userinfo.name; }
3364
+ setDialogMode(2, "Remote Mesh User", 3, p20viewuserEx2, format("Confirm removal of user {0}?", uname), userid);
3365
+ }
3366
function p20deleteUser(e, userid) { haltEvent(e); p20viewuserEx(2, decodeURIComponent(userid)); }
3367
function p20viewuserEx2(button, userid) { meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid }); }
3368
views/default.handlebars
+1
-1
@@ -1500,8 +1500,8 @@
1500
if (authCookieRenewTimer != null) { clearInterval(authCookieRenewTimer); authCookieRenewTimer = null; }
1501
} else if (state == 2) {
1502
// Fetch list of meshes, nodes, files
1503
- meshserver.send({ action: 'meshes' });
1503
meshserver.send({ action: 'usergroups' });
1504
+ meshserver.send({ action: 'meshes' });
1505
meshserver.send({ action: 'nodes', id: '{{currentNode}}' });
1506
if (pluginHandler != null) { meshserver.send({ action: 'plugins' }); }
1507
if ('{{currentNode}}' == '') { meshserver.send({ action: 'files' }); }