0b2b4a23a099
fix: complete PB-26 sender policy compatibility (v5.0.25)
- time
- 2026-08-30 12:06 UTC · 1 month ago
- machine
- koh2
- parent
- 0af21be3f7f9
↓ peach-browser-0b2b4a23.tar.gzatlas at this save
files changed6 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/background/messages.ts+8 −6src/content/passkey-toast/passkey-toast.test.ts+1 −0src/popup/views/contracts.test.tsx+10 −2manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "5.0.22",4+ "version": "5.0.25",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.0.22",5+ "version": "5.0.25",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.0.22",3+ "version": "5.0.25",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/background/messages.ts+8 −6
@@ -244,12 +244,14 @@244244 // PB-26-016: sender authorization is an exhaustive policy, not a245245 // hand-maintained privileged denylist. A missing/unknown policy entry or a246246 // background-only message fails closed before any handler runs.247- if (!isMessageSenderAllowed(248- msg.type,249- sender,250- chrome.runtime.id,251- chrome.runtime.getURL(""),252- )) {247+ // Extension UI messages may legitimately omit sender.url. Resolve the248+ // browser-attested extension origin only when a URL is present; this also249+ // keeps test/runtime shims without getURL fail-closed for URL-bearing250+ // senders instead of throwing before policy evaluation.251+ const extensionOrigin = sender.url && typeof chrome.runtime.getURL === "function"252+ ? chrome.runtime.getURL("")253+ : "";254+ if (!isMessageSenderAllowed(msg.type, sender, chrome.runtime.id, extensionOrigin)) {253255 return { ok: false, error: "invalid_sender" };254256 }255257 src/content/passkey-toast/passkey-toast.test.ts+1 −0
@@ -24,6 +24,7 @@2424 const chromeMock = {2525 runtime: {2626 id: 'peach-extension',27+ getURL: (path: string) => `chrome-extension://peach-extension/${path}`,2728 sendMessage: vi.fn(async () => ({ ok: true })),2829 onMessage: {2930 addListener: vi.fn((fn: MessageListener) => {src/popup/views/contracts.test.tsx+10 −2
@@ -240,7 +240,11 @@240240 241241 it("Lock uses a configured preferred PIN and keeps the password fallback available", async () => {242242 sendMessageMock.mockImplementation(async (msg: unknown) => {243- return (msg as { type: string }).type === "GET_SETTINGS"243+ const type = (msg as { type: string }).type;244+ if (type === "GET_PIN_STATUS") {245+ return { ok: true, data: { configured: true, available: true, attemptsRemaining: 3 } };246+ }247+ return type === "GET_SETTINGS"244248 ? { ok: true, data: { pinEnabled: true, pinPreferred: true } }245249 : { ok: true };246250 });@@ -262,7 +266,11 @@262266 263267 it("places the PIN method switch below the unlock button", async () => {264268 sendMessageMock.mockImplementation(async (msg: unknown) => {265- return (msg as { type: string }).type === "GET_SETTINGS"269+ const type = (msg as { type: string }).type;270+ if (type === "GET_PIN_STATUS") {271+ return { ok: true, data: { configured: true, available: true, attemptsRemaining: 3 } };272+ }273+ return type === "GET_SETTINGS"266274 ? { ok: true, data: { pinEnabled: true, pinPreferred: false } }267275 : { ok: true };268276 });