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 = [];
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;
};

View File

@ -1,6 +1,6 @@
{
"name": "meshcentral",
"version": "0.3.2-m",
"version": "0.3.2-o",
"keywords": [
"Remote Management",
"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 @@

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

View File

@ -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

View File

@ -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);