From 2a363c0f60c616e6bb0f53309b9677026873e8aa Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Thu, 14 Oct 2021 16:57:20 -0700 Subject: [PATCH] Almost done with per-device notifications. --- meshuser.js | 43 +++++++++++++++++++++++++++ views/default.handlebars | 63 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/meshuser.js b/meshuser.js index 68caf774..829570dd 100644 --- a/meshuser.js +++ b/meshuser.js @@ -2150,6 +2150,49 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use 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 'changeusernotify': + { + if ((user.siteadmin != 0xFFFFFFFF) && ((user.siteadmin & 1024) != 0)) return; // If this account is settings locked, return here. + + // 2 = WebPage device connections + // 4 = WebPage device disconnections + // 8 = WebPage device desktop and serial events + // 16 = Email device connections + // 32 = Email device disconnections + + var err = null; + try { + // Change the current user's notification flags for a meshid + if (common.validateString(command.nodeid, 1, 1024) == false) { err = 'Invalid device identifier'; } // Check the meshid + else if (command.nodeid.indexOf('/') == -1) { command.nodeid = 'node/' + domain.id + '/' + command.nodeid; } + if (common.validateInt(command.notify) == false) { err = 'Invalid notification flags'; } + //if (parent.IsMeshViewable(user, command.nodeid) == false) err = 'Access denied'; + } catch (ex) { err = 'Validation exception: ' + ex; } + + // Handle any errors + if (err != null) { if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'changeusernotify', responseid: command.responseid, result: err })); } catch (ex) { } } break; } + + // Check if nothing has changed + if ((user.notify == null) && (command.notify == 0)) return; + if ((user.notify != null) && (user.notify[command.nodeid] == command.notify)) return; + + // Change the notification + if (user.notify == null) { user.notify = {}; } + if (command.notify == 0) { delete user.notify[command.nodeid]; } else { user.notify[command.nodeid] = command.notify; } + if (Object.keys(user.notify).length == 0) { delete user.notify; } + + // Save the user + parent.db.SetUser(user); + + // 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', msgid: 130, msg: 'User notifications changed', 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 'changepassword': diff --git a/views/default.handlebars b/views/default.handlebars index e2e44117..1d2161d4 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2912,6 +2912,7 @@ delete users[message.event.account._id]; // No longer part of our groups, remove this user. } + if (currentNode) { refreshDevice(currentNode._id); } mainUpdate(4 | 16384); break; } @@ -3213,6 +3214,12 @@ n |= userinfo.links[message.event.meshid].notify; } + // Per-user notification settings + if (userinfo.notify != null) { + if (userinfo.notify[message.event.meshid] != null) { n |= userinfo.notify[message.event.meshid]; } + if (userinfo.notify[message.event.nodeid] != null) { n |= userinfo.notify[message.event.nodeid]; } + } + // Show the notification if (n & 2) { var agentPrivilages = "Agent connected"; @@ -6722,9 +6729,24 @@ x += addDeviceAttribute("User Consent", addLinkConditional(meshFeatures, 'p20editmeshconsent(3)', meshrights & 1)); } + var devNotifyStr = []; + if ((userinfo.notify != null) && (userinfo.notify[node._id] != null)) { + var devNotify = userinfo.notify[node._id]; + if (devNotify & 2) { devNotifyStr.push("Connect"); } + if (devNotify & 4) { devNotifyStr.push("Disconnect"); } + if ((node.intelamt != null) && (devNotify & 8)) { devNotifyStr.push("Intel® AMT"); } + if ((features2 & 0x00004000) && (userinfo.emailVerified)) { + if (devNotify & 16) { devNotifyStr.push("Email Connect"); } + if (devNotify & 32) { devNotifyStr.push("Email Disconnect"); } + } + } + devNotifyStr = devNotifyStr.join(', '); + if (devNotifyStr == '') { devNotifyStr = '' + "None" + ''; } + x += addDeviceAttribute("Notifications", addLink(devNotifyStr, 'p20editDeviceNotify()')); + // Attribute: Connectivity (Only show this if more than just the agent is connected). var connectivity = node.conn; - if (connectivity && connectivity > 1) { + if (connectivity && (connectivity > 1)) { var cstate = []; if ((node.conn & 1) != 0) cstate.push('' + "Mesh Agent" + ''); if ((node.conn & 2) != 0) cstate.push('' + "Intel® AMT CIRA" + ''); @@ -7056,6 +7078,42 @@ go(panel); } + function p20editDeviceNotify() { + if (xxdialogMode) return false; + var devNotify = 0, fx = ((features2 & 0x00004000) && (userinfo.emailVerified))?1:0; + if (userinfo.notify && userinfo.notify[currentNode._id]) { devNotify = userinfo.notify[currentNode._id]; } + var x = '
Web Page Notifications
'; + x += '
'; + x += '
'; + if (currentNode.intelamt != null) { fx += 2; x += '
'; } + if (fx & 1) { + x += '
Email Notifications
'; + x += '
'; + x += '
'; + } + setDialogMode(2, "Notification Settings", 3, p20editDeviceNotifyEx, x, fx); + Q('p20notifyIntelDeviceConnect').checked = (devNotify & 2); + Q('p20notifyIntelDeviceDisconnect').checked = (devNotify & 4); + if (fx & 2) { Q('p20notifyIntelAmtKvmActions').checked = (devNotify & 8); } + if (fx & 1) { + Q('p20enotifyIntelDeviceConnect').checked = (devNotify & 16); + Q('p20enotifyIntelDeviceDisconnect').checked = (devNotify & 32); + } + return false; + } + + function p20editDeviceNotifyEx(b, fx) { + var devNotify = 0; + devNotify += Q('p20notifyIntelDeviceConnect').checked ? 2 : 0; + devNotify += Q('p20notifyIntelDeviceDisconnect').checked ? 4 : 0; + if (fx & 2) { devNotify += Q('p20notifyIntelAmtKvmActions').checked ? 8 : 0; } + if (fx & 1) { + devNotify += Q('p20enotifyIntelDeviceConnect').checked ? 16 : 0; + devNotify += Q('p20enotifyIntelDeviceDisconnect').checked ? 32 : 0; + } + meshserver.send({ action: 'changeusernotify', nodeid: currentNode._id, notify: devNotify }); + } + function makeUserDeviceRightsString(rights) { if (rights == 57592) { return "Full Device Rights"; } var str = []; @@ -12937,7 +12995,8 @@ 126: "Left Web-VNC session after {0} second(s).", 127: "Changed account display name to {0}.", 128: "Account created, name is {0}.", - 129: "Removed account display name." + 129: "Removed account display name.", + 130: "User notifications changed" }; // Highlights the device being hovered