More work on server device paging.

Ylian Saint-Hilaire committed Aug 31, 2022 at 11:54 UTC 46e7464b49a62921e6fab76597aa55fac44bc20c
4 files changed +25 -3
meshcentral-config-schema.json
+1
@@ -341,6 +341,7 @@
341 "loginPicture": { "type": "string", "default": null, "description": "Web site .png logo file placed in meshcentral-data that used on the login page when sitestyle is 2." },
342 "rootRedirect": { "type": "string", "default": null, "description": "Redirects HTTP root requests to this URL. When in use, direct users to /login to see the normal login page." },
343 "mobileSite": { "type": "boolean", "default": true, "description": "When set to false, this setting will disable the mobile site." },
344 + "maxDeviceView": { "type": "integer", "default": null, "description": "The maximum number of devices a user can see on the devices page at the same time. By default all devices will show, but this may need to be limited on servers with large number of devices." },
345 "unknownUserRootRedirect": { "type": "string", "default": null, "description": "Redirects HTTP root requests to this URL only where user is not already logged in. When in use, direct users to /login to see the normal login page." },
346 "nightMode": { "type": "integer", "default": 0, "description": "0 = User selects day/night mode, 1 = Always night mode, 2 = Always day mode" },
347 "userQuota": { "type": "integer" },
meshcentral.js
+1
@@ -1278,6 +1278,7 @@ function CreateMeshCentralServer(config, args) {
1278 if (obj.config.domains[i].limits == null) { obj.config.domains[i].limits = {}; }
1279 if (obj.config.domains[i].dns == null) { obj.config.domains[i].url = (i == '') ? '/' : ('/' + i + '/'); } else { obj.config.domains[i].url = '/'; }
1280 obj.config.domains[i].id = i;
1281 + if ((typeof obj.config.domains[i].maxdeviceview != 'number') || (obj.config.domains[i].maxdeviceview < 1)) { delete obj.config.domains[i].maxdeviceview; }
1282 if (typeof obj.config.domains[i].loginkey == 'string') { obj.config.domains[i].loginkey = [obj.config.domains[i].loginkey]; }
1283 if ((obj.config.domains[i].loginkey != null) && (obj.common.validateAlphaNumericArray(obj.config.domains[i].loginkey, 1, 128) == false)) { console.log("ERROR: Invalid login key, must be alpha-numeric string with no spaces."); process.exit(); return; }
1284 if (typeof obj.config.domains[i].agentkey == 'string') { obj.config.domains[i].agentkey = [obj.config.domains[i].agentkey]; }
meshuser.js
+22 -3
@@ -109,6 +109,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
109 obj.deviceSkip = 0; // How many devices to skip
110 obj.deviceLimit = 0; // How many devices to view
111 obj.visibleDevices = null; // An object of visible nodeid's if the user is in paging mode
112 + if (domain.maxdeviceview != null) { obj.deviceLimit = domain.maxdeviceview; obj.visibleDevices = {}; }
113
114 // Check if we are a cross-domain administrator
115 if (parent.parent.config.settings.managecrossdomain && (parent.parent.config.settings.managecrossdomain.indexOf(user._id) >= 0)) { obj.crossDomain = true; }
@@ -613,6 +614,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
614 }
615 serverinfo.preConfiguredScripts = r;
616 }
617 + if (domain.maxdeviceview != null) { serverinfo.maxdeviceview = domain.maxdeviceview; } // Maximum number of devices a user can view at any given time
618
619 // Send server information
620 try { ws.send(JSON.stringify({ action: 'serverinfo', serverinfo: serverinfo })); } catch (ex) { }
@@ -675,6 +677,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
677 switch (command.action) {
678 case 'nodes':
679 {
680 + // If in paging mode, look to set the skip and limit values
681 + if (obj.visibleDevices != null) {
682 + if ((typeof command.skip == 'number') && (command.skip >= 0)) { obj.deviceSkip = command.skip; }
683 + if ((typeof command.limit == 'number') && (command.limit > 0)) { obj.deviceLimit = command.limit; }
684 + if ((domain.maxdeviceview != null) && (obj.deviceLimit > domain.maxdeviceview)) { obj.deviceLimit = domain.maxdeviceview; }
685 + }
686 +
687 var links = [], extraids = null, err = null;
688
689 // Resolve the device group name if needed
@@ -721,7 +730,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
730 if (docs == null) { docs = []; }
731 parent.common.unEscapeAllLinksFieldName(docs);
732
724 - var r = {};
733 + var r = {}, nodeCount = docs.length;
734 if (obj.visibleDevices != null) { obj.visibleDevices = {}; }
735 for (i in docs) {
736 // Check device links, if a link points to an unknown user, remove it.
@@ -805,9 +814,19 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
814 // If in paging mode, report back the skip and limit values
815 response.skip = obj.deviceSkip;
816 response.limit = obj.deviceLimit;
808 - // TODO: Add total device count
817 +
818 + // Add total device count
819 + if (nodeCount < response.limit) {
820 + response.totalcount = obj.deviceSkip + nodeCount;
821 + try { ws.send(JSON.stringify(response)); } catch (ex) { }
822 + } else {
823 + // TODO
824 + //console.log('response.totalcount', '???');
825 + try { ws.send(JSON.stringify(response)); } catch (ex) { }
826 + }
827 + } else {
828 + try { ws.send(JSON.stringify(response)); } catch (ex) { }
829 }
810 - try { ws.send(JSON.stringify(response)); } catch (ex) { }
830 });
831 break;
832 }
sample-config-advanced.json
+1
@@ -180,6 +180,7 @@
180 "_loginPicture": "title-sample.png",
181 "_rootRedirect": "https://www.youtube.com/watch?v=Gs069dndIYk",
182 "_mobileSite": false,
183 + "_maxDeviceView": 1000,
184 "_unknownUserRootRedirect": "https://www.youtube.com/watch?v=2Q_ZzBGPdqE",
185 "_nightMode": 1,
186 "_userQuota": 1048576,