ae31fd7fa22f
wire PASSKEY_AUTH_RESPONSE in messages.ts and toast-based get approval in passkey.ts
- time
- 2026-05-13 15:05 UTC · 5 months ago
- machine
- koh2
- parent
- b8e642f2990b
↓ peach-browser-ae31fd7f.tar.gzatlas at this save
files changed3 files
src/background/messages.ts+12 −0src/background/passkey.ts+39 −1src/shared/types.ts+3 −0src/background/messages.ts+12 −0
@@ -1062,6 +1062,18 @@10621062 return await handleFirefoxPasskeyGet(payload);10631063 }10641064 1065+ case "PASSKEY_AUTH_RESPONSE": {1066+ const { requestId, approved } = (msg.payload ?? {}) as {1067+ requestId?: string;1068+ approved?: boolean;1069+ };1070+ if (!requestId || typeof approved !== 'boolean') {1071+ return { ok: false, error: 'requestId and approved required' };1072+ }1073+ await resolvePendingPasskeyRequest(Number(requestId), approved);1074+ return { ok: true };1075+ }1076+10651077 case "GET_PASSKEY_FOR_DOMAIN": {10661078 const { domain } = (msg.payload ?? {}) as { domain?: string };10671079 if (!domain) return { ok: false, error: "domain required" };src/background/passkey.ts+39 −1
@@ -406,6 +406,44 @@406406 });407407 }408408 409+async function promptViaToast(request: PendingPasskeyRequest): Promise<boolean> {410+ if (chrome.storage.session) {411+ await chrome.storage.session.set({ [pendingStorageKey(request.requestId)]: request });412+ }413+414+ const tabs = await new Promise<chrome.tabs.Tab[]>((resolve) => {415+ chrome.tabs.query({ active: true, currentWindow: true }, resolve);416+ });417+ const tab = tabs[0];418+419+ if (tab?.id) {420+ chrome.tabs.sendMessage(tab.id, {421+ type: 'SHOW_PASSKEY_TOAST',422+ payload: {423+ site: request.rpId,424+ displayName: request.userDisplayName ?? request.userName,425+ username: request.userName,426+ requestId: String(request.requestId),427+ },428+ }).catch(() => {429+ // Content script not loaded on this tab — fall back to popup.430+ void openApprovalPopup();431+ });432+ } else {433+ await openApprovalPopup();434+ }435+436+ return new Promise<boolean>((resolve) => {437+ const timeoutId = setTimeout(async () => {438+ approvals.delete(request.requestId);439+ await clearPendingRequest(request.requestId);440+ resolve(false);441+ }, APPROVAL_TIMEOUT_MS);442+443+ approvals.set(request.requestId, { resolve, timeoutId });444+ });445+}446+409447 async function handleGetRequest(410448 request: chrome.webAuthenticationProxy.GetRequest411449 ): Promise<void> {@@ -454,7 +492,7 @@454492 return;455493 }456494 457- const approved = await promptUserApproval({495+ const approved = await promptViaToast({458496 requestId: request.requestId,459497 type: "get",460498 rpId: credential.rpId,src/shared/types.ts+3 −0
@@ -324,6 +324,9 @@324324 | "PRO_GATE_TRIGGERED" // background → popup: a Pro feature was attempted on free325325 | "PASSKEY_PRO_GATE" // background → content: show passkey Pro gate in inline popup326326 | "OPEN_PRO_GATE" // content → background: open popup and navigate to License section327+ | "SHOW_PASSKEY_TOAST" // background → content tab: show passkey auth toast328+ | "DISMISS_PASSKEY_TOAST" // background → content tab: dismiss passkey auth toast329+ | "PASSKEY_AUTH_RESPONSE" // content → background: user approved or denied the toast327330 | "SHOULD_PLAY_CELEBRATION"328331 | "MARK_CELEBRATION_PLAYED";329332