Added Account Settings Lock Feature.

This commit is contained in:
Ylian Saint-Hilaire 2020-08-05 20:15:34 -07:00
parent 81c8326c9f
commit 7f43e75929
5 changed files with 673 additions and 606 deletions

View File

@ -32,37 +32,38 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
const USERCONSENT_ShowConnectionToolbar = 64;
// Mesh Rights
const MESHRIGHT_EDITMESH = 1;
const MESHRIGHT_MANAGEUSERS = 2;
const MESHRIGHT_MANAGECOMPUTERS = 4;
const MESHRIGHT_REMOTECONTROL = 8;
const MESHRIGHT_AGENTCONSOLE = 16;
const MESHRIGHT_SERVERFILES = 32;
const MESHRIGHT_WAKEDEVICE = 64;
const MESHRIGHT_SETNOTES = 128;
const MESHRIGHT_REMOTEVIEWONLY = 256;
const MESHRIGHT_NOTERMINAL = 512;
const MESHRIGHT_NOFILES = 1024;
const MESHRIGHT_NOAMT = 2048;
const MESHRIGHT_DESKLIMITEDINPUT = 4096;
const MESHRIGHT_LIMITEVENTS = 8192;
const MESHRIGHT_CHATNOTIFY = 16384;
const MESHRIGHT_UNINSTALL = 32768;
const MESHRIGHT_NODESKTOP = 65536;
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
const MESHRIGHT_EDITMESH = 0x00000001;
const MESHRIGHT_MANAGEUSERS = 0x00000002;
const MESHRIGHT_MANAGECOMPUTERS = 0x00000004;
const MESHRIGHT_REMOTECONTROL = 0x00000008;
const MESHRIGHT_AGENTCONSOLE = 0x00000010;
const MESHRIGHT_SERVERFILES = 0x00000020;
const MESHRIGHT_WAKEDEVICE = 0x00000040;
const MESHRIGHT_SETNOTES = 0x00000080;
const MESHRIGHT_REMOTEVIEWONLY = 0x00000100;
const MESHRIGHT_NOTERMINAL = 0x00000200;
const MESHRIGHT_NOFILES = 0x00000400;
const MESHRIGHT_NOAMT = 0x00000800;
const MESHRIGHT_DESKLIMITEDINPUT = 0x00001000;
const MESHRIGHT_LIMITEVENTS = 0x00002000;
const MESHRIGHT_CHATNOTIFY = 0x00004000;
const MESHRIGHT_UNINSTALL = 0x00008000;
const MESHRIGHT_NODESKTOP = 0x00010000;
const MESHRIGHT_ADMIN = 0xFFFFFFFF;
// Site rights
const SITERIGHT_SERVERBACKUP = 1; // 0x00000001
const SITERIGHT_MANAGEUSERS = 2; // 0x00000002
const SITERIGHT_SERVERRESTORE = 4; // 0x00000004
const SITERIGHT_FILEACCESS = 8; // 0x00000008
const SITERIGHT_SERVERUPDATE = 16; // 0x00000010
const SITERIGHT_LOCKED = 32; // 0x00000020
const SITERIGHT_NONEWGROUPS = 64; // 0x00000040
const SITERIGHT_NOMESHCMD = 128; // 0x00000080
const SITERIGHT_USERGROUPS = 256; // 0x00000100
const SITERIGHT_RECORDINGS = 512; // 0x00000200
const SITERIGHT_ADMIN = 0xFFFFFFFF; // 0xFFFFFFFF
const SITERIGHT_SERVERBACKUP = 0x00000001;
const SITERIGHT_MANAGEUSERS = 0x00000002;
const SITERIGHT_SERVERRESTORE = 0x00000004;
const SITERIGHT_FILEACCESS = 0x00000008;
const SITERIGHT_SERVERUPDATE = 0x00000010;
const SITERIGHT_LOCKED = 0x00000020;
const SITERIGHT_NONEWGROUPS = 0x00000040;
const SITERIGHT_NOMESHCMD = 0x00000080;
const SITERIGHT_USERGROUPS = 0x00000100;
const SITERIGHT_RECORDINGS = 0x00000200;
const SITERIGHT_LOCKSETTINGS = 0x00000400;
const SITERIGHT_ADMIN = 0xFFFFFFFF;
var obj = {};
obj.user = user;
@ -1368,6 +1369,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'changelang':
{
// If this account is settings locked, return here.
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return;
if (common.validateString(command.lang, 1, 6) == false) return;
// Always lowercase the email address
@ -1394,6 +1398,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// If the email is the username, this command is not allowed.
if (domain.usernameisemail) return;
// If this account is settings locked, return here.
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return;
// Change our own email address
if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) return;
if (common.validateEmail(command.email, 1, 1024) == false) return;
@ -1439,6 +1446,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'verifyemail':
{
// If this account is settings locked, return here.
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return;
// Send a account email verification email
if ((domain.auth == 'sspi') || (domain.auth == 'ldap')) return;
if (common.validateString(command.email, 3, 1024) == false) return;
@ -2311,6 +2321,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'changemeshnotify':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
var err = null;
try {
// Change the current user's notification flags for a meshid
@ -2347,6 +2359,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'changepassword':
{
// If this account is settings locked, return here.
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return;
// Change our own password
if (common.validateString(command.oldpass, 1, 256) == false) break;
if (common.validateString(command.newpass, 1, 256) == false) break;
@ -3848,6 +3863,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'otpemail':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Check input
if (typeof command.enabled != 'boolean') return;
@ -3870,6 +3887,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'otpauth-request':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Check if 2-step login is supported
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if (twoStepLoginSupported) {
@ -3884,6 +3903,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'otpauth-setup':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Check if 2-step login is supported
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if (twoStepLoginSupported) {
@ -3912,6 +3933,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'otpauth-clear':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Check if 2-step login is supported
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if (twoStepLoginSupported) {
@ -3939,23 +3962,25 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if (twoStepLoginSupported == false) break;
// Perform a sub-action
var actionTaken = false, actionText = null;
if (command.subaction == 1) { // Generate a new set of tokens
var randomNumbers = [], v;
for (var i = 0; i < 10; i++) { do { v = getRandomEightDigitInteger(); } while (randomNumbers.indexOf(v) >= 0); randomNumbers.push(v); }
user.otpkeys = { keys: [] };
for (var i = 0; i < 10; i++) { user.otpkeys.keys[i] = { p: randomNumbers[i], u: true } }
actionTaken = true;
actionText = 'New 2FA backup codes generated.';
} else if (command.subaction == 2) { // Clear all tokens
actionTaken = (user.otpkeys != null);
delete user.otpkeys;
if (actionTaken) { actionText = '2FA backup codes cleared.'; }
}
if ((user.siteadmin == 0xFFFFFFFF) || ((user.siteadmin & 1024) == 0)) { // Don't allow generation of tokens if the account is settings locked
// Perform a sub-action
if (command.subaction == 1) { // Generate a new set of tokens
var randomNumbers = [], v;
for (var i = 0; i < 10; i++) { do { v = getRandomEightDigitInteger(); } while (randomNumbers.indexOf(v) >= 0); randomNumbers.push(v); }
user.otpkeys = { keys: [] };
for (var i = 0; i < 10; i++) { user.otpkeys.keys[i] = { p: randomNumbers[i], u: true } }
actionTaken = true;
actionText = 'New 2FA backup codes generated.';
} else if (command.subaction == 2) { // Clear all tokens
actionTaken = (user.otpkeys != null);
delete user.otpkeys;
if (actionTaken) { actionText = '2FA backup codes cleared.'; }
}
// Save the changed user
if (actionTaken) { parent.db.SetUser(user); }
// Save the changed user
if (actionTaken) { parent.db.SetUser(user); }
}
// Return one time passwords for this user
if (count2factoraAuths() > 0) {
@ -3987,6 +4012,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'otp-hkey-remove':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Check if 2-step login is supported
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if (twoStepLoginSupported == false || command.index == null) break;
@ -4009,6 +4036,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'otp-hkey-yubikey-add':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Yubico API id and signature key can be requested from https://upgrade.yubico.com/getapikey/
var yubikeyotp = null;
try { yubikeyotp = require('yubikeyotp'); } catch (ex) { }
@ -4062,6 +4091,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'webauthn-startregister':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
// Check if 2-step login is supported
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if ((twoStepLoginSupported == false) || (command.name == null)) break;
@ -4074,6 +4105,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
case 'webauthn-endregister':
{
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
const twoStepLoginSupported = ((parent.parent.config.settings.no2factorauth !== true) && (domain.auth != 'sspi') && (parent.parent.certificates.CommonName.indexOf('.') != -1) && (args.nousers !== true));
if ((twoStepLoginSupported == false) || (obj.webAuthnReqistrationRequest == null)) return;
@ -4113,6 +4145,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
break;
}
case 'verifyPhone': {
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
if (parent.parent.smsserver == null) return;
if (common.validateString(command.phone, 1, 18) == false) break; // Check phone length
if (command.phone.match(/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/) == false) break; // Check phone
@ -4124,6 +4157,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
break;
}
case 'confirmPhone': {
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
if ((parent.parent.smsserver == null) || (typeof command.cookie != 'string') || (typeof command.code != 'string') || (obj.failedSmsCookieCheck == 1)) break; // Input checks
var cookie = parent.parent.decodeCookie(command.cookie);
if (cookie == null) break; // Invalid cookie
@ -4150,6 +4184,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
break;
}
case 'removePhone': {
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
if (user.phone == null) break;
// Clear the user's phone
@ -4232,6 +4267,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
break;
}
case 'userWebState': {
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here.
if (common.validateString(command.state, 1, 10000) == false) break; // Check state size, no more than 10k
command.state = parent.filterUserWebState(command.state); // Filter the state to remove anything bad
if ((command.state == null) || (typeof command.state !== 'string')) { console.log('tt'); break; } // If state did not validate correctly, quit here.

File diff suppressed because it is too large Load Diff

View File

@ -908,6 +908,12 @@
}
function updateSelf() {
var accountSettingsLocked = false;
if (userinfo) { accountSettingsLocked = ((userinfo.siteadmin != 0xFFFFFFFF) && ((userinfo.siteadmin & 1024) != 0)); }
QV('p3AccountActions', ((features & 4) == 0) && (serverinfo.domainauth == false) && (accountSettingsLocked == false)); // Hide Account Actions if in single user mode or domain authentication
QV('logoutMenuOption', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide logout if in single user mode or domain authentication
QV('p2AccountSecurity', ((features & 4) == 0) && (serverinfo.domainauth == false) && ((features & 4096) != 0) && (accountSettingsLocked == false)); // Hide Account Security if in single user mode or domain authentication, 2 factor auth not supported.
QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
QV('manageAuthApp', features & 4096);
QV('manageOtp', ((features & 4096) != 0) && ((userinfo.otpsecret == 1) || (userinfo.otphkeys > 0)));
@ -942,9 +948,7 @@
case 'serverinfo': {
serverinfo = message.serverinfo;
if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); }
QV('p3AccountActions', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide Account Actions if in single user mode or domain authentication
QV('logoutMenuOption', ((features & 4) == 0) && (serverinfo.domainauth == false)); // Hide logout if in single user mode or domain authentication
QV('p2AccountSecurity', ((features & 4) == 0) && (serverinfo.domainauth == false) && ((features & 4096) != 0)); // Hide Account Security if in single user mode or domain authentication, 2 factor auth not supported.
if (userinfo != null) updateSelf();
break;
}
case 'authcookie': {
@ -957,7 +961,7 @@
userinfo = message.userinfo;
QH('p3userName', userinfo.name);
//updateSiteAdmin();
updateSelf();
if (serverinfo != null) updateSelf();
break;
}
case 'users': {
@ -1146,7 +1150,7 @@
var oldsiteadmin = userinfo.siteadmin ? userinfo.siteadmin : 0;
if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.send({ action: 'files' }); }
userinfo = message.event.account;
if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
//if (oldsiteadmin != newsiteadmin) updateSiteAdmin();
updateSelf();
// If our list of nodes may have changes, request the new list now.

View File

@ -354,7 +354,7 @@
<table class="pTable">
<tr>
<td class="h1"></td>
<td>
<td class="auto-style1">
<input type="button" style="display:none" value="Download Report" onclick=p3showReportDialog() />
</td>
<td class="auto-style1">
@ -1792,15 +1792,18 @@
function updateSiteAdmin() {
var noServerBackup = '{{{noServerBackup}}}';
var siteRights = userinfo.siteadmin;
var accountSettingsLocked = ((siteRights != 0xFFFFFFFF) && ((siteRights & 1024) != 0));
if (noServerBackup == 1) { siteRights &= 0xFFFFFFFA; } // If not server backups allowed, remove server backup and restore permissions
// Update account actions
QV('p2AccountSecurity', ((features & 4) == 0) && (serverinfo.domainauth == false) && ((features & 4096) != 0)); // Hide Account Security if in single user mode or domain authentication, 2 factor auth not supported.
QV('p2AccountSecurity', ((features & 4) == 0) && (serverinfo.domainauth == false) && ((features & 4096) != 0) && (accountSettingsLocked == false)); // Hide Account Security if in single user mode or domain authentication, 2 factor auth not supported.
QV('p2AccountActions', !accountSettingsLocked)
QV('managePhoneNumber1', (features & 0x02000000) && (features & 0x04000000));
QV('managePhoneNumber2', (features & 0x02000000) && !(features & 0x04000000));
QV('manageEmail2FA', features & 0x00800000);
QV('p2AccountPassActions', ((features & 4) == 0) && (serverinfo.domainauth == false) && (userinfo != null) && (userinfo._id.split('/')[2].startsWith('~') == false)); // Hide Account Actions if in single user mode or domain authentication
//QV('p2AccountImage', ((features & 4) == 0) && (serverinfo.domainauth == false)); // If account actions are not visible, also remove the image on that panel
QV('p2AccountImage', !accountSettingsLocked)
QV('p2ServerActions', siteRights & 21);
QV('LeftMenuMyServer', siteRights & 21); // 16 + 4 + 1
QV('MainMenuMyServer', siteRights & 21);
@ -1878,8 +1881,9 @@
var backupCodesWarningDone = false;
function updateSelf() {
var authFactorCount = count2factoraAuths(); // Get the number of 2nd factors
var accountSettingsLocked = ((userinfo.siteadmin != 0xFFFFFFFF) && ((userinfo.siteadmin & 1024) != 0));
QV('verifyEmailId', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
QV('verifyEmailId2', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true));
QV('verifyEmailId2', (userinfo.emailVerified !== true) && (userinfo.email != null) && (serverinfo.emailcheck == true) && (accountSettingsLocked == false));
QV('manageOtp', authFactorCount > 0);
QV('authPhoneNumberCheck', (userinfo.phone != null));
QV('authEmailSetupCheck', (userinfo.otpekey == 1) && (userinfo.email != null) && (userinfo.emailVerified == true));
@ -9183,14 +9187,16 @@
x += addHtmlValue("User Consent", addLinkConditional(meshFeatures, 'p20editmeshconsent(1)', meshrights & 1));
}
// Display user notification
var meshNotify = 0, meshNotifyStr = [];
if (userinfo.links && userinfo.links[currentMesh._id] && userinfo.links[currentMesh._id].notify) { meshNotify = userinfo.links[currentMesh._id].notify; }
if (meshNotify & 2) { meshNotifyStr.push("Connect"); }
if (meshNotify & 4) { meshNotifyStr.push("Disconnect"); }
if (meshNotify & 8) { meshNotifyStr.push("Intel&reg; AMT"); }
if (meshNotifyStr.length == 0) { meshNotifyStr.push('<i>' + "None" + '</i>'); }
x += addHtmlValue("Notifications", addLink(meshNotifyStr.join(', '), 'p20editMeshNotify()'));
if ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 1024) == 0)) {
// Display user notification
var meshNotify = 0, meshNotifyStr = [];
if (userinfo.links && userinfo.links[currentMesh._id] && userinfo.links[currentMesh._id].notify) { meshNotify = userinfo.links[currentMesh._id].notify; }
if (meshNotify & 2) { meshNotifyStr.push("Connect"); }
if (meshNotify & 4) { meshNotifyStr.push("Disconnect"); }
if (meshNotify & 8) { meshNotifyStr.push("Intel&reg; AMT"); }
if (meshNotifyStr.length == 0) { meshNotifyStr.push('<i>' + "None" + '</i>'); }
x += addHtmlValue("Notifications", addLink(meshNotifyStr.join(', '), 'p20editMeshNotify()'));
}
// Display invitation codes
if ((features & 0x01000000) && (currentMesh.mtype == 2)) {
@ -9567,6 +9573,7 @@
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20limitevents>' + "Show Only Own Events" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20chatnotify>' + "Chat & Notify" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20uninstall>' + "Uninstall Agent" + '</label><br>';
x += '<label><input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20settingslock>' + "Lock Account Settings" + '</label><br>';
x += '</div>';
if (userid == null) {
@ -10633,7 +10640,7 @@
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { permissions += "Locked" + ',&nbsp;'; }
permissions += '<span title=\'' + "Server Permissions" + '\'>';
var urights = user.siteadmin & (0xFFFFFFFF - 224);
var urights = user.siteadmin & (0xFFFFFFFF - 1248);
if ((user.siteadmin == null) || (urights == 0)) {
permissions += "User";
} else if (urights == 8) {
@ -10645,7 +10652,7 @@
} else {
permissions += "Partial";
}
if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128)) != 0)) { permissions += '*'; }
if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128 + 1024)) != 0)) { permissions += '*'; }
permissions += '</span>';
//if ((user.quota != null) && ((user.siteadmin & 8) != 0)) { msg += ", " + (user.quota / 1024) + " k"; }
if (self) { permissions += '</a>'; }
@ -11035,6 +11042,7 @@
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_lockedaccount>' + "Lock Account" + '</label><br>';
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nonewgroups>' + "No New Device Groups" + '</label><br>';
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_nomeshcmd>' + "No Tools (MeshCmd/Router)" + '</label><br>';
x += '<label><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_locksettings>' + "Lock Account Settings" + '</label><br>';
x += '</div>';
setDialogMode(2, "Server Permissions", 2 + (uself?0:1), showUserAdminDialogEx, x, user);
if (user.siteadmin && user.siteadmin != 0) {
@ -11046,6 +11054,7 @@
Q('ua_lockedaccount').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 32) != 0)); // Account locked
Q('ua_nonewgroups').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 64) != 0)); // No New Groups
Q('ua_nomeshcmd').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 128) != 0)); // No Tools (MeshCMD / Router)
Q('ua_locksettings').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)); // Lock account settings
}
if ((userinfo.siteadmin & 2) != 0) {
Q('ua_manageusers').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 2) != 0)); // Manage Users
@ -11075,6 +11084,7 @@
QE('ua_lockedaccount', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
QE('ua_nonewgroups', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
QE('ua_nomeshcmd', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
QE('ua_locksettings', !uself && (userinfo.siteadmin & 2) && (user.siteadmin != 0xFFFFFFFF) && (userinfo._id != user._id));
Q('ua_fileaccessquota').value = (user.quota != null)?(user.quota / 1024):'';
showUserAdminDialogValidate();
return false;
@ -11091,8 +11101,9 @@
QE('ua_nonewgroups', !Q('ua_fulladmin').checked);
QE('ua_nomeshcmd', !Q('ua_fulladmin').checked);
QE('ua_manageusergroups', !Q('ua_fulladmin').checked);
QE('ua_fileaccessquota', Q('ua_fileaccess').checked && !Q('ua_fulladmin').checked);
QE('ua_managerecordings', !Q('ua_fulladmin').checked);
QE('ua_locksettings', !Q('ua_fulladmin').checked);
QE('ua_fileaccessquota', Q('ua_fileaccess').checked && !Q('ua_fulladmin').checked);
}
}
@ -11109,6 +11120,7 @@
if (Q('ua_nomeshcmd').checked == true) siteadmin += 128;
if (Q('ua_manageusergroups').checked == true) siteadmin += 256;
if (Q('ua_managerecordings').checked == true) siteadmin += 512;
if (Q('ua_locksettings').checked == true) siteadmin += 1024;
}
var x = { action: 'edituser', id: user._id, siteadmin: siteadmin };
if (isNaN(quota) == false) { x.quota = (quota * 1024); }
@ -11580,8 +11592,8 @@
// Server permissions
var msg = [], premsg = '';
if ((user.siteadmin != null) && ((user.siteadmin & 32) != 0) && (user.siteadmin != 0xFFFFFFFF)) { premsg = '<img src="images/padlock12.png" height=12 width=8 title="' + "Account is locked" + '" style="margin-top:2px" /> '; msg.push("Locked account"); }
if ((user.siteadmin == null) || ((user.siteadmin & (0xFFFFFFFF - 224)) == 0)) { msg.push("No server rights"); } else if (user.siteadmin == 8) { msg.push("Access to server files"); } else if (user.siteadmin == 0xFFFFFFFF) { msg.push("Full administrator"); } else { msg.push("Partial rights"); }
if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128)) != 0)) { msg.push("Restrictions"); }
if ((user.siteadmin == null) || ((user.siteadmin & (0xFFFFFFFF - 1248)) == 0)) { msg.push("No server rights"); } else if (user.siteadmin == 8) { msg.push("Access to server files"); } else if (user.siteadmin == 0xFFFFFFFF) { msg.push("Full administrator"); } else { msg.push("Partial rights"); }
if ((user.siteadmin != null) && (user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & (64 + 128 + 1024)) != 0)) { msg.push("Restrictions"); }
// Show user attributes
var x = '<div style=min-height:80px><table style=width:100%>';

View File

@ -1754,6 +1754,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
}
}
if (!user) { parent.debug('web', 'handleDeleteAccountRequest: user not found.'); res.sendStatus(404); return; }
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) { parent.debug('web', 'handleDeleteAccountRequest: account settings locked.'); res.sendStatus(404); return; }
// Check if the password is correct
obj.authenticate(user._id.split('/')[2], req.body.apassword1, domain, function (err, userid) {
@ -1874,6 +1875,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
return;
}
// Check account settings locked
if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) {
parent.debug('web', 'handlePasswordChangeRequest: account settings locked.');
res.sendStatus(404);
return;
}
// Check old password
obj.checkUserPassword(domain, user, req.body.apassword0, function (result) {
if (result == true) {