fix: a popup save no longer undoes a network switch the background saved during it (closes #641)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

The popup's saveState() and the background's updateState() each read the
stored record, change it and write it back, each ordered only within its own
context, so a write by one could land between the other's read and write and
be lost. Both now hold the browser's lock (navigator.locks) from the read to
the write, through withLock() in src/shared/browserApi.js, and the recovery
screen's reset takes it too. A page in a Firefox private window gets locks of
its own and is not covered. The lock also orders a page's own saves, so both
per-context queues are gone. The unit tests get a small lock from a Jest setup
file.

Model: opus-5-5
This commit was merged in pull request #644.
This commit is contained in:
2026-10-20 20:13:19 +02:00
parent 4472746b89
commit 93c34e1a2a
19 changed files with 240 additions and 67 deletions
+10 -2
View File
@@ -24,7 +24,11 @@
// than written again locally so that tests/popupElementIds.test.js sees these
// lookups and holds every id below against the markup.
const { $, VIEWS } = require("./helpers");
const { storageGet, storageRemove } = require("../../shared/browserApi");
const {
storageGet,
storageRemove,
withLock,
} = require("../../shared/browserApi");
const { log } = require("../../shared/log");
// Typed in full before anything is erased, in the same spirit as the wallet
@@ -137,7 +141,11 @@ async function resetProfile() {
return;
}
try {
await storageRemove("autistmask");
// Under the lock every write of the stored record takes, so the erase
// cannot land between another write's read and its write and be undone.
// A page in a Firefox private window is the exception: Firefox gives
// it locks of its own (README, "Stored state and its version").
await withLock("autistmask", () => storageRemove("autistmask"));
} catch (e) {
log.errorf("state recovery: reset failed:", e);
setFlash("The saved data could not be erased. Nothing was changed.");