MeshCentral now defaults to not accepting new accounts on login screen.

Ylian Saint-Hilaire committed Apr 23, 2019 at 13:42 UTC 145a804e1c8dbb5d67c6105ff6696e7ab896a482
5 files changed +28 -14
meshuser.js
+6
@@ -288,6 +288,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
288 try { ws.send(JSON.stringify({ action: 'authcookie', cookie: parent.parent.encodeCookie({ userid: user._id, domainid: domain.id }, parent.parent.loginCookieEncryptionKey) })); } catch (ex) { }
289 break;
290 }
291 + case 'logincookie':
292 + {
293 + // Return a login cookie
294 + try { ws.send(JSON.stringify({ action: 'logincookie', cookie: parent.parent.encodeCookie({ u: user._id, a: 3 }, parent.parent.loginCookieEncryptionKey) })); } catch (ex) { }
295 + break;
296 + }
297 case 'servertimelinestats':
298 {
299 if ((user.siteadmin & 21) == 0) return; // Only site administrators with "site backup" or "site restore" or "site update" permissions can use this.
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.3.2-v",
3 + "version": "0.3.2-x",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
sample-config.json
+1 -1
@@ -45,7 +45,7 @@
45 "_TitlePicture": "title-sample.png",
46 "_UserQuota": 1048576,
47 "_MeshQuota": 248576,
48 - "NewAccounts": 1,
48 + "_NewAccounts": true,
49 "_NewAccountEmailDomains": [ "sample.com" ],
50 "Footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>",
51 "_CertUrl": "https://192.168.2.106:443/",
views/login.handlebars
+1 -1
@@ -282,7 +282,7 @@
282 validateLogin();
283 validateCreate();
284 if ('{{loginmode}}' != '') { go(parseInt('{{loginmode}}')); } else { go(1); }
285 - QV('newAccountDiv', ('{{{newAccount}}}' != '0') && ('{{{newAccount}}}' != 'false')); // If new accounts are not allowed, don't display the new account link.
285 + QV('newAccountDiv', ('{{{newAccount}}}' === '1') || ('{{{newAccount}}}' === 'true')); // If new accounts are not allowed, don't display the new account link.
286 if ((passhint != null) && (passhint.length > 0)) { QV("showPassHintLink", true); }
287 QV("newAccountPass", (newAccountPass == 1));
288 QV("resetAccountDiv", (emailCheck == true));
webserver.js
+19 -11
@@ -198,7 +198,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
198 for (i in parent.config.domains) {
199 if (domainUserCount[i] == 0) {
200 // If newaccounts is set to no new accounts, but no accounts exists, temporarly allow account creation.
201 - if ((parent.config.domains[i].newaccounts === 0) || (parent.config.domains[i].newaccounts === false)) { parent.config.domains[i].newaccounts = 2; }
201 + //if ((parent.config.domains[i].newaccounts === 0) || (parent.config.domains[i].newaccounts === false)) { parent.config.domains[i].newaccounts = 2; }
202 console.log('Server ' + ((i == '') ? '' : (i + ' ')) + 'has no users, next new account will be site administrator.');
203 }
204 }
@@ -252,7 +252,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
252 var user = { type: 'user', _id: userid, name: username, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id };
253 var usercount = 0;
254 for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
255 - if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newaccounts === 2) { domain.newaccounts = 0; } } // If this is the first user, give the account site admin.
255 + if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
256 obj.users[user._id] = user;
257 obj.db.SetUser(user);
258 obj.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', userid: userid, username: username, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, name is ' + name, domain: domain.id });
@@ -303,7 +303,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
303 var user = { type: 'user', _id: userid, name: shortname, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id };
304 var usercount = 0;
305 for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
306 - if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newaccounts === 2) { domain.newaccounts = 0; } } // If this is the first user, give the account site admin.
306 + if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
307 obj.users[user._id] = user;
308 obj.db.SetUser(user);
309 obj.parent.DispatchEvent(['*', 'server-users'], obj, { etype: 'user', username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msg: 'Account created, name is ' + name, domain: domain.id });
@@ -721,7 +721,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
721 const domain = checkUserIpAddress(req, res);
722 if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap')) { res.sendStatus(401); return; }
723
724 - if ((domain.newaccounts === 0) || (domain.newaccounts === false)) { res.sendStatus(401); return; }
724 + // Check if we are allowed to create new users using the login screen
725 + var domainUserCount = -1;
726 + if ((domain.newaccounts !== 1) && (domain.newaccounts !== true)) {
727 + domainUserCount = 0;
728 + for (var i in obj.users) { if (obj.users[i].domain == domain.id) { domainUserCount++; } }
729 + if (domainUserCount > 0) { res.sendStatus(401); return; }
730 + }
731
732 // Check if this request is for an allows email domain
733 if ((domain.newaccountemaildomains != null) && Array.isArray(domain.newaccountemaildomains)) {
@@ -777,9 +783,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
783 } else {
784 var user = { type: 'user', _id: 'user/' + domain.id + '/' + req.body.username.toLowerCase(), name: req.body.username, email: req.body.email, creation: Math.floor(Date.now() / 1000), login: Math.floor(Date.now() / 1000), domain: domain.id };
785 if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true) && (req.body.apasswordhint)) { var hint = req.body.apasswordhint; if (hint.length > 250) { hint = hint.substring(0, 250); } user.passhint = hint; }
780 - var usercount = 0;
781 - for (var i in obj.users) { if (obj.users[i].domain == domain.id) { usercount++; } }
782 - if (usercount == 0) { user.siteadmin = 0xFFFFFFFF; if (domain.newaccounts === 2) { domain.newaccounts = 0; } } // If this is the first user, give the account site admin.
786 + if (domainUserCount == 0) { user.siteadmin = 0xFFFFFFFF; /*if (domain.newaccounts === 2) { delete domain.newaccounts; }*/ } // If this is the first user, give the account site admin.
787 obj.users[user._id] = user;
788 req.session.userid = user._id;
789 req.session.domainid = domain.id;
@@ -1354,21 +1358,25 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1358 if (msg != null) message = '<p class="msg success">' + msg + '</p>';
1359 var emailcheck = ((obj.parent.mailserver != null) && (domain.auth != 'sspi'));
1360
1361 + // Check if we are allowed to create new users using the login screen
1362 + var newAccountsAllowed = true;
1363 + if ((domain.newaccounts !== 1) && (domain.newaccounts !== true)) { for (var i in obj.users) { if (obj.users[i].domain == domain.id) { newAccountsAllowed = false; break; } } }
1364 +
1365 if (obj.args.minify && !req.query.nominify) {
1366 // Try to server the minified version if we can.
1367 try {
1360 - res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile-min' : 'login-min'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext?encodeURIComponent(domain.welcometext):null });
1368 + res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile-min' : 'login-min'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext?encodeURIComponent(domain.welcometext):null });
1369 } catch (ex) {
1370 // In case of an exception, serve the non-minified version.
1363 - res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1371 + res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1372 }
1373 } else {
1374 // Serve non-minified version of web pages.
1367 - res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1375 + res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1376 }
1377
1378 /*
1371 - var xoptions = { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, footer: (domain.footer == null) ? '' : domain.footer };
1379 + var xoptions = { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: obj.parent.mailserver != null, features: features, footer: (domain.footer == null) ? '' : domain.footer };
1380 var xpath = obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login');
1381 console.log('Render...');
1382 res.render(xpath, xoptions, function (err, html) {