From da8947d25e480c6022caa2d3e33a35af7bb0d722 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sat, 24 Jul 2021 21:57:38 -0400 Subject: [PATCH 1/7] Factor out meshuser extraids --- meshuser.js | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/meshuser.js b/meshuser.js index 2d655efa..80efe729 100644 --- a/meshuser.js +++ b/meshuser.js @@ -657,17 +657,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use links = parent.GetAllMeshIdWithRights(user); // Add any nodes with direct rights or any nodes with user group direct rights - if (obj.user.links != null) { - for (var i in obj.user.links) { - if (i.startsWith('node/')) { if (extraids == null) { extraids = []; } extraids.push(i); } - else if (i.startsWith('ugrp/')) { - const g = parent.userGroups[i]; - if ((g != null) && (g.links != null)) { - for (var j in g.links) { if (j.startsWith('node/')) { if (extraids == null) { extraids = []; } extraids.push(j); } } - } - } - } - } + extraids = getUserExtraIds(); } else { // Request list of all nodes for one specific meshid meshid = command.meshid; @@ -6181,6 +6171,22 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use return true; } + function getUserExtraIds() { + var extraids = null; + if (obj.user.links != null) { + for (var i in obj.user.links) { + if (i.startsWith('node/')) { if (extraids == null) { extraids = []; } extraids.push(i); } + else if (i.startsWith('ugrp/')) { + const g = parent.userGroups[i]; + if ((g != null) && (g.links != null)) { + for (var j in g.links) { if (j.startsWith('node/')) { if (extraids == null) { extraids = []; } extraids.push(j); } } + } + } + } + } + return extraids; + } + function csvClean(s) { return '\"' + s.split('\"').join('').split(',').join('').split('\r').join('').split('\n').join('') + '\"'; } // Return detailed information about an array of nodeid's @@ -6229,18 +6235,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use var links = parent.GetAllMeshIdWithRights(user); // Add any nodes with direct rights or any nodes with user group direct rights - var extraids = null; - if (obj.user.links != null) { - for (var i in obj.user.links) { - if (i.startsWith('node/')) { if (extraids == null) { extraids = []; } extraids.push(i); } - else if (i.startsWith('ugrp/')) { - const g = parent.userGroups[i]; - if ((g != null) && (g.links != null)) { - for (var j in g.links) { if (j.startsWith('node/')) { if (extraids == null) { extraids = []; } extraids.push(j); } } - } - } - } - } + var extraids = getUserExtraIds(); // Request a list of all nodes db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) { From 18c367040de0b1a05b6d4ec7c339c6fbca49fff7 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sat, 24 Jul 2021 23:19:10 -0400 Subject: [PATCH 2/7] Added initial last seen handler function --- meshuser.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/meshuser.js b/meshuser.js index 80efe729..0eb9817d 100644 --- a/meshuser.js +++ b/meshuser.js @@ -5404,6 +5404,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 'getnetworkinfo': serverCommandGetNetworkInfo, 'getsysinfo': serverCommandGetSysInfo, 'lastconnect': serverCommandLastConnect, + 'lastseen': serverCommandLastSeen, 'meshes': serverCommandMeshes, 'serverconsole': serverCommandServerConsole, 'servererrors': serverCommandServerErrors, @@ -5537,6 +5538,32 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use }); } + function serverCommandLastSeen(command) { + var links = parent.GetAllMeshIdWithRights(user); + var extraids = getUserExtraIds(); + db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, (err, docs) => { + if (docs == null) { docs = []; } + + // use associative array to join lastconnects on to users's nodes (left join) + var LCs = {} + for (var i in docs) { + LCs[docs[i]._id] = ''; + } + + db.GetAllType('lastconnect', (err, docs) => { + for (var j in docs) { + var nodeid = docs[j]._id.substring(2); + if (LCs[nodeid] != null) { + delete docs[j]._id; + LCs[nodeid] = docs[j]; + } + } + + console.log(LCs); + }); + }); + } + function serverCommandMeshes(command) { // Request a list of all meshes this user as rights to try { ws.send(JSON.stringify({ action: 'meshes', meshes: parent.GetAllMeshWithRights(user).map(parent.CloneSafeMesh), tag: command.tag })); } catch (ex) { } From b3be0120fa0c48980be8f6a9c31e7022fe7a2506 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sat, 24 Jul 2021 23:55:07 -0400 Subject: [PATCH 3/7] Added client side handler for lastseen --- meshuser.js | 5 ++--- views/default.handlebars | 8 ++++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/meshuser.js b/meshuser.js index 0eb9817d..30d50cf8 100644 --- a/meshuser.js +++ b/meshuser.js @@ -5554,12 +5554,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use for (var j in docs) { var nodeid = docs[j]._id.substring(2); if (LCs[nodeid] != null) { - delete docs[j]._id; - LCs[nodeid] = docs[j]; + LCs[nodeid] = docs[j].time; } } - console.log(LCs); + try { ws.send(JSON.stringify({ action: 'lastseen', lastconnects: LCs })); } catch (ex) { } }); }); } diff --git a/views/default.handlebars b/views/default.handlebars index 8ba5b988..b47fd4c1 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2291,6 +2291,14 @@ } break; } + case 'lastseen': { + var lcnodes = Object.keys(message.lastconnects); + for (var i in lcnodes) { + var lcnodeid = lcnodes[i]; + var node = getNodeFromId(lcnodeid); + if (node != null) { node.lastconnect = message.lastconnects[lcnodeid] } + } + } case 'msg': { // Check if this is a message from a node if (message.nodeid != null) { From c4f8426da35ef3c0d061277abe9fd7c3cf595805 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 25 Jul 2021 01:23:37 -0400 Subject: [PATCH 4/7] Added last seen column --- views/default.handlebars | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/views/default.handlebars b/views/default.handlebars index b47fd4c1..c62ce9e4 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -3555,6 +3555,7 @@ x += '
'; x += '
'; x += '
'; + x += '
'; setDialogMode(2, "Device View Columns", 3, onDeviceViewSettingsEx, x); } @@ -3566,6 +3567,7 @@ if (Q('d2c4').checked) { cols.push('conn'); } if (Q('d2c5').checked) { cols.push('os'); } if (Q('d2c6').checked) { cols.push('desc'); } + if (Q('d2c7').checked) { cols.push('lastseen'); } deviceViewSettings.devsCols = cols; putstore('_deviceViewSettings', JSON.stringify(deviceViewSettings)); mainUpdate(4); @@ -3981,6 +3983,7 @@ if (deviceViewSettings.devsCols.indexOf('user') >= 0) { colums += '' + "User"; } if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { colums += '' + "Address"; } if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { colums += '' + "Connectivity"; } + if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { colums += '' + "Last Seen"; } // This height of 1 div at the end to fix a problem in Linux firefox browsers r = '
' + colums + r + '
'; @@ -4240,6 +4243,7 @@ if (deviceViewSettings.devsCols.indexOf('user') >= 0) { r += '' + getUserShortStr(node); } // User if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { r += '' + (node.ip != null ? node.ip : ''); } // IP address if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { r += '' + states.join(' + '); } // Connectivity + if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { r += '' + ((node.conn & 23 > 0) ? '' : printDateTime(new Date(node.lastconnect))); } div.innerHTML = r; } else if ((view == 3) || (view == 5)) { From 3cf61c609ffa509f9427eff67a251e37930f9c9d Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 25 Jul 2021 01:52:39 -0400 Subject: [PATCH 5/7] Load last seen data on page load --- views/default.handlebars | 1 + 1 file changed, 1 insertion(+) diff --git a/views/default.handlebars b/views/default.handlebars index c62ce9e4..422ea4d9 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1929,6 +1929,7 @@ meshserver.send({ action: 'usergroups' }); meshserver.send({ action: 'meshes' }); meshserver.send({ action: 'nodes', id: '{{currentNode}}' }); + meshserver.send({ action: 'lastseen' }); meshserver.send({ action: 'loginTokens' }); if (pluginHandler != null) { meshserver.send({ action: 'plugins' }); } if ('{{currentNode}}'.toLowerCase() == '') { meshserver.send({ action: 'files' }); } From 492e71e2b55334336b68c456f8ae2db9b03a6d1e Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 25 Jul 2021 02:51:43 -0400 Subject: [PATCH 6/7] Added guard before setting last seen date --- views/default.handlebars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/default.handlebars b/views/default.handlebars index 422ea4d9..e9c7dff3 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -4244,7 +4244,7 @@ if (deviceViewSettings.devsCols.indexOf('user') >= 0) { r += '' + getUserShortStr(node); } // User if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { r += '' + (node.ip != null ? node.ip : ''); } // IP address if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { r += '' + states.join(' + '); } // Connectivity - if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { r += '' + ((node.conn & 23 > 0) ? '' : printDateTime(new Date(node.lastconnect))); } + if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { r += '' + ((node.conn & 23 > 0 || node.lastconnect != null) ? '' : printDateTime(new Date(node.lastconnect))); } div.innerHTML = r; } else if ((view == 3) || (view == 5)) { From 8d1e4a046b3c16c5334e4ccf013f3d0c11914021 Mon Sep 17 00:00:00 2001 From: Noah Zalev Date: Sun, 25 Jul 2021 02:54:14 -0400 Subject: [PATCH 7/7] Fixed typo in guard --- views/default.handlebars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/default.handlebars b/views/default.handlebars index e9c7dff3..962eb380 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -4244,7 +4244,7 @@ if (deviceViewSettings.devsCols.indexOf('user') >= 0) { r += '' + getUserShortStr(node); } // User if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { r += '' + (node.ip != null ? node.ip : ''); } // IP address if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { r += '' + states.join(' + '); } // Connectivity - if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { r += '' + ((node.conn & 23 > 0 || node.lastconnect != null) ? '' : printDateTime(new Date(node.lastconnect))); } + if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { r += '' + ((node.conn & 23 > 0 || node.lastconnect == null) ? '' : printDateTime(new Date(node.lastconnect))); } div.innerHTML = r; } else if ((view == 3) || (view == 5)) {