diff --git a/agents/meshcore.js b/agents/meshcore.js index bbd4cf97..8d3382c5 100644 --- a/agents/meshcore.js +++ b/agents/meshcore.js @@ -1912,7 +1912,9 @@ function createMeshCore(agent) } case 'sysinfo': { // Return system information getSystemInformation(function (results, err) { - if (results == null) { sendConsoleText(err, this.sessionid); } else { sendConsoleText(JSON.stringify(results, null, 1), this.sessionid); } + if (results == null) { sendConsoleText(err, this.sessionid); } else { + sendConsoleText(JSON.stringify(results, null, 1), this.sessionid); + } }); break; } diff --git a/agents/meshcore.min.js b/agents/meshcore.min.js index bbd4cf97..8d3382c5 100644 --- a/agents/meshcore.min.js +++ b/agents/meshcore.min.js @@ -1912,7 +1912,9 @@ function createMeshCore(agent) } case 'sysinfo': { // Return system information getSystemInformation(function (results, err) { - if (results == null) { sendConsoleText(err, this.sessionid); } else { sendConsoleText(JSON.stringify(results, null, 1), this.sessionid); } + if (results == null) { sendConsoleText(err, this.sessionid); } else { + sendConsoleText(JSON.stringify(results, null, 1), this.sessionid); + } }); break; } diff --git a/meshagent.js b/meshagent.js index 8c8e2be5..74009a0c 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1307,12 +1307,17 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { break; } case 'sysinfo': { - //console.log('sysinfo', obj.nodeid, JSON.stringify(command.data.hash)); - command.data._id = 'si' + obj.dbNodeKey; - command.data.type = 'sysinfo'; - command.data.domain = domain.id; - command.data.time = Date.now(); - db.Set(command.data); // Update system information in the database. + if ((typeof command.data == 'object') && (typeof command.data.hash == 'string')) { + command.data._id = 'si' + obj.dbNodeKey; + command.data.type = 'sysinfo'; + command.data.domain = domain.id; + command.data.time = Date.now(); + db.Set(command.data); // Update system information in the database. + + // Event the new sysinfo hash, this will notify everyone that the sysinfo document was changed + var event = { etype: 'node', action: 'sysinfohash', nodeid: obj.dbNodeKey, domain: domain.id, hash: command.data.hash, nolog: 1 }; + parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, event); + } break; } case 'sysinfocheck': { diff --git a/meshuser.js b/meshuser.js index 3c5f4ee7..8079fc29 100644 --- a/meshuser.js +++ b/meshuser.js @@ -2529,16 +2529,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use if (twoStepLoginSupported == false) break; // Perform a sub-action - var actionTaken = false; + var actionTaken = false, actionText = null; if (command.subaction == 1) { // Generate a new set of tokens var randomNumbers = [], v; for (var i = 0; i < 10; i++) { do { v = getRandomEightDigitInteger(); } while (randomNumbers.indexOf(v) >= 0); randomNumbers.push(v); } user.otpkeys = { keys: [] }; for (var i = 0; i < 10; i++) { user.otpkeys.keys[i] = { p: randomNumbers[i], u: true } } actionTaken = true; + actionText = 'New 2FA backup codes generated.'; } else if (command.subaction == 2) { // Clear all tokens actionTaken = (user.otpkeys != null); user.otpkeys = null; + if (actionTaken) { actionText = '2FA backup codes cleared.'; } } // Save the changed user @@ -2550,11 +2552,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } // Notify change - var targets = ['*', 'server-users', user._id]; - if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } } - var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Added security key.', domain: domain.id }; - if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come. - parent.parent.DispatchEvent(targets, obj, event); + if (actionText != null) { + var targets = ['*', 'server-users', user._id]; + if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } } + var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: actionText, domain: domain.id }; + if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come. + parent.parent.DispatchEvent(targets, obj, event); + } break; } case 'otp-hkey-get': diff --git a/package.json b/package.json index f7b7fdf4..ccc0d68c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.4.1-d", + "version": "0.4.1-e", "keywords": [ "Remote Management", "Intel AMT", diff --git a/public/styles/style.css b/public/styles/style.css index 4d25cbc4..f416a32a 100644 --- a/public/styles/style.css +++ b/public/styles/style.css @@ -1556,6 +1556,11 @@ a { clear: both; } + .filelist:hover { + background: #EEE; + border-radius: 3px; + } + .noselect { -webkit-touch-callout: none; -webkit-user-select: none; diff --git a/views/default-min.handlebars b/views/default-min.handlebars index 768c699a..018482b4 100644 --- a/views/default-min.handlebars +++ b/views/default-min.handlebars @@ -1 +1 @@ - {{{title}}}
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file + {{{title}}}
{{{title}}}
{{{title2}}}

{{{logoutControl}}}

 

\ No newline at end of file diff --git a/views/default.handlebars b/views/default.handlebars index 30a2222c..e4b1e02b 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1494,7 +1494,7 @@ } case 'getsysinfo': { if (message.nodeid != powerTimelineReq) break; - console.log('getsysinfo', message); + //console.log('getsysinfo', message); // *********************** if (message.noinfo === true) { QH('p17info', 'No information for this device.'); } else { @@ -1748,12 +1748,18 @@ var x = "One time tokens can be used as secondary authentication. Generate a set, print them and keep them in a safe place."; x += "
"; if (message.passwords) { - var j = 0; + var j = 0, clipb = ''; for (var i in message.passwords) { if (++j % 2) { x += ''; } var p = '' + message.passwords[i].p; while (p.length < 8) { p = '0' + p; } - if (message.passwords[i].u === true) { x += '
' + p.substring(0, 4) + ' ' + p.substring(4); } else { x += '' + p.substring(0, 4) + ' ' + p.substring(4); + ''; } + if (message.passwords[i].u === true) { + x += '' + p.substring(0, 4) + ' ' + p.substring(4); + if (clipb != '') { clipb += ' '; } + clipb += p; + } else { + x += '' + p.substring(0, 4) + ' ' + p.substring(4); + ''; + } } } else { x += '
No Active Tokens'; @@ -1761,7 +1767,10 @@ x += "

"; x += "
"; x += ""; - if (message.passwords != null) { x += ""; } + if (message.passwords != null) { + x += ""; + x += ' '; + } x += "

"; setDialogMode(2, "Manage Backup Codes", 8, null, x, 'otpauth-manage'); break; @@ -2209,6 +2218,13 @@ } break; } + case 'sysinfohash': { + // If the sysinfo document has changed and we are looking at it, request an update. + if ((currentNode != null) && (message.event.nodeid == powerTimelineReq)) { + meshserver.send({ action: 'getsysinfo', nodeid: message.event.nodeid }); + } + break; + } case 'stopped': { // Server is stopping. // Disconnect //console.log(message.msg); diff --git a/views/messenger-min.handlebars b/views/messenger-min.handlebars index 4f35d574..a2fa1033 100644 --- a/views/messenger-min.handlebars +++ b/views/messenger-min.handlebars @@ -1 +1 @@ - MeshMessenger
MeshMessenger
\ No newline at end of file + MeshMessenger
MeshMessenger
\ No newline at end of file