this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove DPoP key exposure from SDK public API, harden session types

Remove generateDpopKeyPair, createDpopProof, and generatePkce static
methods — WASM handles these internally now. Make OAuthSession token
fields readonly. Add security warning to Identity type. Log proactive
refresh failures instead of silently swallowing them.

+17 -50
+6 -44
packages/opake-sdk/src/opake.ts
··· 16 16 ResolvedIdentity, 17 17 ResolvedWorkspace, 18 18 WorkspaceEntry, 19 + WorkspaceMember, 19 20 WorkspaceRole, 20 21 WorkspaceSyncResult, 21 22 } from "./types"; ··· 183 184 return wasm.generateIdentity(did) as import("./storage").Identity; 184 185 } 185 186 186 - /** Generate a DPoP keypair for OAuth token binding. */ 187 - static async generateDpopKeyPair(): Promise<import("./storage").DpopKeyPair> { 188 - const wasm = await initWasm(); 189 - return wasm.generateDpopKeyPair() as import("./storage").DpopKeyPair; 190 - } 191 - 192 - /** Create a DPoP proof JWT for an OAuth request. */ 193 - static async createDpopProof( 194 - keypair: import("./storage").DpopKeyPair, 195 - method: string, 196 - url: string, 197 - timestamp: number, 198 - nonce?: string, 199 - token?: string, 200 - ): Promise<string> { 201 - const wasm = await initWasm(); 202 - return wasm.createDpopProof( 203 - keypair, 204 - method, 205 - url, 206 - timestamp, 207 - nonce ?? null, 208 - token ?? null, 209 - ); 210 - } 211 - 212 - /** Generate a PKCE challenge for OAuth authorization. */ 213 - static async generatePkce(): Promise<{ 214 - verifier: string; 215 - challenge: string; 216 - }> { 217 - const wasm = await initWasm(); 218 - return wasm.generatePkce() as { verifier: string; challenge: string }; 219 - } 220 - 221 187 // --------------------------------------------------------------------------- 222 188 // Authentication 223 189 // --------------------------------------------------------------------------- ··· 429 395 */ 430 396 @wrapWasmErrors 431 397 async checkSession(): Promise<void> { 432 - const ctx = this.requireContext(); 433 - const existing = await ctx.getAccountConfig(); 434 - const config = existing ?? { telemetryEnabled: false }; 435 - config.modifiedAt = new Date().toISOString(); 436 - await ctx.setAccountConfig(config); 398 + await this.requireContext().checkSession(); 437 399 } 438 400 439 401 // --------------------------------------------------------------------------- ··· 469 431 const ctx = this.requireContext(); 470 432 try { 471 433 await ctx.proactiveRefresh(); 472 - } catch { 473 - // Best effort — reactive refresh via 401 handler covers failures 434 + } catch (e) { 435 + console.warn("opake: proactive token refresh failed", e); 474 436 } 475 437 } 476 438 ··· 577 539 * @returns Array of keyring member records with DIDs and roles. 578 540 */ 579 541 @wrapWasmErrors @withTokenGuard 580 - listWorkspaceMembers(keyringUri: string): Promise<unknown> { 581 - return this.requireContext().listWorkspaceMembers(keyringUri); 542 + listWorkspaceMembers(keyringUri: string): Promise<readonly WorkspaceMember[]> { 543 + return this.requireContext().listWorkspaceMembers(keyringUri) as Promise<readonly WorkspaceMember[]>; 582 544 } 583 545 584 546 /**
+11 -6
packages/opake-sdk/src/storage.ts
··· 20 20 readonly handle: string; 21 21 } 22 22 23 - /** X25519 + Ed25519 keypair derived from seed phrase or generated fresh. */ 23 + /** 24 + * Encryption identity keypairs. Contains private key material. 25 + * 26 + * WARNING: This type transits through JS for IndexedDB persistence. 27 + * Do not log, display, or transmit these values. WASM handles all 28 + * crypto operations — JS only stores and loads identities. 29 + */ 24 30 export interface Identity { 25 31 readonly did: string; 26 32 readonly public_key: string; ··· 57 63 readonly type: "oauth"; 58 64 readonly did: string; 59 65 readonly handle: string; 60 - // Mutable — WASM writes back refreshed tokens via Storage.saveSession() 61 - access_token: string; 62 - refresh_token: string; 66 + readonly access_token: string; 67 + readonly refresh_token: string; 63 68 readonly dpop_key: DpopKeyPair; 64 69 readonly token_endpoint: string; 65 - dpop_nonce?: string; 66 - expires_at?: number; 70 + readonly dpop_nonce?: string; 71 + readonly expires_at?: number; 67 72 readonly client_id: string; 68 73 } 69 74