Fixed default session renew timer.

Ylian Saint-Hilaire committed Jan 5, 2021 at 23:38 UTC 0e697167e9b0b2815f89305a3da2deb8e00a5e47
6 files changed +66 -10
meshcentral-config-schema.json
+2 -2
@@ -15,7 +15,7 @@
15 "WANonly": { "type": "boolean", "default": false, "description": "When enabled, only MeshCentral WAN features are enabled and agents will connect to the server using a well known DNS name." },
16 "LANonly": { "type": "boolean", "default": false, "description": "When enabled, only MeshCentral LAN features are enabled and agents will find the server using multicast LAN packets." },
17 "maintenanceMode": { "type": "boolean", "default": false, "description": "When enabled the server is in maintenance mode, only administrators can login. Use the maintenance command in server console to change." },
18 - "sessionTime": { "type": "integer" },
18 + "sessionTime": { "type": "integer", "default": 60, "description": "Duration of a session cookie in minutes. Changing this affects how often the session needs to be automatically refreshed." },
19 "sessionKey": { "type": "string" },
20 "sessionSameSite": { "type": "string" },
21 "dbEncryptKey": { "type": "string" },
@@ -273,7 +273,7 @@
273 "userBlockedIP": { "type": "string" },
274 "agentAllowedIP": { "type": "string" },
275 "agentBlockedIP": { "type": "string" },
276 - "userSessionIdleTimeout": { "type": "integer" },
276 + "userSessionIdleTimeout": { "type": "integer", "default": null, "description": "When set, idle users will be disconnected after a set amounts of minutes." },
277 "userConsentFlags": {
278 "type": "object",
279 "additionalProperties": false,
meshcentral.js
+1
@@ -1543,6 +1543,7 @@ function CreateMeshCentralServer(config, args) {
1543 for (var i in obj.mpsserver.ciraConnections) { data.conn.am += obj.mpsserver.ciraConnections[i].length; }
1544 }
1545 if (obj.firstStats === true) { delete obj.firstStats; data.first = true; }
1546 + if (obj.multiServer != null) { data.s = obj.multiServer.serverid; }
1547 obj.db.SetServerStats(data); // Save the stats to the database
1548 obj.DispatchEvent(['*'], obj, { action: 'servertimelinestats', data: data }); // Event the server stats
1549 }, 300000);
meshuser.js
+1 -3
@@ -558,9 +558,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
558 if ((user.siteadmin & 21) == 0) return; // Only site administrators with "site backup" or "site restore" or "site update" permissions can use this.
559 if (common.validateInt(command.hours, 0, 24 * 30) == false) return;
560 db.GetServerStats(command.hours, function (err, docs) {
561 - if (err == null) {
562 - try { ws.send(JSON.stringify({ action: 'servertimelinestats', events: docs })); } catch (ex) { }
563 - }
561 + if (err == null) { try { ws.send(JSON.stringify({ action: 'servertimelinestats', events: docs })); } catch (ex) { } }
562 });
563 break;
564 }
sample-config-advanced.json
-1
@@ -9,7 +9,6 @@
9 "_mongoDumpPath": "C:\\Program Files\\MongoDB\\Server\\4.2\\bin\\mongodump.exe",
10 "_WANonly": true,
11 "_LANonly": true,
12 - "_sessionTime": 30,
12 "_sessionKey": "MyReallySecretPassword1",
13 "_sessionSameSite": "strict",
14 "_dbEncryptKey": "MyReallySecretPassword2",
views/default.handlebars
+34 -2
@@ -994,6 +994,8 @@
994 <div id="p40title"><h1>My Server Stats</h1></div>
995 <div class="areaHead">
996 <div class="toright2">
997 + <select id=p40server style="display:none" onchange=updateServerTimelineStats()>
998 + </select>&nbsp;
999 <select id=p40type onchange=updateServerTimelineStats()>
1000 <option value=0>Connections</option>
1001 <option value=1>Memory</option>
@@ -1248,7 +1250,7 @@
1250 <audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3" /></audio>
1251 <iframe style=display:none name="fileDownloadFrame"></iframe>
1252 </div>
1251 - <script type="text/javascript" nonce="abc">
1253 + <script type="text/javascript">
1254 'use strict';
1255
1256 // Process server-side web state
@@ -13377,6 +13379,15 @@
13379 function setServerTimelineStats(stats) { serverTimelineStats = stats; updateServerTimelineStats(); }
13380 function addServerTimelineStats(stats) {
13381 if (serverTimelineStats == null) return;
13382 +
13383 + // Check if this new data is for our selected server
13384 + var selectedServer = null;
13385 + if (Q('p40server').value != null) {
13386 + selectedServer = decodeURIComponent(Q('p40server').value);
13387 + if (selectedServer == "") { selectedServer = null; }
13388 + }
13389 + if (stats.s != selectedServer) return;
13390 +
13391 serverTimelineStats.push(stats);
13392 var chartType = Q('p40type').value;
13393 if (chartType == 0) {
@@ -13406,7 +13417,8 @@
13417 function setupServerTimelineStats() { window.serverMainStats = new Chart(document.getElementById('serverMainStats').getContext('2d'), serverTimelineConfig); }
13418
13419 function updateServerTimelineStats() {
13409 - var data, chartType = Q('p40type').value, timeAfter = pastDate(Q('p40time').value);
13420 + var data, chartType = Q('p40type').value, timeAfter = pastDate(Q('p40time').value), servers = [], selectedServer = null, serverEmptyExists = false, serverAutoSelect = true;
13421 + if (Q('p40server').value != null) { selectedServer = decodeURIComponent(Q('p40server').value); if (selectedServer == "") { selectedServer = null; } serverAutoSelect = false; }
13422 serverTimelineConfig.options.scales.xAxes[0].time = { min: timeAfter };
13423 if (chartType == 0) { // Connections
13424 serverTimelineConfig.options.scales.yAxes[0].scaleLabel.labelString = "Connection Count";
@@ -13422,6 +13434,12 @@
13434 };
13435 for (var i = 0; i < serverTimelineStats.length; i++) {
13436 var t = new Date(serverTimelineStats[i].time);
13437 + if ((serverTimelineStats[i].s != null) && (servers.indexOf(serverTimelineStats[i].s) == -1)) {
13438 + servers.push(serverTimelineStats[i].s);
13439 + if (serverAutoSelect) { selectedServer = serverTimelineStats[i].s; serverAutoSelect = false; }
13440 + }
13441 + if (serverTimelineStats[i].s == null) { serverEmptyExists = true; }
13442 + if (serverTimelineStats[i].s != selectedServer) { continue; }
13443 if (serverTimelineStats[i].first == true) {
13444 data.datasets[0].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
13445 data.datasets[1].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
@@ -13449,6 +13467,12 @@
13467 ]
13468 };
13469 for (var i = 0; i < serverTimelineStats.length; i++) {
13470 + if ((serverTimelineStats[i].s != null) && (servers.indexOf(serverTimelineStats[i].s) == -1)) {
13471 + servers.push(serverTimelineStats[i].s);
13472 + if (serverAutoSelect) { selectedServer = serverTimelineStats[i].s; serverAutoSelect = false; }
13473 + }
13474 + if (serverTimelineStats[i].s == null) { serverEmptyExists = true; }
13475 + if (serverTimelineStats[i].s != selectedServer) { continue; }
13476 if (serverTimelineStats[i].first == true) {
13477 data.datasets[0].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
13478 data.datasets[1].data.push({ x: serverTimelineStats[i].time - 1, y: NaN });
@@ -13480,6 +13504,14 @@
13504 }*/
13505 serverTimelineConfig.data = data;
13506 window.serverMainStats.update();
13507 +
13508 + if (servers.length > 0) {
13509 + var x = '';
13510 + for (var i = 0; i < servers.length; i++) { x += '<option value="' + encodeURIComponentEx(servers[i]) + '"' + ((selectedServer == servers[i])?' selected':'') + '>' + EscapeHtml(servers[i]) + '</option>'; }
13511 + if (serverEmptyExists) { x += '<option value=""' + ((selectedServer == null)?' selected':'') + '>' + "Null" + '</option>'; }
13512 + QH('p40server', x);
13513 + }
13514 + QV('p40server', servers.length > 0);
13515 }
13516
13517 function p40downloadEvents() {
webserver.js
+28 -2
@@ -2458,7 +2458,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2458 serverfeatures: serverFeatures,
2459 features: features,
2460 features2: features2,
2461 - sessiontime: args.sessiontime,
2461 + sessiontime: (args.sessiontime) ? args.sessiontime : 60,
2462 mpspass: args.mpspass,
2463 passRequirements: passRequirements,
2464 customui: customui,
@@ -2562,7 +2562,33 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2562 if (domain.customui != null) { customui = encodeURIComponent(JSON.stringify(domain.customui)); }
2563
2564 // Render the login page
2565 - render(req, res, getRenderPage((domain.sitestyle == 2) ? 'login2' : 'login', req, domain), getRenderArgs({ loginmode: loginmode, rootCertLink: getRootCertLink(), newAccount: newAccountsAllowed, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, passlogin: (typeof domain.showpasswordlogin == 'boolean') ? domain.showpasswordlogin : true, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, customui: customui, footer: (domain.loginfooter == null) ? '' : domain.loginfooter, hkey: encodeURIComponent(hardwareKeyChallenge).replace(/'/g, '%27'), messageid: msgid, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext).split('\'').join('\\\'') : null, hwstate: hwstate, otpemail: otpemail, otpsms: otpsms, twoFactorCookieDays: twoFactorCookieDays, authStrategies: authStrategies.join(','), loginpicture: (typeof domain.loginpicture == 'string') }, req, domain, (domain.sitestyle == 2) ? 'login2' : 'login'));
2565 + render(req, res,
2566 + getRenderPage((domain.sitestyle == 2) ? 'login2' : 'login', req, domain),
2567 + getRenderArgs({
2568 + loginmode: loginmode,
2569 + rootCertLink: getRootCertLink(),
2570 + newAccount: newAccountsAllowed,
2571 + newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1),
2572 + serverDnsName: obj.getWebServerName(domain),
2573 + serverPublicPort: httpsPort,
2574 + passlogin: (typeof domain.showpasswordlogin == 'boolean') ? domain.showpasswordlogin : true,
2575 + emailcheck: emailcheck,
2576 + features: features,
2577 + sessiontime: (args.sessiontime) ? args.sessiontime : 60,
2578 + passRequirements: passRequirements,
2579 + customui: customui,
2580 + footer: (domain.loginfooter == null) ? '' : domain.loginfooter,
2581 + hkey: encodeURIComponent(hardwareKeyChallenge).replace(/'/g, '%27'),
2582 + messageid: msgid,
2583 + passhint: passhint,
2584 + welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext).split('\'').join('\\\'') : null,
2585 + hwstate: hwstate,
2586 + otpemail: otpemail,
2587 + otpsms: otpsms,
2588 + twoFactorCookieDays: twoFactorCookieDays,
2589 + authStrategies: authStrategies.join(','),
2590 + loginpicture: (typeof domain.loginpicture == 'string')
2591 + }, req, domain, (domain.sitestyle == 2) ? 'login2' : 'login'));
2592 }
2593
2594 // Handle a post request on the root