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 {