1 Commits
Author SHA1 Message Date
sneak cb44e9903d fix: AutistMask does not run in Firefox private windows (closes #646)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run
Firefox gives an extension page in a private window locks of its own. A
popup there could save between the background's read and its write of the
stored record, and undo a network switch the background had saved.

manifest/firefox.json now sets "incognito": "not_allowed", so Firefox never
runs AutistMask in a private window. tests/manifest.test.js pins the key.
The README and five code comments no longer describe a private-window
exception to the lock.

Model: opus-5-5
2026-10-26 21:38:59 +00:00
3 changed files with 11 additions and 13 deletions
+10 -10
View File
@@ -1494,16 +1494,16 @@ wrote last, the record says which build's shape it is in.
Each write reads the record, changes it and writes it back, holding a lock from
the read to the write: the browser's own (`navigator.locks`), taken through
`withLock()` in `src/shared/browserApi.js`. Every page of the extension and its
background share it. Firefox gives a page in a private window locks of its own.
`manifest/firefox.json` sets `"incognito": "not_allowed"`, so such a page cannot
read or write extension storage. In Chrome, a page opened from an incognito
window still runs outside incognito and shares the lock. The popup's
`saveState()`, the background's `updateState()` and the StateRecovery reset all
take it, so no write lands between another write's read and its write, where it
would be lost. Chrome has it from version 69, older than any Chrome that runs a
Manifest V3 extension, in pages and in the service worker; Firefox from version
96, older than the 115 `manifest/firefox.json` declares. Where it is missing, a
write fails rather than going ahead without it.
background share it. `manifest/firefox.json` sets `"incognito": "not_allowed"`,
so no page runs in a Firefox private window. Firefox would give a page there
locks of its own. In Chrome, a page opened from an incognito window still runs
outside incognito and shares the lock. The popup's `saveState()`, the
background's `updateState()` and the StateRecovery reset all take it, so no
write lands between another write's read and its write, where it would be lost.
Chrome has it from version 69, older than any Chrome that runs a Manifest V3
extension, in pages and in the service worker; Firefox from version 96, older
than the 115 `manifest/firefox.json` declares. Where it is missing, a write
fails rather than going ahead without it.
Version 1 is the shape that shipped before versions existed, so a stored record
with no `schemaVersion` is version 1 rather than a defect: it loads normally and
-2
View File
@@ -208,8 +208,6 @@ password.
3. Click "Load Temporary Add-on".
4. Select `dist/firefox/manifest.json`.
AutistMask does not work in Firefox private windows.
## Getting Started
### Creating a New Wallet
+1 -1
View File
@@ -169,7 +169,7 @@ describe("declared icons", () => {
// save could land between the background's read and its write (README,
// "Stored state and its version").
describe("private windows", () => {
test("a page in a firefox private window cannot read or write extension storage", () => {
test("firefox never runs AutistMask in a private window", () => {
expect(readManifest("firefox").incognito).toBe("not_allowed");
});
});