Added ListEvents to MeshCtrl.js

Ylian Saint-Hilaire committed Feb 2, 2021 at 18:01 UTC 5fd93b7b4115103ccaad98b59128ccf1e85b3ce2
2 files changed +104 -7
meshctrl.js
+94 -5
@@ -7,7 +7,7 @@ try { require('ws'); } catch (ex) { console.log('Missing module "ws", type "npm
7 var settings = {};
8 const crypto = require('crypto');
9 const args = require('minimist')(process.argv.slice(2));
10 -const possibleCommands = ['edituser', 'listusers', 'listusersessions', 'listdevicegroups', 'listdevices', 'listusersofdevicegroup', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'editdevicegroup', 'broadcast', 'showevents', 'addusertodevicegroup', 'removeuserfromdevicegroup', 'addusertodevice', 'removeuserfromdevice', 'sendinviteemail', 'generateinvitelink', 'config', 'movetodevicegroup', 'deviceinfo', 'addusergroup', 'listusergroups', 'removeusergroup', 'runcommand', 'shell', 'upload', 'download', 'deviceopenurl', 'devicemessage', 'devicetoast', 'addtousergroup', 'removefromusergroup', 'removeallusersfromusergroup', 'devicesharing', 'devicepower'];
10 +const possibleCommands = ['edituser', 'listusers', 'listusersessions', 'listdevicegroups', 'listdevices', 'listusersofdevicegroup', 'listevents', 'serverinfo', 'userinfo', 'adduser', 'removeuser', 'adddevicegroup', 'removedevicegroup', 'editdevicegroup', 'broadcast', 'showevents', 'addusertodevicegroup', 'removeuserfromdevicegroup', 'addusertodevice', 'removeuserfromdevice', 'sendinviteemail', 'generateinvitelink', 'config', 'movetodevicegroup', 'deviceinfo', 'addusergroup', 'listusergroups', 'removeusergroup', 'runcommand', 'shell', 'upload', 'download', 'deviceopenurl', 'devicemessage', 'devicetoast', 'addtousergroup', 'removefromusergroup', 'removeallusersfromusergroup', 'devicesharing', 'devicepower'];
11 if (args.proxy != null) { try { require('https-proxy-agent'); } catch (ex) { console.log('Missing module "https-proxy-agent", type "npm install https-proxy-agent" to install it.'); return; } }
12
13 if (args['_'].length == 0) {
@@ -24,6 +24,7 @@ if (args['_'].length == 0) {
24 console.log(" ListDevices - List devices.");
25 console.log(" ListDeviceGroups - List device groups.");
26 console.log(" ListUsersOfDeviceGroup - List the users in a device group.");
27 + console.log(" ListEvents - List server events.");
28 console.log(" DeviceInfo - Show information about a device.");
29 console.log(" Config - Perform operation on config.json file.");
30 console.log(" AddUser - Create a new user account.");
@@ -81,6 +82,7 @@ if (args['_'].length == 0) {
82 case 'listusergroups': { ok = true; break; }
83 case 'listdevicegroups': { ok = true; break; }
84 case 'listdevices': { ok = true; break; }
85 + case 'listevents': { ok = true; break; }
86 case 'listusersofdevicegroup': {
87 if (args.id == null) { console.log(winRemoveSingleQuotes("Missing group id, use --id '[groupid]'")); }
88 else { ok = true; }
@@ -341,7 +343,7 @@ if (args['_'].length == 0) {
343 break;
344 }
345 case 'listdevicegroups': {
344 - console.log("List the device groups for this account, Example usages:\r\n");
346 + console.log("List the device groups for this account. Example usages:\r\n");
347 console.log(" MeshCtrl ListDeviceGroups ");
348 console.log(" MeshCtrl ListDeviceGroups --json");
349 console.log("\r\nOptional arguments:\r\n");
@@ -353,7 +355,7 @@ if (args['_'].length == 0) {
355 break;
356 }
357 case 'listdevices': {
356 - console.log("List devices, Example usages:\r\n");
358 + console.log("List devices. Example usages:\r\n");
359 console.log(" MeshCtrl ListDevices");
360 console.log(winRemoveSingleQuotes(" MeshCtrl ListDevices -id '[groupid]' --json"));
361 console.log("\r\nOptional arguments:\r\n");
@@ -369,7 +371,7 @@ if (args['_'].length == 0) {
371 break;
372 }
373 case 'listusersofdevicegroup': {
372 - console.log("List users that have permissions for a given device group, Example usage:\r\n");
374 + console.log("List users that have permissions for a given device group. Example usage:\r\n");
375 console.log(" MeshCtrl ListUserOfDeviceGroup ");
376 console.log("\r\nRequired arguments:\r\n");
377 if (process.platform == 'win32') {
@@ -381,8 +383,19 @@ if (args['_'].length == 0) {
383 console.log(" --json - Show result as JSON.");
384 break;
385 }
386 + case 'listevents': {
387 + console.log("List server events optionally filtered by user or device. Example usage:\r\n");
388 + console.log(" MeshCtrl ListEvents ");
389 + console.log("\r\nOptional arguments:\r\n");
390 + console.log(" --userid [name] - User account identifier.");
391 + console.log(" --id [deviceid] - The device identifier.");
392 + console.log(" --limit [number] - Maximum number of events to list.");
393 + console.log(" --raw - Output raw data in JSON format.");
394 + console.log(" --json - Give results in JSON format.");
395 + break;
396 + }
397 case 'adduser': {
385 - console.log("Add a new user account, Example usages:\r\n");
398 + console.log("Add a new user account. Example usages:\r\n");
399 console.log(" MeshCtrl AddUser --user newaccountname --pass newpassword");
400 console.log(" MeshCtrl AddUser --user newaccountname --randompass --rights full");
401 console.log("\r\nRequired arguments:\r\n");
@@ -1058,6 +1071,24 @@ function serverConnect() {
1071 }
1072 break;
1073 }
1074 + case 'listevents': {
1075 + limit = null;
1076 + if (args.limit) { limit = parseInt(args.limit); }
1077 + if ((typeof limit != 'number') || (limit < 1)) { limit = null; }
1078 +
1079 + var cmd = null;
1080 + if (args.userid) {
1081 + cmd = { action: 'events', user: args.userid, responseid: 'meshctrl' };
1082 + } else if (args.id) {
1083 + cmd = { action: 'events', nodeid: args.id, responseid: 'meshctrl' };
1084 + } else {
1085 + cmd = { action: 'events', responseid: 'meshctrl' };
1086 + }
1087 + if (typeof limit == 'number') { cmd.limit = limit; }
1088 + console.log(cmd);
1089 + ws.send(JSON.stringify(cmd));
1090 + break;
1091 + }
1092 case 'adduser': {
1093 var siteadmin = getSiteAdminRights(args);
1094 if (args.randompass) { args.pass = getRandomAmtPassword(); }
@@ -1499,6 +1530,58 @@ function serverConnect() {
1530 }
1531 break;
1532 }
1533 + case 'events': {
1534 + if (settings.cmd == 'listevents') {
1535 + if (args.raw) {
1536 + // RAW JSON
1537 + console.log(JSON.stringify(data.events));
1538 + } else if (args.json) {
1539 + // Formatted JSON
1540 + console.log(JSON.stringify(data.events, null, 2));
1541 + } else {
1542 + if ((args.id == null) && (args.userid == null)) {
1543 + // CSV format
1544 + console.log("time,type,action,nodeid,userid,msg");
1545 + for (var i in data.events) {
1546 + var x = [];
1547 + x.push(data.events[i].time);
1548 + x.push(data.events[i].etype);
1549 + x.push(data.events[i].action);
1550 + x.push(data.events[i].nodeid);
1551 + x.push(data.events[i].userid);
1552 + x.push(data.events[i].msg);
1553 + console.log(csvFormatArray(x));
1554 + }
1555 + } else if (args.id != null) {
1556 + // CSV format
1557 + console.log("time,type,action,userid,msg");
1558 + for (var i in data.events) {
1559 + var x = [];
1560 + x.push(data.events[i].time);
1561 + x.push(data.events[i].etype);
1562 + x.push(data.events[i].action);
1563 + x.push(data.events[i].userid);
1564 + x.push(data.events[i].msg);
1565 + console.log(csvFormatArray(x));
1566 + }
1567 + } else if (args.userid != null) {
1568 + // CSV format
1569 + console.log("time,type,action,nodeid,msg");
1570 + for (var i in data.events) {
1571 + var x = [];
1572 + x.push(data.events[i].time);
1573 + x.push(data.events[i].etype);
1574 + x.push(data.events[i].action);
1575 + x.push(data.events[i].nodeid);
1576 + x.push(data.events[i].msg);
1577 + console.log(csvFormatArray(x));
1578 + }
1579 + }
1580 + }
1581 + process.exit();
1582 + }
1583 + break;
1584 + }
1585 case 'authcookie': { // SHELL, UPLOAD, DOWNLOAD
1586 if ((settings.cmd == 'shell') || (settings.cmd == 'upload') || (settings.cmd == 'download')) {
1587 var protocol = 1; // Terminal
@@ -1986,6 +2069,12 @@ function getRandomHex(count) { return Buffer.from(crypto.randomBytes(count), 'bi
2069 function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
2070 function winRemoveSingleQuotes(str) { if (process.platform != 'win32') return str; else return str.split('\'').join(''); }
2071
2072 +function csvFormatArray(x) {
2073 + var y = [];
2074 + for (var i in x) { if ((x[i] == null) || (x[i] == '')) { y.push(''); } else { y.push('"' + x[i].split('"').join('') + '"'); } }
2075 + return y.join(',');
2076 +}
2077 +
2078 function displayDeviceInfo(sysinfo, lastconnect, network) {
2079 var node = sysinfo.node;
2080 var hardware = sysinfo.hardware;
meshuser.js
+10 -2
@@ -1398,6 +1398,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1398 if ((command.user != null) && ((user.siteadmin & 2) != 0)) { // SITERIGHT_MANAGEUSERS
1399 // TODO: Add the meshes command.user has access to (???)
1400 var filter = ['user/' + domain.id + '/' + command.user];
1401 +
1402 + const userSplit = command.user.split('/');
1403 + if (userSplit.length == 3) { filter = []; if ((userSplit[0] == 'user') && (userSplit[1] == domain.id)) { filter = [command.user]; } }
1404 +
1405 if ((command.limit == null) || (typeof command.limit != 'number')) {
1406 // Send the list of all events for this session
1407 db.GetUserEvents(filter, domain.id, command.user, function (err, docs) {
@@ -1413,12 +1417,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
1417 }
1418 } else if (command.nodeid != null) { // Device filtered events
1419 // Check that the user has access to this nodeid
1420 +
1421 + const nodeSplit = command.nodeid.split('/');
1422 + if (nodeSplit.length == 1) { command.nodeid = 'node/' + domain.id + '/' + command.nodeid; }
1423 +
1424 parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
1417 - if (node == null) return;
1425 + if (node == null) { try { ws.send(JSON.stringify({ action: 'events', events: [], nodeid: command.nodeid, tag: command.tag })); } catch (ex) { } return; }
1426
1427 // Put a limit on the number of returned entries if present
1428 var limit = 10000;
1421 - if (common.validateInt(command.limit, 1, 60000) == true) { limit = command.limit; }
1429 + if (common.validateInt(command.limit, 1, 1000000) == true) { limit = command.limit; }
1430
1431 if (((rights & MESHRIGHT_LIMITEVENTS) != 0) && (rights != MESHRIGHT_ADMIN)) {
1432 // Send the list of most recent events for this nodeid that only apply to us, up to 'limit' count