aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-22 10:32:22 -0700
committerAdam Soltys <[email protected]>2026-10-22 10:32:22 -0700
commit1ea1784c4ad7d6715c0efdcd0078019c692eefe5 (patch)
treee5f86cd28d103341114930444c3980cda72257ac /src
parentd59a7f0c9b32002ff23f74a2996b986cf1f0dd05 (diff)
downloadcoinosv3-1ea1784c4ad7d6715c0efdcd0078019c692eefe5.tar.gz
coinosv3-1ea1784c4ad7d6715c0efdcd0078019c692eefe5.zip
iPhone: a push subscription iOS dropped is made again when the app opens or comes back
WebKit removes a subscription after three pushes that showed no notification (743011c stops new strikes, but a wallet already struck out stayed deaf): background stayed on, getSubscription() came back empty and refreshRegistration gave up, so NWC requests stopped waking the closed app until the switch was toggled (reported by PullCap). It now subscribes again (also when the VAPID key changed) and re-registers with the notifier, on start and whenever the app returns to the screen. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01K5xtiFrkFVsrkWx6JDQjiT
Diffstat (limited to 'src')
-rw-r--r--src/features/nwc.js24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/features/nwc.js b/src/features/nwc.js
index ec79081..9c71a7f 100644
--- a/src/features/nwc.js
+++ b/src/features/nwc.js
@@ -822,6 +822,25 @@ export function nwcFeature(ctx) {
// wrong keys — background wake-ups silently die the first time a
// connection is recreated. Debounced; the server replaces by endpoint.
let regTimer = null;
+ // The browser's subscription, made again when it's gone: iOS drops it after
+ // three pushes that showed no notification (and a key rotation strands an
+ // old one), and nothing else re-arms a wallet whose `background` is still on.
+ async function currentSub() {
+ const reg = await navigator.serviceWorker.ready;
+ const { publicKey } = await (await fetch(`${NOTIFIER}/vapid`)).json();
+ const want = b64ToBytes(publicKey);
+ let sub = await reg.pushManager.getSubscription();
+ if (sub) {
+ let have = [];
+ try { have = new Uint8Array(sub.options.applicationServerKey || []); } catch {}
+ if (have.length === want.length && have.every((b, i) => b === want[i])) return sub.toJSON();
+ try { await sub.unsubscribe(); } catch {}
+ }
+ if (typeof Notification === 'undefined' || Notification.permission !== 'granted') return null;
+ sub = await reg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: want });
+ dlog('nwc: push subscription was gone, made a new one');
+ return sub.toJSON();
+ }
function refreshRegistration() {
if (!load().background) return;
if (typeof navigator === 'undefined' || !('serviceWorker' in navigator)) return;
@@ -831,8 +850,7 @@ export function nwcFeature(ctx) {
const pks = watchPks();
if (!pks.length) return;
const up2 = upEndpoint();
- const sub = up2 ? { endpoint: up2, unifiedpush: true }
- : await (await navigator.serviceWorker.ready).pushManager.getSubscription().then((x) => x && x.toJSON());
+ const sub = up2 ? { endpoint: up2, unifiedpush: true } : await currentSub();
if (!sub) return;
await fetch(`${NOTIFIER}/register`, {
method: 'POST', headers: { 'content-type': 'application/json' },
@@ -949,7 +967,7 @@ export function nwcFeature(ctx) {
if (typeof window !== 'undefined') {
window.addEventListener('online', () => listen());
document.addEventListener('visibilitychange', () => {
- if (document.visibilityState === 'visible' && conns().length) listen();
+ if (document.visibilityState === 'visible' && conns().length) { listen(); refreshRegistration(); }
});
}
}