From 44cfe0d88e125733c271b1dad882c5c309cb38db Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Fri, 22 Dec 2023 14:22:13 -0700 Subject: [PATCH] allow notifications even without an ID --- project.task.yaml | 5 + src/views/HelpNotificationsView.vue | 7 +- sw_scripts/safari-notifications.js | 140 ++++++++++++++-------------- 3 files changed, 81 insertions(+), 71 deletions(-) diff --git a/project.task.yaml b/project.task.yaml index 5ba2e88..df49f3e 100644 --- a/project.task.yaml +++ b/project.task.yaml @@ -4,6 +4,11 @@ tasks: - 08 notifications : - get the rest of our Android devices to work... and insert tooling (exportable logs?) so that we can see problems and troubleshoot as we onboard - get an error registering notifications on Firefox and subscription info is null + - if navigator.serviceWorker is null, then tell the user to wait + - Android DuckDuckGo asked for my permissions, got error, won't download DB + - Android Chrome won't ask permission, will download log but always empty + - + - Chrome will get notification permissions but still complain when I reload (maybe I reload too soon?) - prompt user to install on their home screen https://benborgers.com/posts/pwa-detect-installed - warn if they're using the web (android only?) https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getInstalledRelatedApps diff --git a/src/views/HelpNotificationsView.vue b/src/views/HelpNotificationsView.vue index c734ba4..a7c125b 100644 --- a/src/views/HelpNotificationsView.vue +++ b/src/views/HelpNotificationsView.vue @@ -22,7 +22,7 @@
-

Here are things to try to get notifications working.

+

Here are things to get notifications working.

Test

Somehow call the service-worker self.showNotification

@@ -54,7 +54,10 @@
Make sure your OS (above) supports it.

Mobile Phone - Android

-
Chrome requires version 50.
+
+ Chrome requires version 50. Hold icon, select "App info", and enable + notifications. +
diff --git a/sw_scripts/safari-notifications.js b/sw_scripts/safari-notifications.js index 22dcf99..a50980f 100644 --- a/sw_scripts/safari-notifications.js +++ b/sw_scripts/safari-notifications.js @@ -461,10 +461,10 @@ function updateRecord(store, data) { async function fetchAllAccounts() { return new Promise((resolve, reject) => { - let openRequest = indexedDB.open("TimeSafariAccounts"); + const openRequest = indexedDB.open("TimeSafariAccounts"); openRequest.onupgradeneeded = function (event) { - let db = event.target.result; + const db = event.target.result; if (!db.objectStoreNames.contains("accounts")) { db.createObjectStore("accounts", { keyPath: "id" }); } @@ -474,10 +474,10 @@ async function fetchAllAccounts() { }; openRequest.onsuccess = function (event) { - let db = event.target.result; - let transaction = db.transaction("accounts", "readonly"); - let objectStore = transaction.objectStore("accounts"); - let getAllRequest = objectStore.getAll(); + const db = event.target.result; + const transaction = db.transaction("accounts", "readonly"); + const objectStore = transaction.objectStore("accounts"); + const getAllRequest = objectStore.getAll(); getAllRequest.onsuccess = function () { resolve(getAllRequest.result); @@ -494,76 +494,78 @@ async function fetchAllAccounts() { } async function getNotificationCount() { - let secret = null; let accounts = []; let result = null; - if ("secret" in self) { - secret = self.secret; - const secretUint8Array = self.decodeBase64(secret); - // 1 is our master settings ID; see MASTER_SETTINGS_KEY - const settings = await getSettingById(1); - let lastNotifiedClaimId = null; - if ("lastNotifiedClaimId" in settings) { - lastNotifiedClaimId = settings["lastNotifiedClaimId"]; + // 1 is our master settings ID; see MASTER_SETTINGS_KEY + const settings = await getSettingById(1); + let lastNotifiedClaimId = null; + if ("lastNotifiedClaimId" in settings) { + lastNotifiedClaimId = settings["lastNotifiedClaimId"]; + } + const activeDid = settings["activeDid"]; + console.log("safari-not getNotificationsCount last", lastNotifiedClaimId); + accounts = await fetchAllAccounts(); + let activeAccount = null; + for (let i = 0; i < accounts.length; i++) { + if (accounts[i]["did"] == activeDid) { + activeAccount = accounts[i]; + break; } - const activeDid = settings["activeDid"]; - accounts = await fetchAllAccounts(); - let did = null; - for (var i = 0; i < accounts.length; i++) { - let account = accounts[i]; - let did = account["did"]; - if (did == activeDid) { - let publicKeyHex = account["publicKeyHex"]; - let identity = account["identity"]; - const messageWithNonceAsUint8Array = self.decodeBase64(identity); - const nonce = messageWithNonceAsUint8Array.slice(0, 24); - const message = messageWithNonceAsUint8Array.slice(24, identity.length); - const decoder = new TextDecoder("utf-8"); - const decrypted = self.secretbox.open(message, nonce, secretUint8Array); - - const msg = decoder.decode(decrypted); - const identifier = JSON.parse(JSON.parse(msg)); - - const headers = { - "Content-Type": "application/json", - }; - - headers["Authorization"] = "Bearer " + (await accessToken(identifier)); - - let response = await fetch( - settings["apiServer"] + "/api/v2/report/claims", - { - method: "GET", - headers: headers, - }, - ); - if (response.status == 200) { - let json = await response.json(); - let claims = json["data"]; - let newClaims = 0; - for (var i = 0; i < claims.length; i++) { - let claim = claims[i]; - if (claim["id"] === lastNotifiedClaimId) { - break; - } - newClaims++; - } - if (newClaims > 0) { - result = `There are ${newClaims} new activities on TimeSafari`; - } - const most_recent_notified = claims[0]["id"]; - await setMostRecentNotified(most_recent_notified); - } else { - console.error( - "safari-notifications getNotificationsCount got a bad response status when fetching claims", - response.status, - response, - ); - } + } + + const headers = { + "Content-Type": "application/json", + }; + + const identity = activeAccount && activeAccount["identity"]; + if (identity && "secret" in self) { + const secret = self.secret; + const secretUint8Array = self.decodeBase64(secret); + const messageWithNonceAsUint8Array = self.decodeBase64(identity); + const nonce = messageWithNonceAsUint8Array.slice(0, 24); + const message = messageWithNonceAsUint8Array.slice(24, identity.length); + const decoder = new TextDecoder("utf-8"); + const decrypted = self.secretbox.open(message, nonce, secretUint8Array); + const msg = decoder.decode(decrypted); + const identifier = JSON.parse(JSON.parse(msg)); + + headers["Authorization"] = "Bearer " + (await accessToken(identifier)); + } + + console.log("safari-not getNotificationsCount fetch", headers); + const response = await fetch( + settings["apiServer"] + "/api/v2/report/claims", + { + method: "GET", + headers: headers, + }, + ); + console.log("safari-not getNotificationsCount json", response); + if (response.status == 200) { + const json = await response.json(); + console.log("safari-not getNotificationsCount json", json); + const claims = json["data"]; + let newClaims = 0; + for (let i = 0; i < claims.length; i++) { + const claim = claims[i]; + if (claim["id"] === lastNotifiedClaimId) { break; } + newClaims++; + } + if (newClaims > 0) { + result = `There are ${newClaims} new activities on Time Safari`; } + const most_recent_notified = claims[0]["id"]; + await setMostRecentNotified(most_recent_notified); + } else { + console.error( + "safari-notifications getNotificationsCount got a bad response status when fetching claims", + response.status, + response, + ); } + return result; }