Added option to turn off reset account on login screen.
Ylian Saint-Hilaire committed
Feb 4, 2022 at 07:29 UTC
1f1a80739e768e31d6cd62fda9aa47c9263da97f
3 files changed
+26
-10
meshcentral-config-schema.json
+2
-1
@@ -451,7 +451,8 @@
451
"loginTokens": { "type": "boolean", "default": true, "description": "Allows users to create alternative username/passwords for their account." },
452
"twoFactorTimeout": { "type": "integer", "default": 300, "description": "Maximum about of time the to wait for a 2FA token on the login page in seconds." },
453
"autofido2fa": { "type": "boolean", "default": false, "description": "If true and user account has FIDO key setup, 2FA login screen will automatically request FIDO 2FA." },
454
- "maxfidokeys": { "type": "integer", "default": null, "description": "Maximum number of FIDO/YubikeyOTP hardware 2FA keys that can be setup in a user account." }
454
+ "maxfidokeys": { "type": "integer", "default": null, "description": "Maximum number of FIDO/YubikeyOTP hardware 2FA keys that can be setup in a user account." },
455
+ "allowaccountreset": { "type": "boolean", "default": true, "description": "If set to false, the account reset option on the login screen will not be available to users." }
456
}
457
},
458
"twoFactorCookieDurationDays": { "type": "integer", "default": 30, "description": "Number of days that a user is allowed to remember this device for when completing 2FA. Set this to 0 to remove this option." },
package.json
+14
-2
@@ -36,6 +36,8 @@
36
"sample-config-advanced.json"
37
],
38
"dependencies": {
39
+ "@yetzt/nedb": "^1.8.0",
40
+ "archiver": "^4.0.2",
41
"body-parser": "^1.19.0",
42
"cbor": "~5.2.0",
43
"compression": "^1.7.4",
@@ -43,13 +45,23 @@
45
"express": "^4.17.0",
46
"express-handlebars": "^3.1.0",
47
"express-ws": "^4.0.0",
48
+ "image-size": "^1.0.1",
49
"ipcheck": "^0.1.0",
50
+ "loadavg-windows": "^1.1.1",
51
"minimist": "^1.2.5",
52
"multiparty": "^4.2.1",
49
- "@yetzt/nedb": "^1.8.0",
53
"node-forge": "^1.0.0",
54
+ "node-rdpjs-2": "^0.3.5",
55
+ "node-windows": "^0.1.4",
56
+ "nodemailer": "^6.7.2",
57
+ "otplib": "^10.2.3",
58
+ "pg": "^8.7.1",
59
+ "pgtools": "^0.3.2",
60
+ "ssh2": "^1.6.0",
61
+ "web-push": "^3.4.5",
62
"ws": "^5.2.3",
52
- "yauzl": "^2.10.0"
63
+ "yauzl": "^2.10.0",
64
+ "yubikeyotp": "^0.2.0"
65
},
66
"engines": {
67
"node": ">=10.0.0"
webserver.js
+10
-7
@@ -1144,7 +1144,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1144
}
1145
1146
// Check if email address needs to be confirmed
1147
- var emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
1147
+ const emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
1148
if (emailcheck && (user.emailVerified !== true)) {
1149
parent.debug('web', 'Redirecting using ' + user.name + ' to email check login page');
1150
req.session.messageid = 3; // "Email verification required" message
@@ -1165,7 +1165,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1165
}
1166
1167
// Check if email address needs to be confirmed
1168
- var emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
1168
+ const emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
1169
if (emailcheck && (user.emailVerified !== true)) {
1170
parent.debug('web', 'Redirecting using ' + user.name + ' to email check login page');
1171
req.session.messageid = 3; // "Email verification required" message
@@ -1459,7 +1459,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1459
if (req.session.loginToken != null) { res.sendStatus(404); return; } // Do not allow this command when logged in using a login token
1460
1461
// Check everything is ok
1462
- if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (typeof req.body.rpassword1 != 'string') || (typeof req.body.rpassword2 != 'string') || (req.body.rpassword1 != req.body.rpassword2) || (typeof req.body.rpasswordhint != 'string') || (req.session == null) || (typeof req.session.resettokenusername != 'string') || (typeof req.session.resettokenpassword != 'string')) {
1462
+ const allowAccountReset = ((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.allowaccountreset !== false));
1463
+ if ((allowAccountReset === false) || (domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (typeof req.body.rpassword1 != 'string') || (typeof req.body.rpassword2 != 'string') || (req.body.rpassword1 != req.body.rpassword2) || (typeof req.body.rpasswordhint != 'string') || (req.session == null) || (typeof req.session.resettokenusername != 'string') || (typeof req.session.resettokenpassword != 'string')) {
1464
parent.debug('web', 'handleResetPasswordRequest: checks failed');
1465
delete req.session.u2f;
1466
delete req.session.loginmode;
@@ -1568,7 +1569,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1569
function handleResetAccountRequest(req, res, direct) {
1570
const domain = checkUserIpAddress(req, res);
1571
if (domain == null) { return; }
1571
- if ((domain.auth == 'sspi') || (domain.auth == 'ldap') || (obj.args.lanonly == true) || (obj.parent.certificates.CommonName == null) || (obj.parent.certificates.CommonName.indexOf('.') == -1)) { parent.debug('web', 'handleResetAccountRequest: check failed'); res.sendStatus(404); return; }
1572
+ const allowAccountReset = ((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.allowaccountreset !== false));
1573
+ if ((allowAccountReset === false) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (obj.args.lanonly == true) || (obj.parent.certificates.CommonName == null) || (obj.parent.certificates.CommonName.indexOf('.') == -1)) { parent.debug('web', 'handleResetAccountRequest: check failed'); res.sendStatus(404); return; }
1574
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1575
if (req.session.loginToken != null) { res.sendStatus(404); return; } // Do not allow this command when logged in using a login token
1576
@@ -2903,7 +2905,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
2905
delete req.session.messageid;
2906
delete req.session.passhint;
2907
}
2906
- var emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
2908
+ const allowAccountReset = ((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.allowaccountreset !== false));
2909
+ const emailcheck = (allowAccountReset && (domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
2910
2911
// Check if we are allowed to create new users using the login screen
2912
var newAccountsAllowed = true;
@@ -6456,7 +6459,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6459
var user = obj.users[userid];
6460
if ((err == null) && (user)) {
6461
// Check if a 2nd factor is needed
6459
- var emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
6462
+ const emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
6463
6464
// See if we support two-factor trusted cookies
6465
var twoFactorCookieDays = 30;
@@ -6586,7 +6589,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6589
// Check if inner authentication is requested
6590
if (req.headers['x-meshauth'] === '*') { func(ws, req, domain, null); return; }
6591
6589
- var emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
6592
+ const emailcheck = ((domain.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName.indexOf('.') != -1) && (obj.args.lanonly != true) && (domain.auth != 'sspi') && (domain.auth != 'ldap'))
6593
6594
// A web socket session can be authenticated in many ways (Default user, session, user/pass and cookie). Check authentication here.
6595
if ((req.query.user != null) && (req.query.pass != null)) {