mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-24 06:05:53 -05:00
Merge branch 'master' into revert-189-master
This commit is contained in:
commit
363ee77a13
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
2
agents/meshcmd.min.js
vendored
2
agents/meshcmd.min.js
vendored
File diff suppressed because one or more lines are too long
143
meshuser.js
143
meshuser.js
@ -715,7 +715,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var docs = [];
|
||||
for (i in parent.users) {
|
||||
if ((parent.users[i].domain == domain.id) && (parent.users[i].name != '~')) {
|
||||
docs.push(parent.CloneSafeUser(parent.users[i]));
|
||||
// If we are part of a user group, we can only see other members of our own group
|
||||
if ((user.groups == null) || (user.groups.length == 0) || ((parent.users[i].groups != null) && (findOne(parent.users[i].groups, user.groups)))) {
|
||||
docs.push(parent.CloneSafeUser(parent.users[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
try { ws.send(JSON.stringify({ action: 'users', users: docs, tag: command.tag })); } catch (ex) { }
|
||||
@ -723,7 +726,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
}
|
||||
case 'changeemail':
|
||||
{
|
||||
// Change the email address
|
||||
// Change our own email address
|
||||
if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) return;
|
||||
if (common.validateEmail(command.email, 1, 256) == false) return;
|
||||
if (parent.users[req.session.userid].email != command.email) {
|
||||
@ -746,7 +749,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
} else {
|
||||
message.msg = 'Set email of user ' + user.name + ' to ' + user.email;
|
||||
}
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, message);
|
||||
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, message);
|
||||
|
||||
// Send the verification email
|
||||
if (parent.parent.mailserver != null) { parent.parent.mailserver.sendAccountCheckMail(domain, user.name, user.email); }
|
||||
@ -773,10 +779,36 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if ((user.siteadmin & 2) == 0) break;
|
||||
if (parent.parent.multiServer == null) {
|
||||
// No peering, use simple session counting
|
||||
for (i in parent.wssessions) { if (parent.wssessions[i][0].domainid == domain.id) { wssessions[i] = parent.wssessions[i].length; } }
|
||||
for (i in parent.wssessions) {
|
||||
if (parent.wssessions[i][0].domainid == domain.id) {
|
||||
if ((user.groups == null) || (user.groups.length == 0)) {
|
||||
// No user groups, count everything
|
||||
wssessions[i] = parent.wssessions[i].length;
|
||||
} else {
|
||||
// Only count if session is for a user in our user groups
|
||||
var sessionUser = parent.users[parent.wssessions[i][0].userid];
|
||||
if ((sessionUser != null) && findOne(sessionUser.groups, user.groups)) {
|
||||
wssessions[i] = parent.wssessions[i].length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We have peer servers, use more complex session counting
|
||||
for (i in parent.sessionsCount) { if (i.split('/')[1] == domain.id) { wssessions[i] = parent.sessionsCount[i]; } }
|
||||
for (i in parent.sessionsCount) {
|
||||
if (i.split('/')[1] == domain.id) {
|
||||
if ((user.groups == null) || (user.groups.length == 0)) {
|
||||
// No user groups, count everything
|
||||
wssessions[i] = parent.sessionsCount[i];
|
||||
} else {
|
||||
// Only count if session is for a user in our user groups
|
||||
var sessionUser = parent.users[i];
|
||||
if ((sessionUser != null) && findOne(sessionUser.groups, user.groups)) {
|
||||
wssessions[i] = parent.sessionsCount[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try { ws.send(JSON.stringify({ action: 'wssessioncount', wssessions: wssessions, tag: command.tag })); } catch (ex) { } // wssessions is: userid --> count
|
||||
break;
|
||||
@ -789,6 +821,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var delusersplit = command.userid.split('/'), deluserid = command.userid, deluser = parent.users[deluserid];
|
||||
if ((deluser == null) || (delusersplit.length != 3) || (delusersplit[1] != domain.id)) break; // Invalid domain, operation only valid for current domain
|
||||
if ((deluser.siteadmin != null) && (deluser.siteadmin > 0) && (user.siteadmin != 0xFFFFFFFF)) break; // Need full admin to remote another administrator
|
||||
if ((user.groups != null) && (user.groups.length > 0) && ((deluser.groups == null) || (findOne(deluser.groups, user.groups) == false))) break; // Can only perform this operation on other users of our group.
|
||||
|
||||
// Remove all the mesh links to this user
|
||||
if (deluser.links != null) {
|
||||
@ -816,7 +849,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
|
||||
db.Remove(deluserid);
|
||||
delete parent.users[deluserid];
|
||||
parent.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', userid: deluserid, username: deluser.name, action: 'accountremove', msg: 'Account removed', domain: domain.id });
|
||||
|
||||
var targets = ['*', 'server-users'];
|
||||
if (deluser.groups) { for (var i in deluser.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', userid: deluserid, username: deluser.name, action: 'accountremove', msg: 'Account removed', domain: domain.id });
|
||||
parent.parent.DispatchEvent([deluserid], obj, 'close');
|
||||
|
||||
break;
|
||||
@ -833,7 +869,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Send the notification on all user sessions for this server
|
||||
for (var i in parent.wssessions2) {
|
||||
try {
|
||||
if (parent.wssessions2[i].domainid == domain.id) { parent.wssessions2[i].send(JSON.stringify(notification)); }
|
||||
if (parent.wssessions2[i].domainid == domain.id) {
|
||||
if ((user.groups == null) || (user.groups.length == 0)) {
|
||||
// We are part of no user groups, send to everyone.
|
||||
parent.wssessions2[i].send(JSON.stringify(notification));
|
||||
} else {
|
||||
// We are part of user groups, only send to sessions of users in our groups.
|
||||
var sessionUser = parent.users[parent.wssessions2[i].userid];
|
||||
if ((sessionUser != null) && findOne(sessionUser.groups, user.groups)) {
|
||||
parent.wssessions2[i].send(JSON.stringify(notification));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex) { }
|
||||
}
|
||||
|
||||
@ -870,6 +917,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
var newuser = { type: 'user', _id: newuserid, name: newusername, creation: Math.floor(Date.now() / 1000), domain: domain.id };
|
||||
if (command.email != null) { newuser.email = command.email; } // Email
|
||||
if (command.resetNextLogin === true) { newuser.passchange = -1; } else { newuser.passchange = Math.floor(Date.now() / 1000); }
|
||||
if ((user.groups != null) && (user.groups.length > 0)) { newuser.groups = user.groups; } // New account are automatically part of our groups.
|
||||
parent.users[newuserid] = newuser;
|
||||
|
||||
// Create a user, generate a salt and hash the password
|
||||
@ -878,7 +926,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
newuser.salt = salt;
|
||||
newuser.hash = hash;
|
||||
db.SetUser(newuser);
|
||||
parent.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', username: newusername, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, email is ' + command.email, domain: domain.id });
|
||||
|
||||
var targets = ['*', 'server-users'];
|
||||
if (newuser.groups) { for (var i in newuser.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: newusername, account: parent.CloneSafeUser(newuser), action: 'accountcreate', msg: 'Account created, email is ' + command.email, domain: domain.id });
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -895,7 +946,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if ((command.emailVerified === true || command.emailVerified === false) && (chguser.emailVerified != command.emailVerified)) { chguser.emailVerified = command.emailVerified; change = 1; }
|
||||
if ((common.validateInt(command.quota, 0) || command.quota == null) && (command.quota != chguser.quota)) { chguser.quota = command.quota; if (chguser.quota == null) { delete chguser.quota; } change = 1; }
|
||||
if ((user.siteadmin == 0xFFFFFFFF) && common.validateInt(command.siteadmin) && (chguser.siteadmin != command.siteadmin)) { chguser.siteadmin = command.siteadmin; change = 1; }
|
||||
if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) break; // Can only perform this operation on other users of our group.
|
||||
|
||||
// Went sending a notification about a group change, we need to send to all the previous and new groups.
|
||||
var allTargetGroups = chguser.groups;
|
||||
if ((Array.isArray(command.groups)) && (user._id != command.id)) {
|
||||
if (command.groups.length == 0) {
|
||||
// Remove the user groups
|
||||
@ -913,6 +967,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
|
||||
// Set the user groups
|
||||
if (chguser.groups != groups2) { chguser.groups = groups2; change = 1; }
|
||||
|
||||
// Add any missing groups in the target list
|
||||
if (allTargetGroups == null) { allTargetGroups = []; }
|
||||
for (var i in groups2) { if (allTargetGroups.indexOf(i) == -1) { allTargetGroups.push(i); } }
|
||||
}
|
||||
}
|
||||
|
||||
@ -920,7 +978,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Update the user
|
||||
db.SetUser(chguser);
|
||||
parent.parent.DispatchEvent([chguser._id], obj, 'resubscribe');
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id, chguser._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Account changed: ' + chguser.name, domain: domain.id });
|
||||
|
||||
var targets = ['*', 'server-users', user._id, chguser._id];
|
||||
if (allTargetGroups) { for (var i in allTargetGroups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Account changed: ' + chguser.name, domain: domain.id });
|
||||
}
|
||||
if ((chguser.siteadmin) && (chguser.siteadmin != 0xFFFFFFFF) && (chguser.siteadmin & 32)) {
|
||||
// If the user is locked out of this account, disconnect now
|
||||
@ -958,7 +1019,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
user.passchange = Math.floor(Date.now() / 1000);
|
||||
delete user.passtype;
|
||||
db.SetUser(user);
|
||||
parent.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Account password changed: ' + user.name, domain: domain.id });
|
||||
|
||||
var targets = ['*', 'server-users'];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Account password changed: ' + user.name, domain: domain.id });
|
||||
|
||||
// Send user notification of password change
|
||||
displayNotificationMessage('Password changed.');
|
||||
@ -975,14 +1039,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
{
|
||||
// Change a user's password
|
||||
if (user.siteadmin != 0xFFFFFFFF) break;
|
||||
if (common.validateString(command.user, 1, 256) == false) break;
|
||||
if (common.validateString(command.userid, 1, 256) == false) break;
|
||||
if (common.validateString(command.pass, 1, 256) == false) break;
|
||||
if ((command.hint != null) && (common.validateString(command.hint, 0, 256) == false)) break;
|
||||
if (typeof command.removeMultiFactor != 'boolean') break;
|
||||
if (common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false) break; // Password does not meet requirements
|
||||
|
||||
var chguser = parent.users['user/' + domain.id + '/' + command.user.toLowerCase()];
|
||||
var chguser = parent.users[command.userid];
|
||||
if (chguser) {
|
||||
// Can only perform this operation on other users of our group.
|
||||
if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) break;
|
||||
|
||||
// Compute the password hash & save it
|
||||
require('./pass').hash(command.pass, function (err, salt, hash) {
|
||||
if (!err) {
|
||||
@ -1001,7 +1068,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (chguser.otpkeys) { delete chguser.otpkeys; }
|
||||
}
|
||||
db.SetUser(chguser);
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id, chguser._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Changed account credentials.', domain: domain.id });
|
||||
|
||||
var targets = ['*', 'server-users', user._id, chguser._id];
|
||||
if (chguser.groups) { for (var i in chguser.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(chguser), action: 'accountchange', msg: 'Changed account credentials.', domain: domain.id });
|
||||
} else {
|
||||
// Report that the password change failed
|
||||
// TODO
|
||||
@ -1017,6 +1087,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (common.validateString(command.userid, 1, 2048) == false) break;
|
||||
if (common.validateString(command.msg, 1, 4096) == false) break;
|
||||
|
||||
// Can only perform this operation on other users of our group.
|
||||
var chguser = parent.users[command.userid];
|
||||
if (chguser == null) break; // This user does not exists
|
||||
if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) break;
|
||||
|
||||
// Create the notification message
|
||||
var notification = { "action": "msg", "type": "notify", "value": "<b>" + user.name + "</b>: " + EscapeHtml(command.msg), "userid": user._id, "username": user.name };
|
||||
|
||||
@ -1037,6 +1112,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
// Setup a user-to-user session
|
||||
if (common.validateString(command.userid, 1, 2048)) {
|
||||
|
||||
// Can only perform this operation on other users of our group.
|
||||
var chguser = parent.users[command.userid];
|
||||
if (chguser == null) break; // This user does not exists
|
||||
if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) break;
|
||||
|
||||
// Create the notification message
|
||||
var notification = {
|
||||
"action": "msg", "type": "notify", "value": "<b>" + user.name + "</b>: Chat Request, Click here to accept.", "userid": user._id, "username": user.name, "tag": 'meshmessenger/' + encodeURIComponent(command.userid) + '/' + encodeURIComponent(user._id)
|
||||
@ -1766,7 +1846,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (command.nodeid) { cookieContent.nodeid = command.nodeid; }
|
||||
if (command.tcpaddr) { cookieContent.tcpaddr = command.tcpaddr; } // Indicates the browser want to agent to TCP connect to a remote address
|
||||
if (command.tcpport) { cookieContent.tcpport = command.tcpport; } // Indicates the browser want to agent to TCP connect to a remote port
|
||||
command.cookie = parent.parent.encodeCookie(cookieContent);
|
||||
command.cookie = parent.parent.encodeCookie(cookieContent, parent.parent.loginCookieEncryptionKey);
|
||||
try { ws.send(JSON.stringify(command)); } catch (ex) { }
|
||||
}
|
||||
}
|
||||
@ -1836,6 +1916,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (common.validateString(command.notes, 1) == false) {
|
||||
db.Remove('nt' + command.id); // Delete the note for this node
|
||||
} else {
|
||||
// Can only perform this operation on other users of our group.
|
||||
var chguser = parent.users[command.id];
|
||||
if (chguser == null) break; // This user does not exists
|
||||
if ((user.groups != null) && (user.groups.length > 0) && ((chguser.groups == null) || (findOne(chguser.groups, user.groups) == false))) break;
|
||||
db.Set({ _id: 'nt' + command.id, type: 'note', value: command.notes }); // Set the note for this user
|
||||
}
|
||||
}
|
||||
@ -1873,7 +1957,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
ws.send(JSON.stringify({ action: 'otpauth-setup', success: true })); // Report success
|
||||
|
||||
// Notify change
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added authentication application.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added authentication application.', domain: domain.id });
|
||||
} else {
|
||||
ws.send(JSON.stringify({ action: 'otpauth-setup', success: false })); // Report fail
|
||||
}
|
||||
@ -1892,7 +1978,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
ws.send(JSON.stringify({ action: 'otpauth-clear', success: true })); // Report success
|
||||
|
||||
// Notify change
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed authentication application.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed authentication application.', domain: domain.id });
|
||||
} else {
|
||||
ws.send(JSON.stringify({ action: 'otpauth-clear', success: false })); // Report fail
|
||||
}
|
||||
@ -1927,7 +2015,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
}
|
||||
|
||||
// Notify change
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
break;
|
||||
}
|
||||
case 'otp-hkey-get':
|
||||
@ -1958,7 +2048,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
}
|
||||
|
||||
// Notify change
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed security key.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Removed security key.', domain: domain.id });
|
||||
break;
|
||||
}
|
||||
case 'otp-hkey-yubikey-add':
|
||||
@ -2004,7 +2096,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
ws.send(JSON.stringify({ action: 'otp-hkey-yubikey-add', result: true, name: command.name, index: keyIndex }));
|
||||
|
||||
// Notify change TODO: Should be done on all sessions/servers for this user.
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
} else {
|
||||
ws.send(JSON.stringify({ action: 'otp-hkey-yubikey-add', result: false, name: command.name }));
|
||||
}
|
||||
@ -2061,7 +2155,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
delete obj.hardwareKeyRegistrationRequest;
|
||||
|
||||
// Notify change
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
}, function (error) {
|
||||
ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: false, error: error, name: command.name, index: keyIndex }));
|
||||
delete obj.hardwareKeyRegistrationRequest;
|
||||
@ -2128,7 +2224,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: true, name: command.name, index: keyIndex }));
|
||||
|
||||
// Notify change
|
||||
parent.parent.DispatchEvent(['*', 'server-users', user._id], obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
var targets = ['*', 'server-users', user._id];
|
||||
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'user', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id });
|
||||
}, function (error) {
|
||||
console.log('webauthn-endregister-error', error);
|
||||
ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: false, error: error, name: command.name, index: keyIndex }));
|
||||
@ -2360,5 +2458,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
return results;
|
||||
}
|
||||
|
||||
// Return true if at least one element of arr2 is in arr1
|
||||
function findOne(arr1, arr2) { if ((arr1 == null) || (arr2 == null)) return false; return arr2.some(function (v) { return arr1.indexOf(v) >= 0; }); };
|
||||
|
||||
return obj;
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.3.2-m",
|
||||
"version": "0.3.2-o",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
2311
public/commander.htm
2311
public/commander.htm
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,4 @@
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
@ -11,7 +6,7 @@ body {
|
||||
font-size: 13px;
|
||||
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
|
||||
background-color: #d3d9d6;
|
||||
/* overflow-y: hidden; */
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#container {
|
||||
@ -61,11 +56,10 @@ body {
|
||||
}
|
||||
.fullscreen #container {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
min-width: 700px;
|
||||
min-height: 0px;
|
||||
border-right: 0px none #b7b7b7;
|
||||
border-left: 0px none #b7b7b7;
|
||||
|
||||
height: calc(100% - 0px);
|
||||
position: relative;
|
||||
display: -ms-grid;
|
||||
@ -81,10 +75,9 @@ body {
|
||||
-ms-grid-rows: 66px 24px 1fr 45px;
|
||||
grid-template-rows: 66px 24px auto 45px;
|
||||
}
|
||||
|
||||
|
||||
.fulldesk #container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-width: 700px;
|
||||
min-height: 0px;
|
||||
border-right: 0px none #b7b7b7;
|
||||
@ -162,20 +155,15 @@ body {
|
||||
-ms-grid-row-span: 3;
|
||||
/* height: calc(100vh - 66px); */
|
||||
width: 90px;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
background: #113962;
|
||||
background: linear-gradient(to bottom, #104893 0%,#113962 100%);
|
||||
color: white;
|
||||
overflow-y: hidden;
|
||||
display: none;
|
||||
}
|
||||
.fullscreen #page_leftbar {
|
||||
grid-area: sidebar;
|
||||
display: block;
|
||||
}
|
||||
.menu_stack #page_leftbar {
|
||||
display: none;
|
||||
}
|
||||
.arg_hide #page_leftbar {
|
||||
display: none;
|
||||
}
|
||||
@ -183,7 +171,6 @@ body {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
#topbar {
|
||||
position: relative;
|
||||
grid-area: nav;
|
||||
@ -217,42 +204,22 @@ body {
|
||||
top: 3px;
|
||||
right: 6px
|
||||
}
|
||||
#toggle2 {
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 26px;
|
||||
display: none;
|
||||
}
|
||||
.fullscreen #toggle2 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* #UserDummyMenuSpan, */
|
||||
#MainSubMenuSpan, #MeshSubMenuSpan, #UserSubMenuSpan, #ServerSubMenuSpan, #MainMenuSpan, #MainSubMenu, #MeshSubMenu, #UserSubMenu, #ServerSubMenu, #UserDummyMenu {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
color: white;
|
||||
background-color: #808080;
|
||||
height: 22px
|
||||
}
|
||||
.menu_stack #UserDummyMenu {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#MainMenuSpan {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.fullscreen #MainMenuSpan {
|
||||
display: none;
|
||||
}
|
||||
.fulldesk #MainMenuSpan {
|
||||
display: none;
|
||||
}
|
||||
.menu_stack #MainMenuSpan {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#column_l {
|
||||
position: relative;
|
||||
@ -262,9 +229,12 @@ body {
|
||||
margin: 0;
|
||||
padding: 0 15px;
|
||||
background-color: #fff;
|
||||
/* max-height: calc(100vh - 151px); */
|
||||
/*max-height: calc(100vh - 111px);*/
|
||||
min-width: unset;
|
||||
}
|
||||
.room4submenu {
|
||||
max-height: calc(100vh - 159px) !important;
|
||||
}
|
||||
|
||||
.menu_stack.fullscreen.fulldesk #column_l {
|
||||
-ms-grid-column: 1;
|
||||
@ -277,8 +247,6 @@ body {
|
||||
-ms-grid-row: 3;
|
||||
grid-area: content;
|
||||
width: unset;
|
||||
/* height: calc(100vh - 111px);
|
||||
width: calc(100% - 30px); */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@ -302,10 +270,6 @@ body {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.room4submenu {
|
||||
min-height: calc(100vh - 159px);
|
||||
}
|
||||
|
||||
#centralTable {
|
||||
width: 100%;
|
||||
}
|
||||
@ -424,12 +388,6 @@ body {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#verifyEmailId2 {
|
||||
color:yellow;
|
||||
margin-left:3px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
#dialog {
|
||||
z-index: 1000;
|
||||
background-color: #EEE;
|
||||
@ -447,18 +405,6 @@ body {
|
||||
background-color: #003366;
|
||||
color: #FFF;
|
||||
border-radius: 5px 5px 0 0;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
#id_dialogclose {
|
||||
float: right;
|
||||
padding: 3px;
|
||||
margin-right: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#id_dialogtitle {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#dialogBody {
|
||||
@ -487,58 +433,11 @@ body {
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
#dialog2, #dialog3, #dialog7 {
|
||||
#dialog2, #dialog3 {
|
||||
margin: auto;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
#d3uploadMode, #d3localFile {
|
||||
float:right;
|
||||
width:260px;
|
||||
}
|
||||
|
||||
#d3serveraction {
|
||||
width: 100%;
|
||||
background-color: #d3d9d6;
|
||||
text-align: left;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
#d3serverfiles {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
background-color: white;
|
||||
padding: 2px;
|
||||
border: 1px solid gray;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
|
||||
#d7bitmapquality, #d7bitmapquality, #d7bitmapscaling, #d7framelimiter, #d7desktopmode {
|
||||
float: right;
|
||||
width: 200px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#dialog7 h4 {
|
||||
width:100%;
|
||||
border-bottom: 1px solid gray;
|
||||
}
|
||||
|
||||
#d7meshkvm div, #d7amtkvm div, #d3upload, #d3localmode {
|
||||
margin:3px 0 3px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#d7otherset {
|
||||
display: block;
|
||||
border: 1px solid #666;
|
||||
width: 200px;
|
||||
height: 60px;
|
||||
overflow-y: scroll;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
#idx_dlgButtonBar {
|
||||
padding: 10px;
|
||||
margin-bottom: 5px;
|
||||
@ -574,7 +473,7 @@ body {
|
||||
|
||||
#idx_deskFullBtn2 {
|
||||
float: left;
|
||||
font-size: 16px;
|
||||
font-size: large;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
}
|
||||
@ -719,14 +618,6 @@ body {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
#p2AccountActions .mL {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
#p2ServerActions .mL {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.newMeshBtn {
|
||||
background: url(../images/icon-addnew.png) no-repeat 0px 0px;
|
||||
height: 12px;
|
||||
@ -736,14 +627,10 @@ body {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
#p2noMeshFound, #serverStats {
|
||||
#p2noMeshFound, #p2ServerActionsBackup, #p2ServerActionsRestore, #p2ServerActionsVersion, #p2ServerActionsErrors, #serverStats {
|
||||
margin-left:40px;
|
||||
}
|
||||
|
||||
#p2ServerActionsBackup, #p2ServerActionsRestore, #p2ServerActionsVersion, #p2ServerActionsErrors {
|
||||
margin-left:0px;
|
||||
}
|
||||
|
||||
.pTable {
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
@ -787,10 +674,6 @@ body {
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
#p5toolbar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#p5filehead {
|
||||
width: 100%;
|
||||
background-color: #d3d9d6;
|
||||
@ -823,9 +706,6 @@ body {
|
||||
-webkit-user-select: none;
|
||||
background-color: lightsteelblue;
|
||||
}
|
||||
#p5PublicShare div {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
#bigok {
|
||||
width: 256px;
|
||||
@ -924,14 +804,6 @@ body {
|
||||
font-size: x-small;
|
||||
}
|
||||
|
||||
#dp10devicevalue {
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
.fulldesk #p11 {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#MainComputerImage {
|
||||
border-width: 0px;
|
||||
height: 200px;
|
||||
@ -982,7 +854,6 @@ body {
|
||||
a {
|
||||
color: #036;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.i1 {
|
||||
@ -1280,20 +1151,11 @@ a {
|
||||
background-color: #D3D9D6;
|
||||
}
|
||||
|
||||
/* .pTable .style14 {
|
||||
float: left;
|
||||
} */
|
||||
|
||||
.auto-style1 {
|
||||
text-align: right;
|
||||
background-color: #D3D9D6;
|
||||
}
|
||||
|
||||
#pTable .auto-style1 {
|
||||
height: 100%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.icon2 {
|
||||
float: left;
|
||||
margin: 7px;
|
||||
@ -1433,7 +1295,7 @@ a {
|
||||
.h1 {
|
||||
background-position: 0% 0%;
|
||||
width: 14px;
|
||||
height: 24px;
|
||||
height: 100%;
|
||||
/* fallback (Opera) */
|
||||
/* Mozilla: */
|
||||
/* Chrome, Safari:*/
|
||||
@ -1447,13 +1309,13 @@ a {
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
float: right;
|
||||
background-color: #ffffff;
|
||||
background-color: #ffffff
|
||||
}
|
||||
|
||||
.h2 {
|
||||
background-position: 0% 0%;
|
||||
width: 14px;
|
||||
height: 24px;
|
||||
height: 100%;
|
||||
/* fallback (Opera) */
|
||||
/* Mozilla: */
|
||||
/* Chrome, Safari:*/
|
||||
@ -1655,7 +1517,6 @@ a {
|
||||
padding: 4px
|
||||
}
|
||||
|
||||
|
||||
.deskareaicon {
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
@ -1775,13 +1636,7 @@ a {
|
||||
}
|
||||
|
||||
#DeskParent {
|
||||
margin: 0;
|
||||
overflow:hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
overflow:hidden
|
||||
}
|
||||
|
||||
#Desk {
|
||||
@ -1796,6 +1651,7 @@ a {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
|
||||
#deskToolsBar {
|
||||
position: absolute;
|
||||
padding: 3px;
|
||||
@ -1807,27 +1663,6 @@ a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#deskToolsArea {
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
left: 4px;
|
||||
right: 4px;
|
||||
bottom: 4px;
|
||||
background-color: lightgray;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#deskToolsHeader {
|
||||
border-bottom: 1px solid darkgray;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
#deskToolsHeader .colmn1 {
|
||||
width: 50px;
|
||||
padding-right: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#DeskToolsProcesses {
|
||||
overflow-y: scroll;
|
||||
position: absolute;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
webserver.js
10
webserver.js
@ -1770,7 +1770,15 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
const subscriptions = [userid, 'server-global'];
|
||||
if (user.siteadmin != null) {
|
||||
if (user.siteadmin == 0xFFFFFFFF) subscriptions.push('*');
|
||||
if ((user.siteadmin & 2) != 0) subscriptions.push('server-users');
|
||||
if ((user.siteadmin & 2) != 0) {
|
||||
if ((user.groups == null) || (user.groups.length == 0)) {
|
||||
// Subscribe to all user changes
|
||||
subscriptions.push('server-users');
|
||||
} else {
|
||||
// Subscribe to user changes for some groups
|
||||
for (var i in user.groups) { subscriptions.push('server-users:' + i); }
|
||||
}
|
||||
}
|
||||
}
|
||||
if (user.links != null) { for (var i in user.links) { subscriptions.push(i); } }
|
||||
obj.parent.RemoveAllEventDispatch(target);
|
||||
|
Loading…
Reference in New Issue
Block a user