diff --git a/project.task.yaml b/project.task.yaml index ab097bd1..cc63a57c 100644 --- a/project.task.yaml +++ b/project.task.yaml @@ -1,13 +1,6 @@ tasks: -- 08 notifications : - - Give them a message during/after "turn on notifications" because it takes a while for the message to show after console says "About to send subscription... " - -- fix maskable icon - -- .5 If notifications are not enabled, add message to front page with link/button to enable - - Release Minimum Viable Product : - .5 deploy endorser.ch server above Dec 1 (to get plan searches by names as well as descriptions) - 08 thorough testing for errors & edge cases @@ -27,6 +20,7 @@ tasks: - 04 allow user to download chains of VCs, mine + ones I can see about me from others - add VC confirmation +- .5 If notifications are not enabled, add message to front page with link/button to enable - record donations vs gives - make server endpoint for full English description of limits - make identicons for contacts into more-memorable faces (and maybe change project identicons, too) @@ -99,6 +93,7 @@ tasks: - automated tests, eg. cypress - Notifications (wake on the phone, push notifications) + - 02 change push server so that the web-push/subscribe call sets up a thread for the 10-seconds-later push notification, but returns immediately to the callee - pull instead of push, maybe via scheduled runs - have a notification pop-up on Mac screen diff --git a/src/App.vue b/src/App.vue index f34557a8..63d847da 100644 --- a/src/App.vue +++ b/src/App.vue @@ -291,6 +291,7 @@ interface VapidResponse { import { DEFAULT_PUSH_SERVER } from "@/constants/app"; import { db } from "@/db/index"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; +import { sendTestThroughPushServer } from "@/libs/util"; interface Notification { group: string; @@ -447,23 +448,34 @@ export default class App extends Vue { .then((registration) => { return registration.pushManager.getSubscription(); }) - .then((subscription) => { + .then(async (subscription) => { if (subscription) { - return this.sendSubscriptionToServer(subscription); + await this.$notify( + { + group: "alert", + type: "info", + title: "Notification Setup Underway", + text: "Setting up notifications for interesting activity, which takes about 10 seconds. If you don't see a final confirmation, check the 'Troubleshoot' page.", + }, + -1, + ); + this.sendSubscriptionToServer(subscription); + return subscription; } else { throw new Error("Subscription object is not available."); } }) - .then(() => { + .then(async (subscription) => { console.log( "Subscription data sent to server and all finished successfully.", ); + await sendTestThroughPushServer(subscription, true); this.$notify( { group: "alert", type: "success", title: "Notifications Turned On", - text: "Notifications are on. You should see one on your device; if not, see the 'Troubleshoot' page.", + text: "Notifications are on. You should see at least one on your device; if not, check the 'Troubleshoot' page.", }, -1, ); diff --git a/src/libs/util.ts b/src/libs/util.ts index 4a2dd28b..0149dbe5 100644 --- a/src/libs/util.ts +++ b/src/libs/util.ts @@ -1,5 +1,69 @@ // many of these are also found in endorser-mobile utility.ts +import axios, { AxiosResponse } from "axios"; + +import { DEFAULT_PUSH_SERVER } from "@/constants/app"; +import { db } from "@/db/index"; +import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const Buffer = require("buffer/").Buffer; + export const isGlobalUri = (uri: string) => { return uri && uri.match(new RegExp(/^[A-Za-z][A-Za-z0-9+.-]+:/)); }; + +export const sendTestThroughPushServer = async ( + subscription: PushSubscription, + skipFilter: boolean, +): Promise => { + await db.open(); + const settings = await db.settings.get(MASTER_SETTINGS_KEY); + let pushUrl: string = DEFAULT_PUSH_SERVER as string; + if (settings?.webPushServer) { + pushUrl = settings.webPushServer; + } + + // This is a special value that tells the service worker to send a direct notification to the device, skipping filters. + // This is shared with the service worker and should be a constant. Look for the same name in additional-scripts.js + // Use something other than "Daily Update" https://gitea.anomalistdesign.com/trent_larson/py-push-server/src/commit/3c0e196c11bc98060ec5934e99e7dbd591b5da4d/app.py#L213 + const DIRECT_PUSH_TITLE = "DIRECT_NOTIFICATION"; + + const auth = Buffer.from(subscription.getKey("auth")); + const authB64 = auth + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/, ""); + const p256dh = Buffer.from(subscription.getKey("p256dh")); + const p256dhB64 = p256dh + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace(/=+$/, ""); + const newPayload = { + endpoint: subscription.endpoint, + keys: { + auth: authB64, + p256dh: p256dhB64, + }, + message: `Test, where you will see this message ${ + skipFilter ? "un" : "" + }filtered.`, + title: skipFilter ? DIRECT_PUSH_TITLE : "Your Web Push", + }; + console.log("Sending a test web push message:", newPayload); + const payloadStr = JSON.stringify(newPayload); + const response = await axios.post( + pushUrl + "/web-push/send-test", + payloadStr, + { + headers: { + "Content-Type": "application/json", + }, + }, + ); + + console.log("Got response from web push server:", response); + return response; +}; diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index 33c09c14..fddf9790 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -126,7 +126,7 @@
- Notification status may have changed. Revisit this page to see the + Notification status may have changed. Refresh this page to see the latest setting.
diff --git a/src/views/HelpNotificationsView.vue b/src/views/HelpNotificationsView.vue index 3790ef1e..5c605044 100644 --- a/src/views/HelpNotificationsView.vue +++ b/src/views/HelpNotificationsView.vue @@ -289,16 +289,10 @@