7bae6a15aa4c
prompt for withheld all-sites access so Firefox injects content scripts without a popup click (v5.3.12)
- time
- 2026-10-08 18:34 UTC · 2 weeks ago
- machine
- Junes-MacBook-Pro.local
- agent
- claude-opus-5-5
- session
- firefox content script injection
- parent
- d9428e0ddd2d
↓ peach-browser-7bae6a15.tar.gzatlas at this save
files changed5 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/App.tsx+25 −0src/popup/styles/popup.css+10 −0manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "5.3.11",4+ "version": "5.3.12",55 "description": "Zero-knowledge password manager",66 "browser_specific_settings": {77 "gecko": {manifest.json+1 −1
@@ -2,7 +2,7 @@22 "manifest_version": 3,33 "minimum_chrome_version": "116",44 "name": "Peach Password Manager",5- "version": "5.3.11",5+ "version": "5.3.12",66 "description": "Zero-knowledge password manager",77 "action": {88 "default_popup": "src/popup/index.html",package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "peach",3- "version": "5.3.11",3+ "version": "5.3.12",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/popup/App.tsx+25 −0
@@ -129,6 +129,7 @@129129 }130130 131131 const ENTRY_TRANSITION_SETTLE_MS = 135;132+const ALL_SITES: chrome.permissions.Permissions = { origins: ["<all_urls>"] };132133 133134 export default function App() {134135 const [bootState, setBootState] = createSignal<BootState>("loading");@@ -237,6 +238,9 @@237238 url: string;238239 title: string;239240 } | null>(null);241+ // Firefox MV3 lets users withhold <all_urls>; without it no content script242+ // loads until a toolbar click grants activeTab for that one tab.243+ const [siteAccessMissing, setSiteAccessMissing] = createSignal(false);240244 // True while Panic Step 1 has bounced the user out to Export. When Export's241245 // onBack fires we return to Panic instead of Settings so the user keeps the242246 // destruction context they came from.@@ -532,6 +536,10 @@532536 setResumeRestoreSource(null);533537 }534538 539+ onMount(() => {540+ void chrome.permissions.contains(ALL_SITES).then((granted) => setSiteAccessMissing(!granted));541+ });542+535543 onMount(async () => {536544 // Resolve the active tab in parallel with the unlock/has-vault queries —537545 // openVault()'s smart selection picks the entry matching currentTabDomain,@@ -1357,6 +1365,23 @@13571365 13581366 return (13591367 <div class="popup-root peach-theme">1368+ <Show when={siteAccessMissing()}>1369+ <div class="peach-pro-notice-banner peach-site-access-banner" role="alert">1370+ <span>Peach can't fill on websites until you allow site access.</span>1371+ <button1372+ class="peach-pro-notice-link"1373+ onClick={() => {1374+ // Called synchronously from the click: Firefox requires a user gesture.1375+ chrome.permissions.request(ALL_SITES).then(1376+ (granted) => setSiteAccessMissing(!granted),1377+ (error: unknown) => console.warn("Peach site access request failed:", error),1378+ );1379+ }}1380+ >1381+ Allow1382+ </button>1383+ </div>1384+ </Show>13601385 <Show when={bootState() === "ready"}>13611386 <Show13621387 when={!pendingPasskey()}src/popup/styles/popup.css+10 −0
@@ -5254,6 +5254,16 @@52545254 line-height: 1;52555255 }52565256 5257+/* Overlays the top edge: the popup is a fixed 520px, so a flow banner would clip the bottom. */5258+.peach-site-access-banner {5259+ position: absolute;5260+ inset: 0 0 auto;5261+ background:5262+ linear-gradient(color-mix(in srgb, var(--peach-accent) 12%, transparent), color-mix(in srgb, var(--peach-accent) 12%, transparent)),5263+ var(--bg);5264+ z-index: 50;5265+}5266+52575267 /* ─── First-run onboarding ──────────────────────────────────────────────52585268 Three-card welcome shown once before vault creation. The PeachScript52595269 rune background drifts behind everything at very low opacity — it's