Keep push alive across a deploy, not just across a week
#143 added a device-local flag recording that background notifications were switched on in this browser, and made the renewal on app start key off it. It is not in KEEP_ON_SIGN_OUT, and that is the whole bug: clearSignedInData() runs on two different endings and only one of them is a sign-out. The other is a session expiring, which is what a deploy does to every signed-in browser at once. That path deliberately does not remove the push subscription -- there is no session left to remove it with -- so the subscription stays registered at Stalwart and the browser keeps its own. Losing the flag there left nothing to renew them: push would have gone quiet a week after every deploy, with the switch in Settings still reading as on because both ends of the subscription still existed. That is the exact failure #143 was written to prevent, reintroduced through a different door, and the first deploy carrying #143 would have been the thing that triggered it. Signing out for real still forgets it. That happens directly in unsubscribeThisDevice, next to destroying the subscription, and it happens even when the server cannot be reached -- a browser that goes on believing it has push would have renewal resurrect it on the next sign-in. Both halves are tested now, because they are one invariant seen from two sides: storage.test.ts covers the flag surviving an expiry, webpush.test.ts covers a sign-out clearing it with the server unreachable.
This commit is contained in:
+11
-1
@@ -22,8 +22,18 @@ const PREFIX = "ihasmail:";
|
||||
* - `deviceTrusted` is how the next boot knows to read at all.
|
||||
* - `pushDeviceId` is a random id for this browser, so re-subscribing replaces
|
||||
* rather than accumulates. The subscription itself is removed on sign-out.
|
||||
* - `pushEnabled` records that background notifications were switched on here,
|
||||
* and is what the renewal on app start keys off. It is kept because this
|
||||
* function runs on two different endings and only one of them is a sign-out:
|
||||
* a *deploy* expires every session, and the handler for that clears local
|
||||
* data without removing the push subscription, because there is no longer a
|
||||
* session to remove it with. Dropping the flag there would leave the
|
||||
* subscription registered, the switch still reading as on, and nothing
|
||||
* renewing it -- so push would go quiet a week after every deploy, which is
|
||||
* the exact failure the renewal exists to prevent. Signing out for real
|
||||
* clears it directly, in `unsubscribeThisDevice`, alongside the subscription.
|
||||
*/
|
||||
const KEEP_ON_SIGN_OUT = ["lastUser", "deviceTrusted", "pushDeviceId"];
|
||||
const KEEP_ON_SIGN_OUT = ["lastUser", "deviceTrusted", "pushDeviceId", "pushEnabled"];
|
||||
|
||||
const TRUST_KEY = `${PREFIX}deviceTrusted`;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user