Added last connection time and address to device details export.

Ylian Saint-Hilaire committed Jul 30, 2021 at 18:06 UTC bc316b01ae58e33fe656e3ff9592b3406f9b2db8
3 files changed +168 -129
amt/amt-wsman-comm.js
+1 -1
@@ -410,7 +410,7 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions, mpsConn
410 // We got a chunk with all of the data, handle the chunck now.
411 var data = obj.socketAccumulator.substring(clen + 2, clen + 2 + csize);
412 obj.socketAccumulator = obj.socketAccumulator.substring(clen + 2 + csize + 2);
413 - obj.socketData += data;
413 + try { obj.socketData += data; } catch (ex) { console.log(ex, typeof data, data.length); }
414 }
415 if (csize == 0) {
416 //obj.Debug("xxOnSocketData DONE: (" + obj.socketData.length + "): " + obj.socketData);
meshuser.js
+161 -126
@@ -5265,147 +5265,182 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5265 case 'getDeviceDetails': {
5266 if ((common.validateStrArray(command.nodeids, 1) == false) && (command.nodeids != null)) break; // Check nodeids
5267 if (common.validateString(command.type, 3, 4) == false) break; // Check type
5268 - getDeviceDetailedInfo(command.nodeids, command.type, function (results, type) {
5269 - // Remove any device system and network information is we do not have details rights to this device
5270 - for (var i = 0; i < results.length; i++) { if ((parent.GetNodeRights(user, results[i].node.meshid, results[i].node._id) & MESHRIGHT_DEVICEDETAILS) == 0) { delete results[i].sys; delete results[i].net; } }
5268
5272 - var output = null;
5273 - if (type == 'csv') {
5274 - try {
5275 - // Create the CSV file
5276 - output = 'id,name,rname,host,icon,ip,osdesc,groupname,av,update,firewall,avdetails,cpu,osbuild,biosDate,biosVendor,biosVersion,boardName,boardVendor,boardVersion,productUuid,agentOpenSSL,agentCommitDate,agentCommitHash,agentCompileTime,netIfCount,macs,addresses\r\n';
5277 - for (var i = 0; i < results.length; i++) {
5278 - const nodeinfo = results[i];
5269 + // Create a list of node ids and query them for last device connection time
5270 + const ids = []
5271 + for (var i in command.nodeids) { ids.push('lc' + command.nodeids[i]); }
5272 + db.GetAllIdsOfType(ids, domain.id, 'lastconnect', function (err, docs) {
5273 + const lastConnects = {};
5274 + if (docs != null) { for (var i in docs) { lastConnects[docs[i]._id] = docs[i]; } }
5275 +
5276 + getDeviceDetailedInfo(command.nodeids, command.type, function (results, type) {
5277 + for (var i = 0; i < results.length; i++) {
5278 + // Remove any device system and network information is we do not have details rights to this device
5279 + if ((parent.GetNodeRights(user, results[i].node.meshid, results[i].node._id) & MESHRIGHT_DEVICEDETAILS) == 0) {
5280 + delete results[i].sys; delete results[i].net;
5281 + }
5282
5280 - // Node information
5281 - if (nodeinfo.node != null) {
5282 - const n = nodeinfo.node;
5283 - output += csvClean(n._id) + ',' + csvClean(n.name) + ',' + csvClean(n.rname ? n.rname : '') + ',' + csvClean(n.host ? n.host : '') + ',' + (n.icon ? n.icon : 1) + ',' + (n.ip ? n.ip : '') + ',' + (n.osdesc ? csvClean(n.osdesc) : '') + ',' + csvClean(parent.meshes[n.meshid].name);
5284 - if (typeof n.wsc == 'object') {
5285 - output += ',' + csvClean(n.wsc.antiVirus ? n.wsc.antiVirus : '') + ',' + csvClean(n.wsc.autoUpdate ? n.wsc.autoUpdate : '') + ',' + csvClean(n.wsc.firewall ? n.wsc.firewall : '')
5286 - } else { output += ',,,'; }
5287 - if (typeof n.av == 'object') {
5288 - var avdetails = '', firstav = true;
5289 - for (var a in n.av) { if (typeof n.av[a].product == 'string') { if (firstav) { firstav = false; } else { avdetails += '|'; } avdetails += (n.av[a].product + '/' + ((n.av[a].enabled) ? 'enabled' : 'disabled') + '/' + ((n.av[a].updated) ? 'updated' : 'notupdated')); } }
5290 - output += ',' + csvClean(avdetails);
5283 + // Merge any last connection information
5284 + const lc = lastConnects['lc' + results[i].node._id];
5285 + if (lc != null) { delete lc._id; delete lc.type; delete lc.domain; results[i].lastConnect = lc; }
5286 + }
5287 +
5288 + var output = null;
5289 + if (type == 'csv') {
5290 + try {
5291 + // Create the CSV file
5292 + output = 'id,name,rname,host,icon,ip,osdesc,groupname,av,update,firewall,avdetails,cpu,osbuild,biosDate,biosVendor,biosVersion,boardName,boardVendor,boardVersion,productUuid,agentOpenSSL,agentCommitDate,agentCommitHash,agentCompileTime,netIfCount,macs,addresses,lastConnectTime,lastConnectAddr\r\n';
5293 + for (var i = 0; i < results.length; i++) {
5294 + const nodeinfo = results[i];
5295 +
5296 + // Node information
5297 + if (nodeinfo.node != null) {
5298 + const n = nodeinfo.node;
5299 + output += csvClean(n._id) + ',' + csvClean(n.name) + ',' + csvClean(n.rname ? n.rname : '') + ',' + csvClean(n.host ? n.host : '') + ',' + (n.icon ? n.icon : 1) + ',' + (n.ip ? n.ip : '') + ',' + (n.osdesc ? csvClean(n.osdesc) : '') + ',' + csvClean(parent.meshes[n.meshid].name);
5300 + if (typeof n.wsc == 'object') {
5301 + output += ',' + csvClean(n.wsc.antiVirus ? n.wsc.antiVirus : '') + ',' + csvClean(n.wsc.autoUpdate ? n.wsc.autoUpdate : '') + ',' + csvClean(n.wsc.firewall ? n.wsc.firewall : '')
5302 + } else { output += ',,,'; }
5303 + if (typeof n.av == 'object') {
5304 + var avdetails = '', firstav = true;
5305 + for (var a in n.av) { if (typeof n.av[a].product == 'string') { if (firstav) { firstav = false; } else { avdetails += '|'; } avdetails += (n.av[a].product + '/' + ((n.av[a].enabled) ? 'enabled' : 'disabled') + '/' + ((n.av[a].updated) ? 'updated' : 'notupdated')); } }
5306 + output += ',' + csvClean(avdetails);
5307 + }
5308 + else { output += ','; }
5309 + } else {
5310 + output += ',,,,,,,,,,,';
5311 }
5292 - else { output += ','; }
5293 - } else {
5294 - output += ',,,,,,,,,,,';
5295 - }
5312
5297 - // System infomation
5298 - if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.windows) && (nodeinfo.sys.hardware.windows)) {
5299 - // Windows
5300 - output += ',';
5301 - if (nodeinfo.sys.hardware.windows.cpu && (nodeinfo.sys.hardware.windows.cpu.length > 0) && (typeof nodeinfo.sys.hardware.windows.cpu[0].Name == 'string')) { output += csvClean(nodeinfo.sys.hardware.windows.cpu[0].Name); }
5302 - output += ',';
5303 - if (nodeinfo.sys.hardware.windows.osinfo && (nodeinfo.sys.hardware.windows.osinfo.BuildNumber)) { output += csvClean(nodeinfo.sys.hardware.windows.osinfo.BuildNumber); }
5304 - output += ',';
5305 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.bios_date)) { output += csvClean(nodeinfo.sys.hardware.identifiers.bios_date); }
5306 - output += ',';
5307 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.bios_vendor)) { output += csvClean(nodeinfo.sys.hardware.identifiers.bios_vendor); }
5308 - output += ',';
5309 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.bios_version)) { output += csvClean(nodeinfo.sys.hardware.identifiers.bios_version); }
5310 - output += ',';
5311 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.board_name)) { output += csvClean(nodeinfo.sys.hardware.identifiers.board_name); }
5312 - output += ',';
5313 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.board_vendor)) { output += csvClean(nodeinfo.sys.hardware.identifiers.board_vendor); }
5314 - output += ',';
5315 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.board_version)) { output += csvClean(nodeinfo.sys.hardware.identifiers.board_version); }
5316 - output += ',';
5317 - if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.product_uuid)) { output += csvClean(nodeinfo.sys.hardware.identifiers.product_uuid); }
5318 - } else if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.mobile)) {
5319 - // Mobile
5320 - output += ',';
5321 - output += ',';
5322 - output += ',';
5323 - output += ',';
5324 - output += ',';
5325 - if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.bootloader)) { output += csvClean(nodeinfo.sys.hardware.mobile.bootloader); }
5326 - output += ',';
5327 - if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.model)) { output += csvClean(nodeinfo.sys.hardware.mobile.model); }
5328 - output += ',';
5329 - if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.brand)) { output += csvClean(nodeinfo.sys.hardware.mobile.brand); }
5330 - output += ',';
5331 - output += ',';
5332 - if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.id)) { output += csvClean(nodeinfo.sys.hardware.mobile.id); }
5333 - } else if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.windows) && (nodeinfo.sys.hardware.linux)) {
5334 - // Linux
5335 - output += ',';
5336 - output += ',';
5337 - output += ',';
5338 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.bios_date)) { output += csvClean(nodeinfo.sys.hardware.linux.bios_date); }
5339 - output += ',';
5340 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.bios_vendor)) { output += csvClean(nodeinfo.sys.hardware.linux.bios_vendor); }
5341 - output += ',';
5342 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.bios_version)) { output += csvClean(nodeinfo.sys.hardware.linux.bios_version); }
5343 - output += ',';
5344 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.board_name)) { output += csvClean(nodeinfo.sys.hardware.linux.board_name); }
5345 - output += ',';
5346 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.board_vendor)) { output += csvClean(nodeinfo.sys.hardware.linux.board_vendor); }
5347 - output += ',';
5348 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.board_version)) { output += csvClean(nodeinfo.sys.hardware.linux.board_version); }
5349 - output += ',';
5350 - if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.product_uuid)) { output += csvClean(nodeinfo.sys.hardware.linux.product_uuid); }
5351 - } else {
5352 - output += ',,,,,,,,,';
5353 - }
5313 + // System infomation
5314 + if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.windows) && (nodeinfo.sys.hardware.windows)) {
5315 + // Windows
5316 + output += ',';
5317 + if (nodeinfo.sys.hardware.windows.cpu && (nodeinfo.sys.hardware.windows.cpu.length > 0) && (typeof nodeinfo.sys.hardware.windows.cpu[0].Name == 'string')) { output += csvClean(nodeinfo.sys.hardware.windows.cpu[0].Name); }
5318 + output += ',';
5319 + if (nodeinfo.sys.hardware.windows.osinfo && (nodeinfo.sys.hardware.windows.osinfo.BuildNumber)) { output += csvClean(nodeinfo.sys.hardware.windows.osinfo.BuildNumber); }
5320 + output += ',';
5321 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.bios_date)) { output += csvClean(nodeinfo.sys.hardware.identifiers.bios_date); }
5322 + output += ',';
5323 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.bios_vendor)) { output += csvClean(nodeinfo.sys.hardware.identifiers.bios_vendor); }
5324 + output += ',';
5325 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.bios_version)) { output += csvClean(nodeinfo.sys.hardware.identifiers.bios_version); }
5326 + output += ',';
5327 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.board_name)) { output += csvClean(nodeinfo.sys.hardware.identifiers.board_name); }
5328 + output += ',';
5329 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.board_vendor)) { output += csvClean(nodeinfo.sys.hardware.identifiers.board_vendor); }
5330 + output += ',';
5331 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.board_version)) { output += csvClean(nodeinfo.sys.hardware.identifiers.board_version); }
5332 + output += ',';
5333 + if (nodeinfo.sys.hardware.identifiers && (nodeinfo.sys.hardware.identifiers.product_uuid)) { output += csvClean(nodeinfo.sys.hardware.identifiers.product_uuid); }
5334 + } else if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.mobile)) {
5335 + // Mobile
5336 + output += ',';
5337 + output += ',';
5338 + output += ',';
5339 + output += ',';
5340 + output += ',';
5341 + if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.bootloader)) { output += csvClean(nodeinfo.sys.hardware.mobile.bootloader); }
5342 + output += ',';
5343 + if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.model)) { output += csvClean(nodeinfo.sys.hardware.mobile.model); }
5344 + output += ',';
5345 + if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.brand)) { output += csvClean(nodeinfo.sys.hardware.mobile.brand); }
5346 + output += ',';
5347 + output += ',';
5348 + if (nodeinfo.sys.hardware.mobile && (nodeinfo.sys.hardware.mobile.id)) { output += csvClean(nodeinfo.sys.hardware.mobile.id); }
5349 + } else if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.windows) && (nodeinfo.sys.hardware.linux)) {
5350 + // Linux
5351 + output += ',';
5352 + output += ',';
5353 + output += ',';
5354 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.bios_date)) { output += csvClean(nodeinfo.sys.hardware.linux.bios_date); }
5355 + output += ',';
5356 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.bios_vendor)) { output += csvClean(nodeinfo.sys.hardware.linux.bios_vendor); }
5357 + output += ',';
5358 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.bios_version)) { output += csvClean(nodeinfo.sys.hardware.linux.bios_version); }
5359 + output += ',';
5360 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.board_name)) { output += csvClean(nodeinfo.sys.hardware.linux.board_name); }
5361 + output += ',';
5362 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.board_vendor)) { output += csvClean(nodeinfo.sys.hardware.linux.board_vendor); }
5363 + output += ',';
5364 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.board_version)) { output += csvClean(nodeinfo.sys.hardware.linux.board_version); }
5365 + output += ',';
5366 + if (nodeinfo.sys.hardware.linux && (nodeinfo.sys.hardware.linux.product_uuid)) { output += csvClean(nodeinfo.sys.hardware.linux.product_uuid); }
5367 + } else {
5368 + output += ',,,,,,,,,';
5369 + }
5370
5355 - // Agent information
5356 - if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.agentvers)) {
5357 - output += ',';
5358 - if (nodeinfo.sys.hardware.agentvers.openssl) { output += csvClean(nodeinfo.sys.hardware.agentvers.openssl); }
5359 - output += ',';
5360 - if (nodeinfo.sys.hardware.agentvers.commitDate) { output += csvClean(nodeinfo.sys.hardware.agentvers.commitDate); }
5361 - output += ',';
5362 - if (nodeinfo.sys.hardware.agentvers.commitHash) { output += csvClean(nodeinfo.sys.hardware.agentvers.commitHash); }
5363 - output += ',';
5364 - if (nodeinfo.sys.hardware.agentvers.compileTime) { output += csvClean(nodeinfo.sys.hardware.agentvers.compileTime); }
5365 - } else {
5366 - output += ',,,,';
5367 - }
5371 + // Agent information
5372 + if ((nodeinfo.sys) && (nodeinfo.sys.hardware) && (nodeinfo.sys.hardware.agentvers)) {
5373 + output += ',';
5374 + if (nodeinfo.sys.hardware.agentvers.openssl) { output += csvClean(nodeinfo.sys.hardware.agentvers.openssl); }
5375 + output += ',';
5376 + if (nodeinfo.sys.hardware.agentvers.commitDate) { output += csvClean(nodeinfo.sys.hardware.agentvers.commitDate); }
5377 + output += ',';
5378 + if (nodeinfo.sys.hardware.agentvers.commitHash) { output += csvClean(nodeinfo.sys.hardware.agentvers.commitHash); }
5379 + output += ',';
5380 + if (nodeinfo.sys.hardware.agentvers.compileTime) { output += csvClean(nodeinfo.sys.hardware.agentvers.compileTime); }
5381 + } else {
5382 + output += ',,,,';
5383 + }
5384
5369 - // Network interfaces
5370 - if ((nodeinfo.net) && (nodeinfo.net.netif2)) {
5371 - output += ',';
5372 - output += Object.keys(nodeinfo.net.netif2).length; // Interface count
5373 - var macs = [], addresses = [];
5374 - for (var j in nodeinfo.net.netif2) {
5375 - if (Array.isArray(nodeinfo.net.netif2[j])) {
5376 - for (var k = 0; k < nodeinfo.net.netif2[j].length; k++) {
5377 - if (typeof nodeinfo.net.netif2[j][k].mac == 'string') { macs.push(nodeinfo.net.netif2[j][k].mac); }
5378 - if (typeof nodeinfo.net.netif2[j][k].address == 'string') { addresses.push(nodeinfo.net.netif2[j][k].address); }
5385 + // Network interfaces
5386 + if ((nodeinfo.net) && (nodeinfo.net.netif2)) {
5387 + output += ',';
5388 + output += Object.keys(nodeinfo.net.netif2).length; // Interface count
5389 + var macs = [], addresses = [];
5390 + for (var j in nodeinfo.net.netif2) {
5391 + if (Array.isArray(nodeinfo.net.netif2[j])) {
5392 + for (var k = 0; k < nodeinfo.net.netif2[j].length; k++) {
5393 + if (typeof nodeinfo.net.netif2[j][k].mac == 'string') { macs.push(nodeinfo.net.netif2[j][k].mac); }
5394 + if (typeof nodeinfo.net.netif2[j][k].address == 'string') { addresses.push(nodeinfo.net.netif2[j][k].address); }
5395 + }
5396 }
5397 }
5398 + output += ',';
5399 + output += csvClean(macs.join(' ')); // MACS
5400 + output += ',';
5401 + output += csvClean(addresses.join(' ')); // Addresses
5402 + } else {
5403 + output += ',,,';
5404 }
5382 - output += ',';
5383 - output += csvClean(macs.join(' ')); // MACS
5384 - output += ',';
5385 - output += csvClean(addresses.join(' ')); // Addresses
5386 - } else {
5387 - output += ',,,';
5405 +
5406 + // Last connection information
5407 + if (nodeinfo.lastConnect) {
5408 + output += ',';
5409 + if (nodeinfo.lastConnect.time) {
5410 + // Last connection time
5411 + if ((typeof command.l == 'string') && (typeof command.tz == 'string')) {
5412 + output += csvClean(new Date(nodeinfo.lastConnect.time).toLocaleString(command.l, { timeZone: command.tz }))
5413 + } else {
5414 + output += nodeinfo.lastConnect.time;
5415 + }
5416 + }
5417 + output += ',';
5418 + if (typeof nodeinfo.lastConnect.addr == 'string') { output += csvClean(nodeinfo.lastConnect.addr); } // Last connection address and port
5419 + } else {
5420 + output += ',,';
5421 + }
5422 +
5423 + output += '\r\n';
5424 }
5425 + } catch (ex) { console.log(ex); }
5426 + } else {
5427 + // Create the JSON file
5428
5390 - output += '\r\n';
5429 + // Add the device group name to each device
5430 + for (var i = 0; i < results.length; i++) {
5431 + const nodeinfo = results[i];
5432 + if (nodeinfo.node) {
5433 + const mesh = parent.meshes[nodeinfo.node.meshid];
5434 + if (mesh) { results[i].node.groupname = mesh.name; }
5435 + }
5436 }
5392 - } catch (ex) { console.log(ex); }
5393 - } else {
5394 - // Create the JSON file
5437
5396 - // Add the device group name to each device
5397 - for (var i = 0; i < results.length; i++) {
5398 - const nodeinfo = results[i];
5399 - if (nodeinfo.node) {
5400 - const mesh = parent.meshes[nodeinfo.node.meshid];
5401 - if (mesh) { results[i].node.groupname = mesh.name; }
5402 - }
5438 + output = JSON.stringify(results, null, 2);
5439 }
5404 -
5405 - output = JSON.stringify(results, null, 2);
5406 - }
5407 - try { ws.send(JSON.stringify({ action: 'getDeviceDetails', data: output, type: type })); } catch (ex) { }
5440 + try { ws.send(JSON.stringify({ action: 'getDeviceDetails', data: output, type: type })); } catch (ex) { }
5441 + });
5442 });
5443 +
5444 break;
5445 }
5446 default: {
views/default.handlebars
+6 -2
@@ -5227,7 +5227,9 @@
5227 function p2downloadDeviceInfoCSV() {
5228 var chkNodeIds = getCheckedDevices();
5229 if (Q('d2DevInfoDetailsCheck').checked) {
5230 - meshserver.send({ action: 'getDeviceDetails', nodeids: chkNodeIds, type: 'csv' }); // With details
5230 + var tz = null;
5231 + try { tz = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (ex) {}
5232 + meshserver.send({ action: 'getDeviceDetails', nodeids: chkNodeIds, tz: tz, tf: new Date().getTimezoneOffset(), l: getLang(), type: 'csv' }); // With details
5233 } else {
5234 // Without details
5235 var csv = "id, name, rname, host, icon, ip, osdesc, state, groupname, conn, pwr, av, update, firewall, avdetails" + '\r\n', r = [];
@@ -5268,7 +5270,9 @@
5270 function p2downloadDeviceInfoJSON() {
5271 var chkNodeIds = getCheckedDevices();
5272 if (Q('d2DevInfoDetailsCheck').checked) {
5271 - meshserver.send({ action: 'getDeviceDetails', nodeids: chkNodeIds, type: 'json' }); // With details
5273 + var tz = null;
5274 + try { tz = Intl.DateTimeFormat().resolvedOptions().timeZone; } catch (ex) {}
5275 + meshserver.send({ action: 'getDeviceDetails', nodeids: chkNodeIds, tz: tz, tf: new Date().getTimezoneOffset(), l: getLang(), type: 'json' }); // With details
5276 } else {
5277 // Without details
5278 var r = [];