From 5fbdd30a19b9327924fac18e2a6238cfedc8fbf8 Mon Sep 17 00:00:00 2001 From: adlee-was-taken Date: Fri, 1 May 2026 18:08:34 -0400 Subject: [PATCH] ext(sw): add list_groups popup handler --- .../router/__tests__/router.test.ts | 28 +++++++++++++++++++ .../src/service-worker/router/popup-only.ts | 10 +++++++ extension/src/shared/messages.ts | 3 +- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/extension/src/service-worker/router/__tests__/router.test.ts b/extension/src/service-worker/router/__tests__/router.test.ts index 0a41a39..f4b4cf3 100644 --- a/extension/src/service-worker/router/__tests__/router.test.ts +++ b/extension/src/service-worker/router/__tests__/router.test.ts @@ -972,3 +972,31 @@ describe('get_active_tab_url', () => { expect(resp.data).toBeNull(); }); }); + +// --- list_groups --- + +describe('list_groups', () => { + it('list_groups returns deduplicated sorted groups from manifest', async () => { + const state = makeState(); + state.manifest = { + schema_version: 2, + items: { + a: { id: 'a', title: 't1', type: 'login', group: 'work', tags: [], modified: 0, created: 0, favorite: false, attachment_summaries: [] }, + b: { id: 'b', title: 't2', type: 'login', group: 'personal', tags: [], modified: 0, created: 0, favorite: false, attachment_summaries: [] }, + c: { id: 'c', title: 't3', type: 'login', group: 'work', tags: [], modified: 0, created: 0, favorite: false, attachment_summaries: [] }, + d: { id: 'd', title: 't4', type: 'login', tags: [], modified: 0, created: 0, favorite: false, attachment_summaries: [] }, // no group + }, + }; + const resp = await route({ type: 'list_groups' } as any, state, makePopupSender()); + expect(resp.ok).toBe(true); + expect(resp.data).toEqual({ groups: ['personal', 'work'] }); + }); + + it('list_groups returns empty array when manifest is null', async () => { + const state = makeState(); + state.manifest = null; + const resp = await route({ type: 'list_groups' } as any, state, makePopupSender()); + expect(resp.ok).toBe(true); + expect(resp.data).toEqual({ groups: [] }); + }); +}); diff --git a/extension/src/service-worker/router/popup-only.ts b/extension/src/service-worker/router/popup-only.ts index f1217e2..55842db 100644 --- a/extension/src/service-worker/router/popup-only.ts +++ b/extension/src/service-worker/router/popup-only.ts @@ -159,6 +159,16 @@ export async function handle( return { ok: true, data: { url: tab.url, title: tab.title ?? '' } }; } + case 'list_groups': { + if (!state.manifest) return { ok: true, data: { groups: [] } }; + const set = new Set(); + for (const id in state.manifest.items) { + const g = state.manifest.items[id].group; + if (g) set.add(g); + } + return { ok: true, data: { groups: Array.from(set).sort() } }; + } + case 'generate_password': { const password = state.wasm.generate_password(JSON.stringify(msg.request)); return { ok: true, data: { password } }; diff --git a/extension/src/shared/messages.ts b/extension/src/shared/messages.ts index ecbcafe..e68de37 100644 --- a/extension/src/shared/messages.ts +++ b/extension/src/shared/messages.ts @@ -37,6 +37,7 @@ export type PopupMessage = | { type: 'get_blacklist' } | { type: 'remove_blacklist'; hostname: string } | { type: 'get_active_tab_url' } + | { type: 'list_groups' } | { type: 'upload_attachment'; itemId: string; filename: string; mimeType: string; bytes: ArrayBuffer } | { type: 'download_attachment'; itemId: string; attachmentId: string } | { type: 'list_devices' } @@ -158,7 +159,7 @@ export const POPUP_ONLY_TYPES: ReadonlySet = new Set([ 'fill_credentials', 'ack_autofill_origin', 'get_settings', 'update_settings', 'get_vault_settings', 'update_vault_settings', 'get_blacklist', - 'remove_blacklist', 'get_active_tab_url', 'upload_attachment', 'download_attachment', + 'remove_blacklist', 'get_active_tab_url', 'list_groups', 'upload_attachment', 'download_attachment', 'list_devices', 'add_device', 'register_this_device', 'revoke_device', 'list_trashed', 'restore_item', 'purge_item', 'purge_all_trash', 'get_field_history',