mirror of
				https://github.com/Ylianst/MeshCentral.git
				synced 2025-03-09 15:40:18 +00:00 
			
		
		
		
	More web push progress.
This commit is contained in:
		
							parent
							
								
									50185dac86
								
							
						
					
					
						commit
						af1fcb8431
					
				
					 4 changed files with 86 additions and 22 deletions
				
			
		
							
								
								
									
										27
									
								
								meshuser.js
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								meshuser.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2746,6 +2746,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                    if (parent.parent.multiServer != null) {
 | 
			
		||||
                        // TODO: Add multi-server support
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // If the user is not connected, use web push if available.
 | 
			
		||||
                    if ((parent.wssessions[chguser._id] == null) && (parent.sessionsCount[chguser._id] == null)) {
 | 
			
		||||
                        // Perform web push notification
 | 
			
		||||
                        var payload = { body: command.msg, icon: 8 }; // Icon 8 is the user icon.
 | 
			
		||||
                        if (command.url) { payload.url = command.url; }
 | 
			
		||||
                        if (domain.title != null) { payload.title = domain.title; } else { payload.title = "MeshCentral"; }
 | 
			
		||||
                        payload.title += ' - ' + user.name;
 | 
			
		||||
                        parent.performWebPush(domain, chguser, payload, { TTL: 60 }); // For now, 1 minute TTL
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            case 'meshmessenger':
 | 
			
		||||
| 
						 | 
				
			
			@ -2772,6 +2783,22 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
 | 
			
		|||
                        if (parent.parent.multiServer != null) {
 | 
			
		||||
                            // TODO: Add multi-server support
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // If the user is not connected, use web push if available.
 | 
			
		||||
                        if ((parent.wssessions[chguser._id] == null) && (parent.sessionsCount[chguser._id] == null)) {
 | 
			
		||||
                            // Create the server url
 | 
			
		||||
                            var httpsPort = ((args.aliasport == null) ? args.port : args.aliasport); // Use HTTPS alias port is specified
 | 
			
		||||
                            var xdomain = (domain.dns == null) ? domain.id : '';
 | 
			
		||||
                            if (xdomain != '') xdomain += "/";
 | 
			
		||||
                            var url = "https://" + parent.getWebServerName(domain) + ":" + httpsPort + "/" + xdomain + "messenger?id=meshmessenger/" + encodeURIComponent(command.userid) + "/" + encodeURIComponent(user._id);
 | 
			
		||||
 | 
			
		||||
                            // Perform web push notification
 | 
			
		||||
                            var payload = { body: "Chat Request, Click here to accept.", icon: 8, url: url }; // Icon 8 is the user icon.
 | 
			
		||||
                            if (domain.title != null) { payload.title = domain.title; } else { payload.title = "MeshCentral"; }
 | 
			
		||||
                            payload.title += ' - ' + user.name;
 | 
			
		||||
                            parent.performWebPush(domain, chguser, payload, { TTL: 60 }); // For now, 1 minute TTL
 | 
			
		||||
                        }
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // User-to-device chat is not support in LAN-only mode yet. We need the agent to replace the IP address of the server??
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +1,13 @@
 | 
			
		|||
 | 
			
		||||
self.addEventListener('push', function (event) {
 | 
			
		||||
    console.log('Service Worker push', JSON.stringify(event));
 | 
			
		||||
    if (event.data) {
 | 
			
		||||
        console.log("Push event!! ", event.data.text());
 | 
			
		||||
        showLocalNotification("Yolo", event.data.text(), self.registration);
 | 
			
		||||
    } else {
 | 
			
		||||
        console.log("Push event but no data");
 | 
			
		||||
    }
 | 
			
		||||
    if (event.data == null) return;
 | 
			
		||||
    var json = event.data.json();
 | 
			
		||||
    const options = { body: json.body, icon: '/favicon-303x303.png', tag: json.url };
 | 
			
		||||
    if (json.icon) { options.icon = '/images/notify/icons128-' + json.icon + '.png'; }
 | 
			
		||||
    self.registration.showNotification(json.title, options);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const showLocalNotification = function(title, body, swRegistration) {
 | 
			
		||||
  const options = {
 | 
			
		||||
    body
 | 
			
		||||
    // here you can add more properties like icon, image, vibrate, etc.
 | 
			
		||||
  };
 | 
			
		||||
  swRegistration.showNotification(title, options);
 | 
			
		||||
};
 | 
			
		||||
self.addEventListener('notificationclick', function (event) {
 | 
			
		||||
    event.notification.close();
 | 
			
		||||
    if ((event.notification.tag != null) && (event.notification.tag != '')) { event.waitUntil(self.clients.openWindow(event.notification.tag)); }
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -12732,10 +12732,10 @@
 | 
			
		|||
            x += '<input type=button value="' + "Notes" + '" title="' + "View notes about this user" + '" onclick=showNotes(false,"' + encodeURIComponentEx(user._id) + '") />';
 | 
			
		||||
            if (user.phone && (features & 0x02000000)) { x += '<input type=button value="' + "SMS" + '" title="' + "Send a SMS message to this user" + '" onclick=showSendSMS("' + encodeURIComponentEx(user._id) + '") />'; }
 | 
			
		||||
            if ((typeof user.email == 'string') && (user.emailVerified === true) && (features & 0x00000040)) { x += '<input type=button value="' + "Email" + '" title="' + "Send a email message to this user" + '" onclick=showSendEmail("' + encodeURIComponentEx(user._id) + '") />'; }
 | 
			
		||||
            if (!self && (activeSessions > 0)) {
 | 
			
		||||
            if (!self && ((activeSessions > 0) || ((features2 & 8) && (user.webpush)))) {
 | 
			
		||||
                x += '<input type=button value="' + "Notify" + '" title="' + "Send user notification" + '" onclick=showUserAlertDialog(event,"' + encodeURIComponentEx(user._id) + '") />';
 | 
			
		||||
                x += '<input type=button value="' + "Chat" + '" title="' + "Chat" + '" onclick=userChat(event,"' + encodeURIComponentEx(user._id) + '","' + encodeURIComponentEx(user.name) + '") />';
 | 
			
		||||
                if ((serverinfo != null) && (serverinfo.altmessenging != null)) { for (var i in serverinfo.altmessenging) { x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altUserChat(event,"' + encodeURIComponentEx(user._id) + '","' + encodeURIComponentEx(user.name) + '",' + i + ') />'; } }
 | 
			
		||||
                if ((activeSessions > 0) && (serverinfo != null) && (serverinfo.altmessenging != null)) { for (var i in serverinfo.altmessenging) { x += '<input type=button value="' + EscapeHtml(serverinfo.altmessenging[i].name) + '" onclick=altUserChat(event,"' + encodeURIComponentEx(user._id) + '","' + encodeURIComponentEx(user.name) + '",' + i + ') />'; } }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Setup the panel
 | 
			
		||||
| 
						 | 
				
			
			@ -13852,11 +13852,11 @@
 | 
			
		|||
                    navigator.serviceWorker.ready.then(function(reg) {
 | 
			
		||||
                        reg.pushManager.subscribe({ applicationServerKey: urlBase64ToUint8Array(serverinfo.vapidpublickey), userVisibleOnly: true }).then(function(sub) {
 | 
			
		||||
                            meshserver.send({ action: 'webpush', sub: sub });
 | 
			
		||||
                        }).catch(function(e) { console.error('Unable to subscribe to push', e); });
 | 
			
		||||
                        }).catch(function(e) { console.error('Worker: Unable to subscribe to push', e); });
 | 
			
		||||
                    })
 | 
			
		||||
                }).catch(function(error) {
 | 
			
		||||
                    // Registration failed
 | 
			
		||||
                    console.log('Registration failed', error);
 | 
			
		||||
                    console.log('Worker: Registration failed', error);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -14405,10 +14405,10 @@
 | 
			
		|||
 | 
			
		||||
        // Used to convert Base64 public VAPID key to bytearray.
 | 
			
		||||
        function urlBase64ToUint8Array(base64String) {
 | 
			
		||||
            const padding = '='.repeat((4 - base64String.length % 4) % 4);
 | 
			
		||||
            const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
 | 
			
		||||
            const rawData = atob(base64);
 | 
			
		||||
            const outputArray = new Uint8Array(rawData.length);
 | 
			
		||||
            var padding = '='.repeat((4 - base64String.length % 4) % 4);
 | 
			
		||||
            var base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
 | 
			
		||||
            var rawData = atob(base64);
 | 
			
		||||
            var outputArray = new Uint8Array(rawData.length);
 | 
			
		||||
            for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); }
 | 
			
		||||
            return outputArray;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										42
									
								
								webserver.js
									
										
									
									
									
								
							
							
						
						
									
										42
									
								
								webserver.js
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6686,6 +6686,48 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Perform a web push to a user
 | 
			
		||||
    // If any of the push fail, remove the subscription from the user's webpush subscription list.
 | 
			
		||||
    obj.performWebPush = function (domain, user, payload, options) {
 | 
			
		||||
        if ((parent.webpush == null) || (Array.isArray(user.webpush) == false) || (user.webpush.length == 0)) return;
 | 
			
		||||
 | 
			
		||||
        var completionFunc = function pushCompletionFunc(sub, fail) {
 | 
			
		||||
            pushCompletionFunc.failCount += fail;
 | 
			
		||||
            if (--pushCompletionFunc.pushCount == 0) {
 | 
			
		||||
                if (pushCompletionFunc.failCount > 0) {
 | 
			
		||||
                    var user = pushCompletionFunc.user, newwebpush = [];
 | 
			
		||||
                    for (var i in user.webpush) { if (user.webpush[i].fail == null) { newwebpush.push(user.webpush[i]); } }
 | 
			
		||||
                    user.webpush = newwebpush;
 | 
			
		||||
 | 
			
		||||
                    // Update the database
 | 
			
		||||
                    obj.db.SetUser(user);
 | 
			
		||||
 | 
			
		||||
                    // Event the change
 | 
			
		||||
                    var message = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', domain: domain.id, nolog: 1 };
 | 
			
		||||
                    if (db.changeStream) { message.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
 | 
			
		||||
                    var targets = ['*', 'server-users', user._id];
 | 
			
		||||
                    if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
 | 
			
		||||
                    parent.DispatchEvent(targets, obj, message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        completionFunc.pushCount = user.webpush.length;
 | 
			
		||||
        completionFunc.user = user;
 | 
			
		||||
        completionFunc.domain = domain;
 | 
			
		||||
        completionFunc.failCount = 0;
 | 
			
		||||
 | 
			
		||||
        for (var i in user.webpush) {
 | 
			
		||||
            var errorFunc = function pushErrorFunc(error) { pushErrorFunc.sub.fail = 1; pushErrorFunc.call(pushErrorFunc.sub, 1); }
 | 
			
		||||
            errorFunc.sub = user.webpush[i];
 | 
			
		||||
            errorFunc.call = completionFunc;
 | 
			
		||||
            var successFunc = function pushSuccessFunc(value) { pushSuccessFunc.call(pushSuccessFunc.sub, 0); }
 | 
			
		||||
            successFunc.sub = user.webpush[i];
 | 
			
		||||
            successFunc.call = completionFunc;
 | 
			
		||||
            parent.webpush.sendNotification(user.webpush[i], JSON.stringify(payload), options).then(successFunc, errorFunc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Return true if a mobile browser is detected.
 | 
			
		||||
    // This code comes from "http://detectmobilebrowsers.com/" and was modified, This is free and unencumbered software released into the public domain. For more information, please refer to the http://unlicense.org/
 | 
			
		||||
    function isMobileBrowser(req) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue