More work on cross-domain administrator
This commit is contained in:
parent
27afc80cb5
commit
7c91660cd2
138
meshuser.js
138
meshuser.js
|
@ -396,19 +396,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
if (args.notls == true) { serverinfo.https = false; } else { serverinfo.https = true; serverinfo.redirport = args.redirport; }
|
||||
if (typeof domain.userconsentflags == 'number') { serverinfo.consent = domain.userconsentflags; }
|
||||
if ((typeof domain.usersessionidletimeout == 'number') && (domain.usersessionidletimeout > 0)) { serverinfo.timeout = (domain.usersessionidletimeout * 60 * 1000); }
|
||||
if (user.siteadmin == 0xFFFFFFFF) {
|
||||
if (parent.parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) { serverinfo.manageAllDeviceGroups = true; }
|
||||
if (obj.crossDomain === true) { serverinfo.crossDomain = []; for (var i in parent.parent.config.domains) { serverinfo.crossDomain.push(i); } }
|
||||
}
|
||||
|
||||
// Send server information
|
||||
try { ws.send(JSON.stringify({ action: 'serverinfo', serverinfo: serverinfo })); } catch (ex) { }
|
||||
|
||||
// Send user information to web socket, this is the first thing we send
|
||||
try {
|
||||
var xuserinfo = parent.CloneSafeUser(parent.users[user._id]);
|
||||
if (user.siteadmin == 0xFFFFFFFF) {
|
||||
if (parent.parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) { xuserinfo.manageAllDeviceGroups = true; }
|
||||
if (obj.crossDomain === true) { xuserinfo.crossDomain = []; for (var i in parent.parent.config.domains) { xuserinfo.crossDomain.push(i); } }
|
||||
}
|
||||
ws.send(JSON.stringify({ action: 'userinfo', userinfo: xuserinfo }));
|
||||
} catch (ex) { }
|
||||
try { ws.send(JSON.stringify({ action: 'userinfo', userinfo: parent.CloneSafeUser(parent.users[user._id]) })); } catch (ex) { }
|
||||
|
||||
if (user.siteadmin == 0xFFFFFFFF) {
|
||||
// Send server tracing information
|
||||
|
@ -1832,7 +1829,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
}
|
||||
case 'usergroups':
|
||||
{
|
||||
// TODO: Return only groups in the same administrative domain?
|
||||
// Return only groups in the same administrative domain
|
||||
if ((user.siteadmin & SITERIGHT_USERGROUPS) == 0) {
|
||||
// We are not user group administrator, return a list with limited data for our domain.
|
||||
var groups = {}, groupCount = 0;
|
||||
|
@ -1841,35 +1838,44 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
} else {
|
||||
// We are user group administrator, return a full user group list for our domain.
|
||||
var groups = {}, groupCount = 0;
|
||||
for (var i in parent.userGroups) { if (parent.userGroups[i].domain == domain.id) { groupCount++; groups[i] = parent.userGroups[i]; } }
|
||||
for (var i in parent.userGroups) { if ((obj.crossDomain == true) || (parent.userGroups[i].domain == domain.id)) { groupCount++; groups[i] = parent.userGroups[i]; } }
|
||||
try { ws.send(JSON.stringify({ action: 'usergroups', ugroups: groupCount ? groups : null, tag: command.tag })); } catch (ex) { }
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'createusergroup':
|
||||
{
|
||||
var err = null;
|
||||
var ugrpdomain, err = null;
|
||||
try {
|
||||
// Check if we have new group restriction
|
||||
if ((user.siteadmin & SITERIGHT_USERGROUPS) == 0) { err = 'Permission denied'; }
|
||||
if ((user.siteadmin & SITERIGHT_USERGROUPS) == 0) { err = "Permission denied"; }
|
||||
|
||||
// In some situations, we need a verified email address to create a device group.
|
||||
else if ((parent.parent.mailserver != null) && (domain.auth != 'sspi') && (domain.auth != 'ldap') && (user.emailVerified !== true) && (user.siteadmin != 0xFFFFFFFF)) { err = 'Email verification required'; } // User must verify it's email first.
|
||||
|
||||
// Create user group
|
||||
else if (common.validateString(command.name, 1, 64) == false) { err = 'Invalid group name'; } // User group name is between 1 and 64 characters
|
||||
else if ((command.desc != null) && (common.validateString(command.desc, 0, 1024) == false)) { err = 'Invalid group description'; } // User group description is between 0 and 1024 characters
|
||||
// Create user group validation
|
||||
else if (common.validateString(command.name, 1, 64) == false) { err = "Invalid group name"; } // User group name is between 1 and 64 characters
|
||||
else if ((command.desc != null) && (common.validateString(command.desc, 0, 1024) == false)) { err = "Invalid group description"; } // User group description is between 0 and 1024 characters
|
||||
|
||||
// If we are cloning from an existing user group, check that.
|
||||
if (command.clone) {
|
||||
if (common.validateString(command.clone, 1, 256) == false) { err = 'Invalid clone groupid'; }
|
||||
if (common.validateString(command.clone, 1, 256) == false) { err = "Invalid clone groupid"; }
|
||||
else {
|
||||
var clonesplit = command.clone.split('/');
|
||||
if ((clonesplit.length != 3) || (clonesplit[0] != 'ugrp') || (clonesplit[1] != domain.id)) { err = 'Invalid clone groupid'; }
|
||||
else if (parent.userGroups[command.clone] == null) { err = 'Invalid clone groupid'; }
|
||||
if ((clonesplit.length != 3) || (clonesplit[0] != 'ugrp') || ((command.domain == null) && (clonesplit[1] != domain.id))) { err = "Invalid clone groupid"; }
|
||||
else if (parent.userGroups[command.clone] == null) { err = "Invalid clone groupid"; }
|
||||
}
|
||||
|
||||
// Get new user group domain
|
||||
ugrpdomain = parent.parent.config.domains[clonesplit[1]];
|
||||
if (ugrpdomain == null) { err = "Invalid domain"; }
|
||||
} else {
|
||||
// Get new user group domain
|
||||
ugrpdomain = domain;
|
||||
if ((obj.crossDomain === true) && (command.domain != null)) { ugrpdomain = parent.parent.config.domains[command.domain]; }
|
||||
if (ugrpdomain == null) { err = "Invalid domain"; }
|
||||
}
|
||||
} catch (ex) { err = 'Validation exception: ' + ex; }
|
||||
|
||||
// In some situations, we need a verified email address to create a device group.
|
||||
if ((err == null) && (parent.parent.mailserver != null) && (ugrpdomain.auth != 'sspi') && (ugrpdomain.auth != 'ldap') && (user.emailVerified !== true) && (user.siteadmin != 0xFFFFFFFF)) { err = "Email verification required"; } // User must verify it's email first.
|
||||
} catch (ex) { err = "Validation exception: " + ex; }
|
||||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
|
@ -1880,10 +1886,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
// We only create Agent-less Intel AMT mesh (Type1), or Agent mesh (Type2)
|
||||
parent.crypto.randomBytes(48, function (err, buf) {
|
||||
// Create new device group identifier
|
||||
var ugrpid = 'ugrp/' + domain.id + '/' + buf.toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||
var ugrpid = 'ugrp/' + ugrpdomain.id + '/' + buf.toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||
|
||||
// Create the new device group
|
||||
var ugrp = { type: 'ugrp', _id: ugrpid, name: command.name, desc: command.desc, domain: domain.id, links: {} };
|
||||
var ugrp = { type: 'ugrp', _id: ugrpid, name: command.name, desc: command.desc, domain: ugrpdomain.id, links: {} };
|
||||
|
||||
// Clone the existing group if required
|
||||
var pendingDispatchEvents = [];
|
||||
|
@ -1901,7 +1907,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
|
||||
// Notify user change
|
||||
var targets = ['*', 'server-users', user._id, xuser._id];
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(xuser), action: 'accountchange', msg: 'User group membership changed: ' + xuser.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(xuser), action: 'accountchange', msg: 'User group membership changed: ' + xuser.name, domain: ugrpdomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
//parent.parent.DispatchEvent(targets, obj, event);
|
||||
pendingDispatchEvents.push([targets, obj, event]);
|
||||
|
@ -1914,7 +1920,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
db.Set(xmesh);
|
||||
|
||||
// Notify mesh change
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: xmesh._id, name: xmesh.name, mtype: xmesh.mtype, desc: xmesh.desc, action: 'meshchange', links: xmesh.links, msg: 'Added group ' + ugrp.name + ' to mesh ' + xmesh.name, domain: domain.id, invite: mesh.invite };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: xmesh._id, name: xmesh.name, mtype: xmesh.mtype, desc: xmesh.desc, action: 'meshchange', links: xmesh.links, msg: 'Added group ' + ugrp.name + ' to mesh ' + xmesh.name, domain: ugrpdomain.id, invite: mesh.invite };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
//parent.parent.DispatchEvent(['*', xmesh._id, user._id], obj, event);
|
||||
pendingDispatchEvents.push([parent.CreateMeshDispatchTargets(xmesh, [user._id]), obj, event]);
|
||||
|
@ -1929,7 +1935,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
if (db.changeStream == false) { parent.userGroups[ugrpid] = ugrp; }
|
||||
|
||||
// Event the device group creation
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugrpid, name: ugrp.name, desc: ugrp.desc, action: 'createusergroup', links: ugrp.links, msg: 'User group created: ' + ugrp.name, domain: domain.id };
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugrpid, name: ugrp.name, desc: ugrp.desc, action: 'createusergroup', links: ugrp.links, msg: 'User group created: ' + ugrp.name, ugrpdomain: domain.id };
|
||||
parent.parent.DispatchEvent(['*', ugrpid, user._id], obj, event); // Even if DB change stream is active, this event must be acted upon.
|
||||
|
||||
// Event any pending events, these must be sent out after the group creation event is displatched.
|
||||
|
@ -1949,7 +1955,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
// Change the name or description of a user group
|
||||
if (common.validateString(command.ugrpid, 1, 1024) == false) break; // Check the user group id
|
||||
var ugroupidsplit = command.ugrpid.split('/');
|
||||
if ((ugroupidsplit.length != 3) || (ugroupidsplit[0] != 'ugrp') || (ugroupidsplit[1] != domain.id)) break;
|
||||
if ((ugroupidsplit.length != 3) || (ugroupidsplit[0] != 'ugrp') || ((obj.crossDomain !== true) && (ugroupidsplit[1] != domain.id))) break;
|
||||
|
||||
// Get the domain
|
||||
var delGroupDomain = parent.parent.config.domains[ugroupidsplit[1]];
|
||||
if (delGroupDomain == null) break;
|
||||
|
||||
db.Get(command.ugrpid, function (err, groups) {
|
||||
if ((err != null) || (groups.length != 1)) return;
|
||||
|
@ -1967,7 +1977,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
|
||||
// Notify user change
|
||||
var targets = ['*', 'server-users', user._id, xuser._id];
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(xuser), action: 'accountchange', msg: 'User group membership changed: ' + xuser.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(xuser), action: 'accountchange', msg: 'User group membership changed: ' + xuser.name, delGroupDomain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
}
|
||||
|
@ -1978,7 +1988,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
db.Set(xmesh);
|
||||
|
||||
// Notify mesh change
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: xmesh._id, name: xmesh.name, mtype: xmesh.mtype, desc: xmesh.desc, action: 'meshchange', links: xmesh.links, msg: 'Removed group ' + group.name + ' from mesh ' + xmesh.name, domain: domain.id, invite: mesh.invite };
|
||||
var event = { etype: 'mesh', userid: user._id, username: user.name, meshid: xmesh._id, name: xmesh.name, mtype: xmesh.mtype, desc: xmesh.desc, action: 'meshchange', links: xmesh.links, msg: 'Removed group ' + group.name + ' from mesh ' + xmesh.name, domain: delGroupDomain.id, invite: mesh.invite };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(xmesh, [user._id]), obj, event);
|
||||
}
|
||||
|
@ -1991,7 +2001,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
if (db.changeStream == false) { delete parent.userGroups[group._id]; }
|
||||
|
||||
// Event the user group being removed
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, action: 'deleteusergroup', msg: change, domain: domain.id };
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, action: 'deleteusergroup', msg: change, domain: delGroupDomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', group._id, user._id], obj, event);
|
||||
|
||||
|
@ -2032,10 +2042,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
else if (common.validateStrArray(command.usernames, 1, 64) == false) { err = 'Invalid usernames'; } // Username is between 1 and 64 characters
|
||||
else {
|
||||
var ugroupidsplit = command.ugrpid.split('/');
|
||||
if ((ugroupidsplit.length != 3) || (ugroupidsplit[0] != 'ugrp') || (ugroupidsplit[1] != domain.id)) { err = 'Invalid groupid'; }
|
||||
if ((ugroupidsplit.length != 3) || (ugroupidsplit[0] != 'ugrp') || ((obj.crossDomain !== true) && (ugroupidsplit[1] != domain.id))) { err = 'Invalid groupid'; }
|
||||
}
|
||||
} catch (ex) { err = 'Validation exception: ' + ex; }
|
||||
|
||||
// Fetch the domain
|
||||
var addUserDomain = domain;
|
||||
if (obj.crossDomain === true) { addUserDomain = parent.parent.config.domains[ugroupidsplit[1]]; }
|
||||
if (addUserDomain == null) { err = 'Invalid domain'; }
|
||||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addusertousergroup', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
|
@ -2050,7 +2065,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
var unknownUsers = [], addedCount = 0, failCount = 0;
|
||||
for (var i in command.usernames) {
|
||||
// Check if the user exists
|
||||
var chguserid = 'user/' + domain.id + '/' + command.usernames[i].toLowerCase(), chguser = parent.users[chguserid];
|
||||
var chguserid = 'user/' + addUserDomain.id + '/' + command.usernames[i].toLowerCase(), chguser = parent.users[chguserid];
|
||||
if (chguser != null) {
|
||||
// Add mesh to user
|
||||
if (chguser.links == null) { chguser.links = {}; }
|
||||
|
@ -2060,7 +2075,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
|
||||
// Notify user change
|
||||
var targets = ['*', 'server-users', user._id, chguser._id];
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'User group membership changed: ' + chguser.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'User group membership changed: ' + chguser.name, domain: addUserDomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
|
||||
|
@ -2078,7 +2093,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
db.Set(group);
|
||||
|
||||
// Notify user group change
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, name: group.name, desc: group.desc, action: 'usergroupchange', links: group.links, msg: 'Added user ' + chguser.name + ' to user group ' + group.name, domain: domain.id };
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, name: group.name, desc: group.desc, action: 'usergroupchange', links: group.links, msg: 'Added user ' + chguser.name + ' to user group ' + group.name, addUserDomain: domain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', group._id, user._id, chguserid], obj, event);
|
||||
}
|
||||
|
@ -2102,10 +2117,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
else if (common.validateString(command.userid, 1, 256) == false) { err = 'Invalid userid'; }
|
||||
else {
|
||||
var ugroupidsplit = command.ugrpid.split('/');
|
||||
if ((ugroupidsplit.length != 3) || (ugroupidsplit[0] != 'ugrp') || (ugroupidsplit[1] != domain.id)) { err = 'Invalid groupid'; }
|
||||
if ((ugroupidsplit.length != 3) || (ugroupidsplit[0] != 'ugrp') || ((obj.crossDomain !== true) && (ugroupidsplit[1] != domain.id))) { err = 'Invalid groupid'; }
|
||||
}
|
||||
} catch (ex) { err = 'Validation exception: ' + ex; }
|
||||
|
||||
// Fetch the domain
|
||||
var removeUserDomain = domain;
|
||||
if (obj.crossDomain !== true) { removeUserDomain = parent.parent.config.domains[ugroupidsplit[1]]; }
|
||||
if (removeUserDomain == null) { err = 'Invalid domain'; }
|
||||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removeuserfromusergroup', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
|
@ -2122,7 +2142,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
|
||||
// Notify user change
|
||||
var targets = ['*', 'server-users', user._id, chguser._id];
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'User group membership changed: ' + chguser.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'User group membership changed: ' + chguser.name, domain: removeUserDomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
|
||||
|
@ -2141,7 +2161,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
|
||||
// Notify user group change
|
||||
if (change) {
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, name: group.name, desc: group.desc, action: 'usergroupchange', links: group.links, msg: 'Removed user ' + chguser.name + ' from user group ' + group.name, domain: domain.id };
|
||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: group._id, name: group.name, desc: group.desc, action: 'usergroupchange', links: group.links, msg: 'Removed user ' + chguser.name + ' from user group ' + group.name, domain: removeUserDomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
|
||||
parent.parent.DispatchEvent(['*', group._id, user._id, chguser._id], obj, event);
|
||||
}
|
||||
|
@ -2593,7 +2613,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
}
|
||||
case 'addmeshuser':
|
||||
{
|
||||
var err = null;
|
||||
var err = null, mesh, meshIdSplit;
|
||||
if (typeof command.userid == 'string') { command.userids = [command.userid]; }
|
||||
|
||||
// Resolve the device group name if needed
|
||||
|
@ -2614,9 +2634,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
else {
|
||||
if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
|
||||
mesh = parent.meshes[command.meshid];
|
||||
meshIdSplit = command.meshid.split('/');
|
||||
if (mesh == null) { err = 'Unknown group'; }
|
||||
else if (((selfMeshRights = parent.GetMeshRights(user, mesh)) & MESHRIGHT_MANAGEUSERS) == 0) { err = 'Permission denied'; }
|
||||
else if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
|
||||
else if ((meshIdSplit.length != 3) || (meshIdSplit[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
|
||||
}
|
||||
} catch (ex) { err = 'Validation exception: ' + ex; }
|
||||
|
||||
|
@ -2644,6 +2665,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { newuser = parent.users[i]; command.userids[i] = newuserid = parent.users[i]._id; break; } }
|
||||
}
|
||||
|
||||
// Make sure this user is in the same domain as the device group
|
||||
if (meshIdSplit[1] != newuserid.split('/')[1]) { msgs.push("Mismatch domains"); continue; }
|
||||
|
||||
if (newuser != null) {
|
||||
// Can't add or modify self
|
||||
if (newuserid == obj.user._id) { msgs.push("Can't change self"); continue; }
|
||||
|
@ -2719,7 +2743,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
}
|
||||
case 'adddeviceuser': {
|
||||
if (typeof command.userid == 'string') { command.userids = [command.userid]; }
|
||||
var err = null;
|
||||
var err = null, nodeIdSplit;
|
||||
try {
|
||||
if (common.validateString(command.nodeid, 1, 1024) == false) { err = 'Invalid nodeid'; } // Check the nodeid
|
||||
else if (common.validateInt(command.rights) == false) { err = 'Invalid rights'; } // Device rights must be an integer
|
||||
|
@ -2772,6 +2796,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
}
|
||||
}
|
||||
|
||||
// Check the the user and device are in the same domain
|
||||
if (command.nodeid.split('/')[1] != newuserid.split('/')[1]) return; // Domain mismatch
|
||||
|
||||
if (newuser != null) {
|
||||
// Add this user to the dispatch target list
|
||||
dispatchTargets.push(newuser._id);
|
||||
|
@ -2840,7 +2867,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
}
|
||||
case 'removemeshuser':
|
||||
{
|
||||
var err = null;
|
||||
var xdomain, err = null;
|
||||
|
||||
// Resolve the device group name if needed
|
||||
if ((typeof command.meshname == 'string') && (command.meshid == null)) {
|
||||
|
@ -2857,19 +2884,26 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
if (common.validateString(command.meshid, 1, 1024) == false) { err = "Invalid groupid"; } // Check meshid
|
||||
if (command.userid.indexOf('/') == -1) { command.userid = 'user/' + domain.id + '/' + command.userid; }
|
||||
if (command.userid == obj.user._id) { err = "Can't remove self"; } // Can't add of modify self
|
||||
if ((command.userid.split('/').length != 3) || (command.userid.split('/')[1] != domain.id)) { err = "Invalid userid"; } // Invalid domain, operation only valid for current domain
|
||||
if ((command.userid.split('/').length != 3) || ((obj.crossDomain !== true) && (command.userid.split('/')[1] != domain.id))) { err = "Invalid userid"; } // Invalid domain, operation only valid for current domain
|
||||
else {
|
||||
if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
|
||||
mesh = parent.meshes[command.meshid];
|
||||
var meshIdSplit = command.meshid.split('/');
|
||||
if (mesh == null) { err = "Unknown device group"; }
|
||||
else if ((parent.GetMeshRights(user, mesh) & MESHRIGHT_MANAGEUSERS) == 0) { err = "Permission denied"; }
|
||||
else if ((command.meshid.split('/').length != 3) || (command.meshid.split('/')[1] != domain.id)) { err = "Invalid domain"; } // Invalid domain, operation only valid for current domain
|
||||
else if (meshIdSplit.length != 3) { err = "Invalid domain"; } // Invalid domain, operation only valid for current domain
|
||||
else {
|
||||
xdomain = domain;
|
||||
if (obj.crossDomain !== true) { xdomain = parent.parent.config.domains[meshIdSplit[1]]; }
|
||||
if (xdomain == null) { err = "Invalid domain"; }
|
||||
}
|
||||
}
|
||||
} catch (ex) { err = "Validation exception: " + ex; }
|
||||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
console.log(err);
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removemeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2879,9 +2913,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
else if (deluserid.startsWith('ugrp/')) { deluser = parent.userGroups[deluserid]; }
|
||||
|
||||
// Search for a user name in that windows domain is the username starts with *\
|
||||
if ((deluser == null) && (deluserid.startsWith('user/' + domain.id + '/*\\')) == true) {
|
||||
if ((deluser == null) && (deluserid.startsWith('user/' + xdomain.id + '/*\\')) == true) {
|
||||
var search = deluserid.split('/')[2].substring(1);
|
||||
for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { deluser = parent.users[i]; command.userid = deluserid = deluser._id; break; } }
|
||||
for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == xdomain.id)) { deluser = parent.users[i]; command.userid = deluserid = deluser._id; break; } }
|
||||
}
|
||||
|
||||
if (deluser != null) {
|
||||
|
@ -2897,13 +2931,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
if (deluserid.startsWith('user/')) {
|
||||
// Notify user change
|
||||
var targets = ['*', 'server-users', user._id, deluser._id];
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(deluser), action: 'accountchange', msg: 'Device group membership changed: ' + deluser.name, domain: domain.id };
|
||||
var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(deluser), action: 'accountchange', msg: 'Device group membership changed: ' + deluser.name, domain: xdomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
} else if (deluserid.startsWith('ugrp/')) {
|
||||
// Notify user group change
|
||||
var targets = ['*', 'server-ugroups', user._id, deluser._id];
|
||||
var event = { etype: 'ugrp', username: user.name, ugrpid: deluser._id, name: deluser.name, desc: deluser.desc, action: 'usergroupchange', links: deluser.links, msg: 'User group changed: ' + deluser.name, domain: domain.id };
|
||||
var event = { etype: 'ugrp', username: user.name, ugrpid: deluser._id, name: deluser.name, desc: deluser.desc, action: 'usergroupchange', links: deluser.links, msg: 'User group changed: ' + deluser.name, domain: xdomain.id };
|
||||
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
}
|
||||
|
@ -2918,9 +2952,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
// Notify mesh change
|
||||
var event;
|
||||
if (deluser != null) {
|
||||
event = { etype: 'mesh', username: user.name, userid: deluser.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + deluser.name + ' from group ' + mesh.name, domain: domain.id, invite: mesh.invite };
|
||||
event = { etype: 'mesh', username: user.name, userid: deluser.name, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + deluser.name + ' from group ' + mesh.name, domain: xdomain.id, invite: mesh.invite };
|
||||
} else {
|
||||
event = { etype: 'mesh', username: user.name, userid: (deluserid.split('/')[2]), meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + (deluserid.split('/')[2]) + ' from group ' + mesh.name, domain: domain.id, invite: mesh.invite };
|
||||
event = { etype: 'mesh', username: user.name, userid: (deluserid.split('/')[2]), meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + (deluserid.split('/')[2]) + ' from group ' + mesh.name, domain: xdomain.id, invite: mesh.invite };
|
||||
}
|
||||
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(mesh, [user._id, command.userid]), obj, event);
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removemeshuser', responseid: command.responseid, result: 'ok' })); } catch (ex) { } }
|
||||
|
@ -3054,7 +3088,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
|||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'changeDeviceMesh', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2407,7 +2407,7 @@
|
|||
}
|
||||
case 'createmesh': {
|
||||
// A new mesh was created
|
||||
if ((meshes[message.event.meshid] == null) && ((userinfo.manageAllDeviceGroups) || (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.
|
||||
if ((meshes[message.event.meshid] == null) && ((serverinfo.manageAllDeviceGroups) || (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.
|
||||
meshes[message.event.meshid] = { _id: message.event.meshid, name: message.event.name, mtype: message.event.mtype, desc: message.event.desc, links: message.event.links };
|
||||
masterUpdate(4 + 128 + 8192 + 16384);
|
||||
meshserver.send({ action: 'files' });
|
||||
|
@ -2873,8 +2873,10 @@
|
|||
go(xviewmode);
|
||||
goBackStack.push(4);
|
||||
} else if (args.gotougrp != null) {
|
||||
if ((usergroups == null) || usergroups['ugrp/' + domain + '/' + args.gotougrp] == null) return; // This user group is not loaded yet
|
||||
gotoUserGroup('ugrp/' + domain + '/' + args.gotougrp);
|
||||
var xusergrpid = args.gotougrp;
|
||||
if (args.gotougrp.indexOf('/') < 0) { xusergrpid = 'ugrp/' + domain + '/' + args.gotougrp; }
|
||||
if ((usergroups == null) || usergroups[xusergrpid] == null) return; // This user group is not loaded yet
|
||||
gotoUserGroup(xusergrpid);
|
||||
go(xviewmode);
|
||||
goBackStack.push(50);
|
||||
} else if (!isNaN(xviewmode)) {
|
||||
|
@ -5300,7 +5302,10 @@
|
|||
x += '<a href=# onclick="return p20showAddMeshUserDialog(5)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add User" + '</a>';
|
||||
if (usergroups != null) {
|
||||
var userGroupCount = 0, newUserGroup = false;
|
||||
for (var i in usergroups) { userGroupCount++; if ((currentNode.links == null) || (currentNode.links[i] == null)) { newUserGroup = true; } }
|
||||
for (var i in usergroups) {
|
||||
if (usergroups[i]._id.split('/')[1] != nodeid.split('/')[1]) continue;
|
||||
userGroupCount++; if ((currentNode.links == null) || (currentNode.links[i] == null)) { newUserGroup = true; }
|
||||
}
|
||||
if ((userGroupCount > 0) && (newUserGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(6)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add User Group" + '</a>'; }
|
||||
}
|
||||
}
|
||||
|
@ -8671,7 +8676,11 @@
|
|||
x += '<a href=# onclick="return p20showAddMeshUserDialog()" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Users" + '</a>';
|
||||
if (usergroups != null) {
|
||||
var userGroupCount = 0, newUserGroup = false;
|
||||
for (var i in usergroups) { userGroupCount++; if ((currentMesh.links == null) || (currentMesh.links[i] == null)) { newUserGroup = true; } }
|
||||
for (var i in usergroups) {
|
||||
if (usergroups[i]._id.split('/')[1] != currentMesh._id.split('/')[1]) continue;
|
||||
userGroupCount++;
|
||||
if ((currentMesh.links == null) || (currentMesh.links[i] == null)) { newUserGroup = true; }
|
||||
}
|
||||
if ((userGroupCount > 0) && (newUserGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(2)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add User Group" + '</a>'; }
|
||||
}
|
||||
}
|
||||
|
@ -8914,6 +8923,7 @@
|
|||
}
|
||||
|
||||
function p20showAddMeshUserDialog(userid, selected) {
|
||||
console.log('p20showAddMeshUserDialog', userid, selected);
|
||||
if (xxdialogMode) return false;
|
||||
var x = '';
|
||||
if ((userid == null) || (userid == 5)) {
|
||||
|
@ -8939,14 +8949,20 @@
|
|||
if (usergroups == null) return;
|
||||
var y = '';
|
||||
var ousergroups = getOrderedList(usergroups, 'name');
|
||||
for (var i in ousergroups) { if ((currentMesh.links == null) || (currentMesh.links[ousergroups[i]._id] == null)) { y += '<option value=' + encodeURIComponentEx(ousergroups[i]._id) + '>' + EscapeHtml(ousergroups[i].name) + '</option>'; } }
|
||||
for (var i in ousergroups) {
|
||||
if (currentMesh._id.split('/')[1] != ousergroups[i]._id.split('/')[1]) continue;
|
||||
if ((currentMesh.links == null) || (currentMesh.links[ousergroups[i]._id] == null)) { y += '<option value=' + encodeURIComponentEx(ousergroups[i]._id) + '>' + EscapeHtml(ousergroups[i].name) + '</option>'; }
|
||||
}
|
||||
x += addHtmlValue("User Group", '<div style=width:230px;margin:0;padding:0><select onchange=p20validateAddMeshUserDialog() id=dp2groupid style=width:100%>' + y + '</select></div>');
|
||||
} else if (userid == 6) {
|
||||
if (usergroups == null) return;
|
||||
var y = '';
|
||||
if (selected == null) {
|
||||
var ousergroups = getOrderedList(usergroups, 'name');
|
||||
for (var i in ousergroups) { if ((currentNode.links == null) || (currentNode.links[ousergroups[i]._id] == null)) { y += '<option value=' + encodeURIComponentEx(ousergroups[i]._id) + '>' + EscapeHtml(ousergroups[i].name) + '</option>'; } }
|
||||
for (var i in ousergroups) {
|
||||
if (currentNode._id.split('/')[1] != ousergroups[i]._id.split('/')[1]) continue;
|
||||
if ((currentNode.links == null) || (currentNode.links[ousergroups[i]._id] == null)) { y += '<option value=' + encodeURIComponentEx(ousergroups[i]._id) + '>' + EscapeHtml(ousergroups[i].name) + '</option>'; }
|
||||
}
|
||||
} else {
|
||||
y += '<option value=' + selected + '>' + EscapeHtml(usergroups[decodeURIComponent(selected)].name) + '</option>';
|
||||
}
|
||||
|
@ -9149,7 +9165,10 @@
|
|||
var lastuser = xusers[xusers.length - 1].trim(), lastuserl = lastuser.toLowerCase(), matchingUsers = [];
|
||||
if (lastuser.length > 0) {
|
||||
for (var i in users) {
|
||||
if (users[i].name === lastuser) { exactMatch = true; break; }
|
||||
var userSplit = users[i]._id.split('/');
|
||||
if ((currentMesh != null) && (currentMesh.domain != userSplit[1])) continue;
|
||||
if ((currentNode != null) && (currentNode.domain != userSplit[1])) continue;
|
||||
if (userSplit[2] === lastuserl) { exactMatch = true; break; }
|
||||
if (users[i].name.toLowerCase().indexOf(lastuserl) >= 0) { matchingUsers.push([users[i]._id, users[i].name]); if (matchingUsers.length >= 8) break; }
|
||||
}
|
||||
if ((exactMatch == false) && (matchingUsers.length > 0)) {
|
||||
|
@ -10075,7 +10094,7 @@
|
|||
}
|
||||
|
||||
// If we are a cross-domain administrator, add the domain.
|
||||
if ((userinfo.crossDomain != null)) {
|
||||
if ((serverinfo.crossDomain != null)) {
|
||||
var userdomain = user._id.split('/')[1];
|
||||
if (userdomain != '') { username += ', <span style=color:#26F>' + userdomain + '</span>'; }
|
||||
}
|
||||
|
@ -10297,9 +10316,9 @@
|
|||
if (xxdialogMode) return;
|
||||
var x = '';
|
||||
|
||||
if (userinfo.crossDomain) {
|
||||
if (serverinfo.crossDomain) {
|
||||
var y = '<select style=width:240px id=p4domain>';
|
||||
for (var i in userinfo.crossDomain) { y += '<option value=' + i + '>' + ((userinfo.crossDomain[i] == '')?"Default":EscapeHtml(userinfo.crossDomain[i])) + '</option>'; }
|
||||
for (var i in serverinfo.crossDomain) { y += '<option value=' + i + '>' + ((serverinfo.crossDomain[i] == '')?"Default":EscapeHtml(serverinfo.crossDomain[i])) + '</option>'; }
|
||||
y += '</select>';
|
||||
x += addHtmlValue("Domain", y);
|
||||
}
|
||||
|
@ -10361,7 +10380,7 @@
|
|||
x.emailVerified = Q('p4verifiedEmail').checked;
|
||||
x.emailInvitation = Q('p4invitationEmail').checked;
|
||||
}
|
||||
if (userinfo.crossDomain) { x.domain = userinfo.crossDomain[parseInt(Q('p4domain').value)]; }
|
||||
if (serverinfo.crossDomain) { x.domain = serverinfo.crossDomain[parseInt(Q('p4domain').value)]; }
|
||||
meshserver.send(x);
|
||||
}
|
||||
|
||||
|
@ -10522,12 +10541,20 @@
|
|||
function addUserGroupHtml(group) {
|
||||
var usercount = 0, meshcount = 0, devicecount = 0;
|
||||
if (group.links) { for (var i in group.links) { if (i.startsWith('user/')) { usercount++; } if (i.startsWith('mesh/')) { meshcount++; } if (i.startsWith('node/')) { devicecount++; } } }
|
||||
|
||||
// Group name, if we are a cross-domain administrator, add the domain.
|
||||
var name = EscapeHtml(group.name);
|
||||
if ((serverinfo.crossDomain != null)) {
|
||||
var grpdomain = group._id.split('/')[1];
|
||||
if (grpdomain != '') { name += ', <span style=color:#26F>' + EscapeHtml(grpdomain) + '</span>'; }
|
||||
}
|
||||
|
||||
var x = '<tr tabindex=0 onmouseover=userMouseHover2(this,1) onmouseout=userMouseHover2(this,0) onkeypress="if (event.key==\'Enter\') gotoUserGroup(\'' + encodeURIComponentEx(group._id) + '\')"><td style=cursor:pointer>';
|
||||
x += '<div class=bar style=width:100%>';
|
||||
x += '<div class=baricon><input class=UserGroupCheckbox value=' + encodeURIComponentEx(group._id) + ' onclick=p50updateInfo() type=checkbox></div>';
|
||||
x += '<div class=baricon onclick=gotoUserGroup("' + encodeURIComponentEx(group._id) + '")><div class=m4></div></div>';
|
||||
x += '<div class=g1 onclick=gotoUserGroup("' + encodeURIComponentEx(group._id) + '")></div><div class=g2 onclick=gotoUserGroup("' + encodeURIComponentEx(group._id) + '")></div>';
|
||||
x += '<div onclick=gotoUserGroup("' + encodeURIComponentEx(group._id) + '")><span style=font-size:16px>' + group.name + '</span></div></div><td style=text-align:center>' + usercount + '<td style=text-align:center>' + meshcount + '<td style=text-align:center>' + devicecount;
|
||||
x += '<div onclick=gotoUserGroup("' + encodeURIComponentEx(group._id) + '")><span style=font-size:16px>' + name + '</span></div></div><td style=text-align:center>' + usercount + '<td style=text-align:center>' + meshcount + '<td style=text-align:center>' + devicecount;
|
||||
return x;
|
||||
}
|
||||
|
||||
|
@ -10586,6 +10613,12 @@
|
|||
if (usergroups) { for (var i in usergroups) { y += '<option value=' + encodeURIComponentEx(i) + '>' + EscapeHtml(usergroups[i].name) + '</option>'; } }
|
||||
x += addHtmlValue("User Group", '<div style=width:230px;margin:0;padding:0><select id=dp4groupid style=width:100%>' + y + '</select></div>');
|
||||
}
|
||||
if ((mode == 1) && (serverinfo.crossDomain)) {
|
||||
var y = '<select style=width:240px id=p4domain>';
|
||||
for (var i in serverinfo.crossDomain) { y += '<option value=' + i + '>' + ((serverinfo.crossDomain[i] == '')?"Default":EscapeHtml(serverinfo.crossDomain[i])) + '</option>'; }
|
||||
y += '</select>';
|
||||
x += addHtmlValue("Domain", y);
|
||||
}
|
||||
x += addHtmlValue("Name", '<input id=p4name maxlength=64 onchange=showCreateUserGroupDialogValidate() onkeyup=showCreateUserGroupDialogValidate() />');
|
||||
x += addHtmlValue("Description", '<textarea id=p4desc value="" style=width:230px;height:60px;resize:none maxlength=1024 /></textarea>');
|
||||
setDialogMode(2, (mode == 1)?"Create User Group":"Duplicate User Group", 3, showCreateUserGroupDialogEx, x, mode);
|
||||
|
@ -10598,6 +10631,7 @@
|
|||
function showCreateUserGroupDialogEx(b, mode) {
|
||||
var x = { action: 'createusergroup', name: Q('p4name').value, desc: Q('p4desc').value };
|
||||
if (mode == 2) { x.clone = decodeURIComponent(Q('dp4groupid').value); }
|
||||
if ((mode == 1) && (serverinfo.crossDomain)) { x.domain = serverinfo.crossDomain[parseInt(Q('p4domain').value)]; }
|
||||
meshserver.send(x);
|
||||
}
|
||||
|
||||
|
@ -10635,6 +10669,8 @@
|
|||
} else {
|
||||
x += addDeviceAttribute("Description", desc);
|
||||
}
|
||||
|
||||
if (serverinfo.crossDomain != null) { x += addDeviceAttribute("Group Identifier", group._id); }
|
||||
x += addDeviceAttribute("Users", usercount);
|
||||
x += addDeviceAttribute("Device Groups", meshcount);
|
||||
x += addDeviceAttribute("Devices", devicecount);
|
||||
|
@ -10681,7 +10717,7 @@
|
|||
// Display all device groups for this user group
|
||||
count = 1;
|
||||
var deviceGroupCount = 0, newDeviceGroup = false;
|
||||
for (var i in meshes) { deviceGroupCount++; if ((currentUserGroup.links == null) || (currentUserGroup.links[i] == null)) { newDeviceGroup = true; } }
|
||||
for (var i in meshes) { if (currentUserGroup._id.split('/')[1] != meshes[i]._id.split('/')[1]) continue; deviceGroupCount++; if ((currentUserGroup.links == null) || (currentUserGroup.links[i] == null)) { newDeviceGroup = true; } }
|
||||
if ((deviceGroupCount > 0) && (newDeviceGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(3)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device Group" + '</a>'; }
|
||||
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 Device Groups" + '</th><th scope=col style=text-align:left></th></tr>';
|
||||
if (currentUserGroup.links) {
|
||||
|
@ -10705,7 +10741,8 @@
|
|||
|
||||
// Display all devices for this user group
|
||||
count = 1;
|
||||
x += '<br /><a href=# onclick="return p20showAddMeshUserDialog(7)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device" + '</a>';
|
||||
x += '<br />';
|
||||
if (currentUserGroup._id.split('/')[1] == userinfo._id.split('/')[1]) { x += '<a href=# onclick="return p20showAddMeshUserDialog(7)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device" + '</a>'; }
|
||||
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>';
|
||||
if (currentUserGroup.links) {
|
||||
var onodes = [];
|
||||
|
@ -10735,7 +10772,7 @@
|
|||
// Change the URL
|
||||
var urlviewmode = '';
|
||||
if (((features & 0x10000000) == 0) && (xxcurrentView >= 51) && (xxcurrentView <= 59) && (currentUserGroup != null)) {
|
||||
urlviewmode = '?viewmode=' + xxcurrentView + '&gotougrp=' + currentUserGroup._id.split('/')[2];
|
||||
urlviewmode = '?viewmode=' + xxcurrentView + '&gotougrp=' + ((serverinfo.crossDomain)?currentUserGroup._id:currentUserGroup._id.split('/')[2]);
|
||||
for (var i in urlargs) { urlviewmode += ('&' + i + '=' + urlargs[i]); }
|
||||
try { window.history.replaceState({}, document.title, window.location.pathname + urlviewmode); } catch (ex) { }
|
||||
}
|
||||
|
@ -10839,9 +10876,7 @@
|
|||
}
|
||||
|
||||
function p51validateAddUserDialog() {
|
||||
var meshrights = GetMeshRights(currentMesh);
|
||||
var ok = true;
|
||||
|
||||
if (Q('dp51username')) {
|
||||
var xusers = Q('dp51username').value.split(',');
|
||||
for (var i in xusers) {
|
||||
|
@ -10855,8 +10890,9 @@
|
|||
var lastuser = xusers[xusers.length - 1].trim(), lastuserl = lastuser.toLowerCase(), matchingUsers = [];
|
||||
if (lastuser.length > 0) {
|
||||
for (var i in users) {
|
||||
if (users[i].name === lastuser) { exactMatch = true; break; }
|
||||
if (users[i].name.toLowerCase().indexOf(lastuserl) >= 0) { matchingUsers.push([users[i]._id, users[i].name]); if (matchingUsers.length >= 8) break; }
|
||||
var userSplit = users[i]._id.split('/');
|
||||
if ((currentUserGroup.domain == userSplit[1]) && (userSplit[2] === lastuserl)) { exactMatch = true; break; }
|
||||
if ((users[i].name.toLowerCase().indexOf(lastuserl) >= 0) && (currentUserGroup.domain == userSplit[1])) { matchingUsers.push([users[i]._id, users[i].name]); if (matchingUsers.length >= 8) break; }
|
||||
}
|
||||
if ((exactMatch == false) && (matchingUsers.length > 0)) {
|
||||
var x = '';
|
||||
|
@ -10934,7 +10970,7 @@
|
|||
var email = user.email?EscapeHtml(user.email):'<i>' + "Not set" + '</i>', everify = '';
|
||||
if (serverinfo.emailcheck) { everify = ((user.emailVerified == true) ? '<b style=color:green;cursor:pointer title="' + "Email is verified" + '">✓</b> ' : '<b style=color:red;cursor:pointer title="' + "Email not verified" + '">✗</b> '); }
|
||||
|
||||
if (userinfo.crossDomain) {
|
||||
if (serverinfo.crossDomain) {
|
||||
x += addDeviceAttribute("User Identifier", EscapeHtml(user._id));
|
||||
} else {
|
||||
if (user.name.toLowerCase() != user._id.split('/')[2]) { x += addDeviceAttribute("User Identifier", EscapeHtml(user._id.split('/')[2])); }
|
||||
|
@ -11039,7 +11075,7 @@
|
|||
// Change the URL
|
||||
var urlviewmode = '';
|
||||
if (((features & 0x10000000) == 0) && (xxcurrentView >= 30) && (xxcurrentView <= 39) && (currentUser != null)) {
|
||||
urlviewmode = '?viewmode=' + xxcurrentView + '&gotouser=' + ((userinfo.crossDomain)?currentUser._id:currentUser._id.split('/')[2]);
|
||||
urlviewmode = '?viewmode=' + xxcurrentView + '&gotouser=' + ((serverinfo.crossDomain)?currentUser._id:currentUser._id.split('/')[2]);
|
||||
for (var i in urlargs) { urlviewmode += ('&' + i + '=' + urlargs[i]); }
|
||||
try { window.history.replaceState({}, document.title, window.location.pathname + urlviewmode); } catch (ex) { }
|
||||
}
|
||||
|
@ -11150,7 +11186,7 @@
|
|||
|
||||
// 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; } }
|
||||
for (var i in meshes) { if (meshes[i]._id.split('/')[1] != currentUser._id.split('/')[1]) continue; deviceGroupCount++; if ((currentUser.links == null) || (currentUser.links[i] == null)) { newDeviceGroup = true; } }
|
||||
if ((deviceGroupCount > 0) && (newDeviceGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(1)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device Group" + '</a>'; }
|
||||
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 Device Groups" + '</th><th scope=col style=text-align:left></th></tr>';
|
||||
if (currentUser.links) {
|
||||
|
@ -11179,7 +11215,11 @@
|
|||
x += '<br />';
|
||||
if ((userinfo.siteadmin & 256) != 0) {
|
||||
var userGroupCount = 0, newUserGroup = false;
|
||||
for (var i in usergroups) { userGroupCount++; if ((currentUser.links == null) || (currentUser.links[i] == null)) { newUserGroup = true; } }
|
||||
for (var i in usergroups) {
|
||||
if (usergroups[i]._id.split('/')[1] != currentUser._id.split('/')[1]) continue;
|
||||
userGroupCount++;
|
||||
if ((currentUser.links == null) || (currentUser.links[i] == null)) { newUserGroup = true; }
|
||||
}
|
||||
if ((userGroupCount > 0) && (newUserGroup)) { x += '<a href=# onclick="return p30showAddUserGroupDialog()" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add User Group" + '</a>'; }
|
||||
}
|
||||
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>' + "User Group Memberships" + '</th><th scope=col style=text-align:left></th></tr>';
|
||||
|
@ -11204,7 +11244,8 @@
|
|||
|
||||
// Display common devices
|
||||
count = 1;
|
||||
x += '<br /><a href=# onclick="return p20showAddMeshUserDialog(4)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device" + '</a>';
|
||||
x += '<br />';
|
||||
if (currentUser._id.split('/')[1] == userinfo._id.split('/')[1]) { x += '<a href=# onclick="return p20showAddMeshUserDialog(4)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Device" + '</a>'; }
|
||||
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>';
|
||||
if (currentUser.links) {
|
||||
// Sort the list of devices to display
|
||||
|
@ -11262,7 +11303,10 @@
|
|||
function p30showAddUserGroupDialog() {
|
||||
if (xxdialogMode || (usergroups == null)) return;
|
||||
var y = '';
|
||||
for (var i in usergroups) { if ((currentUser.links == null) || (currentUser.links[i] == null)) { y += '<option value=' + encodeURIComponentEx(i) + '>' + EscapeHtml(usergroups[i].name) + '</option>'; } }
|
||||
for (var i in usergroups) {
|
||||
if (usergroups[i]._id.split('/')[1] != currentUser._id.split('/')[1]) continue;
|
||||
if ((currentUser.links == null) || (currentUser.links[i] == null)) { y += '<option value=' + encodeURIComponentEx(i) + '>' + EscapeHtml(usergroups[i].name) + '</option>'; }
|
||||
}
|
||||
var x = addHtmlValue("User Group", '<div style=width:230px;margin:0;padding:0><select id=dp2groupid style=width:100%>' + y + '</select></div>');
|
||||
setDialogMode(2, "Add Membership", 3, p30showAddUserGroupDialogEx, x);
|
||||
Q('dp2groupid').focus();
|
||||
|
@ -12027,9 +12071,9 @@
|
|||
} else if ((x >= 20) && (x <= 29)) {
|
||||
if (currentMesh) { window.open(window.location.origin + '{{{domainurl}}}' + '?gotomesh=' + currentMesh._id.split('/')[2] + '&viewmode=' + x + '&hide=16', 'meshcentral:' + currentMesh._id); }
|
||||
} else if ((x >= 30) && (x <= 39)) {
|
||||
if (currentUser) { window.open(window.location.origin + '{{{domainurl}}}' + '?gotouser=' + ((userinfo.crossDomain)?currentUser._id:currentUser._id.split('/')[2]) + '&viewmode=' + x + '&hide=16', 'meshcentral:' + currentUser._id); }
|
||||
if (currentUser) { window.open(window.location.origin + '{{{domainurl}}}' + '?gotouser=' + ((serverinfo.crossDomain)?currentUser._id:currentUser._id.split('/')[2]) + '&viewmode=' + x + '&hide=16', 'meshcentral:' + currentUser._id); }
|
||||
} else if ((x >= 50) && (x <= 59)) {
|
||||
if (currentUserGroup) { window.open(window.location.origin + '{{{domainurl}}}' + '?gotougrp=' + currentUserGroup._id.split('/')[2] + '&viewmode=' + x + '&hide=16', 'meshcentral:' + currentUserGroup._id); }
|
||||
if (currentUserGroup) { window.open(window.location.origin + '{{{domainurl}}}' + '?gotougrp=' + ((serverinfo.crossDomain)?currentUserGroup._id:currentUserGroup._id.split('/')[2]) + '&viewmode=' + x + '&hide=16', 'meshcentral:' + currentUserGroup._id); }
|
||||
} else { // if (x < 10))
|
||||
window.open(window.location.origin + '{{{domainurl}}}' + '?viewmode=' + x + '&hide=0', 'meshcentral:' + x);
|
||||
}
|
||||
|
@ -12066,9 +12110,9 @@
|
|||
} else if ((xxcurrentView >= 20) && (xxcurrentView <= 29)) { // Device Group Link
|
||||
if (currentMesh != null) { urlviewmode = '?viewmode=' + xxcurrentView + '&gotomesh=' + currentMesh._id.split('/')[2]; }
|
||||
} else if ((xxcurrentView >= 30) && (xxcurrentView <= 39)) { // User Link
|
||||
if (currentUser != null) { urlviewmode = '?viewmode=' + xxcurrentView + '&gotouser=' + ((userinfo.crossDomain)?currentUser._id:currentUser._id.split('/')[2]); }
|
||||
if (currentUser != null) { urlviewmode = '?viewmode=' + xxcurrentView + '&gotouser=' + ((serverinfo.crossDomain)?currentUser._id:currentUser._id.split('/')[2]); }
|
||||
} else if ((xxcurrentView >= 51) && (xxcurrentView <= 51)) { // User Group Link
|
||||
if ((currentUserGroup != null) && (currentUserGroup._id != null)) { urlviewmode = '?viewmode=' + xxcurrentView + '&gotougrp=' + currentUserGroup._id.split('/')[2]; }
|
||||
if ((currentUserGroup != null) && (currentUserGroup._id != null)) { urlviewmode = '?viewmode=' + xxcurrentView + '&gotougrp=' + ((serverinfo.crossDomain)?currentUserGroup._id:currentUserGroup._id.split('/')[2]); }
|
||||
} else if (xxcurrentView > 1) { urlviewmode = '?viewmode=' + xxcurrentView; }
|
||||
for (var i in urlargs) { urlviewmode += (((urlviewmode == '')?'?':'&') + i + '=' + urlargs[i]); }
|
||||
try { window.history.replaceState({}, document.title, window.location.pathname + urlviewmode); } catch (ex) { }
|
||||
|
@ -12344,7 +12388,7 @@
|
|||
if ((mesh == null) || (mesh.links == null)) { return 0; }
|
||||
|
||||
// Check if super user
|
||||
if (userinfo.manageAllDeviceGroups) return 0xFFFFFFFF;
|
||||
if (serverinfo.manageAllDeviceGroups) return 0xFFFFFFFF;
|
||||
|
||||
// Check device group link permission
|
||||
var rights = 0, r = mesh.links[userid];
|
||||
|
@ -12380,7 +12424,7 @@
|
|||
if (mesh.links[userid] != null) { return true; } // User has visilibity thru a direct link
|
||||
|
||||
// Check if user user
|
||||
if (userinfo.manageAllDeviceGroups) return true;
|
||||
if (serverinfo.manageAllDeviceGroups) return true;
|
||||
|
||||
// Check permissions thru user groups
|
||||
var user = null;
|
||||
|
|
Loading…
Reference in New Issue