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:
@@ -44,7 +44,7 @@
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `relicario_core::org::unwrap_org_key(wrapped: &[u8], ed25519_seed: &Zeroizing<[u8;32]>) -> Result<Zeroizing<[u8;32]>>` (`crates/relicario-core/src/org.rs:299`); `session::insert(master_key, image_secret) -> u32` (`crates/relicario-wasm/src/session.rs`).
|
||||
- Produces: `org_unwrap_key(keys_blob: &[u8], device_private_key_base64: &str) -> Result<SessionHandle, JsError>`. The returned handle is an ordinary `SessionHandle` — callers use the existing `item_decrypt`/`item_encrypt`/`manifest_decrypt`/`manifest_encrypt` with it.
|
||||
- Produces: `org_unwrap_key(keys_blob: &[u8]) -> Result<SessionHandle, JsError>` (reads `DEVICE_STATE` internally — no private-key param crosses JS). The returned handle is an ordinary `SessionHandle` — callers use the existing `item_decrypt`/`item_encrypt`/`manifest_decrypt`/`manifest_encrypt` with it.
|
||||
|
||||
- [ ] **Step 1: Confirm the device-key form.** Read how `device_private_key` is produced — `crates/relicario-wasm/src/lib.rs` `register_device`/`generate_device_keypair` and `crates/relicario-core/src/device.rs`. Determine whether `private_key_base64` is the raw 32-byte ed25519 seed or an OpenSSH blob, and write `org_unwrap_key` to decode it to the 32-byte seed `Zeroizing<[u8;32]>` that `unwrap_org_key` expects. Note the finding in a code comment.
|
||||
|
||||
@@ -407,7 +407,7 @@ git commit -m "feat(ext/sw): org-vault — unwrap, fetch, grant-filter manifest"
|
||||
- Test: `extension/src/service-worker/__tests__/org-vault.test.ts`
|
||||
|
||||
**Interfaces:**
|
||||
- Produces SW messages: `org_switch {context}` → `{ ok, data: { context, offline } }`; `org_list_items` → `{ ok, data: ManifestEntry[] }`; `org_get_item {id}` → `{ ok, data: Item }`; `org_list_collections` → `{ ok, data: Collection[] }`. On a git network error during switch, set `offline: true` and serve the last-cached manifest read-only.
|
||||
- Produces SW messages: `org_switch {context}` → `{ ok, data: { context, offline } }`; `org_list_items` → `{ ok, data: OrgManifestEntry[] }`; `org_get_item {id}` → `{ ok, data: Item }`; `org_list_collections` → `{ ok, data: Collection[] }`. On a git network error during switch, set `offline: true` and serve the last-cached manifest read-only.
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
|
||||
Reference in New Issue
Block a user