Merge branch 'master' into revert-189-master

This commit is contained in:
elastalink 2019-04-19 14:50:03 -04:00 committed by GitHub
commit 363ee77a13
15 changed files with 1423 additions and 2884 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -715,7 +715,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
var docs = []; var docs = [];
for (i in parent.users) { for (i in parent.users) {
if ((parent.users[i].domain == domain.id) && (parent.users[i].name != '~')) { 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) { } 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': case 'changeemail':
{ {
// Change the email address // Change our own email address
if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) return; if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) return;
if (common.validateEmail(command.email, 1, 256) == false) return; if (common.validateEmail(command.email, 1, 256) == false) return;
if (parent.users[req.session.userid].email != command.email) { 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 { } else {
message.msg = 'Set email of user ' + user.name + ' to ' + user.email; 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 // Send the verification email
if (parent.parent.mailserver != null) { parent.parent.mailserver.sendAccountCheckMail(domain, user.name, user.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 ((user.siteadmin & 2) == 0) break;
if (parent.parent.multiServer == null) { if (parent.parent.multiServer == null) {
// No peering, use simple session counting // 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 { } else {
// We have peer servers, use more complex session counting // 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 try { ws.send(JSON.stringify({ action: 'wssessioncount', wssessions: wssessions, tag: command.tag })); } catch (ex) { } // wssessions is: userid --> count
break; 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]; 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 == 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 ((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 // Remove all the mesh links to this user
if (deluser.links != null) { if (deluser.links != null) {
@ -816,7 +849,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
db.Remove(deluserid); db.Remove(deluserid);
delete parent.users[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'); parent.parent.DispatchEvent([deluserid], obj, 'close');
break; 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 // Send the notification on all user sessions for this server
for (var i in parent.wssessions2) { for (var i in parent.wssessions2) {
try { 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) { } } 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 }; 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.email != null) { newuser.email = command.email; } // Email
if (command.resetNextLogin === true) { newuser.passchange = -1; } else { newuser.passchange = Math.floor(Date.now() / 1000); } 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; parent.users[newuserid] = newuser;
// Create a user, generate a salt and hash the password // 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.salt = salt;
newuser.hash = hash; newuser.hash = hash;
db.SetUser(newuser); 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 ((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 ((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.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 ((Array.isArray(command.groups)) && (user._id != command.id)) {
if (command.groups.length == 0) { if (command.groups.length == 0) {
// Remove the user groups // Remove the user groups
@ -913,6 +967,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Set the user groups // Set the user groups
if (chguser.groups != groups2) { chguser.groups = groups2; change = 1; } 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 // Update the user
db.SetUser(chguser); db.SetUser(chguser);
parent.parent.DispatchEvent([chguser._id], obj, 'resubscribe'); 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 ((chguser.siteadmin) && (chguser.siteadmin != 0xFFFFFFFF) && (chguser.siteadmin & 32)) {
// If the user is locked out of this account, disconnect now // 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); user.passchange = Math.floor(Date.now() / 1000);
delete user.passtype; delete user.passtype;
db.SetUser(user); 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 // Send user notification of password change
displayNotificationMessage('Password changed.'); displayNotificationMessage('Password changed.');
@ -975,14 +1039,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
{ {
// Change a user's password // Change a user's password
if (user.siteadmin != 0xFFFFFFFF) break; 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 (common.validateString(command.pass, 1, 256) == false) break;
if ((command.hint != null) && (common.validateString(command.hint, 0, 256) == false)) break; if ((command.hint != null) && (common.validateString(command.hint, 0, 256) == false)) break;
if (typeof command.removeMultiFactor != 'boolean') break; if (typeof command.removeMultiFactor != 'boolean') break;
if (common.checkPasswordRequirements(command.pass, domain.passwordrequirements) == false) break; // Password does not meet requirements 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) { 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 // Compute the password hash & save it
require('./pass').hash(command.pass, function (err, salt, hash) { require('./pass').hash(command.pass, function (err, salt, hash) {
if (!err) { if (!err) {
@ -1001,7 +1068,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (chguser.otpkeys) { delete chguser.otpkeys; } if (chguser.otpkeys) { delete chguser.otpkeys; }
} }
db.SetUser(chguser); 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 { } else {
// Report that the password change failed // Report that the password change failed
// TODO // 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.userid, 1, 2048) == false) break;
if (common.validateString(command.msg, 1, 4096) == 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 // Create the notification message
var notification = { "action": "msg", "type": "notify", "value": "<b>" + user.name + "</b>: " + EscapeHtml(command.msg), "userid": user._id, "username": user.name }; 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 // Setup a user-to-user session
if (common.validateString(command.userid, 1, 2048)) { 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 // Create the notification message
var notification = { 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) "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.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.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 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) { } 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) { if (common.validateString(command.notes, 1) == false) {
db.Remove('nt' + command.id); // Delete the note for this node db.Remove('nt' + command.id); // Delete the note for this node
} else { } 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 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 ws.send(JSON.stringify({ action: 'otpauth-setup', success: true })); // Report success
// Notify change // 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 { } else {
ws.send(JSON.stringify({ action: 'otpauth-setup', success: false })); // Report fail 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 ws.send(JSON.stringify({ action: 'otpauth-clear', success: true })); // Report success
// Notify change // 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 { } else {
ws.send(JSON.stringify({ action: 'otpauth-clear', success: false })); // Report fail 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 // 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; break;
} }
case 'otp-hkey-get': case 'otp-hkey-get':
@ -1958,7 +2048,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
} }
// Notify change // 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; break;
} }
case 'otp-hkey-yubikey-add': 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 })); 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. // 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 { } else {
ws.send(JSON.stringify({ action: 'otp-hkey-yubikey-add', result: false, name: command.name })); 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; delete obj.hardwareKeyRegistrationRequest;
// Notify change // 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) { }, function (error) {
ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: false, error: error, name: command.name, index: keyIndex })); ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: false, error: error, name: command.name, index: keyIndex }));
delete obj.hardwareKeyRegistrationRequest; 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 })); ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: true, name: command.name, index: keyIndex }));
// Notify change // 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) { }, function (error) {
console.log('webauthn-endregister-error', 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 })); 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 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; return obj;
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.3.2-m", "version": "0.3.2-o",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,4 @@
 body {
html, body {
width: 100%;
height: 100%;
}
body {
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
@ -11,7 +6,7 @@ body {
font-size: 13px; font-size: 13px;
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
background-color: #d3d9d6; background-color: #d3d9d6;
/* overflow-y: hidden; */ overflow-y: hidden;
} }
#container { #container {
@ -61,11 +56,10 @@ body {
} }
.fullscreen #container { .fullscreen #container {
width: 100%; width: 100%;
min-width: 100%; min-width: 700px;
min-height: 0px; min-height: 0px;
border-right: 0px none #b7b7b7; border-right: 0px none #b7b7b7;
border-left: 0px none #b7b7b7; border-left: 0px none #b7b7b7;
height: calc(100% - 0px); height: calc(100% - 0px);
position: relative; position: relative;
display: -ms-grid; display: -ms-grid;
@ -81,10 +75,9 @@ body {
-ms-grid-rows: 66px 24px 1fr 45px; -ms-grid-rows: 66px 24px 1fr 45px;
grid-template-rows: 66px 24px auto 45px; grid-template-rows: 66px 24px auto 45px;
} }
.fulldesk #container { .fulldesk #container {
width: 100%; width: 100%;
height: 100%;
min-width: 700px; min-width: 700px;
min-height: 0px; min-height: 0px;
border-right: 0px none #b7b7b7; border-right: 0px none #b7b7b7;
@ -162,20 +155,15 @@ body {
-ms-grid-row-span: 3; -ms-grid-row-span: 3;
/* height: calc(100vh - 66px); */ /* height: calc(100vh - 66px); */
width: 90px; width: 90px;
position: absolute;
z-index: 1000; z-index: 1000;
background: #113962; background: #113962;
background: linear-gradient(to bottom, #104893 0%,#113962 100%); background: linear-gradient(to bottom, #104893 0%,#113962 100%);
color: white; color: white;
overflow-y: hidden;
display: none;
} }
.fullscreen #page_leftbar { .fullscreen #page_leftbar {
grid-area: sidebar;
display: block; display: block;
} }
.menu_stack #page_leftbar {
display: none;
}
.arg_hide #page_leftbar { .arg_hide #page_leftbar {
display: none; display: none;
} }
@ -183,7 +171,6 @@ body {
display: none; display: none;
} }
#topbar { #topbar {
position: relative; position: relative;
grid-area: nav; grid-area: nav;
@ -217,42 +204,22 @@ body {
top: 3px; top: 3px;
right: 6px right: 6px
} }
#toggle2 {
cursor: pointer;
color: white;
position: absolute;
top: 3px;
right: 26px;
display: none;
}
.fullscreen #toggle2 {
display: block;
}
/* #UserDummyMenuSpan, */ /* #UserDummyMenuSpan, */
#MainSubMenuSpan, #MeshSubMenuSpan, #UserSubMenuSpan, #ServerSubMenuSpan, #MainMenuSpan, #MainSubMenu, #MeshSubMenu, #UserSubMenu, #ServerSubMenu, #UserDummyMenu { #MainSubMenuSpan, #MeshSubMenuSpan, #UserSubMenuSpan, #ServerSubMenuSpan, #MainMenuSpan, #MainSubMenu, #MeshSubMenu, #UserSubMenu, #ServerSubMenu, #UserDummyMenu {
width: 100%; width: 100%;
height: 24px; height: 22px
color: white;
background-color: #808080;
} }
.menu_stack #UserDummyMenu {
display: none;
}
#MainMenuSpan { #MainMenuSpan {
display: table; display: table;
} }
.fullscreen #MainMenuSpan { .fullscreen #MainMenuSpan {
display: none; display: none;
} }
.fulldesk #MainMenuSpan { .fulldesk #MainMenuSpan {
display: none; display: none;
} }
.menu_stack #MainMenuSpan {
display: block;
}
#column_l { #column_l {
position: relative; position: relative;
@ -262,9 +229,12 @@ body {
margin: 0; margin: 0;
padding: 0 15px; padding: 0 15px;
background-color: #fff; background-color: #fff;
/* max-height: calc(100vh - 151px); */ /*max-height: calc(100vh - 111px);*/
min-width: unset; min-width: unset;
} }
.room4submenu {
max-height: calc(100vh - 159px) !important;
}
.menu_stack.fullscreen.fulldesk #column_l { .menu_stack.fullscreen.fulldesk #column_l {
-ms-grid-column: 1; -ms-grid-column: 1;
@ -277,8 +247,6 @@ body {
-ms-grid-row: 3; -ms-grid-row: 3;
grid-area: content; grid-area: content;
width: unset; width: unset;
/* height: calc(100vh - 111px);
width: calc(100% - 30px); */
overflow-y: auto; overflow-y: auto;
} }
@ -302,10 +270,6 @@ body {
display: none; display: none;
} }
.room4submenu {
min-height: calc(100vh - 159px);
}
#centralTable { #centralTable {
width: 100%; width: 100%;
} }
@ -424,12 +388,6 @@ body {
text-decoration: none; text-decoration: none;
} }
#verifyEmailId2 {
color:yellow;
margin-left:3px;
cursor:pointer;
}
#dialog { #dialog {
z-index: 1000; z-index: 1000;
background-color: #EEE; background-color: #EEE;
@ -447,18 +405,6 @@ body {
background-color: #003366; background-color: #003366;
color: #FFF; color: #FFF;
border-radius: 5px 5px 0 0; 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 { #dialogBody {
@ -487,58 +433,11 @@ body {
padding:10px; padding:10px;
} }
#dialog2, #dialog3, #dialog7 { #dialog2, #dialog3 {
margin: auto;
margin: 3px; 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 { #idx_dlgButtonBar {
padding: 10px; padding: 10px;
margin-bottom: 5px; margin-bottom: 5px;
@ -574,7 +473,7 @@ body {
#idx_deskFullBtn2 { #idx_deskFullBtn2 {
float: left; float: left;
font-size: 16px; font-size: large;
cursor: pointer; cursor: pointer;
display: none; display: none;
} }
@ -719,14 +618,6 @@ body {
font-size: 10px; font-size: 10px;
} }
#p2AccountActions .mL {
margin-left: 40px;
}
#p2ServerActions .mL {
margin-left: 40px;
}
.newMeshBtn { .newMeshBtn {
background: url(../images/icon-addnew.png) no-repeat 0px 0px; background: url(../images/icon-addnew.png) no-repeat 0px 0px;
height: 12px; height: 12px;
@ -736,14 +627,10 @@ body {
padding-left: 15px; padding-left: 15px;
} }
#p2noMeshFound, #serverStats { #p2noMeshFound, #p2ServerActionsBackup, #p2ServerActionsRestore, #p2ServerActionsVersion, #p2ServerActionsErrors, #serverStats {
margin-left:40px; margin-left:40px;
} }
#p2ServerActionsBackup, #p2ServerActionsRestore, #p2ServerActionsVersion, #p2ServerActionsErrors {
margin-left:0px;
}
.pTable { .pTable {
width: 100%; width: 100%;
height: 24px; height: 24px;
@ -787,10 +674,6 @@ body {
width: 230px; width: 230px;
} }
#p5toolbar {
width: 100%;
}
#p5filehead { #p5filehead {
width: 100%; width: 100%;
background-color: #d3d9d6; background-color: #d3d9d6;
@ -823,9 +706,6 @@ body {
-webkit-user-select: none; -webkit-user-select: none;
background-color: lightsteelblue; background-color: lightsteelblue;
} }
#p5PublicShare div {
padding: 4px;
}
#bigok { #bigok {
width: 256px; width: 256px;
@ -924,14 +804,6 @@ body {
font-size: x-small; font-size: x-small;
} }
#dp10devicevalue {
width: 230px;
}
.fulldesk #p11 {
height: 100%;
}
#MainComputerImage { #MainComputerImage {
border-width: 0px; border-width: 0px;
height: 200px; height: 200px;
@ -982,7 +854,6 @@ body {
a { a {
color: #036; color: #036;
text-decoration: underline; text-decoration: underline;
cursor: pointer;
} }
.i1 { .i1 {
@ -1280,20 +1151,11 @@ a {
background-color: #D3D9D6; background-color: #D3D9D6;
} }
/* .pTable .style14 {
float: left;
} */
.auto-style1 { .auto-style1 {
text-align: right; text-align: right;
background-color: #D3D9D6; background-color: #D3D9D6;
} }
#pTable .auto-style1 {
height: 100%;
float: right;
}
.icon2 { .icon2 {
float: left; float: left;
margin: 7px; margin: 7px;
@ -1433,7 +1295,7 @@ a {
.h1 { .h1 {
background-position: 0% 0%; background-position: 0% 0%;
width: 14px; width: 14px;
height: 24px; height: 100%;
/* fallback (Opera) */ /* fallback (Opera) */
/* Mozilla: */ /* Mozilla: */
/* Chrome, Safari:*/ /* Chrome, Safari:*/
@ -1447,13 +1309,13 @@ a {
height: 100%; height: 100%;
width: 20px; width: 20px;
float: right; float: right;
background-color: #ffffff; background-color: #ffffff
} }
.h2 { .h2 {
background-position: 0% 0%; background-position: 0% 0%;
width: 14px; width: 14px;
height: 24px; height: 100%;
/* fallback (Opera) */ /* fallback (Opera) */
/* Mozilla: */ /* Mozilla: */
/* Chrome, Safari:*/ /* Chrome, Safari:*/
@ -1655,7 +1517,6 @@ a {
padding: 4px padding: 4px
} }
.deskareaicon { .deskareaicon {
cursor: pointer; cursor: pointer;
border: none; border: none;
@ -1775,13 +1636,7 @@ a {
} }
#DeskParent { #DeskParent {
margin: 0; overflow:hidden
overflow:hidden;
height: 100%;
width: 100%;
position: absolute;
right: 0;
top: 0;
} }
#Desk { #Desk {
@ -1796,6 +1651,7 @@ a {
margin: auto; margin: auto;
} }
#deskToolsBar { #deskToolsBar {
position: absolute; position: absolute;
padding: 3px; padding: 3px;
@ -1807,27 +1663,6 @@ a {
cursor: pointer; 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 { #DeskToolsProcesses {
overflow-y: scroll; overflow-y: scroll;
position: absolute; position: absolute;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!DOCTYPE html>
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head> <head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <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

View File

@ -1770,7 +1770,15 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
const subscriptions = [userid, 'server-global']; const subscriptions = [userid, 'server-global'];
if (user.siteadmin != null) { if (user.siteadmin != null) {
if (user.siteadmin == 0xFFFFFFFF) subscriptions.push('*'); 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); } } if (user.links != null) { for (var i in user.links) { subscriptions.push(i); } }
obj.parent.RemoveAllEventDispatch(target); obj.parent.RemoveAllEventDispatch(target);