mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2025-01-24 13:13:13 -05:00
Added device state notifications to messaging applications.
This commit is contained in:
parent
1e45b69ca7
commit
1a6e78efed
@ -2302,7 +2302,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
const domainId = meshSplit[1];
|
||||
if (obj.config.domains[domainId] == null) return;
|
||||
const mailserver = obj.config.domains[domainId].mailserver;
|
||||
if (mailserver == null) return;
|
||||
if ((mailserver == null) && (obj.msgserver == null)) return;
|
||||
|
||||
// Get the device group for this device
|
||||
const mesh = obj.webserver.meshes[meshid];
|
||||
@ -2335,7 +2335,8 @@ function CreateMeshCentralServer(config, args) {
|
||||
if (user.notify[nodeid] != null) { notify |= user.notify[nodeid]; }
|
||||
}
|
||||
|
||||
if ((notify & 48) != 0) {
|
||||
// Email notifications
|
||||
if ((mailserver != null) && ((notify & 48) != 0)) {
|
||||
if (stateSet == true) {
|
||||
if ((notify & 16) != 0) {
|
||||
mailserver.notifyDeviceConnect(user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo);
|
||||
@ -2351,6 +2352,24 @@ function CreateMeshCentralServer(config, args) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Messaging notifications
|
||||
if ((obj.msgserver != null) && ((notify & 384) != 0)) {
|
||||
if (stateSet == true) {
|
||||
if ((notify & 128) != 0) {
|
||||
obj.msgserver.notifyDeviceConnect(user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo);
|
||||
} else {
|
||||
obj.msgserver.cancelNotifyDeviceDisconnect(user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo);
|
||||
}
|
||||
}
|
||||
else if (stateSet == false) {
|
||||
if ((notify & 256) != 0) {
|
||||
obj.msgserver.notifyDeviceDisconnect(user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo);
|
||||
} else {
|
||||
obj.msgserver.cancelNotifyDeviceConnect(user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
207
meshmessaging.js
207
meshmessaging.js
@ -122,6 +122,7 @@ module.exports.CreateServer = function (parent) {
|
||||
obj.callMeBotClient = null;
|
||||
obj.pushoverClient = null;
|
||||
obj.zulipClient = null;
|
||||
const sortCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })
|
||||
|
||||
// Telegram client setup
|
||||
if (parent.config.messaging.telegram) {
|
||||
@ -347,7 +348,7 @@ module.exports.CreateServer = function (parent) {
|
||||
if (func != null) { func(true); }
|
||||
} else {
|
||||
// No providers found
|
||||
func(false, "No messaging providers found for this message.");
|
||||
if (func != null) { func(false, "No messaging providers found for this message."); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,6 +437,210 @@ module.exports.CreateServer = function (parent) {
|
||||
obj.sendMessage(to, sms, domain, func);
|
||||
};
|
||||
|
||||
// Send device state change notification
|
||||
obj.sendDeviceNotify = function (domain, username, to, connections, disconnections, lang) {
|
||||
if (to == null) return;
|
||||
parent.debug('email', "Sending device state change message to " + to);
|
||||
|
||||
var sms = [];
|
||||
if (connections.length > 0) { sms.push('Connections: ' + connections.join(', ')); } // TODO: Translate 'Connections: '
|
||||
if (disconnections.length > 0) { sms.push('Disconnections: ' + disconnections.join(', ')); } // TODO: Translate 'Disconnections: '
|
||||
if (sms.length == 0) return;
|
||||
sms = sms.join(' - ');
|
||||
if (sms.length > 1000) { sms = sms.substring(0, 997) + '...'; } // Limit messages to 1000 characters
|
||||
|
||||
// Send the message
|
||||
obj.sendMessage(to, sms, domain, null);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Device connetion and disconnection notifications
|
||||
//
|
||||
|
||||
obj.deviceNotifications = {}; // UserId --> { timer, nodes: nodeid --> connectType }
|
||||
|
||||
// A device connected and a user needs to be notified about it.
|
||||
obj.notifyDeviceConnect = function (user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo) {
|
||||
const mesh = parent.webserver.meshes[meshid];
|
||||
if (mesh == null) return;
|
||||
|
||||
// Add the user and start a timer
|
||||
if (obj.deviceNotifications[user._id] == null) {
|
||||
obj.deviceNotifications[user._id] = { nodes: {} };
|
||||
obj.deviceNotifications[user._id].timer = setTimeout(function () { sendDeviceNotifications(user._id); }, 1 * 60 * 1000); // 1 minute before message is sent
|
||||
}
|
||||
|
||||
// Add the device
|
||||
if (obj.deviceNotifications[user._id].nodes[nodeid] == null) {
|
||||
obj.deviceNotifications[user._id].nodes[nodeid] = { c: connectType }; // This device connection need to be added
|
||||
} else {
|
||||
const info = obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if ((info.d != null) && ((info.d & connectType) != 0)) {
|
||||
info.d -= connectType; // This device disconnect cancels out a device connection
|
||||
if (((info.c == null) || (info.c == 0)) && ((info.d == null) || (info.d == 0))) {
|
||||
// This device no longer needs a notification
|
||||
delete obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if (Object.keys(obj.deviceNotifications[user._id].nodes).length == 0) {
|
||||
// This user no longer needs a notification
|
||||
clearTimeout(obj.deviceNotifications[user._id].timer);
|
||||
delete obj.deviceNotifications[user._id];
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (info.c != null) {
|
||||
info.c |= connectType; // This device disconnect needs to be added
|
||||
} else {
|
||||
info.c = connectType; // This device disconnect needs to be added
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the device group name
|
||||
if ((extraInfo != null) && (extraInfo.name != null)) { obj.deviceNotifications[user._id].nodes[nodeid].nn = extraInfo.name; }
|
||||
obj.deviceNotifications[user._id].nodes[nodeid].mn = mesh.name;
|
||||
}
|
||||
|
||||
// Cancel a device disconnect notification
|
||||
obj.cancelNotifyDeviceDisconnect = function (user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo) {
|
||||
const mesh = parent.webserver.meshes[meshid];
|
||||
if (mesh == null) return;
|
||||
|
||||
if ((obj.deviceNotifications[user._id] != null) && (obj.deviceNotifications[user._id].nodes[nodeid] != null)) {
|
||||
const info = obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if ((info.d != null) && ((info.d & connectType) != 0)) {
|
||||
info.d -= connectType; // This device disconnect cancels out a device connection
|
||||
if (((info.c == null) || (info.c == 0)) && ((info.d == null) || (info.d == 0))) {
|
||||
// This device no longer needs a notification
|
||||
delete obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if (Object.keys(obj.deviceNotifications[user._id].nodes).length == 0) {
|
||||
// This user no longer needs a notification
|
||||
clearTimeout(obj.deviceNotifications[user._id].timer);
|
||||
delete obj.deviceNotifications[user._id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A device disconnected and a user needs to be notified about it.
|
||||
obj.notifyDeviceDisconnect = function (user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo) {
|
||||
const mesh = parent.webserver.meshes[meshid];
|
||||
if (mesh == null) return;
|
||||
|
||||
// Add the user and start a timer
|
||||
if (obj.deviceNotifications[user._id] == null) {
|
||||
obj.deviceNotifications[user._id] = { nodes: {} };
|
||||
obj.deviceNotifications[user._id].timer = setTimeout(function () { sendDeviceNotifications(user._id); }, 1 * 60 * 1000); // 1 minute before message is sent
|
||||
}
|
||||
|
||||
// Add the device
|
||||
if (obj.deviceNotifications[user._id].nodes[nodeid] == null) {
|
||||
obj.deviceNotifications[user._id].nodes[nodeid] = { d: connectType }; // This device disconnect need to be added
|
||||
} else {
|
||||
const info = obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if ((info.c != null) && ((info.c & connectType) != 0)) {
|
||||
info.c -= connectType; // This device disconnect cancels out a device connection
|
||||
if (((info.d == null) || (info.d == 0)) && ((info.c == null) || (info.c == 0))) {
|
||||
// This device no longer needs a notification
|
||||
delete obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if (Object.keys(obj.deviceNotifications[user._id].nodes).length == 0) {
|
||||
// This user no longer needs a notification
|
||||
clearTimeout(obj.deviceNotifications[user._id].timer);
|
||||
delete obj.deviceNotifications[user._id];
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (info.d != null) {
|
||||
info.d |= connectType; // This device disconnect needs to be added
|
||||
} else {
|
||||
info.d = connectType; // This device disconnect needs to be added
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the device group name
|
||||
if ((extraInfo != null) && (extraInfo.name != null)) { obj.deviceNotifications[user._id].nodes[nodeid].nn = extraInfo.name; }
|
||||
obj.deviceNotifications[user._id].nodes[nodeid].mn = mesh.name;
|
||||
}
|
||||
|
||||
// Cancel a device connect notification
|
||||
obj.cancelNotifyDeviceConnect = function (user, meshid, nodeid, connectTime, connectType, powerState, serverid, extraInfo) {
|
||||
const mesh = parent.webserver.meshes[meshid];
|
||||
if (mesh == null) return;
|
||||
|
||||
if ((obj.deviceNotifications[user._id] != null) && (obj.deviceNotifications[user._id].nodes[nodeid] != null)) {
|
||||
const info = obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if ((info.c != null) && ((info.c & connectType) != 0)) {
|
||||
info.c -= connectType; // This device disconnect cancels out a device connection
|
||||
if (((info.d == null) || (info.d == 0)) && ((info.c == null) || (info.c == 0))) {
|
||||
// This device no longer needs a notification
|
||||
delete obj.deviceNotifications[user._id].nodes[nodeid];
|
||||
if (Object.keys(obj.deviceNotifications[user._id].nodes).length == 0) {
|
||||
// This user no longer needs a notification
|
||||
clearTimeout(obj.deviceNotifications[user._id].timer);
|
||||
delete obj.deviceNotifications[user._id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send a notification about device connections and disconnections to a user
|
||||
function sendDeviceNotifications(userid) {
|
||||
if (obj.deviceNotifications[userid] == null) return;
|
||||
clearTimeout(obj.deviceNotifications[userid].timer);
|
||||
|
||||
var connections = [];
|
||||
var disconnections = [];
|
||||
|
||||
for (var nodeid in obj.deviceNotifications[userid].nodes) {
|
||||
var info = obj.deviceNotifications[userid].nodes[nodeid];
|
||||
if ((info.c != null) && (info.c > 0) && (info.nn != null) && (info.mn != null)) {
|
||||
/*
|
||||
var c = [];
|
||||
if (info.c & 1) { c.push("Agent"); }
|
||||
if (info.c & 2) { c.push("CIRA"); }
|
||||
if (info.c & 4) { c.push("AMT"); }
|
||||
if (info.c & 8) { c.push("AMT-Relay"); }
|
||||
if (info.c & 16) { c.push("MQTT"); }
|
||||
connections.push(info.mn + ', ' + info.nn + ': ' + c.join(', '));
|
||||
*/
|
||||
if (info.c & 1) { connections.push(info.nn); }
|
||||
}
|
||||
if ((info.d != null) && (info.d > 0) && (info.nn != null) && (info.mn != null)) {
|
||||
/*
|
||||
var d = [];
|
||||
if (info.d & 1) { d.push("Agent"); }
|
||||
if (info.d & 2) { d.push("CIRA"); }
|
||||
if (info.d & 4) { d.push("AMT"); }
|
||||
if (info.d & 8) { d.push("AMT-Relay"); }
|
||||
if (info.d & 16) { d.push("MQTT"); }
|
||||
disconnections.push(info.mn + ', ' + info.nn + ': ' + d.join(', '));
|
||||
*/
|
||||
if (info.d & 1) { disconnections.push(info.nn); }
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the notifications
|
||||
connections.sort(sortCollator.compare);
|
||||
disconnections.sort(sortCollator.compare);
|
||||
|
||||
// Get the user and domain
|
||||
const user = parent.webserver.users[userid];
|
||||
if ((user == null) || (user.email == null) || (user.emailVerified !== true)) return;
|
||||
const domain = obj.parent.config.domains[user.domain];
|
||||
if (domain == null) return;
|
||||
|
||||
// Send the message
|
||||
obj.sendDeviceNotify(domain, user.name, user.msghandle, connections, disconnections, user.llang);
|
||||
|
||||
// Clean up
|
||||
delete obj.deviceNotifications[userid];
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
49
meshuser.js
49
meshuser.js
@ -1717,12 +1717,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
{
|
||||
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
|
||||
// 64 = Email device help request
|
||||
// 2 = WebPage device connections
|
||||
// 4 = WebPage device disconnections
|
||||
// 8 = WebPage device desktop and serial events
|
||||
// 16 = Email device connections
|
||||
// 32 = Email device disconnections
|
||||
// 64 = Email device help request
|
||||
// 128 = Messaging device connections
|
||||
// 256 = Messaging device disconnections
|
||||
// 512 = Messaging device help request
|
||||
|
||||
var err = null;
|
||||
try {
|
||||
@ -1767,12 +1770,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
{
|
||||
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
|
||||
// 64 = Email device help request
|
||||
// 2 = WebPage device connections
|
||||
// 4 = WebPage device disconnections
|
||||
// 8 = WebPage device desktop and serial events
|
||||
// 16 = Email device connections
|
||||
// 32 = Email device disconnections
|
||||
// 64 = Email device help request
|
||||
// 128 = Messaging device connections
|
||||
// 256 = Messaging device disconnections
|
||||
// 512 = Messaging device help request
|
||||
|
||||
var err = null;
|
||||
try {
|
||||
@ -5312,6 +5318,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
'dupagents': [serverUserCommandDupAgents, ""],
|
||||
'email': [serverUserCommandEmail, ""],
|
||||
'emailnotifications': [serverUserCommandEmailNotifications, ""],
|
||||
'msgnotifications': [serverUserCommandMessageNotifications, ""],
|
||||
'firebase': [serverUserCommandFirebase, ""],
|
||||
'heapdump': [serverUserCommandHeapDump, ""],
|
||||
'heapdump2': [serverUserCommandHeapDump2, ""],
|
||||
@ -6892,7 +6899,23 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
x += ' ' + info.mn + ', ' + info.nn + ', c:' + (info.c ? info.c : 0) + ', d:' + (info.d ? info.d : 0) + '\r\n';
|
||||
}
|
||||
}
|
||||
cmdData.result = ((x == '')?'None':x);
|
||||
cmdData.result = ((x == '') ? 'None' : x);
|
||||
}
|
||||
}
|
||||
|
||||
function serverUserCommandMessageNotifications(cmdData) {
|
||||
if (parent.parent.msgserver == null) {
|
||||
cmdData.result = "No messaging service enabled.";
|
||||
} else {
|
||||
var x = '';
|
||||
for (var userid in parent.parent.msgserver.deviceNotifications) {
|
||||
x += userid + '\r\n';
|
||||
for (var nodeid in parent.parent.msgserver.deviceNotifications[userid].nodes) {
|
||||
const info = parent.parent.msgserver.deviceNotifications[userid].nodes[nodeid];
|
||||
x += ' ' + info.mn + ', ' + info.nn + ', c:' + (info.c ? info.c : 0) + ', d:' + (info.d ? info.d : 0) + '\r\n';
|
||||
}
|
||||
}
|
||||
cmdData.result = ((x == '') ? 'None' : x);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user