Added support to lockout accounts
Ylian Saint-Hilaire committed
Apr 13, 2018 at 15:26 UTC
ea2a0bb321e4932d03e378ce4d97782f624082c2
4 files changed
+25
-12
meshuser.js
+6
-3
@@ -91,7 +91,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
91
obj.ws.HandleEvent = function (source, event) {
92
if (!event.domain || event.domain == obj.domain.id) {
93
try {
94
- if (event == 'close') { obj.req.session.destroy(); obj.ws.close(); }
94
+ if (event == 'close') { req.session.destroy(); obj.close(); }
95
else if (event == 'resubscribe') { user.subscriptions = obj.parent.subscribe(user._id, ws); }
96
else if (event == 'updatefiles') { updateUserFiles(user, ws, domain); }
97
else { ws.send(JSON.stringify({ action: 'event', event: event })); }
@@ -280,10 +280,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
280
{
281
if ((command.limit == null) || (typeof command.limit != 'number')) {
282
// Send the list of all events for this session
283
- obj.db.GetEvents(user.subscriptions, domain.id, function (err, docs) { if (err != null) return; ws.send(JSON.stringify({ action: 'events', events: docs, tag: command.tag })); });
283
+ obj.db.GetEvents(user.subscriptions, domain.id, function (err, docs) { if (err != null) return; try { ws.send(JSON.stringify({ action: 'events', events: docs, tag: command.tag })); } catch (ex) { } });
284
} else {
285
// Send the list of most recent events for this session, up to 'limit' count
286
- obj.db.GetEventsWithLimit(user.subscriptions, domain.id, command.limit, function (err, docs) { if (err != null) return; ws.send(JSON.stringify({ action: 'events', events: docs, tag: command.tag })); });
286
+ obj.db.GetEventsWithLimit(user.subscriptions, domain.id, command.limit, function (err, docs) { if (err != null) return; try { ws.send(JSON.stringify({ action: 'events', events: docs, tag: command.tag })); } catch (ex) { } });
287
}
288
break;
289
}
@@ -452,6 +452,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
452
delete userinfo.passtype;
453
obj.parent.parent.DispatchEvent(['*', 'server-users', user._id, chguser._id], obj, { etype: 'user', username: user.name, account: userinfo, action: 'accountchange', msg: 'Account changed: ' + command.name, domain: domain.id })
454
}
455
+ if ((chguser.siteadmin) && (chguser.siteadmin != 0xFFFFFFFF) && (chguser.siteadmin & 32)) {
456
+ obj.parent.parent.DispatchEvent([chguser._id], obj, 'close'); // Disconnect all this user's sessions
457
+ }
458
}
459
}
460
break;
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.1.6-h",
3
+ "version": "0.1.6-j",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
views/default.handlebars
+11
-6
@@ -3457,7 +3457,7 @@
3457
function dmousedown(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) desktop.m.mousedown(e) }
3458
function dmouseup(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) desktop.m.mouseup(e) }
3459
function dmousemove(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) desktop.m.mousemove(e) }
3460
- function dmousewheel(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
3460
+ function dmousewheel(e) { if (!xxdialogMode && desktop != null && Q('DeskControl').checked && desktop.m.mousewheel) { desktop.m.mousewheel(e); haltEvent(e); return true; } return false; }
3461
function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
3462
function stopProcess(id, name) { setDialogMode(2, "Process Control", 3, stopProcessEx, 'Stop process #' + id + ' "' + name + '"?', id); }
3463
function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type:'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
@@ -4856,8 +4856,9 @@
4856
if (self) { msg += "</a>"; }
4857
}
4858
if (msg != '') msg += ', ';
4859
- if (self) { msg += "<a onclick=showUserAdminDialog(event,\"" + user._id + "\")>"; }
4860
- if ((user.siteadmin == null) || (user.siteadmin == 0)) {
4859
+ if (self) { msg += "<a onclick=showUserAdminDialog(event,\"" + encodeURIComponent(user._id) + "\")>"; }
4860
+ if ((user.siteadmin != null) && (user.siteadmin == 32)) { msg += "Locked, "; }
4861
+ if ((user.siteadmin == null) || (user.siteadmin == 0) || (user.siteadmin == 32)) {
4862
msg += "User";
4863
} else if (user.siteadmin == 8) {
4864
msg += "User with server files";
@@ -4938,6 +4939,7 @@
4939
function showUserAdminDialog(e, userid) {
4940
if (xxdialogMode) return;
4941
haltEvent(e);
4942
+ userid = decodeURIComponent(userid);
4943
var x = '<div>';
4944
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fileaccess>Server Files, <input type=number onchange=showUserAdminDialogValidate() maxlength=10 style=width:80px;text-align:right id=ua_fileaccessquota>k max, blank for default<br><hr/>';
4945
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_fulladmin>Full Administrator<br>';
@@ -4945,9 +4947,10 @@
4947
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverrestore>Server Restore<br>';
4948
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_serverupdate>Server Updates<br>';
4949
x += '<input type=checkbox onchange=showUserAdminDialogValidate() id=ua_manageusers>Manage Users<br>';
4950
+ x += '<hr/><input type=checkbox onchange=showUserAdminDialogValidate() id=ua_lockedaccount>Lock Account<br>';
4951
x += '</div>';
4949
- var user = users[userid];
4950
- setDialogMode(2, "Site Permissions", 3, showUserAdminDialogEx, x, user);
4952
+ var user = users[userid.toLowerCase()];
4953
+ setDialogMode(2, "Server Permissions", 3, showUserAdminDialogEx, x, user);
4954
if (user.siteadmin && user.siteadmin != 0) {
4955
Q('ua_fulladmin').checked = (user.siteadmin == 0xFFFFFFFF);
4956
Q('ua_serverbackup').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1) != 0)); // Server Backup
@@ -4955,6 +4958,7 @@
4958
Q('ua_serverrestore').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 4) != 0)); // Server Restore
4959
Q('ua_fileaccess').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 8) != 0)); // Server Files
4960
Q('ua_serverupdate').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 16) != 0)); // Server Update
4961
+ Q('ua_lockedaccount').checked = ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 32) != 0)); // Account locked
4962
}
4963
QE('ua_fulladmin', userinfo.siteadmin == 0xFFFFFFFF);
4964
QE('ua_serverbackup', userinfo.siteadmin == 0xFFFFFFFF);
@@ -4974,7 +4978,7 @@
4978
QE('ua_serverrestore', !Q('ua_fulladmin').checked);
4979
QE('ua_fileaccess', !Q('ua_fulladmin').checked);
4980
QE('ua_serverupdate', !Q('ua_fulladmin').checked);
4977
- QE('ua_fileaccessquota', Q('ua_fileaccess').checked || Q('ua_fulladmin').checked);
4981
+ QE('ua_fileaccessquota', Q('ua_fileaccess').checked && !Q('ua_fulladmin').checked);
4982
}
4983
}
4984
@@ -4986,6 +4990,7 @@
4990
if (Q('ua_serverrestore').checked == true) siteadmin += 4;
4991
if (Q('ua_fileaccess').checked == true) siteadmin += 8;
4992
if (Q('ua_serverupdate').checked == true) siteadmin += 16;
4993
+ if (Q('ua_lockedaccount').checked == true) siteadmin += 32;
4994
}
4995
var x = { action: 'edituser', name: user.name, siteadmin: siteadmin };
4996
if (isNaN(quota) == false) { x.quota = (quota * 1024); }
webserver.js
+7
-2
@@ -88,6 +88,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
88
const SITERIGHT_SERVERRESTORE = 4;
89
const SITERIGHT_FILEACCESS = 8;
90
const SITERIGHT_SERVERUPDATE = 16;
91
+ const SITERIGHT_LOCKED = 32;
92
93
// Setup SSPI authentication if needed
94
if ((obj.parent.platform == 'win32') && (obj.args.nousers != true) && (obj.parent.config != null) && (obj.parent.config.domains != null)) {
@@ -207,6 +208,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
208
if (hash == user.hash) {
209
// Update the password to the stronger format.
210
require('./pass').hash(pass, function (err, salt, hash) { if (err) throw err; user.salt = salt; user.hash = hash; delete user.passtype; obj.db.SetUser(user); });
211
+ if ((user.siteadmin) && (user.siteadmin != 0xFFFFFFFF) && (user.siteadmin & 32) != 0) { fn('locked'); return; }
212
return fn(null, user._id);
213
}
214
fn(new Error('invalid password'), null, user.passhint);
@@ -215,7 +217,10 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
217
// Default strong password hashing (pbkdf2 SHA384)
218
require('./pass').hash(pass, user.salt, function (err, hash) {
219
if (err) return fn(err);
218
- if (hash == user.hash) return fn(null, user._id);
220
+ if (hash == user.hash) {
221
+ if ((user.siteadmin) && (user.siteadmin != 0xFFFFFFFF) && (user.siteadmin & 32) != 0) { fn('locked'); return; }
222
+ return fn(null, user._id);
223
+ }
224
fn(new Error('invalid password'), null, user.passhint);
225
});
226
}
@@ -330,7 +335,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
335
obj.parent.DispatchEvent(['*'], obj, { etype: 'user', username: user.name, action: 'login', msg: 'Account login', domain: domain.id })
336
} else {
337
delete req.session.loginmode;
333
- req.session.error = '<b style=color:#8C001A>Login failed, check username and password.</b>';
338
+ if (err == 'locked') { req.session.error = '<b style=color:#8C001A>Account locked.</b>'; } else { req.session.error = '<b style=color:#8C001A>Login failed, check username and password.</b>'; }
339
if ((passhint != null) && (passhint.length > 0)) {
340
req.session.passhint = passhint;
341
} else {