diff --git a/meshuser.js b/meshuser.js
index 3fcb5ed2..e26b071a 100644
--- a/meshuser.js
+++ b/meshuser.js
@@ -1291,6 +1291,39 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
}
}
+ break;
+ }
+ case 'changemeshnotify':
+ {
+ var err = null;
+ try {
+ // Change the current user's notification flags for a meshid
+ if (common.validateString(command.meshid, 1, 1024) == false) { err = 'Invalid group identifier'; } // Check the meshid
+ else if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
+ if (common.validateInt(command.notify) == false) { err = 'Invalid notification flags'; }
+ if ((user.links == null) || (user.links[command.meshid] == null)) { err = 'Incorrect group identifier'; }
+ } catch (ex) { err = 'Validation exception: ' + ex; }
+
+ // Handle any errors
+ if (err != null) { if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'changemeshnotify', responseid: command.responseid, result: err })); } catch (ex) { } } break; }
+
+ // Change the notification
+ if (command.notify == 0) {
+ delete user.links[command.meshid].notify;
+ } else {
+ user.links[command.meshid].notify = command.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', username: user.name, account: parent.CloneSafeUser(user), action: 'accountchange', msg: 'Mesh notification change.', 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/package.json b/package.json
index ce32ebd8..24fbcb18 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "meshcentral",
- "version": "0.3.8-f",
+ "version": "0.3.8-h",
"keywords": [
"Remote Management",
"Intel AMT",
diff --git a/views/default-min.handlebars b/views/default-min.handlebars
index 2631e27c..64666d70 100644
--- a/views/default-min.handlebars
+++ b/views/default-min.handlebars
@@ -1 +1 @@
-
{{{title}}}
My Devices My Account My Events My Files My Users My Server
General Desktop Terminal Files Events Intel® AMT Console
Server disconnected , click to reconnect .
My Devices No device groups.
My Account Device Groups ( New )
My Files These files are shared publicly, click "link" to get public url.
✓
✗
My Server Server Statistics
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
General -
File Selection
Local file upload Server file selection Agent Remote Desktop Scaling
100% 87.5% 75% 62.5% 50% 37.5% 25% 12.5% Frame rate
Fast Medium Slow Very slow Intel® AMT Hardware KVM Image Encoding
RLE8, Fastest RLE16, Recommended RAW8, Slow RAW16, Very Slow
\ No newline at end of file
+ {{{title}}}
My Devices My Account My Events My Files My Users My Server
General Desktop Terminal Files Events Intel® AMT Console
Server disconnected , click to reconnect .
My Devices No device groups.
My Account Device Groups ( New )
My Files These files are shared publicly, click "link" to get public url.
✓
✗
My Server Server Statistics
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
General -
File Selection
Local file upload Server file selection Agent Remote Desktop Scaling
100% 87.5% 75% 62.5% 50% 37.5% 25% 12.5% Frame rate
Fast Medium Slow Very slow Intel® AMT Hardware KVM Image Encoding
RLE8, Fastest RLE16, Recommended RAW8, Slow RAW16, Very Slow
\ No newline at end of file
diff --git a/views/default-mobile-min.handlebars b/views/default-mobile-min.handlebars
index ffb60084..bf953002 100644
--- a/views/default-mobile-min.handlebars
+++ b/views/default-mobile-min.handlebars
@@ -1 +1 @@
- {{{title}}}
Server disconnected , click to reconnect .
◀
Account Security
Account Actions
Device Groups ( New )
◀
My Files
◀
\ No newline at end of file
+ {{{title}}}
Server disconnected , click to reconnect .
◀
Account Security
Account Actions
Device Groups ( New )
◀
My Files
◀
\ No newline at end of file
diff --git a/views/default.handlebars b/views/default.handlebars
index c0f8ffcb..99994c7c 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -1282,6 +1282,7 @@
if (updateNaggleFlags & 256) { drawDeviceTimeline(); }
if (updateNaggleFlags & 1024) { deviceEventsUpdate(); }
if (updateNaggleFlags & 2048) { userEventsUpdate(); }
+ if (updateNaggleFlags & 4096) { p20updateMesh(); }
updateNaggleTimer = null;
updateNaggleFlags = 0;
}, 150);
@@ -1295,7 +1296,7 @@
QV('authAppSetupCheck', userinfo.otpsecret == 1);
QV('authKeySetupCheck', userinfo.otphkeys > 0);
QV('authCodesSetupCheck', userinfo.otpkeys > 0);
- masterUpdate(4 + 128);
+ masterUpdate(4 + 128 + 4096);
// If we can't create new groups, hide all links that can do that.
var newGroupsAllowed = ((userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.siteadmin & 64) == 0));
@@ -1791,7 +1792,7 @@
//meshserver.send({ action: 'files' }); // TODO: Why do we need to do this??
// If we are looking at a mesh that is now deleted, move back to "My Account"
- if (xxcurrentView == 20 && currentMesh._id == message.event.meshid) { p20updateMesh(); }
+ if (xxcurrentView == 20 && currentMesh._id == message.event.meshid) { masterUpdate(4096); }
break;
}
case 'deletemesh': {
@@ -1946,7 +1947,14 @@
var node = nodes[index];
// Event the connection change if needed
- var n = getstore('notifications', 0);
+ var n = getstore('notifications', 0); // Account notification settings
+
+ // Per-group notification settings
+ if (message.event.meshid && userinfo.links && userinfo.links[message.event.meshid] && userinfo.links[message.event.meshid].notify) {
+ n |= userinfo.links[message.event.meshid].notify;
+ }
+
+ // Show the notification
if (n & 2) {
if (((node.conn & 1) == 0) && ((message.event.conn & 1) != 0)) { addNotification({ text: 'Agent connected', title: node.name, icon: node.icon, nodeid: node._id }); }
if (((node.conn & 2) == 0) && ((message.event.conn & 2) != 0)) { addNotification({ text: 'Intel AMT detected', title: node.name, icon: node.icon, nodeid: node._id }); }
@@ -6379,6 +6387,15 @@
x += addHtmlValue('User Consent', addLinkConditional(meshFeatures, 'p20editmeshconsent()', meshrights & 1));
}
+ // Display user consent
+ var meshNotify = 0, meshNotifyStr = [];
+ if (userinfo.links && userinfo.links[currentMesh._id] && userinfo.links[currentMesh._id].notify) { meshNotify = userinfo.links[currentMesh._id].notify; }
+ if (meshNotify & 2) { meshNotifyStr.push('Connect'); }
+ if (meshNotify & 4) { meshNotifyStr.push('Disconnect'); }
+ if (meshNotify & 8) { meshNotifyStr.push('Intel® AMT'); }
+ if (meshNotifyStr.length == 0) { meshNotifyStr.push('None'); }
+ x += addHtmlValue('Notifications', addLink(meshNotifyStr.join(', '), 'p20editMeshNotify()'));
+
// Intel AMT setup
var intelAmtPolicy = 'No Policy';
if (currentMesh.amt) {
@@ -6755,6 +6772,29 @@
function p20deleteUser(e, userid) { haltEvent(e); p20viewuserEx(2, decodeURIComponent(userid)); return false; }
function p20viewuserEx2(button, userid) { meshserver.send({ action: 'removemeshuser', meshid: currentMesh._id, meshname: currentMesh.name, userid: userid }); }
+ function p20editMeshNotify() {
+ if (xxdialogMode) return false;
+ var meshNotify = 0;
+ if (userinfo.links && userinfo.links[currentMesh._id] && userinfo.links[currentMesh._id].notify) { meshNotify = userinfo.links[currentMesh._id].notify; }
+ var x = '';
+ x += ' Device connections.
';
+ x += ' Device disconnections.
';
+ x += ' Intel® AMT desktop and serial events.
';
+ setDialogMode(2, "Notification Settings", 3, p20editMeshNotifyEx, x);
+ Q('p20notifyIntelDeviceConnect').checked = (meshNotify & 2);
+ Q('p20notifyIntelDeviceDisconnect').checked = (meshNotify & 4);
+ Q('p20notifyIntelAmtKvmActions').checked = (meshNotify & 8);
+ return false;
+ }
+
+ function p20editMeshNotifyEx() {
+ var meshNotify = 0;
+ meshNotify += Q('p20notifyIntelDeviceConnect').checked ? 2 : 0;
+ meshNotify += Q('p20notifyIntelDeviceDisconnect').checked ? 4 : 0;
+ meshNotify += Q('p20notifyIntelAmtKvmActions').checked ? 8 : 0;
+ meshserver.send({ action: 'changemeshnotify', meshid: currentMesh._id, notify: meshNotify });
+ }
+
//
// MY FILES
//