mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	Partial support for device paging support on the server side, allows a user to view only a subset of the devices.
This commit is contained in:
		
							parent
							
								
									d4d1f7d454
								
							
						
					
					
						commit
						15c882f24e
					
				
					 2 changed files with 139 additions and 44 deletions
				
			
		
							
								
								
									
										132
									
								
								meshuser.js
									
										
									
									
									
								
							
							
						
						
									
										132
									
								
								meshuser.js
									
										
									
									
									
								
							|  | @ -105,6 +105,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|     obj.domain = domain; | ||||
|     obj.ws = ws; | ||||
| 
 | ||||
|     // Information related to the current page the user is looking at
 | ||||
|     obj.deviceSkip = 0; // How many devices to skip
 | ||||
|     obj.deviceLimit = 0; // How many devices to view
 | ||||
|     obj.visibleDevices = null; // An object of visible nodeid's if the user is in paging mode
 | ||||
| 
 | ||||
|     // Check if we are a cross-domain administrator
 | ||||
|     if (parent.parent.config.settings.managecrossdomain && (parent.parent.config.settings.managecrossdomain.indexOf(user._id) >= 0)) { obj.crossDomain = true; } | ||||
| 
 | ||||
|  | @ -414,6 +419,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|                 // If this session is logged in using a loginToken and the token is removed, disconnect.
 | ||||
|                 if ((req.session.loginToken != null) && (typeof event == 'object') && (event.action == 'loginTokenChanged') && (event.removed != null) && (event.removed.indexOf(req.session.loginToken) >= 0)) { delete req.session; obj.close(); return; } | ||||
| 
 | ||||
|                 // If this user is not viewing all devices and paging, check if this event is in the current page
 | ||||
|                 if (isEventWithinPage(ids) == false) return; | ||||
| 
 | ||||
|                 // Normally, only allow this user to receive messages from it's own domain.
 | ||||
|                 // If the user is a cross domain administrator, allow some select messages from different domains.
 | ||||
|                 if ((event.domain == null) || (event.domain == domain.id) || ((obj.crossDomain === true) && (allowedCrossDomainMessages.indexOf(event.action) >= 0))) { | ||||
|  | @ -706,7 +714,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|                     } | ||||
| 
 | ||||
|                     // Request a list of all nodes
 | ||||
|                     db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', command.id, function (err, docs) { | ||||
|                     db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', command.id, obj.deviceSkip, obj.deviceLimit, function (err, docs) { | ||||
| 
 | ||||
|                         //console.log(err, docs, links, extraids, domain.id, 'node', command.id);
 | ||||
| 
 | ||||
|  | @ -714,10 +722,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|                         parent.common.unEscapeAllLinksFieldName(docs); | ||||
| 
 | ||||
|                         var r = {}; | ||||
|                         if (obj.visibleDevices != null) { obj.visibleDevices = {}; } | ||||
|                         for (i in docs) { | ||||
|                             // Check device links, if a link points to an unknown user, remove it.
 | ||||
|                             parent.cleanDevice(docs[i]); | ||||
| 
 | ||||
|                             // If we are paging, add the device to the page here
 | ||||
|                             if (obj.visibleDevices != null) { obj.visibleDevices[docs[i]._id] = 1; } | ||||
| 
 | ||||
|                             // Remove any connectivity and power state information, that should not be in the database anyway.
 | ||||
|                             // TODO: Find why these are sometimes saved in the db.
 | ||||
|                             if (docs[i].conn != null) { delete docs[i].conn; } | ||||
|  | @ -788,7 +800,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
| 
 | ||||
|                             r[meshid].push(docs[i]); | ||||
|                         } | ||||
|                         try { ws.send(JSON.stringify({ action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag })); } catch (ex) { } | ||||
|                         const response = { action: 'nodes', responseid: command.responseid, nodes: r, tag: command.tag }; | ||||
|                         if (obj.visibleDevices != null) { | ||||
|                             // If in paging mode, report back the skip and limit values
 | ||||
|                             response.skip = obj.deviceSkip; | ||||
|                             response.limit = obj.deviceLimit; | ||||
|                             // TODO: Add total device count
 | ||||
|                         } | ||||
|                         try { ws.send(JSON.stringify(response)); } catch (ex) { } | ||||
|                     }); | ||||
|                     break; | ||||
|                 } | ||||
|  | @ -6128,14 +6147,30 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|     } | ||||
| 
 | ||||
|     function serverCommandLastConnects(command) { | ||||
|         const links = parent.GetAllMeshIdWithRights(user); | ||||
|         const extraids = getUserExtraIds(); | ||||
|         db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) { | ||||
|             if (docs == null) return; | ||||
|         if (obj.visibleDevices == null) { | ||||
|             // If we are not paging, get all devices visible to this user
 | ||||
|             const links = parent.GetAllMeshIdWithRights(user); | ||||
|             const extraids = getUserExtraIds(); | ||||
|             db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, obj.deviceSkip, obj.deviceLimit, function (err, docs) { | ||||
|                 if (docs == null) return; | ||||
| 
 | ||||
|                 // Create a list of node ids for this user and query them for last device connection time
 | ||||
|                 const ids = [] | ||||
|                 for (var i in docs) { ids.push('lc' + docs[i]._id); } | ||||
| 
 | ||||
|                 // Pull list of last connections only for device owned by this user
 | ||||
|                 db.GetAllIdsOfType(ids, domain.id, 'lastconnect', function (err, docs) { | ||||
|                     if (docs == null) return; | ||||
|                     const response = {}; | ||||
|                     for (var j in docs) { response[docs[j]._id.substring(2)] = docs[j].time; } | ||||
|                     obj.send({ action: 'lastconnects', lastconnects: response, tag: command.tag }); | ||||
|                 }); | ||||
|             }); | ||||
|         } else { | ||||
|             // If we are paging, we know what devices the user is look at
 | ||||
|             // Create a list of node ids for this user and query them for last device connection time
 | ||||
|             const ids = [] | ||||
|             for (var i in docs) { ids.push('lc' + docs[i]._id); } | ||||
|             for (var i in obj.visibleDevices) { ids.push('lc' + i); } | ||||
| 
 | ||||
|             // Pull list of last connections only for device owned by this user
 | ||||
|             db.GetAllIdsOfType(ids, domain.id, 'lastconnect', function (err, docs) { | ||||
|  | @ -6144,7 +6179,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|                 for (var j in docs) { response[docs[j]._id.substring(2)] = docs[j].time; } | ||||
|                 obj.send({ action: 'lastconnects', lastconnects: response, tag: command.tag }); | ||||
|             }); | ||||
|         }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function serverCommandLoginCookie(command) { | ||||
|  | @ -7505,22 +7540,62 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
| 
 | ||||
|     // Return detailed information about all nodes this user has access to
 | ||||
|     function getAllDeviceDetailedInfo(type, func) { | ||||
|         // Get all device groups this user has access to
 | ||||
|         var links = parent.GetAllMeshIdWithRights(user); | ||||
|         // If we are not paging, get all devices visible to this user
 | ||||
|         if (obj.visibleDevices == null) { | ||||
| 
 | ||||
|         // Add any nodes with direct rights or any nodes with user group direct rights
 | ||||
|         var extraids = getUserExtraIds(); | ||||
|             // Get all device groups this user has access to
 | ||||
|             var links = parent.GetAllMeshIdWithRights(user); | ||||
| 
 | ||||
|         // Request a list of all nodes
 | ||||
|         db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) { | ||||
|             if (docs == null) { docs = []; } | ||||
|             parent.common.unEscapeAllLinksFieldName(docs); | ||||
|             // Add any nodes with direct rights or any nodes with user group direct rights
 | ||||
|             var extraids = getUserExtraIds(); | ||||
| 
 | ||||
|             var results = [], resultPendingCount = 0; | ||||
|             for (i in docs) { | ||||
|                 // Check device links, if a link points to an unknown user, remove it.
 | ||||
|                 parent.cleanDevice(docs[i]); | ||||
|             // Request a list of all nodes
 | ||||
|             db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, obj.deviceSkip, obj.deviceLimit, function (err, docs) { | ||||
|                 if (docs == null) { docs = []; } | ||||
|                 parent.common.unEscapeAllLinksFieldName(docs); | ||||
| 
 | ||||
|                 var results = [], resultPendingCount = 0; | ||||
|                 for (i in docs) { | ||||
|                     // Check device links, if a link points to an unknown user, remove it.
 | ||||
|                     parent.cleanDevice(docs[i]); | ||||
| 
 | ||||
|                     // Fetch the node from the database
 | ||||
|                     resultPendingCount++; | ||||
|                     const getNodeFunc = function (node, rights, visible) { | ||||
|                         if ((node != null) && (visible == true)) { | ||||
|                             const getNodeSysInfoFunc = function (err, docs) { | ||||
|                                 const getNodeNetInfoFunc = function (err, docs) { | ||||
|                                     var netinfo = null; | ||||
|                                     if ((err == null) && (docs != null) && (docs.length == 1)) { netinfo = docs[0]; } | ||||
|                                     resultPendingCount--; | ||||
|                                     getNodeNetInfoFunc.results.push({ node: parent.CloneSafeNode(getNodeNetInfoFunc.node), sys: getNodeNetInfoFunc.sysinfo, net: netinfo }); | ||||
|                                     if (resultPendingCount == 0) { func(getNodeFunc.results, type); } | ||||
|                                 } | ||||
|                                 getNodeNetInfoFunc.results = getNodeSysInfoFunc.results; | ||||
|                                 getNodeNetInfoFunc.nodeid = getNodeSysInfoFunc.nodeid; | ||||
|                                 getNodeNetInfoFunc.node = getNodeSysInfoFunc.node; | ||||
|                                 if ((err == null) && (docs != null) && (docs.length == 1)) { getNodeNetInfoFunc.sysinfo = docs[0]; } | ||||
| 
 | ||||
|                                 // Query the database for network information
 | ||||
|                                 db.Get('if' + getNodeSysInfoFunc.nodeid, getNodeNetInfoFunc); | ||||
|                             } | ||||
|                             getNodeSysInfoFunc.results = getNodeFunc.results; | ||||
|                             getNodeSysInfoFunc.nodeid = getNodeFunc.nodeid; | ||||
|                             getNodeSysInfoFunc.node = node; | ||||
| 
 | ||||
|                             // Query the database for system information
 | ||||
|                             db.Get('si' + getNodeFunc.nodeid, getNodeSysInfoFunc); | ||||
|                         } else { resultPendingCount--; } | ||||
|                         if (resultPendingCount == 0) { func(getNodeFunc.results.join('\r\n'), type); } | ||||
|                     } | ||||
|                     getNodeFunc.results = results; | ||||
|                     getNodeFunc.nodeid = docs[i]._id; | ||||
|                     parent.GetNodeWithRights(domain, user, docs[i]._id, getNodeFunc); | ||||
|                 } | ||||
|             }); | ||||
|         } else { | ||||
|             // If we are paging, we know what devices the user is look at
 | ||||
|             for (var id in obj.visibleDevices) { | ||||
|                 // Fetch the node from the database
 | ||||
|                 resultPendingCount++; | ||||
|                 const getNodeFunc = function (node, rights, visible) { | ||||
|  | @ -7551,10 +7626,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|                     if (resultPendingCount == 0) { func(getNodeFunc.results.join('\r\n'), type); } | ||||
|                 } | ||||
|                 getNodeFunc.results = results; | ||||
|                 getNodeFunc.nodeid = docs[i]._id; | ||||
|                 parent.GetNodeWithRights(domain, user, docs[i]._id, getNodeFunc); | ||||
|                 getNodeFunc.nodeid = id; | ||||
|                 parent.GetNodeWithRights(domain, user, id, getNodeFunc); | ||||
|             } | ||||
|         }); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // Display a notification message for this session only.
 | ||||
|  | @ -7721,5 +7796,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use | |||
|         return authFactorCount; | ||||
|     } | ||||
| 
 | ||||
|     // Return true if the event is for a device that is part of the currently visible page
 | ||||
|     function isEventWithinPage(ids) { | ||||
|         if (obj.visibleDevices == null) return true; // Add devices are visible
 | ||||
|         var r = true; | ||||
|         for (var i in ids) { | ||||
|             // If the event is for a visible device, return true
 | ||||
|             if (ids[i].startsWith('node/')) { r = false; if (obj.visibleDevices[ids[i]] != null) return true; } | ||||
|         } | ||||
|         return r; // If this event is not for any specific device, return true
 | ||||
|     } | ||||
| 
 | ||||
|     return obj; | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue