@arbidocs/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session.ts","../src/crypto/sodium.ts","../src/crypto/keypairs.ts","../src/crypto/credentials.ts","../src/middleware/bearer-auth.ts","../src/middleware/workspace-key.ts","../src/middleware/auto-relogin.ts","../src/relogin/handler.ts","../src/storage/indexed-db.ts","../src/auth/register.ts","../src/auth/login.ts","../src/auth/logout.ts","../src/auth/change-password.ts","../src/client.ts","../src/websocket.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SessionManager - In-memory session state for SDK consumers\n *\n * Replaces Zustand for SDK consumers. Simple in-memory store with subscribe pattern.\n * Implements TokenProvider, WorkspaceKeyProvider, and AuthStateProvider —\n * plugs directly into middleware and relogin handler without any framework.\n */\n\nimport type { TokenProvider, WorkspaceKeyProvider } from './middleware/types'\nimport type { AuthStateProvider } from './relogin/types'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SessionState {\n accessToken: string | null\n userEmail: string | null\n userExtId: string | null\n selectedWorkspaceId: string | null\n cachedWorkspaceHeaders: Record<string, string>\n isSsoMode: boolean\n isAuth0Authenticated: boolean\n auth0AccessToken: string | null\n}\n\nexport interface SessionManager {\n getState(): Readonly<SessionState>\n setAccessToken(token: string | null): void\n setUser(email: string, extId?: string): void\n setSelectedWorkspace(id: string | null): void\n setCachedWorkspaceHeader(workspaceId: string, header: string): void\n clearWorkspaceHeaders(): void\n getWorkspaceKeyHeader(): string | null\n setSsoState(\n opts: Partial<{\n isSsoMode: boolean\n isAuth0Authenticated: boolean\n auth0AccessToken: string | null\n }>\n ): void\n clear(): void\n subscribe(listener: (state: SessionState) => void): () => void\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nfunction createInitialState(): SessionState {\n return {\n accessToken: null,\n userEmail: null,\n userExtId: null,\n selectedWorkspaceId: null,\n cachedWorkspaceHeaders: {},\n isSsoMode: false,\n isAuth0Authenticated: false,\n auth0AccessToken: null,\n }\n}\n\nexport function createSessionManager(): SessionManager {\n let state: SessionState = createInitialState()\n const listeners = new Set<(state: SessionState) => void>()\n\n function notify() {\n const snapshot = { ...state }\n for (const listener of listeners) {\n listener(snapshot)\n }\n }\n\n return {\n getState() {\n return state\n },\n\n setAccessToken(token: string | null) {\n state = { ...state, accessToken: token }\n notify()\n },\n\n setUser(email: string, extId?: string) {\n state = { ...state, userEmail: email, userExtId: extId ?? state.userExtId }\n notify()\n },\n\n setSelectedWorkspace(id: string | null) {\n state = { ...state, selectedWorkspaceId: id }\n notify()\n },\n\n setCachedWorkspaceHeader(workspaceId: string, header: string) {\n state = {\n ...state,\n cachedWorkspaceHeaders: {\n ...state.cachedWorkspaceHeaders,\n [workspaceId]: header,\n },\n }\n notify()\n },\n\n clearWorkspaceHeaders() {\n state = { ...state, cachedWorkspaceHeaders: {} }\n notify()\n },\n\n getWorkspaceKeyHeader(): string | null {\n const { selectedWorkspaceId, cachedWorkspaceHeaders } = state\n if (!selectedWorkspaceId) return null\n return cachedWorkspaceHeaders[selectedWorkspaceId] ?? null\n },\n\n setSsoState(opts) {\n state = {\n ...state,\n isSsoMode: opts.isSsoMode ?? state.isSsoMode,\n isAuth0Authenticated: opts.isAuth0Authenticated ?? state.isAuth0Authenticated,\n auth0AccessToken:\n opts.auth0AccessToken !== undefined ? opts.auth0AccessToken : state.auth0AccessToken,\n }\n notify()\n },\n\n clear() {\n state = createInitialState()\n notify()\n },\n\n subscribe(listener: (state: SessionState) => void) {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n }\n}\n\n// ============================================================================\n// Provider adapters\n// ============================================================================\n\n/**\n * Create a TokenProvider from a SessionManager\n */\nexport function createTokenProvider(session: SessionManager): TokenProvider {\n return {\n getAccessToken: () => session.getState().accessToken,\n }\n}\n\n/**\n * Create a WorkspaceKeyProvider from a SessionManager\n */\nexport function createWorkspaceKeyProvider(session: SessionManager): WorkspaceKeyProvider {\n return {\n getWorkspaceKeyHeader: () => session.getWorkspaceKeyHeader(),\n }\n}\n\n/**\n * Create an AuthStateProvider from a SessionManager\n */\nexport function createAuthStateProvider(session: SessionManager): AuthStateProvider {\n return {\n getUserEmail: () => session.getState().userEmail,\n\n getSsoState: () => {\n const s = session.getState()\n return {\n isSsoMode: s.isSsoMode,\n isAuth0Authenticated: s.isAuth0Authenticated,\n auth0AccessToken: s.auth0AccessToken,\n }\n },\n\n getSelectedWorkspaceId: () => session.getState().selectedWorkspaceId,\n\n setAccessToken: (token: string) => session.setAccessToken(token),\n\n clearWorkspaceHeaders: () => session.clearWorkspaceHeaders(),\n\n setCachedWorkspaceHeader: (workspaceId: string, header: string) =>\n session.setCachedWorkspaceHeader(workspaceId, header),\n }\n}\n","/**\n * Layer 1: Pure libsodium wrappers\n *\n * All low-level cryptographic operations using libsodium-wrappers-sumo.\n * No application logic — just type-safe wrappers around sodium functions.\n */\n\nimport sodium from 'libsodium-wrappers-sumo'\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\nexport interface KeyPair {\n publicKey: Uint8Array\n secretKey: Uint8Array\n}\n\nexport interface UserKeypairs {\n signingKeyPair: KeyPair // Ed25519 for signing/authentication\n encryptionKeyPair: KeyPair // X25519 derived from Ed25519 for encryption\n}\n\n// ============================================================================\n// libsodium initialization\n// ============================================================================\n\nlet sodiumReady: Promise<void> | null = null\n\n/**\n * Initialize sodium library\n */\nexport async function initSodium(): Promise<void> {\n if (sodiumReady) {\n await sodiumReady\n return\n }\n\n sodiumReady = sodium.ready\n await sodiumReady\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Convert base64 string to Uint8Array\n */\nexport function base64ToBytes(base64String: string): Uint8Array {\n return sodium.from_base64(base64String, sodium.base64_variants.ORIGINAL)\n}\n\n/**\n * Convert Uint8Array to base64 string\n */\nexport function bytesToBase64(bytes: Uint8Array): string {\n return sodium.to_base64(bytes, sodium.base64_variants.ORIGINAL)\n}\n\n/**\n * Base64 encode a Uint8Array (for compatibility with existing code)\n */\nexport function base64Encode(bytes: Uint8Array): string {\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join('')\n return btoa(binString)\n}\n\n/**\n * Base64 decode to Uint8Array (for compatibility with existing code)\n */\nexport function base64Decode(base64: string): Uint8Array {\n const binString = atob(base64)\n return Uint8Array.from(binString, (m) => m.codePointAt(0) || 0)\n}\n\n// ============================================================================\n// Core Cryptographic Functions\n// ============================================================================\n\n/**\n * Deterministic salt generation for Argon2id\n */\nfunction generateSalt(username: string, deploymentDomain: string): Uint8Array {\n if (!deploymentDomain) {\n throw new Error('Deployment domain must be provided for salt generation')\n }\n const normalized = username.toLowerCase()\n const saltString = `${normalized}|${deploymentDomain}`\n // Use SHA-256 to create a deterministic salt, then take first 16 bytes\n // (Argon2id requires exactly 16 bytes for salt)\n const hash = sodium.crypto_hash_sha256(sodium.from_string(saltString))\n return hash.slice(0, 16) // Return first 16 bytes\n}\n\n/**\n * Generate Ed25519 signing keypair and derive X25519 encryption keypair\n *\n * @param username - User's email/username\n * @param password - User's password\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns Object with Ed25519 signing keypair and derived X25519 encryption keypair\n */\nexport async function generateKeyPairs(\n username: string,\n password: string,\n deploymentDomain: string\n): Promise<{\n signing: { publicKey: Uint8Array; privateKey: Uint8Array; publicKeyBase64: string }\n encryption: { publicKey: Uint8Array; privateKey: Uint8Array; publicKeyBase64: string }\n}> {\n await initSodium()\n\n if (!deploymentDomain) {\n throw new Error('Deployment domain not available. Cannot generate keys.')\n }\n\n // Generate deterministic salt for key derivation\n const salt = generateSalt(username, deploymentDomain)\n\n // Derive seed using Argon2id\n const seed = sodium.crypto_pwhash(\n 32, // 32 bytes for Ed25519 seed\n password,\n salt,\n sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,\n sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,\n sodium.crypto_pwhash_ALG_ARGON2ID13\n )\n\n // Generate Ed25519 signing keypair from seed\n const signingKeyPair = sodium.crypto_sign_seed_keypair(seed)\n\n // Derive X25519 encryption keypair from Ed25519 keypair\n const encryptionPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(signingKeyPair.publicKey)\n const encryptionPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(\n signingKeyPair.privateKey\n )\n\n return {\n signing: {\n publicKey: signingKeyPair.publicKey,\n privateKey: signingKeyPair.privateKey,\n publicKeyBase64: sodium.to_base64(signingKeyPair.publicKey, sodium.base64_variants.ORIGINAL),\n },\n encryption: {\n publicKey: encryptionPublicKey,\n privateKey: encryptionPrivateKey,\n publicKeyBase64: sodium.to_base64(encryptionPublicKey, sodium.base64_variants.ORIGINAL),\n },\n }\n}\n\n/**\n * Sign a message with Ed25519 private key\n *\n * @param message - Message to sign (string)\n * @param privateKey - Ed25519 private key (64 bytes)\n * @returns Base64-encoded signature\n */\nexport function signMessage(message: string, privateKey: Uint8Array): string {\n const messageBytes = sodium.from_string(message)\n const signature = sodium.crypto_sign_detached(messageBytes, privateKey)\n return base64Encode(signature)\n}\n\n/**\n * Create Workspace-Key header for API requests using SealedBox\n */\nexport async function createWorkspaceKeyHeader(\n workspaceKey: Uint8Array,\n serverSessionPublicKey: Uint8Array\n): Promise<string> {\n await initSodium()\n\n // Encrypt workspace key using SealedBox (anonymous encryption)\n const encryptedKey = sealedBoxEncrypt(workspaceKey, serverSessionPublicKey)\n\n // Return just the encrypted key value\n return encryptedKey\n}\n\n/**\n * Decrypt data using SealedBox (anonymous decryption).\n *\n * @param encryptedBase64 - Base64-encoded SealedBox encrypted data\n * @param userEncryptionPrivateKey - User's X25519 private key (32 bytes)\n * @returns Decrypted data\n */\nexport function sealedBoxDecrypt(\n encryptedBase64: string,\n userEncryptionPrivateKey: Uint8Array\n): Uint8Array {\n const encrypted = base64ToBytes(encryptedBase64)\n\n // Get the public key from private key for SealedBox\n const publicKey = sodium.crypto_scalarmult_base(userEncryptionPrivateKey)\n\n // Decrypt using SealedBox\n const decrypted = sodium.crypto_box_seal_open(encrypted, publicKey, userEncryptionPrivateKey)\n\n return decrypted\n}\n\n/**\n * Encrypt data using SealedBox (anonymous encryption).\n *\n * @param message - Data to encrypt\n * @param publicKey - Recipient's X25519 public key (32 bytes)\n * @returns Base64-encoded encrypted data\n */\nexport function sealedBoxEncrypt(message: Uint8Array, publicKey: Uint8Array): string {\n // Encrypt using SealedBox\n const encrypted = sodium.crypto_box_seal(message, publicKey)\n\n return bytesToBase64(encrypted)\n}\n\n/**\n * Derive X25519 public key from X25519 private key\n * Used for instant re-login when we have stored private key\n */\nexport function derivePublicKey(privateKey: Uint8Array): Uint8Array {\n return sodium.crypto_scalarmult_base(privateKey)\n}\n\n/**\n * Derive X25519 keypair from Ed25519 keypair\n * Used when we have stored Ed25519 keys and need X25519 for encryption\n */\nexport function deriveEncryptionKeypairFromSigning(signingKeyPair: KeyPair): KeyPair {\n const encryptionPublicKey = sodium.crypto_sign_ed25519_pk_to_curve25519(signingKeyPair.publicKey)\n const encryptionPrivateKey = sodium.crypto_sign_ed25519_sk_to_curve25519(signingKeyPair.secretKey)\n return {\n publicKey: encryptionPublicKey,\n secretKey: encryptionPrivateKey,\n }\n}\n\n// ============================================================================\n// E2E Message Encryption (ECDH + Symmetric)\n// ============================================================================\n\n/**\n * Precompute shared secret for ECDH encryption.\n *\n * Call once per contact, cache for efficiency.\n *\n * @param theirPublicKeyBase64 - Other party's X25519 public key (base64)\n * @param myPrivateKey - Your X25519 private key (Uint8Array)\n * @returns 32-byte shared secret (Uint8Array)\n */\nexport async function computeSharedSecret(\n theirPublicKeyBase64: string,\n myPrivateKey: Uint8Array\n): Promise<Uint8Array> {\n await initSodium()\n const theirPublicKey = base64ToBytes(theirPublicKeyBase64)\n return sodium.crypto_box_beforenm(theirPublicKey, myPrivateKey)\n}\n\n/**\n * Encrypt a message using precomputed shared secret.\n *\n * @param message - Plaintext message to encrypt\n * @param sharedSecret - Precomputed 32-byte shared secret\n * @returns Base64-encoded ciphertext (nonce prepended)\n */\nexport async function encryptMessageWithSharedSecret(\n message: string,\n sharedSecret: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const messageBytes = sodium.from_string(message)\n const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES)\n const ciphertext = sodium.crypto_box_easy_afternm(messageBytes, nonce, sharedSecret)\n\n const combined = new Uint8Array(nonce.length + ciphertext.length)\n combined.set(nonce, 0)\n combined.set(ciphertext, nonce.length)\n\n return bytesToBase64(combined)\n}\n\n/**\n * Decrypt a message using precomputed shared secret.\n *\n * @param encryptedBase64 - Base64-encoded ciphertext (nonce prepended)\n * @param sharedSecret - Precomputed 32-byte shared secret\n * @returns Decrypted plaintext message\n */\nexport async function decryptMessageWithSharedSecret(\n encryptedBase64: string,\n sharedSecret: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const combined = base64ToBytes(encryptedBase64)\n const nonce = combined.slice(0, sodium.crypto_box_NONCEBYTES)\n const ciphertext = combined.slice(sodium.crypto_box_NONCEBYTES)\n const decrypted = sodium.crypto_box_open_easy_afternm(ciphertext, nonce, sharedSecret)\n\n return sodium.to_string(decrypted)\n}\n\n/**\n * Encrypt a message for a specific recipient using ECDH (X25519 + XSalsa20-Poly1305).\n *\n * @param message - Plaintext message to encrypt\n * @param recipientPublicKeyBase64 - Recipient's X25519 public key (base64)\n * @param senderPrivateKey - Sender's X25519 private key (Uint8Array)\n * @returns Base64-encoded ciphertext (nonce prepended)\n */\nexport async function encryptMessage(\n message: string,\n recipientPublicKeyBase64: string,\n senderPrivateKey: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const recipientPublicKey = base64ToBytes(recipientPublicKeyBase64)\n const messageBytes = sodium.from_string(message)\n\n // Generate random nonce\n const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES)\n\n // Encrypt using crypto_box (ECDH + XSalsa20-Poly1305)\n const ciphertext = sodium.crypto_box_easy(\n messageBytes,\n nonce,\n recipientPublicKey,\n senderPrivateKey\n )\n\n // Prepend nonce to ciphertext for transmission\n const combined = new Uint8Array(nonce.length + ciphertext.length)\n combined.set(nonce, 0)\n combined.set(ciphertext, nonce.length)\n\n return bytesToBase64(combined)\n}\n\n/**\n * Decrypt a message from a specific sender using ECDH (X25519 + XSalsa20-Poly1305).\n *\n * @param encryptedBase64 - Base64-encoded ciphertext (nonce prepended)\n * @param senderPublicKeyBase64 - Sender's X25519 public key (base64)\n * @param recipientPrivateKey - Recipient's X25519 private key (Uint8Array)\n * @returns Decrypted plaintext message\n * @throws Error if decryption fails (wrong keys or tampered message)\n */\nexport async function decryptMessage(\n encryptedBase64: string,\n senderPublicKeyBase64: string,\n recipientPrivateKey: Uint8Array\n): Promise<string> {\n await initSodium()\n\n const combined = base64ToBytes(encryptedBase64)\n const senderPublicKey = base64ToBytes(senderPublicKeyBase64)\n\n // Extract nonce and ciphertext\n const nonce = combined.slice(0, sodium.crypto_box_NONCEBYTES)\n const ciphertext = combined.slice(sodium.crypto_box_NONCEBYTES)\n\n // Decrypt using crypto_box_open (ECDH + XSalsa20-Poly1305)\n const decrypted = sodium.crypto_box_open_easy(\n ciphertext,\n nonce,\n senderPublicKey,\n recipientPrivateKey\n )\n\n return sodium.to_string(decrypted)\n}\n","/**\n * Layer 2: User keypair generation\n *\n * Generates Ed25519 signing and X25519 encryption keypairs from email + password.\n * Takes `deploymentDomain` as an explicit parameter (no window.RUNTIME_CONFIG).\n */\n\nimport { generateKeyPairs, type KeyPair, type UserKeypairs } from './sodium'\n\n/**\n * Generate user keypairs deterministically using Argon2id.\n *\n * Creates Ed25519 signing keypair and derives X25519 encryption keypair.\n * Ed25519 is used for authentication (signing), X25519 for encryption.\n *\n * This is a zero-knowledge system - the server never sees private keys.\n *\n * @param username - User's email/username\n * @param password - User's password\n * @param deploymentDomain - Deployment domain (used for salt derivation)\n * @returns Object with Ed25519 signing keypair and X25519 encryption keypair\n */\nexport async function generateUserKeypairs(\n username: string,\n password: string,\n deploymentDomain: string\n): Promise<UserKeypairs> {\n if (!deploymentDomain) {\n throw new Error('Deployment domain must be provided. Cannot generate keypairs.')\n }\n\n // Generate keypairs using the libsodium implementation\n const keypairs = await generateKeyPairs(username, password, deploymentDomain)\n\n const signingKeyPair: KeyPair = {\n publicKey: keypairs.signing.publicKey,\n secretKey: keypairs.signing.privateKey,\n }\n\n const encryptionKeyPair: KeyPair = {\n publicKey: keypairs.encryption.publicKey,\n secretKey: keypairs.encryption.privateKey,\n }\n\n return {\n signingKeyPair,\n encryptionKeyPair,\n }\n}\n","/**\n * Layer 3: High-level credential generation\n *\n * Generates registration, login, and password-change credentials.\n * Uses inline type definitions (structurally identical to OpenAPI schema types)\n * to avoid coupling the crypto module to the schema file.\n */\n\nimport { signMessage, base64Encode } from './sodium'\nimport { generateUserKeypairs } from './keypairs'\n\n// ============================================================================\n// Inline types (structurally identical to OpenAPI schema equivalents)\n// ============================================================================\n\nexport interface RegisterRequest {\n email: string\n signing_key: string\n verification_credential: string\n given_name?: string | null\n family_name?: string | null\n picture?: string | null\n}\n\nexport interface LoginRequest {\n email: string\n signature: string\n timestamp: number\n sso_token?: string | null\n}\n\nexport interface ChangePasswordRequest {\n signature: string\n timestamp: number\n new_signing_key: string\n rewrapped_workspace_keys: Record<string, string>\n}\n\n// ============================================================================\n// Credential types\n// ============================================================================\n\n/**\n * Credentials returned by generate functions.\n * Contains both the backend request AND client-side private keys.\n * Private keys never leave the client.\n */\nexport interface RegistrationCredentials {\n request: RegisterRequest\n signingPrivateKey: Uint8Array\n}\n\nexport interface LoginCredentials {\n request: LoginRequest\n signingPrivateKey: Uint8Array\n}\n\nexport interface PasswordChangeCredentials {\n request: Omit<ChangePasswordRequest, 'rewrapped_workspace_keys'>\n newSigningPrivateKey: Uint8Array\n}\n\n// ============================================================================\n// Credential generation functions\n// ============================================================================\n\n/**\n * Generate registration credentials with Ed25519 signing key.\n *\n * Creates Ed25519 keypair deterministically from email + password.\n * Server receives the Ed25519 public key (signing_key) and derives X25519 from it.\n *\n * @param registrationData - Registration fields (signing_key will be generated)\n * @param password - User's password (to generate keypair)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns RegistrationCredentials with request body and private key (kept separate)\n */\nexport async function generateRegistrationCredentials(\n registrationData: Omit<RegisterRequest, 'signing_key'>,\n password: string,\n deploymentDomain: string\n): Promise<RegistrationCredentials> {\n const { signingKeyPair } = await generateUserKeypairs(\n registrationData.email,\n password,\n deploymentDomain\n )\n\n const request: RegisterRequest = {\n ...registrationData,\n signing_key: base64Encode(signingKeyPair.publicKey),\n }\n\n return { request, signingPrivateKey: signingKeyPair.secretKey }\n}\n\n/**\n * Generate login credentials with Ed25519 signature authentication.\n *\n * Derives Ed25519 keypair from email + password and signs \"email|timestamp\".\n * Server verifies signature using stored Ed25519 public key.\n *\n * @param loginData - Login fields (signature and timestamp will be generated)\n * @param password - User's password (to regenerate keypair)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns LoginCredentials with request body and private key (kept separate)\n */\nexport async function generateLoginCredentials(\n loginData: Omit<LoginRequest, 'signature' | 'timestamp'>,\n password: string,\n deploymentDomain: string\n): Promise<LoginCredentials> {\n const { signingKeyPair } = await generateUserKeypairs(loginData.email, password, deploymentDomain)\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${loginData.email}|${timestamp}`\n const signature = signMessage(message, signingKeyPair.secretKey)\n\n const request: LoginRequest = {\n ...loginData,\n signature,\n timestamp,\n }\n\n return { request, signingPrivateKey: signingKeyPair.secretKey }\n}\n\n/**\n * Generate login credentials using an existing signing key (for password recovery).\n *\n * Bypasses password derivation and uses the provided key directly.\n *\n * @param loginData - Login fields (signature and timestamp will be generated)\n * @param signingPrivateKey - The Ed25519 signing private key (64 bytes)\n * @returns LoginCredentials with request body and private key\n */\nexport function generateLoginCredentialsFromKey(\n loginData: Omit<LoginRequest, 'signature' | 'timestamp'>,\n signingPrivateKey: Uint8Array\n): LoginCredentials {\n if (signingPrivateKey.length !== 64) {\n throw new Error('Invalid signing key: must be exactly 64 bytes')\n }\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${loginData.email}|${timestamp}`\n const signature = signMessage(message, signingPrivateKey)\n\n const request: LoginRequest = {\n ...loginData,\n signature,\n timestamp,\n }\n\n return { request, signingPrivateKey }\n}\n\n/**\n * Generate change password credentials with Ed25519 signature authentication.\n *\n * Signs \"email|timestamp\" with current Ed25519 key to prove knowledge of current password.\n * Provides new Ed25519 public key derived from new password.\n *\n * @param email - User's email address\n * @param currentPassword - Current password (to sign with current key)\n * @param newPassword - New password (to generate new key)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns PasswordChangeCredentials with request body and new private key (kept separate)\n */\nexport async function generatePasswordChangeCredentials(\n email: string,\n currentPassword: string,\n newPassword: string,\n deploymentDomain: string\n): Promise<PasswordChangeCredentials> {\n const currentKeypairs = await generateUserKeypairs(email, currentPassword, deploymentDomain)\n const newKeypairs = await generateUserKeypairs(email, newPassword, deploymentDomain)\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${email}|${timestamp}`\n const signature = signMessage(message, currentKeypairs.signingKeyPair.secretKey)\n\n const request: Omit<ChangePasswordRequest, 'rewrapped_workspace_keys'> = {\n signature,\n timestamp,\n new_signing_key: base64Encode(newKeypairs.signingKeyPair.publicKey),\n }\n\n return { request, newSigningPrivateKey: newKeypairs.signingKeyPair.secretKey }\n}\n\n/**\n * Generate password change credentials for recovery mode.\n *\n * Used when the user is recovering their account with a recovery key.\n * Signs with the existing signing key (from recovery) instead of deriving from password.\n *\n * @param email - User's email address\n * @param currentSigningKey - Current signing key (from recovery)\n * @param newPassword - New password (to generate new key)\n * @param deploymentDomain - Deployment domain for salt derivation\n * @returns PasswordChangeCredentials with request body and new private key\n */\nexport async function generateRecoveryPasswordChangeCredentials(\n email: string,\n currentSigningKey: Uint8Array,\n newPassword: string,\n deploymentDomain: string\n): Promise<PasswordChangeCredentials> {\n const newKeypairs = await generateUserKeypairs(email, newPassword, deploymentDomain)\n\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${email}|${timestamp}`\n const signature = signMessage(message, currentSigningKey)\n\n const request: Omit<ChangePasswordRequest, 'rewrapped_workspace_keys'> = {\n signature,\n timestamp,\n new_signing_key: base64Encode(newKeypairs.signingKeyPair.publicKey),\n }\n\n return { request, newSigningPrivateKey: newKeypairs.signingKeyPair.secretKey }\n}\n","/**\n * Bearer Auth Middleware\n *\n * Injects Authorization header on every request using the provided TokenProvider.\n */\n\nimport type { Middleware } from 'openapi-fetch'\nimport type { BearerAuthMiddlewareConfig } from './types'\n\nexport function createBearerAuthMiddleware(config: BearerAuthMiddlewareConfig): Middleware {\n return {\n async onRequest({ request }) {\n const accessToken = config.tokenProvider.getAccessToken()\n if (accessToken) {\n request.headers.set('Authorization', `Bearer ${accessToken}`)\n }\n return request\n },\n }\n}\n","/**\n * Workspace Key Middleware\n *\n * Injects Workspace-Key header on workspace-scoped requests.\n * URL matching is data-driven via WorkspaceKeyUrlConfig.\n */\n\nimport type { Middleware } from 'openapi-fetch'\nimport type { WorkspaceKeyMiddlewareConfig, WorkspaceKeyUrlConfig } from './types'\n\n/**\n * Check if a URL needs the Workspace-Key header based on URL patterns.\n */\nexport function needsWorkspaceKey(url: string, urlConfig: WorkspaceKeyUrlConfig): boolean {\n // Skip if it matches an exclude pattern\n if (urlConfig.excludePatterns.some((pattern) => url.includes(pattern))) {\n return false\n }\n\n // Include if it matches an include pattern\n return urlConfig.includePatterns.some((pattern) => url.includes(pattern))\n}\n\nexport function createWorkspaceKeyMiddleware(config: WorkspaceKeyMiddlewareConfig): Middleware {\n return {\n async onRequest({ request }) {\n if (needsWorkspaceKey(request.url, config.urlConfig)) {\n const workspaceHeader = config.workspaceKeyProvider.getWorkspaceKeyHeader()\n if (workspaceHeader) {\n request.headers.set('Workspace-Key', workspaceHeader)\n }\n }\n return request\n },\n }\n}\n","/**\n * Auto Re-login Middleware\n *\n * Handles 401 and 400 responses by triggering re-login and retrying the request.\n * Framework-agnostic — the actual re-login logic is provided via ReloginHandler.\n */\n\nimport type { Middleware } from 'openapi-fetch'\nimport type { AutoReloginMiddlewareConfig } from './types'\nimport { needsWorkspaceKey } from './workspace-key'\n\nexport function createAutoReloginMiddleware(config: AutoReloginMiddlewareConfig): Middleware {\n return {\n async onResponse({ response, request }) {\n // Log response with workspace key status for workspace-scoped endpoints\n if (needsWorkspaceKey(request.url, config.urlConfig)) {\n const hasWorkspaceKey = request.headers.has('Workspace-Key')\n console.debug(\n `[${request.method}] ${response.status}`,\n request.url,\n `Workspace-Key: ${hasWorkspaceKey ? '\\u2713' : '\\u2717'}`\n )\n }\n\n // Handle 400 errors on protected endpoints - try instant re-login once\n if (response.status === 400) {\n const isSafeMethod = ['GET', 'HEAD', 'DELETE'].includes(request.method)\n\n if (isSafeMethod) {\n console.info('[API] 400 error on protected endpoint - triggering instant re-login')\n const newToken = await config.reloginHandler()\n if (newToken) {\n const newRequest = request.clone()\n newRequest.headers.set('Authorization', `Bearer ${newToken}`)\n\n if (needsWorkspaceKey(request.url, config.urlConfig)) {\n const workspaceHeader = config.workspaceKeyProvider.getWorkspaceKeyHeader()\n if (workspaceHeader) {\n newRequest.headers.set('Workspace-Key', workspaceHeader)\n }\n }\n console.info('[API] Retrying request after re-login')\n return fetch(newRequest)\n }\n }\n }\n\n if (response.status === 401) {\n const excludePatterns = config.reloginExcludePatterns ?? []\n const isExcluded = excludePatterns.some((pattern) => request.url.includes(pattern))\n\n // Retry ALL requests after re-login, not just safe methods\n if (!isExcluded) {\n const newToken = await config.reloginHandler()\n if (newToken) {\n try {\n const newRequest = request.clone()\n newRequest.headers.set('Authorization', `Bearer ${newToken}`)\n\n if (needsWorkspaceKey(request.url, config.urlConfig)) {\n const workspaceHeader = config.workspaceKeyProvider.getWorkspaceKeyHeader()\n if (workspaceHeader) {\n newRequest.headers.set('Workspace-Key', workspaceHeader)\n }\n }\n\n console.info('[API] Retrying request after re-login:', request.method, request.url)\n return fetch(newRequest)\n } catch (cloneError) {\n // If cloning fails (rare - only for streaming requests), notify caller\n console.warn('[API] Could not clone request for retry:', cloneError)\n config.onRetryCloneFailed?.()\n }\n }\n }\n }\n\n return response\n },\n }\n}\n","/**\n * Re-login Handler Factory\n *\n * Framework-agnostic instant re-login using stored private key.\n * All app-specific dependencies (state management, crypto, storage,\n * API transport) are injected via provider interfaces.\n *\n * Zero external dependencies beyond TypeScript types.\n */\n\nimport type { ReloginDeps } from './types'\n\n/**\n * Create a re-login handler with injected dependencies.\n *\n * Returns a function: `() => Promise<string | null>`\n * Resolves to the new access token, or null on failure.\n *\n * Includes debounce protection: if multiple 401s occur simultaneously,\n * they all wait for the same re-login promise.\n */\nexport function createReloginHandler(deps: ReloginDeps): () => Promise<string | null> {\n let reloginPromise: Promise<string | null> | null = null\n\n return function instantReLogin(): Promise<string | null> {\n if (reloginPromise) {\n console.info('[API] Re-login already in progress, waiting...')\n return reloginPromise\n }\n\n reloginPromise = (async () => {\n try {\n await deps.crypto.ensureReady()\n\n const userEmail = deps.authState.getUserEmail()\n if (!userEmail) {\n console.warn('[API] No user email found for instant re-login')\n return null\n }\n\n const session = await deps.sessionStorage.getSession()\n if (!session) {\n console.warn('[API] No session found for instant re-login')\n return null\n }\n\n // Derive encryption key from signing key (for workspace key decryption)\n // Ed25519 secret key is 64 bytes: [32-byte seed][32-byte public key]\n const ed25519PublicKey = session.signingPrivateKey.slice(32, 64)\n const encryptionKeyPair = deps.crypto.deriveEncryptionKeypair({\n publicKey: ed25519PublicKey,\n secretKey: session.signingPrivateKey,\n })\n\n // Create timestamp and signature for login\n const timestamp = Math.floor(Date.now() / 1000)\n const message = `${userEmail}|${timestamp}`\n const signature = deps.crypto.signMessage(message, session.signingPrivateKey)\n\n console.info('[API] Attempting instant re-login')\n\n // SSO token handling\n const ssoState = deps.authState.getSsoState()\n console.info('[API] Re-login SSO mode:', ssoState.isSsoMode)\n console.info('[API] Auth0 authenticated:', ssoState.isAuth0Authenticated)\n console.info('[API] Persisted Auth0 token available:', !!ssoState.auth0AccessToken)\n\n const isSsoAccount =\n ssoState.isSsoMode || ssoState.isAuth0Authenticated || !!ssoState.auth0AccessToken\n\n // Try to get SSO token from the injected provider\n let ssoToken: string | null = null\n\n if (deps.ssoTokenProvider) {\n console.info('[API] SSO token provider available: true')\n try {\n ssoToken = await deps.ssoTokenProvider.getToken()\n console.info(\n '[API] Got SSO token from provider:',\n ssoToken ? 'yes (length: ' + ssoToken.length + ')' : 'no'\n )\n } catch (error) {\n console.error('[API] Failed to get SSO token from provider:', error)\n }\n } else {\n console.info('[API] SSO token provider available: false')\n }\n\n // Fallback to persisted token\n if (!ssoToken && ssoState.auth0AccessToken) {\n ssoToken = ssoState.auth0AccessToken\n console.info(\n '[API] Using persisted SSO token (length:',\n ssoToken.length,\n ') - may be expired'\n )\n }\n\n if (!ssoToken && isSsoAccount) {\n console.warn('[API] SSO account requires token but none available - aborting re-login')\n return null\n }\n\n // Perform login via injected provider\n const loginResult = await deps.loginProvider.login({\n email: userEmail,\n signature,\n timestamp,\n ssoToken: ssoToken ?? undefined,\n })\n\n if (!loginResult) {\n console.warn('[API] Instant re-login failed')\n return null\n }\n\n // Save new session key (so it survives page reload)\n await deps.sessionStorage.saveSession({\n signingPrivateKey: session.signingPrivateKey,\n serverSessionKey: loginResult.sessionKey,\n userExtId: loginResult.userExtId,\n })\n\n // Notify consumers (e.g. cache update)\n deps.onReloginSuccess?.({\n email: userEmail,\n accessToken: loginResult.accessToken,\n userExtId: loginResult.userExtId,\n serverSessionKey: loginResult.sessionKey,\n })\n\n deps.authState.setAccessToken(loginResult.accessToken)\n\n // Clear cached workspace headers — they were encrypted with the old session key\n deps.authState.clearWorkspaceHeaders()\n\n // Regenerate workspace header for currently selected workspace\n const selectedWorkspaceId = deps.authState.getSelectedWorkspaceId()\n if (selectedWorkspaceId) {\n try {\n const wrappedKey = await deps.workspaceKeyRefreshProvider.getWrappedKey(\n loginResult.accessToken,\n selectedWorkspaceId\n )\n\n if (wrappedKey) {\n // Decrypt workspace key with user's encryption key\n const workspaceKey = deps.crypto.sealedBoxDecrypt(\n wrappedKey,\n encryptionKeyPair.secretKey\n )\n\n // Create header encrypted with NEW server session key\n const workspaceKeyHeader = await deps.crypto.createWorkspaceKeyHeader(\n workspaceKey,\n loginResult.sessionKey\n )\n\n // Cache the regenerated header\n deps.authState.setCachedWorkspaceHeader(selectedWorkspaceId, workspaceKeyHeader)\n }\n } catch (error) {\n console.error('[API] Failed to regenerate workspace header:', error)\n }\n }\n\n console.info('[API] Re-login successful')\n return loginResult.accessToken\n } catch (error) {\n console.error('[API] Instant re-login error:', error)\n return null\n } finally {\n reloginPromise = null\n }\n })()\n\n return reloginPromise\n }\n}\n","/**\n * storage.ts - IndexedDB Storage Module\n *\n * Handles persistent storage of cryptographic keys and session data.\n *\n * Storage Strategy (with encryption-at-rest):\n * - Private keys encrypted with non-extractable Web Crypto AES-GCM key\n * - Wrapping key stored as opaque CryptoKey object (can't be exported)\n * - Session data persists across page refreshes\n *\n * Database Schema:\n * - Store: 'session' - User session data (encrypted private key only)\n * - Store: 'wrapping-key' - Non-extractable CryptoKey for encrypting private keys\n *\n * Security Model:\n * - Passive attacks (reading IndexedDB) get encrypted data + opaque CryptoKey\n * - Active attacks (calling decrypt) can still access keys (XSS with code execution)\n * - Defense-in-depth: Requires active XSS, not just storage access\n *\n * Ported from: /home/dev/ARBI/src/static/js/storage.js\n */\n\nconst DB_NAME = 'arbi-crypto'\nconst DB_VERSION = 2 // Incremented for new wrapping-key store\n\nlet db: IDBDatabase | null = null\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/**\n * SessionData in IndexedDB - PERSISTED ENCRYPTED DATA\n * Everything needed to resume session without re-login:\n * - signingPrivateKey: Ed25519 private key (64 bytes, encrypted at rest)\n * Used for authentication (signing). X25519 encryption key is derived from this.\n * - serverSessionKey: Server session key for workspace key encryption (encrypted at rest)\n * - userExtId: User external ID (not sensitive, stored in plain text)\n *\n * Note: accessToken is stored in Zustand (persisted separately), not here.\n */\nexport interface SessionData {\n signingPrivateKey: Uint8Array // Ed25519 (64 bytes) - X25519 derived from this\n serverSessionKey?: Uint8Array\n userExtId?: string\n}\n\n/**\n * How session is stored in IndexedDB (with ALL sensitive data encrypted)\n */\ninterface StoredSession {\n id: string\n encryptedSigningPrivateKey: Uint8Array\n signingPrivateKeyIV: Uint8Array\n encryptedServerSessionKey?: Uint8Array\n serverSessionKeyIV?: Uint8Array\n userExtId?: string\n timestamp: number\n}\n\ninterface WrappingKeyData {\n id: string\n key: CryptoKey\n created: number\n}\n\n// ============================================================================\n// Database Initialization\n// ============================================================================\n\n/**\n * Initialize IndexedDB database.\n *\n * Creates two object stores:\n * - 'session': Stores user session data (with encrypted private key)\n * - 'wrapping-key': Stores non-extractable CryptoKey for key encryption\n */\nexport async function initializeDatabase(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to open IndexedDB:', request.error)\n reject(request.error)\n }\n\n request.onsuccess = () => {\n db = request.result\n resolve(db)\n }\n\n request.onupgradeneeded = (event) => {\n const database = (event.target as IDBOpenDBRequest).result\n\n // Create 'session' store if it doesn't exist\n if (!database.objectStoreNames.contains('session')) {\n database.createObjectStore('session', { keyPath: 'id' })\n }\n\n // Create 'wrapping-key' store if it doesn't exist (v2+)\n if (!database.objectStoreNames.contains('wrapping-key')) {\n database.createObjectStore('wrapping-key', { keyPath: 'id' })\n }\n }\n })\n}\n\n/**\n * Ensure database is initialized before operations.\n */\nasync function ensureDatabase(): Promise<void> {\n if (!db) {\n await initializeDatabase()\n }\n}\n\n// ============================================================================\n// Wrapping Key Management (Web Crypto Non-Extractable Keys)\n// ============================================================================\n\n/**\n * Generate or retrieve the non-extractable wrapping key.\n *\n * This key is used to encrypt private keys before storing in IndexedDB.\n * - Generated once per browser (survives page refreshes)\n * - Stored as opaque CryptoKey object in IndexedDB\n * - Non-extractable: XSS can't dump the raw key bytes\n * - Can still be used for encrypt/decrypt operations\n *\n * @returns Non-extractable AES-GCM key\n */\nasync function getOrCreateWrappingKey(): Promise<CryptoKey> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['wrapping-key'], 'readwrite')\n const store = transaction.objectStore('wrapping-key')\n const request = store.get('master')\n\n request.onsuccess = () => {\n const result = request.result as WrappingKeyData | undefined\n\n if (result?.key) {\n resolve(result.key)\n } else {\n // Generate new non-extractable wrapping key\n // We need to generate the key and store it, but the transaction will auto-commit\n // after this callback. So we need to open a NEW transaction for the put.\n crypto.subtle\n .generateKey(\n {\n name: 'AES-GCM',\n length: 256,\n },\n false, // ❌ NON-EXTRACTABLE - Can't be exported!\n ['encrypt', 'decrypt']\n )\n .then((key) => {\n // Open a NEW transaction to store the key\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const putTransaction = db.transaction(['wrapping-key'], 'readwrite')\n const putStore = putTransaction.objectStore('wrapping-key')\n const putRequest = putStore.put({\n id: 'master',\n key: key,\n created: Date.now(),\n } as WrappingKeyData)\n\n putRequest.onsuccess = () => {\n resolve(key)\n }\n\n putRequest.onerror = () => {\n reject(new Error('Failed to store wrapping key'))\n }\n })\n .catch((error) => {\n const errorMsg = error instanceof Error ? error.message : String(error)\n reject(new Error(`Failed to generate wrapping key: ${errorMsg}`))\n })\n }\n }\n\n request.onerror = () => {\n reject(new Error('Failed to retrieve wrapping key from IndexedDB'))\n }\n })\n}\n\n/**\n * Encrypt data using the non-extractable wrapping key.\n *\n * @param data - Data to encrypt\n * @returns Encrypted data and IV\n */\nasync function encryptWithWrappingKey(\n data: Uint8Array\n): Promise<{ ciphertext: Uint8Array; iv: Uint8Array }> {\n const wrappingKey = await getOrCreateWrappingKey()\n\n // Generate random IV for AES-GCM\n const iv = crypto.getRandomValues(new Uint8Array(12))\n\n // Encrypt the data\n const ciphertext = await crypto.subtle.encrypt(\n {\n name: 'AES-GCM',\n iv: iv,\n },\n wrappingKey,\n data as BufferSource\n )\n\n return {\n ciphertext: new Uint8Array(ciphertext),\n iv: iv,\n }\n}\n\n/**\n * Decrypt data using the non-extractable wrapping key.\n *\n * @param ciphertext - Encrypted data\n * @param iv - Initialization vector\n * @returns Decrypted data\n */\nasync function decryptWithWrappingKey(ciphertext: Uint8Array, iv: Uint8Array): Promise<Uint8Array> {\n const wrappingKey = await getOrCreateWrappingKey()\n\n const decrypted = await crypto.subtle.decrypt(\n {\n name: 'AES-GCM',\n iv: iv as BufferSource,\n },\n wrappingKey,\n ciphertext as BufferSource\n )\n\n return new Uint8Array(decrypted)\n}\n\n// ============================================================================\n// Session Storage\n// ============================================================================\n\n/**\n * Store session data in IndexedDB (ALL data encrypted at rest).\n *\n * Stores everything needed to resume session without re-login:\n * - signingPrivateKey: User's Ed25519 private key (ENCRYPTED)\n * - serverSessionKey: Server session key (ENCRYPTED)\n * - userExtId: User external ID (plain text, not sensitive)\n *\n * Note: accessToken is NOT stored here - it's in Zustand (persisted separately).\n *\n * @param sessionData - Complete session data to persist\n */\nexport async function saveSession(sessionData: SessionData): Promise<void> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n try {\n // Encrypt the signing private key (required)\n const encryptedSigningKey = await encryptWithWrappingKey(sessionData.signingPrivateKey)\n\n // Encrypt optional fields if present\n let encryptedServerSessionKey: { ciphertext: Uint8Array; iv: Uint8Array } | undefined\n\n if (sessionData.serverSessionKey) {\n encryptedServerSessionKey = await encryptWithWrappingKey(sessionData.serverSessionKey)\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['session'], 'readwrite')\n const store = transaction.objectStore('session')\n\n const data: StoredSession = {\n id: 'current',\n encryptedSigningPrivateKey: encryptedSigningKey.ciphertext,\n signingPrivateKeyIV: encryptedSigningKey.iv,\n encryptedServerSessionKey: encryptedServerSessionKey?.ciphertext,\n serverSessionKeyIV: encryptedServerSessionKey?.iv,\n userExtId: sessionData.userExtId,\n timestamp: Date.now(),\n }\n\n const request = store.put(data)\n\n request.onsuccess = () => {\n resolve()\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to save session:', request.error)\n reject(request.error)\n }\n })\n } catch (error) {\n console.error('[STORAGE] Failed to encrypt session data:', error)\n throw error\n }\n}\n\n/**\n * Retrieve session data from IndexedDB (with decrypted private key).\n *\n * @returns Session data or null if not found\n */\nexport async function getSession(): Promise<SessionData | null> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['session'], 'readonly')\n const store = transaction.objectStore('session')\n const request = store.get('current')\n\n request.onsuccess = async () => {\n const result = request.result as StoredSession | undefined\n\n if (result) {\n try {\n // Decrypt the signing private key (required)\n const signingPrivateKey = await decryptWithWrappingKey(\n result.encryptedSigningPrivateKey,\n result.signingPrivateKeyIV\n )\n\n // Decrypt optional fields if present\n let serverSessionKey\n\n if (result.encryptedServerSessionKey && result.serverSessionKeyIV) {\n serverSessionKey = await decryptWithWrappingKey(\n result.encryptedServerSessionKey,\n result.serverSessionKeyIV\n )\n }\n\n resolve({\n signingPrivateKey,\n serverSessionKey,\n userExtId: result.userExtId,\n })\n } catch (error) {\n console.error('[STORAGE] Failed to decrypt session data:', error)\n reject(error)\n }\n } else {\n resolve(null)\n }\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to get session:', request.error)\n reject(request.error)\n }\n })\n}\n\n/**\n * Update the signing private key in IndexedDB (used when changing password).\n * This re-encrypts the new key while preserving other session data.\n *\n * @param newSigningPrivateKey - New Ed25519 private key to store\n */\nexport async function updateSigningPrivateKey(newSigningPrivateKey: Uint8Array): Promise<void> {\n await ensureDatabase()\n\n try {\n // Get existing session to preserve serverSessionKey, etc.\n const existingSession = await getSession()\n\n if (!existingSession) {\n throw new Error('No existing session to update')\n }\n\n // Save complete session with new signing key\n await saveSession({\n signingPrivateKey: newSigningPrivateKey,\n serverSessionKey: existingSession.serverSessionKey,\n userExtId: existingSession.userExtId,\n })\n } catch (error) {\n console.error('[STORAGE] Failed to update signing private key:', error)\n throw error\n }\n}\n\n/**\n * Clear session data from IndexedDB.\n */\nexport async function clearSession(): Promise<void> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['session'], 'readwrite')\n const store = transaction.objectStore('session')\n const request = store.delete('current')\n\n request.onsuccess = () => {\n resolve()\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to clear session:', request.error)\n reject(request.error)\n }\n })\n}\n\n/**\n * Clear the wrapping key from IndexedDB.\n *\n * ⚠️ WARNING: This will make all encrypted private keys unrecoverable!\n * Only call this during full logout/reset.\n */\nasync function clearWrappingKey(): Promise<void> {\n await ensureDatabase()\n\n if (!db) {\n throw new Error('Database not initialized')\n }\n\n return new Promise((resolve, reject) => {\n if (!db) {\n reject(new Error('Database not initialized'))\n return\n }\n\n const transaction = db.transaction(['wrapping-key'], 'readwrite')\n const store = transaction.objectStore('wrapping-key')\n const request = store.delete('master')\n\n request.onsuccess = () => {\n resolve()\n }\n\n request.onerror = () => {\n console.error('[STORAGE] Failed to clear wrapping key:', request.error)\n reject(request.error)\n }\n })\n}\n\n/**\n * Clear all data from IndexedDB (session + wrapping key).\n *\n * Used during logout to ensure all cryptographic material is removed.\n */\nexport async function clearAllData(): Promise<void> {\n await clearSession()\n await clearWrappingKey()\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a session exists in IndexedDB.\n *\n * @returns True if session exists\n */\nexport async function hasSession(): Promise<boolean> {\n const session = await getSession()\n return session !== null\n}\n","/**\n * Registration flow\n *\n * Generates Ed25519 keypair → posts to /api/user/register\n */\n\nimport type createFetchClient from 'openapi-fetch'\nimport type { paths } from '../schema'\nimport type { SessionManager } from '../session'\nimport { generateRegistrationCredentials } from '../crypto'\nimport { saveSession } from '../storage'\n\nexport interface RegisterParams {\n email: string\n password: string\n verificationCode: string\n firstName?: string\n lastName?: string\n picture?: string\n}\n\nexport interface RegisterResult {\n signingPrivateKey: Uint8Array\n}\n\nexport async function register(\n params: RegisterParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<RegisterResult> {\n const credentials = await generateRegistrationCredentials(\n {\n email: params.email,\n verification_credential: params.verificationCode,\n given_name: params.firstName,\n family_name: params.lastName,\n picture: params.picture,\n },\n params.password,\n deps.deploymentDomain\n )\n\n const response = await deps.fetchClient.POST('/api/user/register', {\n body: credentials.request,\n })\n\n if (response.error) {\n throw new Error(\n `Registration failed: ${typeof response.error === 'object' && response.error !== null && 'detail' in response.error ? (response.error as { detail?: string }).detail : 'Unknown error'}`\n )\n }\n\n return { signingPrivateKey: credentials.signingPrivateKey }\n}\n","/**\n * Login flow\n *\n * Generates Ed25519 signature → posts to /api/user/login → saves session\n */\n\nimport type createFetchClient from 'openapi-fetch'\nimport type { paths } from '../schema'\nimport type { SessionManager } from '../session'\nimport { generateLoginCredentials, generateLoginCredentialsFromKey, base64ToBytes } from '../crypto'\nimport { saveSession } from '../storage'\n\nexport interface LoginParams {\n email: string\n password: string\n ssoToken?: string\n}\n\nexport interface LoginWithKeyParams {\n email: string\n signingPrivateKey: Uint8Array\n ssoToken?: string\n}\n\nexport interface LoginResult {\n accessToken: string\n userExtId?: string\n signingPrivateKey: Uint8Array\n serverSessionKey: Uint8Array\n}\n\nexport async function login(\n params: LoginParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<LoginResult> {\n const credentials = await generateLoginCredentials(\n {\n email: params.email,\n sso_token: params.ssoToken,\n },\n params.password,\n deps.deploymentDomain\n )\n\n return performLogin(credentials.request, credentials.signingPrivateKey, deps)\n}\n\nexport async function loginWithKey(\n params: LoginWithKeyParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<LoginResult> {\n const credentials = generateLoginCredentialsFromKey(\n {\n email: params.email,\n sso_token: params.ssoToken,\n },\n params.signingPrivateKey\n )\n\n return performLogin(credentials.request, credentials.signingPrivateKey, deps)\n}\n\nasync function performLogin(\n request: { email: string; signature: string; timestamp: number; sso_token?: string | null },\n signingPrivateKey: Uint8Array,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n }\n): Promise<LoginResult> {\n const response = await deps.fetchClient.POST('/api/user/login', {\n body: request,\n })\n\n if (response.error || !response.data) {\n throw new Error(\n `Login failed: ${typeof response.error === 'object' && response.error !== null && 'detail' in response.error ? (response.error as { detail?: string }).detail : 'Unknown error'}`\n )\n }\n\n const data = response.data\n const serverSessionKey = base64ToBytes(data.session_key)\n\n // Save session to IndexedDB\n await saveSession({\n signingPrivateKey,\n serverSessionKey,\n userExtId: data.user.external_id ?? undefined,\n })\n\n // Update in-memory session\n deps.session.setAccessToken(data.access_token)\n deps.session.setUser(request.email, data.user.external_id ?? undefined)\n\n return {\n accessToken: data.access_token,\n userExtId: data.user.external_id ?? undefined,\n signingPrivateKey,\n serverSessionKey,\n }\n}\n","/**\n * Logout flow\n *\n * Clears session manager + IndexedDB storage\n */\n\nimport type { SessionManager } from '../session'\nimport { clearAllData } from '../storage'\n\nexport async function logout(session: SessionManager): Promise<void> {\n session.clear()\n await clearAllData()\n}\n","/**\n * Change password flow\n *\n * Generates old + new credentials → posts to /api/user/change_password → updates stored key\n */\n\nimport type createFetchClient from 'openapi-fetch'\nimport type { paths } from '../schema'\nimport type { SessionManager } from '../session'\nimport { generatePasswordChangeCredentials } from '../crypto'\nimport { updateSigningPrivateKey } from '../storage'\n\nexport interface ChangePasswordParams {\n email: string\n currentPassword: string\n newPassword: string\n rewrappedWorkspaceKeys?: Record<string, string>\n}\n\nexport interface ChangePasswordResult {\n newSigningPrivateKey: Uint8Array\n}\n\nexport async function changePassword(\n params: ChangePasswordParams,\n deps: {\n fetchClient: ReturnType<typeof createFetchClient<paths>>\n session: SessionManager\n deploymentDomain: string\n }\n): Promise<ChangePasswordResult> {\n const credentials = await generatePasswordChangeCredentials(\n params.email,\n params.currentPassword,\n params.newPassword,\n deps.deploymentDomain\n )\n\n const response = await deps.fetchClient.POST('/api/user/change_password', {\n body: {\n ...credentials.request,\n rewrapped_workspace_keys: params.rewrappedWorkspaceKeys ?? {},\n },\n })\n\n if (response.error) {\n throw new Error(\n `Password change failed: ${typeof response.error === 'object' && response.error !== null && 'detail' in response.error ? (response.error as { detail?: string }).detail : 'Unknown error'}`\n )\n }\n\n // Update stored signing key\n await updateSigningPrivateKey(credentials.newSigningPrivateKey)\n\n return { newSigningPrivateKey: credentials.newSigningPrivateKey }\n}\n","/**\n * createArbiClient() — SDK entry point\n *\n * Factory that wires together:\n * - SessionManager (in-memory state)\n * - Crypto providers (libsodium wrappers)\n * - Login / WorkspaceKeyRefresh providers (openapi-fetch transport)\n * - Relogin handler (zero-knowledge re-authentication)\n * - openapi-fetch client with 3 middleware layers\n * - High-level auth methods (register, login, logout, changePassword)\n *\n * Returns an ArbiClient object that SDK consumers interact with.\n */\n\nimport createFetchClient from 'openapi-fetch'\nimport type { paths } from './schema'\nimport {\n createSessionManager,\n createTokenProvider,\n createWorkspaceKeyProvider,\n createAuthStateProvider,\n type SessionManager,\n} from './session'\nimport {\n initSodium,\n signMessage,\n sealedBoxDecrypt,\n deriveEncryptionKeypairFromSigning,\n createWorkspaceKeyHeader,\n base64ToBytes,\n bytesToBase64,\n base64Encode,\n base64Decode,\n sealedBoxEncrypt,\n derivePublicKey,\n computeSharedSecret,\n encryptMessageWithSharedSecret,\n decryptMessageWithSharedSecret,\n encryptMessage,\n decryptMessage,\n generateUserKeypairs,\n} from './crypto'\nimport { createBearerAuthMiddleware } from './middleware/bearer-auth'\nimport { createWorkspaceKeyMiddleware } from './middleware/workspace-key'\nimport { createAutoReloginMiddleware } from './middleware/auto-relogin'\nimport type { WorkspaceKeyUrlConfig } from './middleware/types'\nimport { createReloginHandler } from './relogin'\nimport type { CryptoProvider, LoginProvider, WorkspaceKeyRefreshProvider } from './relogin/types'\nimport { getSession, saveSession } from './storage'\nimport { register, login, loginWithKey, logout, changePassword } from './auth'\nimport type {\n RegisterParams,\n RegisterResult,\n LoginParams,\n LoginWithKeyParams,\n LoginResult,\n ChangePasswordParams,\n ChangePasswordResult,\n} from './auth'\n\n// ============================================================================\n// Default URL config (matches ARBI backend API patterns)\n// ============================================================================\n\nconst DEFAULT_WORKSPACE_KEY_URL_CONFIG: WorkspaceKeyUrlConfig = {\n excludePatterns: ['/api/user/', '/api/health/', '/api/configs/', '/api/workspace/create'],\n includePatterns: [\n '/api/workspace/wrk-',\n '/api/document/',\n '/api/conversation/',\n '/api/assistant/',\n '/api/tag/',\n ],\n}\n\n// ============================================================================\n// Client options\n// ============================================================================\n\nexport interface ArbiClientOptions {\n /** Base URL for the ARBI API (e.g. \"https://api.mydeployment.com\") */\n baseUrl: string\n /** Deployment domain used for deterministic key derivation (e.g. \"mydeployment.com\") */\n deploymentDomain: string\n /** Optional custom URL patterns for workspace key injection */\n workspaceKeyUrlConfig?: WorkspaceKeyUrlConfig\n /** URL patterns that should never trigger re-login */\n reloginExcludePatterns?: string[]\n /** Include credentials (cookies) in requests. Default: true */\n credentials?: RequestCredentials\n /** Optional SSO token provider */\n ssoTokenProvider?: { getToken(): Promise<string | null> } | null\n /** Optional callback when re-login succeeds */\n onReloginSuccess?: (data: {\n email: string\n accessToken: string\n userExtId?: string\n serverSessionKey: Uint8Array\n }) => void\n}\n\n// ============================================================================\n// ArbiClient interface\n// ============================================================================\n\nexport interface ArbiClient {\n /** Type-safe openapi-fetch client with middleware */\n fetch: ReturnType<typeof createFetchClient<paths>>\n\n /** In-memory session state */\n session: SessionManager\n\n /** High-level auth operations */\n auth: {\n register(params: RegisterParams): Promise<RegisterResult>\n login(params: LoginParams): Promise<LoginResult>\n loginWithKey(params: LoginWithKeyParams): Promise<LoginResult>\n logout(): Promise<void>\n changePassword(params: ChangePasswordParams): Promise<ChangePasswordResult>\n /** Instant re-login using stored private key */\n relogin(): Promise<string | null>\n }\n\n /** Crypto utilities */\n crypto: {\n initSodium: typeof initSodium\n generateUserKeypairs(email: string, password: string): ReturnType<typeof generateUserKeypairs>\n signMessage: typeof signMessage\n sealedBoxDecrypt: typeof sealedBoxDecrypt\n sealedBoxEncrypt: typeof sealedBoxEncrypt\n createWorkspaceKeyHeader: typeof createWorkspaceKeyHeader\n deriveEncryptionKeypairFromSigning: typeof deriveEncryptionKeypairFromSigning\n derivePublicKey: typeof derivePublicKey\n base64ToBytes: typeof base64ToBytes\n bytesToBase64: typeof bytesToBase64\n base64Encode: typeof base64Encode\n base64Decode: typeof base64Decode\n computeSharedSecret: typeof computeSharedSecret\n encryptMessage: typeof encryptMessage\n decryptMessage: typeof decryptMessage\n encryptMessageWithSharedSecret: typeof encryptMessageWithSharedSecret\n decryptMessageWithSharedSecret: typeof decryptMessageWithSharedSecret\n }\n\n /** IndexedDB storage operations */\n storage: {\n getSession: typeof getSession\n saveSession: typeof saveSession\n }\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nexport function createArbiClient(options: ArbiClientOptions): ArbiClient {\n const {\n baseUrl,\n deploymentDomain,\n workspaceKeyUrlConfig = DEFAULT_WORKSPACE_KEY_URL_CONFIG,\n reloginExcludePatterns = ['/api/user/login'],\n credentials = 'include',\n ssoTokenProvider = null,\n onReloginSuccess,\n } = options\n\n // 1. Create SessionManager\n const session = createSessionManager()\n\n // 2. Create provider adapters\n const tokenProvider = createTokenProvider(session)\n const workspaceKeyProvider = createWorkspaceKeyProvider(session)\n const authState = createAuthStateProvider(session)\n\n // 3. Create CryptoProvider\n const cryptoProvider: CryptoProvider = {\n ensureReady: initSodium,\n signMessage,\n deriveEncryptionKeypair: deriveEncryptionKeypairFromSigning,\n sealedBoxDecrypt,\n createWorkspaceKeyHeader,\n fromBase64: base64ToBytes,\n }\n\n // 4. Create LoginProvider (raw fetch client for login — no middleware)\n const loginProvider: LoginProvider = {\n async login(payload) {\n const rawFetch = createFetchClient<paths>({\n baseUrl,\n credentials,\n })\n\n const response = await rawFetch.POST('/api/user/login', {\n body: {\n email: payload.email,\n signature: payload.signature,\n timestamp: payload.timestamp,\n sso_token: payload.ssoToken,\n },\n })\n\n if (response.error || !response.data) {\n console.warn('[API] Login call failed:', response.error)\n return null\n }\n\n const data = response.data\n return {\n accessToken: data.access_token,\n sessionKey: base64ToBytes(data.session_key),\n userExtId: data.user.external_id ?? undefined,\n }\n },\n }\n\n // 5. Create WorkspaceKeyRefreshProvider\n const workspaceKeyRefreshProvider: WorkspaceKeyRefreshProvider = {\n async getWrappedKey(accessToken, workspaceId) {\n const workspacesResponse = await fetch(`${baseUrl}/api/user/workspaces`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'Content-Type': 'application/json',\n },\n credentials,\n })\n\n if (!workspacesResponse.ok) return null\n\n const workspacesData = await workspacesResponse.json()\n const workspace = workspacesData.find(\n (w: { external_id: string; wrapped_key?: string }) => w.external_id === workspaceId\n )\n\n return workspace?.wrapped_key ?? null\n },\n }\n\n // 6. Create relogin handler\n const reloginHandler = createReloginHandler({\n crypto: cryptoProvider,\n sessionStorage: { getSession, saveSession },\n authState,\n ssoTokenProvider,\n loginProvider,\n workspaceKeyRefreshProvider,\n onReloginSuccess,\n })\n\n // 7. Create openapi-fetch client with middleware\n const fetchClient = createFetchClient<paths>({\n baseUrl,\n credentials,\n })\n\n fetchClient.use(createBearerAuthMiddleware({ tokenProvider }))\n\n fetchClient.use(\n createWorkspaceKeyMiddleware({\n workspaceKeyProvider,\n urlConfig: workspaceKeyUrlConfig,\n })\n )\n\n fetchClient.use(\n createAutoReloginMiddleware({\n reloginHandler,\n workspaceKeyProvider,\n urlConfig: workspaceKeyUrlConfig,\n reloginExcludePatterns,\n })\n )\n\n // 8. Auth + fetch deps for high-level methods\n const authDeps = {\n fetchClient,\n session,\n deploymentDomain,\n }\n\n // 9. Build and return ArbiClient\n return {\n fetch: fetchClient,\n session,\n\n auth: {\n register: (params) => register(params, authDeps),\n login: (params) => login(params, authDeps),\n loginWithKey: (params) => loginWithKey(params, authDeps),\n logout: () => logout(session),\n changePassword: (params) => changePassword(params, authDeps),\n relogin: reloginHandler,\n },\n\n crypto: {\n initSodium,\n generateUserKeypairs: (email, password) =>\n generateUserKeypairs(email, password, deploymentDomain),\n signMessage,\n sealedBoxDecrypt,\n sealedBoxEncrypt,\n createWorkspaceKeyHeader,\n deriveEncryptionKeypairFromSigning,\n derivePublicKey,\n base64ToBytes,\n bytesToBase64,\n base64Encode,\n base64Decode,\n computeSharedSecret,\n encryptMessage,\n decryptMessage,\n encryptMessageWithSharedSecret,\n decryptMessageWithSharedSecret,\n },\n\n storage: {\n getSession,\n saveSession,\n },\n }\n}\n","/**\n * WebSocket helpers — pure functions, no runtime dependencies.\n *\n * Consumers bring their own WebSocket implementation (browser native, Node 22+, ws package).\n * This module provides URL building, auth message creation, typed message parsing,\n * and type guards for the discriminated-union server messages.\n */\n\nimport type { components } from './schema'\n\n// ==========================================\n// Type aliases from OpenAPI schema\n// ==========================================\n\nexport type WsAuthMessage = components['schemas']['AuthMessage']\nexport type WsAuthResultMessage = components['schemas']['AuthResultMessage']\nexport type WsTaskUpdateMessage = components['schemas']['TaskUpdateMessage']\nexport type WsBatchCompleteMessage = components['schemas']['BatchCompleteMessage']\nexport type WsConnectionClosedMessage = components['schemas']['ConnectionClosedMessage']\nexport type WsErrorMessage = components['schemas']['ErrorMessage']\nexport type WsPresenceUpdateMessage = components['schemas']['PresenceUpdateMessage']\nexport type WsNotificationResponse = components['schemas']['NotificationResponse']\n\n/** Union of all server → client message types (discriminated on `type` field). */\nexport type WebSocketServerMessage =\n | WsTaskUpdateMessage\n | WsAuthResultMessage\n | WsConnectionClosedMessage\n | WsPresenceUpdateMessage\n | WsErrorMessage\n | WsNotificationResponse\n | WsBatchCompleteMessage\n\n/** Union of all client → server message types. */\nexport type WebSocketClientMessage = WsAuthMessage\n\n// ==========================================\n// Pure helper functions\n// ==========================================\n\n/**\n * Build a WebSocket URL from an HTTP(S) base URL.\n *\n * \"https://box-105.arbibox.com\" → \"wss://box-105.arbibox.com/api/notifications/ws\"\n * \"http://localhost:8000\" → \"ws://localhost:8000/api/notifications/ws\"\n */\nexport function buildWebSocketUrl(baseUrl: string): string {\n const wsScheme = baseUrl.startsWith('https') ? 'wss' : 'ws'\n const hostAndPath = baseUrl.replace(/^https?:\\/\\//, '').replace(/\\/+$/, '')\n return `${wsScheme}://${hostAndPath}/api/notifications/ws`\n}\n\n/**\n * Create the JSON auth message to send after WebSocket connection opens.\n * Returns the serialized JSON string ready to send.\n */\nexport function createAuthMessage(accessToken: string): string {\n const msg: WsAuthMessage = { type: 'auth', token: accessToken }\n return JSON.stringify(msg)\n}\n\n/**\n * Parse a raw WebSocket message string into a typed server message.\n * Returns `null` for unparseable data. Accepts any object with a string `type`\n * field — no hardcoded list of known types, so this stays valid as the schema evolves.\n */\nexport function parseServerMessage(data: string): WebSocketServerMessage | null {\n try {\n const parsed = JSON.parse(data)\n if (typeof parsed === 'object' && parsed !== null && typeof parsed.type === 'string') {\n return parsed as WebSocketServerMessage\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Type guard to narrow a server message to a specific type by its `type` field value.\n *\n * Usage:\n * if (isMessageType(msg, 'task_update')) {\n * // msg is WsTaskUpdateMessage\n * }\n */\nexport function isMessageType<T extends WebSocketServerMessage>(\n msg: WebSocketServerMessage,\n type: T['type']\n): msg is T {\n return msg.type === type\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@arbidocs/sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for the ARBI API — zero-knowledge auth, E2E encryption, and type-safe REST client",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup",
21
+ "test": "vitest run",
22
+ "typecheck": "tsc --noEmit"
23
+ },
24
+ "dependencies": {
25
+ "libsodium-wrappers-sumo": "^0.7.15",
26
+ "openapi-fetch": "^0.15.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/libsodium-wrappers-sumo": "^0.7.8",
30
+ "fake-indexeddb": "^6.2.5",
31
+ "tsup": "^8.4.0",
32
+ "typescript": "^5.9.3",
33
+ "vitest": "^4.0.18"
34
+ },
35
+ "license": "MIT",
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/arbitrationcity/ARBI-frontend.git",
42
+ "directory": "packages/arbi-api-client"
43
+ },
44
+ "keywords": ["arbi", "api", "sdk", "e2e-encryption", "zero-knowledge", "openapi", "typescript"]
45
+ }