More web push progress.

Ylian Saint-Hilaire committed Feb 9, 2021 at 01:46 UTC c122402dd828c36587758f844987786b3c492fdf
3 files changed +58 -89
meshuser.js
+20
@@ -907,6 +907,22 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
907 }
908 break;
909 }
910 + case 'webpush': {
911 + if (parent.parent.webpush == null) {
912 + r = "Web push not supported.";
913 + } else {
914 + if (cmdargs['_'].length != 1) {
915 + r = "Usage: WebPush \"Message\"";
916 + } else {
917 + const pushSubscription = { "endpoint": "https://updates.push.services.mozilla.com/wpush/v2/gAAAAABgIkO9hjXHWhMPiuk-ppNRw7r_pUZitddwCEK4ykdzeIxOIjFnYhIt_nr-qUca2mpZziwQsSEhYTUCiuYrhWnVDRweMtiUj16yJJq8V5jneaEaUYjEIe5jp3DOMNpoTm1aHgX74gCR8uTXSITcM97bNi-hRxcQ4f6Ie4WSAmoXpd89B_g", "keys": { "auth": "UB2sbLVK7ALnSHw5P1dahg", "p256dh": "BIoRbcNSxBuTjN39CCCUCHo1f4NxBJ1YDdu_k4MbPW_q3NK1_RufnydUzLPDp8ibBVItSI72-s48QJvOjQ_S8Ok" } }
918 + parent.parent.webpush.sendNotification(pushSubscription, cmdargs['_'][0]).then(
919 + function (value) { try { ws.send(JSON.stringify({ action: 'OK', value: r, tag: command.tag })); } catch (ex) { } },
920 + function (error) { try { ws.send(JSON.stringify({ action: 'Error', value: r, tag: command.tag })); } catch (ex) { } }
921 + );
922 + }
923 + }
924 + break;
925 + }
926 case 'amtmanager': {
927 if (parent.parent.amtManager == null) { r = 'Intel AMT Manager not active.'; } else { r = parent.parent.amtManager.getStatusString(); }
928 break;
@@ -5275,6 +5291,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5291 });
5292 break;
5293 }
5294 + case 'webpush': {
5295 + //console.log(command);
5296 + break;
5297 + }
5298 case 'print': {
5299 console.log(command.value);
5300 break;
public/serviceworker.js
+2 -49
@@ -1,25 +1,6 @@
1
2 -// "BMWzSl5zZPWw_lAKVvQb8NZBQwCs83jQJc68cj04yQTYt_kAIvuCMte0wU7BXjODXuGn8ut5qwU0pR_44dZuAmQ"
3 -
4 -self.addEventListener('install', event => {
5 - console.log('Service Worker install', event);
6 -});
7 -
8 -
9 -// This will be called only once when the service worker is activated.
10 -self.addEventListener('activate', async() => {
11 -try {
12 - const applicationServerKey = urlB64ToUint8Array('BMWzSl5zZPWw_lAKVvQb8NZBQwCs83jQJc68cj04yQTYt_kAIvuCMte0wU7BXjODXuGn8ut5qwU0pR_44dZuAmQ')
13 - const options = { applicationServerKey, userVisibleOnly: true }
14 - const subscription = await self.registration.pushManager.subscribe(options)
15 - console.log(JSON.stringify(subscription))
16 - } catch (err) {
17 - console.log('Error', err)
18 - }
19 -})
20 -
2 self.addEventListener('push', function (event) {
22 - console.log('Service Worker push', event);
3 + console.log('Service Worker push', JSON.stringify(event));
4 if (event.data) {
5 console.log("Push event!! ", event.data.text());
6 showLocalNotification("Yolo", event.data.text(), self.registration);
@@ -28,38 +9,10 @@ self.addEventListener('push', function (event) {
9 }
10 });
11
31 -
32 -self.addEventListener('message', function(event) {
33 - console.log('Service Worker message', event);
34 - if (isObject(event.data)) {
35 - if (event.data.type === 'sync') {
36 - // in this way, you can decide your tag
37 - //const id = event.data.id || uuid()
38 - // pass the port into the memory stor
39 - //syncStore[id] = Object.assign({ port: event.ports[0] }, event.data)
40 - //self.registration.sync.register(id)
41 - }
42 - }
43 -})
44 -
45 -self.addEventListener('sync', function(event) {
46 - console.log('Service Worker sync', event);
47 -})
48 -
12 const showLocalNotification = function(title, body, swRegistration) {
13 const options = {
14 body
15 // here you can add more properties like icon, image, vibrate, etc.
16 };
17 swRegistration.showNotification(title, options);
55 -};
56 -
57 -// Used to convert Base64 public VAPID key to bytearray.
58 -function urlBase64ToUint8Array(base64String) {
59 - const padding = '='.repeat((4 - base64String.length % 4) % 4);
60 - const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
61 - const rawData = window.atob(base64);
62 - const outputArray = new Uint8Array(rawData.length);
63 - for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); }
64 - return outputArray;
65 -}
\ No newline at end of file
18 +};
\ No newline at end of file
views/default.handlebars
+36 -40
@@ -354,7 +354,6 @@
354 <p class="mL">
355 <span id="managePhoneNumber2" style="display:none"><a href=# onclick="return account_managePhone()">Manage phone number</a><br /></span>
356 <span id="verifyEmailId" style="display:none"><a href=# onclick="return account_showVerifyEmail()">Verify email</a><br /></span>
357 - <span id="accountEnablePushNotificationsSpan" style="display:none"><a href=# onclick="return account_enablePushNotifications()">Enable push notifications</a><br /></span>
357 <span id="accountEnableNotificationsSpan" style="display:none"><a href=# onclick="return account_enableNotifications()">Enable web notifications</a><br /></span>
358 <a href=# onclick="return account_showLocalizationSettings()">Localization Settings</a><br />
359 <a href=# onclick="return account_showAccountNotifySettings()">Notification Settings</a><br />
@@ -1360,37 +1359,6 @@
1359 // Fix links if a loginKey is used
1360 if (urlargs.key) { Q('termsLinkFooter').href += '?key=' + urlargs.key; }
1361
1363 - /*
1364 - // Register the service worker
1365 - if ('serviceWorker' in navigator) {
1366 - navigator.serviceWorker.addEventListener('message', function(event) {
1367 - console.log("Client message from service worker: " + event);
1368 - });
1369 -
1370 - navigator.serviceWorker.register('serviceworker.js')
1371 - .then(function(reg) {
1372 - // Registration worked
1373 - console.log('Registration succeeded. Scope is ' + reg.scope);
1374 -
1375 - reg.pushManager.getSubscription().then(function(sub) {
1376 - if (sub === null) {
1377 - // Update UI to ask user to register for Push
1378 - console.log('Not subscribed to push service.');
1379 - } else {
1380 - // We have a subscription, update the database
1381 - console.log('Subscription object: ', sub);
1382 -
1383 - navigator.serviceWorker.controller.postMessage({type: 'sync', text: 'Hello!'})
1384 - }
1385 - });
1386 -
1387 - }).catch((error) => {
1388 - // Registration failed
1389 - console.log('Registration failed with ' + error);
1390 - });
1391 - }
1392 - */
1393 -
1362 // Check if we are in debug mode
1363 args = parseUriArgs();
1364 if (args.key && (isAlphaNumeric(args.key) == false)) { delete args.key; }
@@ -2098,7 +2066,7 @@
2066 serverinfo = message.serverinfo;
2067 if (serverinfo.timeout) { setInterval(checkIdleSessionTimeout, 10000); checkIdleSessionTimeout(); }
2068 if (debugmode == 1) { console.log('Server time: ', printDateTime(new Date(serverinfo.serverTime))); }
2101 - //console.log(serverinfo);
2069 + setupServiceWorker();
2070 break;
2071 }
2072 case 'userinfo': {
@@ -9692,13 +9660,8 @@
9660 }
9661 }
9662
9695 - function account_enablePushNotifications() {
9696 - if ((serverinfo == null) || (serverinfo.vapidpublickey == null)) return;
9697 - return false;
9698 - }
9699 -
9663 function account_enableNotifications() {
9701 - if (Notification) { Notification.requestPermission().then(function (permission) { QV('accountEnableNotificationsSpan', permission != 'granted'); }); }
9664 + if (Notification) { Notification.requestPermission().then(function (permission) { QV('accountEnableNotificationsSpan', permission != 'granted'); setupServiceWorker(); }); }
9665 return false;
9666 }
9667
@@ -13873,6 +13836,30 @@
13836 return false;
13837 }
13838
13839 +
13840 + //
13841 + // SERVICE WORKER
13842 + //
13843 +
13844 + function setupServiceWorker() {
13845 + if ((typeof serverinfo.vapidpublickey != 'string') || (Notification == null) || (Notification.permission != 'granted')) return;
13846 + // Register the service worker
13847 + if ('serviceWorker' in navigator) {
13848 + navigator.serviceWorker.register('serviceworker.js')
13849 + .then(function(reg) {
13850 + // Subscribe to push notifications
13851 + navigator.serviceWorker.ready.then(function(reg) {
13852 + reg.pushManager.subscribe({ applicationServerKey: urlBase64ToUint8Array(serverinfo.vapidpublickey), userVisibleOnly: true }).then(function(sub) {
13853 + meshserver.send({ action: 'webpush', sub: sub });
13854 + }).catch(function(e) { console.error('Unable to subscribe to push', e); });
13855 + })
13856 + }).catch(function(error) {
13857 + // Registration failed
13858 + console.log('Registration failed', error);
13859 + });
13860 + }
13861 + }
13862 +
13863 //
13864 // POPUP DIALOG
13865 //
@@ -14081,7 +14068,6 @@
14068
14069 // Setup web notifications
14070 if ((x == 2) && Notification) { QV('accountEnableNotificationsSpan', Notification.permission != 'granted'); }
14084 - //QV('accountEnablePushNotificationsSpan', true);
14071
14072 // Fetch the server timeline stats if needed
14073 if ((x == 40) && (serverTimelineStats == null)) { refreshServerTimelineStats(); }
@@ -14416,6 +14402,16 @@
14402 if (typeof Symbol!=='undefined')TextEncoder.prototype[Symbol.toStringTag]='TextEncoder';
14403 }
14404
14405 + // Used to convert Base64 public VAPID key to bytearray.
14406 + function urlBase64ToUint8Array(base64String) {
14407 + const padding = '='.repeat((4 - base64String.length % 4) % 4);
14408 + const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
14409 + const rawData = atob(base64);
14410 + const outputArray = new Uint8Array(rawData.length);
14411 + for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); }
14412 + return outputArray;
14413 + }
14414 +
14415 function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); }
14416 function putstore(name, val) {
14417 try {