fix(server-storage): forget the token for another server, listen before sign-in, adopt only stale records

- A server that answers as another backend URL or instance id than the
  remembered one makes the browser forget the stored token, so server A's
  token never reaches server B.
- The session installs its page-hide and heartbeat listeners before it
  returns for sign-in, so a page holding another page load's writes still
  marks itself closed on unload.
- Closed tabs are found by stale records only again: saved writes without
  a record may belong to a running tab whose record storage refused, and
  are left to that tab's own reload.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-10-13 20:08:33 +02:00
1 parent cf715a7573
commit 4908803ceb
7 files changed
+94 -41

No files matched your search

+7 -5
View File
@@ -272,9 +272,10 @@ settings and guards read them in every build.
`localStorage` (`iptvnator-server:unconfirmed:<instanceId>:<page>`, one
key per page load so tabs never overwrite each other's, renewed every
30 s while it has unsent writes, stale after ten minutes) let a re-read
in one tab keep the cache values another tab is still sending; saved
writes without a fresh record, also when the record was lost, count as a
closed tab's (the storage adapter lists its keys for this). A value too big for `localStorage`, or any
in one tab keep the cache values another tab is still sending, and a
stale record marks a closed tab whose writes another tab adopts (the
storage adapter lists its keys for this). Saved writes without any record
are left to the tab's own reload: that tab may still run. A value too big for `localStorage`, or any
value when the browser refuses storage access, stays readable from
memory, so callers and the diff baseline agree. A re-read
updates the cache; views already open show another device's changes on
@@ -298,8 +299,9 @@ settings and guards read them in every build.
browser that refuses to store it is told so instead).
`ServerAccessTokenInterceptor` adds the header to `HttpClient` calls to the
backend, and `PwaService` adds it to its two raw `fetch` calls only while
server mode runs (a backend that answers without server storage also
makes the browser forget the token). Both turn
server mode runs. The browser forgets the token when the backend answers
without server storage, or as another server or database (backend URL or
instance id) than the one it remembers. Both turn
the guard's 401 (`isServerAccessChallenge`) into `reportAccessDenied()`,
so a token changed on the server sends an open page back to sign-in; a
late 401 for a token replaced since (a new sign-in) changes nothing.