1 Commits
Author SHA1 Message Date
sneak cb44e9903d fix: AutistMask does not run in Firefox private windows (closes #646)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s
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 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 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 `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. background share it. `manifest/firefox.json` sets `"incognito": "not_allowed"`,
`manifest/firefox.json` sets `"incognito": "not_allowed"`, so such a page cannot so no page runs in a Firefox private window. Firefox would give a page there
read or write extension storage. In Chrome, a page opened from an incognito locks of its own. In Chrome, a page opened from an incognito window still runs
window still runs outside incognito and shares the lock. The popup's outside incognito and shares the lock. The popup's `saveState()`, the
`saveState()`, the background's `updateState()` and the StateRecovery reset all background's `updateState()` and the StateRecovery reset all take it, so no
take it, so no write lands between another write's read and its write, where it write lands between another write's read and its write, where it would be lost.
would be lost. Chrome has it from version 69, older than any Chrome that runs a Chrome has it from version 69, older than any Chrome that runs a Manifest V3
Manifest V3 extension, in pages and in the service worker; Firefox from version extension, in pages and in the service worker; Firefox from version 96, older
96, older than the 115 `manifest/firefox.json` declares. Where it is missing, a than the 115 `manifest/firefox.json` declares. Where it is missing, a write
write fails rather than going ahead without it. fails rather than going ahead without it.
Version 1 is the shape that shipped before versions existed, so a stored record 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 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". 3. Click "Load Temporary Add-on".
4. Select `dist/firefox/manifest.json`. 4. Select `dist/firefox/manifest.json`.
AutistMask does not work in Firefox private windows.
## Getting Started ## Getting Started
### Creating a New Wallet ### 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, // save could land between the background's read and its write (README,
// "Stored state and its version"). // "Stored state and its version").
describe("private windows", () => { 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"); expect(readManifest("firefox").incognito).toBe("not_allowed");
}); });
}); });