feat(ext/sw): org-vault read core (openOrg, grant-filtered list, collection-scoped get, offline)

- Add extension/src/service-worker/org-vault.ts: openOrg (members.json fingerprint
  match → org_unwrap_key → org_manifest_decrypt_filtered), listOrgItems, getOrgItem
  (collection-scoped path: items/<collection>/<id>.enc), listOrgCollections (grants filter).
- Add OrgMember, OrgMembers, CollectionDef, OrgCollections, Collection types to shared/types.ts
  (mirrors relicario-core org.rs shapes).
- Add 8-test suite covering: fingerprint match, not_an_org_member, listOrgItems passthrough,
  collection-scoped item path, listOrgCollections grant filter, storage.set never called,
  offline fallback (TypeError → cached manifest), offline with no cache → rethrow.
- Fix plan doc line ~326: wasm.manifest_decrypt → wasm.org_manifest_decrypt_filtered.

Gate results: 158/158 SW tests pass; npm run build:all clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014s527M917W47LDrfQ4t47g
This commit is contained in:
adlee-was-taken
2026-06-26 22:30:39 -04:00
parent 288956c089
commit 2eb49ac217
4 changed files with 560 additions and 1 deletions

View File

@@ -225,6 +225,45 @@ export interface OrgConfigSummary {
displayName: string;
}
// --- Org members + collections (mirror Rust org.rs shapes) ---
export type OrgRole = 'owner' | 'admin' | 'member';
export interface OrgMember {
member_id: string;
display_name: string;
role: OrgRole;
/** SSH public key string (openssh format: "ssh-ed25519 AAAA...") */
ed25519_pubkey: string;
/** Collection slugs this member can access. */
collections: string[];
added_at: number;
added_by: string;
}
export interface OrgMembers {
schema_version: number;
members: OrgMember[];
}
export interface CollectionDef {
slug: string;
display_name: string;
created_by: string;
created_at: number;
}
export interface OrgCollections {
schema_version: number;
collections: CollectionDef[];
}
/** Public shape returned by listOrgCollections — slug + display_name only. */
export interface Collection {
slug: string;
display_name: string;
}
// --- Org manifest ---
// Org manifest — a dedicated, leaner shape than the personal ManifestEntry.
// Faithful to relicario-core OrgManifestEntry; collection is REQUIRED.