aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
Diffstat (limited to 'src/features')
-rw-r--r--src/features/messages.js17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/features/messages.js b/src/features/messages.js
index 582bf3b..66a1270 100644
--- a/src/features/messages.js
+++ b/src/features/messages.js
@@ -1101,10 +1101,23 @@ export function messagesFeature(ctx) {
if ((await Notification.requestPermission()) !== 'granted') return false;
}
const reg = await navigator.serviceWorker.ready;
+ const { publicKey } = await (await fetch(`${NOTIFIER}/vapid`)).json();
+ const wantKey = b64ToBytes(publicKey);
let sub = await reg.pushManager.getSubscription();
+ // A subscription made against a DIFFERENT VAPID key can never receive a
+ // push — the notifier's sends fail with a permanent 403 and it keeps
+ // reusing the dead sub, so the device goes silent forever (this is what
+ // stranded notifications after the key last rotated). Re-subscribe when
+ // the existing sub's server key doesn't match the current one.
+ const keyMatches = (s) => {
+ try {
+ const cur = new Uint8Array(s.options.applicationServerKey || []);
+ return cur.length === wantKey.length && cur.every((b, i) => b === wantKey[i]);
+ } catch { return false; }
+ };
+ if (sub && !keyMatches(sub)) { try { await sub.unsubscribe(); } catch {} sub = null; }
if (!sub) {
- const { publicKey } = await (await fetch(`${NOTIFIER}/vapid`)).json();
- sub = await reg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: b64ToBytes(publicKey) });
+ sub = await reg.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: wantKey });
}
const r = await fetch(`${NOTIFIER}/register`, {
method: 'POST', headers: { 'content-type': 'application/json' },