Merge pull request #2939 from nzalev/lastseen

Added Last Seen column to device view
This commit is contained in:
Ylian Saint-Hilaire 2021-07-26 23:39:50 -07:00 committed by GitHub
commit a5ab48242a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 23 deletions

View File

@ -657,17 +657,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
links = parent.GetAllMeshIdWithRights(user); links = parent.GetAllMeshIdWithRights(user);
// Add any nodes with direct rights or any nodes with user group direct rights // Add any nodes with direct rights or any nodes with user group direct rights
if (obj.user.links != null) { extraids = getUserExtraIds();
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); } }
}
}
}
}
} else { } else {
// Request list of all nodes for one specific meshid // Request list of all nodes for one specific meshid
meshid = command.meshid; meshid = command.meshid;
@ -5414,6 +5404,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
'getnetworkinfo': serverCommandGetNetworkInfo, 'getnetworkinfo': serverCommandGetNetworkInfo,
'getsysinfo': serverCommandGetSysInfo, 'getsysinfo': serverCommandGetSysInfo,
'lastconnect': serverCommandLastConnect, 'lastconnect': serverCommandLastConnect,
'lastseen': serverCommandLastSeen,
'meshes': serverCommandMeshes, 'meshes': serverCommandMeshes,
'serverconsole': serverCommandServerConsole, 'serverconsole': serverCommandServerConsole,
'servererrors': serverCommandServerErrors, 'servererrors': serverCommandServerErrors,
@ -5547,6 +5538,31 @@ 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) {
LCs[nodeid] = docs[j].time;
}
}
try { ws.send(JSON.stringify({ action: 'lastseen', lastconnects: LCs })); } catch (ex) { }
});
});
}
function serverCommandMeshes(command) { function serverCommandMeshes(command) {
// Request a list of all meshes this user as rights to // 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) { } try { ws.send(JSON.stringify({ action: 'meshes', meshes: parent.GetAllMeshWithRights(user).map(parent.CloneSafeMesh), tag: command.tag })); } catch (ex) { }
@ -6181,6 +6197,22 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
return true; 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('') + '\"'; } function csvClean(s) { return '\"' + s.split('\"').join('').split(',').join('').split('\r').join('').split('\n').join('') + '\"'; }
// Return detailed information about an array of nodeid's // Return detailed information about an array of nodeid's
@ -6229,18 +6261,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
var links = parent.GetAllMeshIdWithRights(user); var links = parent.GetAllMeshIdWithRights(user);
// Add any nodes with direct rights or any nodes with user group direct rights // Add any nodes with direct rights or any nodes with user group direct rights
var extraids = null; var extraids = getUserExtraIds();
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); } }
}
}
}
}
// Request a list of all nodes // Request a list of all nodes
db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) { db.GetAllTypeNoTypeFieldMeshFiltered(links, extraids, domain.id, 'node', null, function (err, docs) {

View File

@ -1929,6 +1929,7 @@
meshserver.send({ action: 'usergroups' }); meshserver.send({ action: 'usergroups' });
meshserver.send({ action: 'meshes' }); meshserver.send({ action: 'meshes' });
meshserver.send({ action: 'nodes', id: '{{currentNode}}' }); meshserver.send({ action: 'nodes', id: '{{currentNode}}' });
meshserver.send({ action: 'lastseen' });
meshserver.send({ action: 'loginTokens' }); meshserver.send({ action: 'loginTokens' });
if (pluginHandler != null) { meshserver.send({ action: 'plugins' }); } if (pluginHandler != null) { meshserver.send({ action: 'plugins' }); }
if ('{{currentNode}}'.toLowerCase() == '') { meshserver.send({ action: 'files' }); } if ('{{currentNode}}'.toLowerCase() == '') { meshserver.send({ action: 'files' }); }
@ -2291,6 +2292,14 @@
} }
break; 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': { case 'msg': {
// Check if this is a message from a node // Check if this is a message from a node
if (message.nodeid != null) { if (message.nodeid != null) {
@ -3547,6 +3556,7 @@
x += '<label><input id=d2c2 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('user') >= 0)?' checked':'') + '>' + "Logged in users" + '</label><br />'; x += '<label><input id=d2c2 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('user') >= 0)?' checked':'') + '>' + "Logged in users" + '</label><br />';
x += '<label><input id=d2c3 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('ip') >= 0)?' checked':'') + '>' + "Agent IP address" + '</label><br />'; x += '<label><input id=d2c3 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('ip') >= 0)?' checked':'') + '>' + "Agent IP address" + '</label><br />';
x += '<label><input id=d2c4 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('conn') >= 0)?' checked':'') + '>' + "Server Connectivity" + '</label><br />'; x += '<label><input id=d2c4 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('conn') >= 0)?' checked':'') + '>' + "Server Connectivity" + '</label><br />';
x += '<label><input id=d2c7 type=checkbox' + ((deviceViewSettings.devsCols.indexOf('lastseen') >= 0)?' checked':'') + '>' + "Last Seen" + '</label><br />';
setDialogMode(2, "Device View Columns", 3, onDeviceViewSettingsEx, x); setDialogMode(2, "Device View Columns", 3, onDeviceViewSettingsEx, x);
} }
@ -3558,6 +3568,7 @@
if (Q('d2c4').checked) { cols.push('conn'); } if (Q('d2c4').checked) { cols.push('conn'); }
if (Q('d2c5').checked) { cols.push('os'); } if (Q('d2c5').checked) { cols.push('os'); }
if (Q('d2c6').checked) { cols.push('desc'); } if (Q('d2c6').checked) { cols.push('desc'); }
if (Q('d2c7').checked) { cols.push('lastseen'); }
deviceViewSettings.devsCols = cols; deviceViewSettings.devsCols = cols;
putstore('_deviceViewSettings', JSON.stringify(deviceViewSettings)); putstore('_deviceViewSettings', JSON.stringify(deviceViewSettings));
mainUpdate(4); mainUpdate(4);
@ -3973,6 +3984,7 @@
if (deviceViewSettings.devsCols.indexOf('user') >= 0) { colums += '<th style=color:gray;width:120px>' + "User"; } if (deviceViewSettings.devsCols.indexOf('user') >= 0) { colums += '<th style=color:gray;width:120px>' + "User"; }
if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { colums += '<th style=color:gray;width:120px>' + "Address"; } if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { colums += '<th style=color:gray;width:120px>' + "Address"; }
if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { colums += '<th style=color:gray;width:100px>' + "Connectivity"; } if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { colums += '<th style=color:gray;width:100px>' + "Connectivity"; }
if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { colums += '<th style=color:gray;width:120px>' + "Last Seen"; }
// This height of 1 div at the end to fix a problem in Linux firefox browsers // This height of 1 div at the end to fix a problem in Linux firefox browsers
r = '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray>' + colums + r + '</tr></table><div style=height:1px></div>'; r = '<table style=width:100%;margin-top:4px cellpadding=0 cellspacing=0><th style=color:gray>' + colums + r + '</tr></table><div style=height:1px></div>';
@ -4232,6 +4244,7 @@
if (deviceViewSettings.devsCols.indexOf('user') >= 0) { r += '<td style=text-align:center>' + getUserShortStr(node); } // User if (deviceViewSettings.devsCols.indexOf('user') >= 0) { r += '<td style=text-align:center>' + getUserShortStr(node); } // User
if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { r += '<td style=text-align:center>' + (node.ip != null ? node.ip : ''); } // IP address if (deviceViewSettings.devsCols.indexOf('ip') >= 0) { r += '<td style=text-align:center>' + (node.ip != null ? node.ip : ''); } // IP address
if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { r += '<td style=text-align:center>' + states.join('&nbsp;+&nbsp;'); } // Connectivity if (deviceViewSettings.devsCols.indexOf('conn') >= 0) { r += '<td style=text-align:center>' + states.join('&nbsp;+&nbsp;'); } // Connectivity
if (deviceViewSettings.devsCols.indexOf('lastseen') >= 0) { r += '<td style=text-align:center;font-size:x-small>' + ((node.conn & 23 > 0 || node.lastconnect == null) ? '' : printDateTime(new Date(node.lastconnect))); }
div.innerHTML = r; div.innerHTML = r;
} else if ((view == 3) || (view == 5)) { } else if ((view == 3) || (view == 5)) {