fix: a site allowed without Remember stays connected when the background worker idles (closes #526)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

A connection allowed without "Remember my choice for this site" was held
in a module-level object in the background worker. Chrome stops the worker
after about 30 seconds idle, so the connection ended at the first idle
spell. Each such connection is now one item in the browser's session
storage, which outlives the worker but not the browser, read and written
through new wrappers in src/shared/browserApi.js. Settings now waits for
the background to end a removed site's connections before listing the
connected sites again. The Firefox manifest declares 115.0, the first
version with session storage, as its minimum.

Model: opus-5-5
This commit is contained in:
2026-10-18 20:58:47 +00:00
parent 1f5ec1c8de
commit 234c6c4032
11 changed files with 572 additions and 93 deletions
+20 -12
View File
@@ -571,9 +571,12 @@ the worker stopping. It starts Chromium itself, speaks the DevTools protocol
over `--remote-debugging-pipe`, and attaches to pages only. Before raising the
approvals it requires the worker to stop on its own with nothing pending, so a
run in which something else keeps the worker running fails. The site is
connected and the RPC endpoint set through the extension's own screens, against
the loopback dApp page and stub node the Firefox suite also uses
(`tests/e2e/dapp.js`). Unlike the suite above, it does not fail on page errors.
connected, without "Remember my choice for this site", and the RPC endpoint set
through the extension's own screens, against the loopback dApp page and stub
node the Firefox suite also uses (`tests/e2e/dapp.js`). Once the worker has
stopped, the run requires the site still to be told the address
([#526](https://git.eeqj.de/sneak/AutistMask/issues/526)). Unlike the suite
above, it does not fail on page errors.
### Firefox (`make test-e2e-firefox`)
@@ -857,7 +860,11 @@ on the next event. Two consequences shape every recurring job in the background:
- Module-level variables do not survive either. Anything that must be remembered
across a restart goes in extension storage. `localStorage` does not exist in a
service worker at all — the one remaining user of it, `src/shared/ens.js`,
runs only in the popup and is marked as such.
runs only in the popup and is marked as such. The sites allowed without
"Remember my choice for this site" are kept in the browser's session storage
(`storage.session`), which outlives the worker but not the browser, so such a
connection lasts until it is ended or the browser closes. Firefox has session
storage from version 115, the minimum `manifest/firefox.json` declares.
Pending approvals are the exception: an approval waiting for the user, and the
site's request waiting on it, live only in the worker's memory, and only the
@@ -1936,7 +1943,7 @@ view would leave a wallet one click from deletion.
under any address, with remove buttons
- Connected Sites: the origins of the sites allowed without "Remember my
choice" that are still connected, with remove buttons. Only the background
holds these, in memory, and Settings asks it for them with
holds these, in session storage, and Settings asks it for them with
`AUTISTMASK_GET_CONNECTED_SITES`
- Denied Sites: the origins remembered as denied, under any address, with
remove buttons
@@ -1955,9 +1962,10 @@ view would leave a wallet one click from deletion.
its origin is dropped from Allowed Sites under every address, and
`AUTISTMASK_REMOVE_SITE` has the background end every connection approved
without "Remember" from that origin, under any address, and send
`accountsChanged` with an empty list to the open tabs of that origin. The
same host under another scheme or port is another site and is left alone.
Only the extension's own pages may send either message
`accountsChanged` with an empty list to the open tabs of that origin.
Settings waits for the background's answer before it draws the lists
again. The same host under another scheme or port is another site and is
left alone. Only the extension's own pages may send either message
- `[x]` on a denied site → forgets the refusal, in place; it connects
nothing and tells the background nothing
- Ten clicks on the version → reveals the Debug well (no screen change)
@@ -2018,8 +2026,8 @@ view would leave a wallet one click from deletion.
(`src/shared/walletDelete.js`)
- Either way, every address the wallet held loses its site permissions of
both kinds: the remembered ones in storage, and the connections approved
without "Remember", which only the background holds, in memory, and drops
on `AUTISTMASK_ADDRESSES_REMOVED`
without "Remember", which only the background holds, in session storage,
and drops on `AUTISTMASK_ADDRESSES_REMOVED`
- "Confirm Delete" (wrong password) → "That password is incorrect. Please
try again." on the error line, nothing deleted
- "I have lost my password" → **DeleteWalletLostPassword**
@@ -2132,8 +2140,8 @@ view would leave a wallet one click from deletion.
one in this wallet follows the splice.
- The address loses its site permissions of both kinds, whether or not it was
the active one: the remembered ones in storage, and any connection approved
without "Remember", which only the background holds, in memory, and drops on
`AUTISTMASK_ADDRESSES_REMOVED`.
without "Remember", which only the background holds, in session storage, and
drops on `AUTISTMASK_ADDRESSES_REMOVED`.
- The wallet's derivation counter (`nextIndex`) is not rewound, so "+" derives a
fresh address rather than handing back the one just removed.