feat(ext/sw): org_switch + org read messages (grant-filtered, offline-aware, cache cleared on lock)
Wires 4 SW messages to the org-vault.ts read functions (Task 5b): - org_switch: opens org vault via openOrg(), caches OrgHandleState, sets session context; switching to 'personal' resets context without openOrg. Offline-aware: if openOrg throws a network error and a prior cached state exists, reuses it read-only (offline:true) via exported isNetworkError. - org_list_items: returns cached, grant-filtered OrgManifestEntry[] (not personal ManifestEntry[]) via listOrgItems(requireCurrentOrgState()). - org_get_item: decrypts a single org item via getOrgItem. - org_list_collections: returns granted Collection[] via listOrgCollections. Three-place rule satisfied for all 4 messages: 1. messages.ts PopupMessage union (4 variants) 2. messages.ts POPUP_ONLY_TYPES (4 entries) 3. popup-only.ts switch (4 case arms) Cache lifecycle / use-after-free guard: - clearOrgCache() added to org-handlers.ts; exports. - Called in popup-only.ts 'lock' handler (before session.clearCurrent). - Called in index.ts inactivity-timer onExpired (before clearCurrent). Plan doc fixes: - Line ~410: org_list_items return type corrected to OrgManifestEntry[]. - Line ~47: org_unwrap_key signature updated (no device_private_key_base64 param — reads DEVICE_STATE internally). 9 new tests in org-handlers.test.ts (TDD: all watched fail before passing). Full SW suite: 167 tests (17 files) green. build:all type-checks clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014s527M917W47LDrfQ4t47g
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type {
|
||||
Item, ItemId, Manifest, ManifestEntry, VaultConfig, SetupState,
|
||||
DeviceSettings, GeneratorRequest, VaultSettings, AttachmentRef, Device,
|
||||
FieldHistoryView, OrgConfigSummary,
|
||||
FieldHistoryView, OrgConfigSummary, OrgManifestEntry, Collection,
|
||||
} from './types';
|
||||
|
||||
// --- Session timeout config ---
|
||||
@@ -69,7 +69,11 @@ export type PopupMessage =
|
||||
| { type: 'attach_vault'; config: VaultConfig; passphrase: string;
|
||||
referenceImageBytes: ArrayBuffer; deviceName: string }
|
||||
| { type: 'get_vault_status' }
|
||||
| { type: 'org_list_configs' };
|
||||
| { type: 'org_list_configs' }
|
||||
| { type: 'org_switch'; context: string }
|
||||
| { type: 'org_list_items' }
|
||||
| { type: 'org_get_item'; id: string }
|
||||
| { type: 'org_list_collections' };
|
||||
|
||||
// --- Messages a content script may send ---
|
||||
|
||||
@@ -184,6 +188,7 @@ export const POPUP_ONLY_TYPES: ReadonlySet<PopupMessage['type']> = new Set([
|
||||
'generate_recovery_qr', 'unwrap_recovery_qr',
|
||||
'create_vault', 'attach_vault', 'get_vault_status',
|
||||
'org_list_configs',
|
||||
'org_switch', 'org_list_items', 'org_get_item', 'org_list_collections',
|
||||
] as PopupMessage['type'][]);
|
||||
|
||||
export interface ExportBackupResponse extends Extract<Response, { ok: true }> {
|
||||
@@ -227,6 +232,22 @@ export interface OrgListConfigsResponse extends Extract<Response, { ok: true }>
|
||||
data: OrgConfigSummary[];
|
||||
}
|
||||
|
||||
export interface OrgSwitchResponse extends Extract<Response, { ok: true }> {
|
||||
data: { context: string; offline: boolean };
|
||||
}
|
||||
|
||||
export interface OrgListItemsResponse extends Extract<Response, { ok: true }> {
|
||||
data: OrgManifestEntry[];
|
||||
}
|
||||
|
||||
export interface OrgGetItemResponse extends Extract<Response, { ok: true }> {
|
||||
data: Item;
|
||||
}
|
||||
|
||||
export interface OrgListCollectionsResponse extends Extract<Response, { ok: true }> {
|
||||
data: Collection[];
|
||||
}
|
||||
|
||||
export const CONTENT_CALLABLE_TYPES: ReadonlySet<ContentMessage['type']> = new Set([
|
||||
'get_autofill_candidates', 'get_credentials', 'check_credential', 'blacklist_site',
|
||||
'capture_save_login',
|
||||
|
||||
Reference in New Issue
Block a user