{"version":3,"sources":["../src/types.ts","../src/key-derivation.ts","../src/decryption.ts"],"sourcesContent":["/**\n * TypeScript interfaces for Django-CFG encryption.\n *\n * These types match the encrypted response format from Django-CFG backend.\n */\n\n/**\n * Encrypted field envelope returned by Django-CFG API.\n *\n * When a serializer field is encrypted, it returns this structure\n * instead of the plain value.\n *\n * @example\n * ```json\n * {\n *   \"encrypted\": true,\n *   \"field\": \"price\",\n *   \"algorithm\": \"AES-256-GCM\",\n *   \"iv\": \"base64...\",\n *   \"data\": \"base64...\",\n *   \"auth_tag\": \"base64...\"\n * }\n * ```\n */\nexport interface EncryptedField {\n  /** Always true for encrypted fields */\n  encrypted: true;\n  /** Field name that was encrypted */\n  field?: string;\n  /** Encryption algorithm used */\n  algorithm: 'AES-256-GCM' | 'AES-256-CBC';\n  /** Base64-encoded initialization vector */\n  iv: string;\n  /** Base64-encoded ciphertext */\n  data: string;\n  /** Base64-encoded authentication tag (GCM only) */\n  auth_tag: string;\n}\n\n/**\n * Full encrypted response envelope.\n *\n * When response-level encryption is enabled, the entire response\n * body is wrapped in this structure.\n *\n * @example\n * ```json\n * {\n *   \"encrypted\": true,\n *   \"algorithm\": \"AES-256-GCM\",\n *   \"salt\": \"base64...\",\n *   \"iv\": \"base64...\",\n *   \"data\": \"base64...\",\n *   \"auth_tag\": \"base64...\"\n * }\n * ```\n */\nexport interface EncryptedResponse {\n  /** Always true for encrypted responses */\n  encrypted: true;\n  /** Encryption algorithm used */\n  algorithm: 'AES-256-GCM' | 'AES-256-CBC';\n  /** Base64-encoded salt for key derivation */\n  salt: string;\n  /** Base64-encoded initialization vector */\n  iv: string;\n  /** Base64-encoded ciphertext */\n  data: string;\n  /** Base64-encoded authentication tag (GCM only) */\n  auth_tag: string;\n}\n\n/**\n * Configuration for the decryption client.\n */\nexport interface DecryptionConfig {\n  /**\n   * Secret key for key derivation.\n   * Should match the Django SECRET_KEY or a derived key.\n   */\n  secretKey: string;\n\n  /**\n   * User ID for per-user key derivation (optional).\n   * When provided, keys are derived per-user for isolation.\n   */\n  userId?: string | number;\n\n  /**\n   * Session ID for per-session key derivation (optional).\n   * Takes precedence over userId if both provided.\n   */\n  sessionId?: string;\n\n  /**\n   * Number of PBKDF2 iterations (default: 100000).\n   * Must match backend configuration.\n   */\n  iterations?: number;\n\n  /**\n   * Key prefix for derivation (default: \"djangocfg_encryption\").\n   * Must match backend configuration.\n   */\n  keyPrefix?: string;\n}\n\n/**\n * Result of a decryption operation.\n */\nexport interface DecryptionResult<T = unknown> {\n  /** Decrypted data */\n  data: T;\n  /** Whether decryption was successful */\n  success: true;\n}\n\n/**\n * Error from a decryption operation.\n */\nexport interface DecryptionError {\n  /** Error message */\n  message: string;\n  /** Error code */\n  code: 'INVALID_FORMAT' | 'DECRYPTION_FAILED' | 'AUTH_FAILED' | 'KEY_ERROR';\n  /** Whether decryption was successful */\n  success: false;\n}\n\n/**\n * Type guard to check if a value is an encrypted field.\n */\nexport function isEncryptedField(value: unknown): value is EncryptedField {\n  if (typeof value !== 'object' || value === null) return false;\n  const obj = value as Record<string, unknown>;\n  return (\n    obj.encrypted === true &&\n    typeof obj.algorithm === 'string' &&\n    typeof obj.iv === 'string' &&\n    typeof obj.data === 'string' &&\n    typeof obj.auth_tag === 'string'\n  );\n}\n\n/**\n * Type guard to check if a value is an encrypted response.\n */\nexport function isEncryptedResponse(value: unknown): value is EncryptedResponse {\n  if (typeof value !== 'object' || value === null) return false;\n  const obj = value as Record<string, unknown>;\n  return (\n    obj.encrypted === true &&\n    typeof obj.algorithm === 'string' &&\n    typeof obj.salt === 'string' &&\n    typeof obj.iv === 'string' &&\n    typeof obj.data === 'string' &&\n    typeof obj.auth_tag === 'string'\n  );\n}\n","/**\n * PBKDF2 key derivation using Web Crypto API.\n *\n * Matches Django-CFG backend key derivation for decryption compatibility.\n */\n\n/**\n * Derive an encryption key using PBKDF2.\n *\n * Uses Web Crypto API for secure key derivation that matches\n * the Django-CFG backend implementation.\n *\n * @param password - The password/secret key to derive from\n * @param salt - Salt bytes for key derivation\n * @param iterations - Number of PBKDF2 iterations (default: 100000)\n * @param keyLength - Desired key length in bytes (default: 32 for AES-256)\n * @returns Promise resolving to derived key as CryptoKey\n *\n * @example\n * ```typescript\n * const salt = new TextEncoder().encode('my-salt');\n * const key = await deriveKey('secret', salt, 100000);\n * ```\n */\nexport async function deriveKey(\n  password: string,\n  salt: Uint8Array,\n  iterations: number = 100000,\n  keyLength: number = 32\n): Promise<CryptoKey> {\n  const encoder = new TextEncoder();\n  const passwordBuffer = encoder.encode(password);\n\n  // Import password as raw key material\n  const keyMaterial = await crypto.subtle.importKey(\n    'raw',\n    passwordBuffer,\n    'PBKDF2',\n    false,\n    ['deriveBits', 'deriveKey']\n  );\n\n  // Derive AES-GCM key using PBKDF2\n  return crypto.subtle.deriveKey(\n    {\n      name: 'PBKDF2',\n      salt: salt.buffer as ArrayBuffer,\n      iterations: iterations,\n      hash: 'SHA-256',\n    },\n    keyMaterial,\n    { name: 'AES-GCM', length: keyLength * 8 },\n    false,\n    ['decrypt']\n  );\n}\n\n/**\n * Derive raw key bytes using PBKDF2.\n *\n * @param password - The password/secret key to derive from\n * @param salt - Salt bytes for key derivation\n * @param iterations - Number of PBKDF2 iterations (default: 100000)\n * @param keyLength - Desired key length in bytes (default: 32 for AES-256)\n * @returns Promise resolving to derived key as Uint8Array\n */\nexport async function deriveKeyBytes(\n  password: string,\n  salt: Uint8Array,\n  iterations: number = 100000,\n  keyLength: number = 32\n): Promise<Uint8Array> {\n  const encoder = new TextEncoder();\n  const passwordBuffer = encoder.encode(password);\n\n  // Import password as raw key material\n  const keyMaterial = await crypto.subtle.importKey(\n    'raw',\n    passwordBuffer,\n    'PBKDF2',\n    false,\n    ['deriveBits']\n  );\n\n  // Derive raw bits\n  const keyBits = await crypto.subtle.deriveBits(\n    {\n      name: 'PBKDF2',\n      salt: salt.buffer as ArrayBuffer,\n      iterations: iterations,\n      hash: 'SHA-256',\n    },\n    keyMaterial,\n    keyLength * 8\n  );\n\n  return new Uint8Array(keyBits);\n}\n\n/**\n * Build a deterministic salt from context components.\n *\n * Matches Django-CFG backend salt generation for key derivation.\n *\n * @param keyPrefix - Key prefix (default: \"djangocfg_encryption\")\n * @param userId - Optional user ID for per-user keys\n * @param sessionId - Optional session ID for per-session keys\n * @returns Salt as Uint8Array (first 16 bytes of SHA-256 hash)\n */\nexport async function buildSalt(\n  keyPrefix: string = 'djangocfg_encryption',\n  userId?: string | number,\n  sessionId?: string\n): Promise<Uint8Array> {\n  const parts = [keyPrefix];\n\n  if (sessionId) {\n    parts.push(`session:${sessionId}`);\n  } else if (userId !== undefined) {\n    parts.push(`user:${userId}`);\n  } else {\n    parts.push('global');\n  }\n\n  const saltInput = parts.join(':');\n  const encoder = new TextEncoder();\n  const inputBuffer = encoder.encode(saltInput);\n\n  // SHA-256 hash and take first 16 bytes\n  const hashBuffer = await crypto.subtle.digest('SHA-256', inputBuffer);\n  return new Uint8Array(hashBuffer).slice(0, 16);\n}\n\n/**\n * Derive encryption key from Django-CFG config.\n *\n * Convenience function that matches backend key derivation.\n *\n * @param config - Configuration object with secretKey and optional context\n * @returns Promise resolving to CryptoKey for decryption\n *\n * @example\n * ```typescript\n * const key = await deriveKeyFromConfig({\n *   secretKey: 'django-secret-key',\n *   userId: 123,\n *   iterations: 100000\n * });\n * ```\n */\nexport async function deriveKeyFromConfig(config: {\n  secretKey: string;\n  userId?: string | number;\n  sessionId?: string;\n  iterations?: number;\n  keyPrefix?: string;\n}): Promise<CryptoKey> {\n  const {\n    secretKey,\n    userId,\n    sessionId,\n    iterations = 100000,\n    keyPrefix = 'djangocfg_encryption',\n  } = config;\n\n  const salt = await buildSalt(keyPrefix, userId, sessionId);\n  return deriveKey(secretKey, salt, iterations);\n}\n","/**\n * AES-256-GCM decryption using Web Crypto API.\n *\n * Decrypts data encrypted by Django-CFG backend.\n */\n\nimport type {\n  DecryptionConfig,\n  DecryptionError,\n  DecryptionResult,\n  EncryptedField,\n  EncryptedResponse,\n} from './types';\nimport { deriveKeyFromConfig } from './key-derivation';\nimport { isEncryptedField, isEncryptedResponse } from './types';\n\n/**\n * Decode base64 string to Uint8Array.\n */\nfunction base64ToBytes(base64: string): Uint8Array {\n  const binary = atob(base64);\n  const bytes = new Uint8Array(binary.length);\n  for (let i = 0; i < binary.length; i++) {\n    bytes[i] = binary.charCodeAt(i);\n  }\n  return bytes;\n}\n\n/**\n * Decrypt AES-256-GCM ciphertext.\n *\n * @param ciphertext - Encrypted data bytes\n * @param key - CryptoKey for decryption\n * @param iv - Initialization vector\n * @param authTag - Authentication tag\n * @returns Promise resolving to decrypted bytes\n */\nexport async function decryptAES256GCM(\n  ciphertext: Uint8Array,\n  key: CryptoKey,\n  iv: Uint8Array,\n  authTag: Uint8Array\n): Promise<Uint8Array> {\n  // GCM expects ciphertext + authTag concatenated\n  const combined = new Uint8Array(ciphertext.length + authTag.length);\n  combined.set(ciphertext);\n  combined.set(authTag, ciphertext.length);\n\n  const decrypted = await crypto.subtle.decrypt(\n    {\n      name: 'AES-GCM',\n      iv: iv.buffer as ArrayBuffer,\n      tagLength: 128, // 16 bytes = 128 bits\n    },\n    key,\n    combined\n  );\n\n  return new Uint8Array(decrypted);\n}\n\n/**\n * Decrypt a single encrypted field value.\n *\n * @param field - Encrypted field envelope\n * @param key - CryptoKey for decryption\n * @returns Promise resolving to decrypted value\n *\n * @example\n * ```typescript\n * const key = await deriveKeyFromConfig({ secretKey: '...' });\n * const price = await decryptField(response.price, key);\n * console.log(price); // 99.99\n * ```\n */\nexport async function decryptField<T = unknown>(\n  field: EncryptedField,\n  key: CryptoKey\n): Promise<T> {\n  if (field.algorithm !== 'AES-256-GCM') {\n    throw new Error(`Unsupported algorithm: ${field.algorithm}`);\n  }\n\n  const iv = base64ToBytes(field.iv);\n  const ciphertext = base64ToBytes(field.data);\n  const authTag = base64ToBytes(field.auth_tag);\n\n  const decrypted = await decryptAES256GCM(ciphertext, key, iv, authTag);\n  const text = new TextDecoder().decode(decrypted);\n\n  return JSON.parse(text) as T;\n}\n\n/**\n * Decrypt an entire encrypted response.\n *\n * @param response - Encrypted response envelope\n * @param secretKey - Secret key for key derivation\n * @param config - Additional config (userId, sessionId, etc.)\n * @returns Promise resolving to decrypted response data\n */\nexport async function decryptResponse<T = unknown>(\n  response: EncryptedResponse,\n  secretKey: string,\n  config?: Partial<Omit<DecryptionConfig, 'secretKey'>>\n): Promise<T> {\n  if (response.algorithm !== 'AES-256-GCM') {\n    throw new Error(`Unsupported algorithm: ${response.algorithm}`);\n  }\n\n  // Use salt from response for key derivation\n  const salt = base64ToBytes(response.salt);\n  const iterations = config?.iterations ?? 100000;\n\n  // Import secret key for PBKDF2\n  const encoder = new TextEncoder();\n  const keyMaterial = await crypto.subtle.importKey(\n    'raw',\n    encoder.encode(secretKey),\n    'PBKDF2',\n    false,\n    ['deriveKey']\n  );\n\n  // Derive decryption key\n  const key = await crypto.subtle.deriveKey(\n    {\n      name: 'PBKDF2',\n      salt: salt.buffer as ArrayBuffer,\n      iterations: iterations,\n      hash: 'SHA-256',\n    },\n    keyMaterial,\n    { name: 'AES-GCM', length: 256 },\n    false,\n    ['decrypt']\n  );\n\n  const iv = base64ToBytes(response.iv);\n  const ciphertext = base64ToBytes(response.data);\n  const authTag = base64ToBytes(response.auth_tag);\n\n  const decrypted = await decryptAES256GCM(ciphertext, key, iv, authTag);\n  const text = new TextDecoder().decode(decrypted);\n\n  return JSON.parse(text) as T;\n}\n\n/**\n * Recursively decrypt all encrypted fields in an object.\n *\n * @param data - Object potentially containing encrypted fields\n * @param key - CryptoKey for decryption\n * @returns Promise resolving to object with all fields decrypted\n *\n * @example\n * ```typescript\n * const key = await deriveKeyFromConfig({ secretKey: '...' });\n * const product = await decryptObject(response, key);\n * // product.price is now decrypted\n * ```\n */\nexport async function decryptObject<T>(\n  data: unknown,\n  key: CryptoKey\n): Promise<T> {\n  if (data === null || data === undefined) {\n    return data as T;\n  }\n\n  // Check if this is an encrypted field\n  if (isEncryptedField(data)) {\n    return decryptField<T>(data, key);\n  }\n\n  // Handle arrays\n  if (Array.isArray(data)) {\n    const decrypted = await Promise.all(\n      data.map((item) => decryptObject(item, key))\n    );\n    return decrypted as T;\n  }\n\n  // Handle objects\n  if (typeof data === 'object') {\n    const result: Record<string, unknown> = {};\n    const entries = Object.entries(data as Record<string, unknown>);\n\n    for (const [objKey, value] of entries) {\n      result[objKey] = await decryptObject(value, key);\n    }\n\n    return result as T;\n  }\n\n  // Primitive values pass through\n  return data as T;\n}\n\n/**\n * Create a decryption client with pre-configured key.\n *\n * @param config - Decryption configuration\n * @returns Object with decryption methods\n *\n * @example\n * ```typescript\n * const crypto = await createDecryptionClient({\n *   secretKey: 'django-secret-key',\n *   userId: currentUser.id\n * });\n *\n * const response = await fetch('/api/products/?encrypt=true');\n * const data = await crypto.decryptObject(await response.json());\n * ```\n */\nexport async function createDecryptionClient(config: DecryptionConfig) {\n  const key = await deriveKeyFromConfig(config);\n\n  return {\n    /**\n     * Decrypt a single encrypted field.\n     */\n    decryptField: <T = unknown>(field: EncryptedField) =>\n      decryptField<T>(field, key),\n\n    /**\n     * Recursively decrypt all encrypted fields in an object.\n     */\n    decryptObject: <T>(data: unknown) => decryptObject<T>(data, key),\n\n    /**\n     * Check if a value is an encrypted field.\n     */\n    isEncryptedField,\n\n    /**\n     * Check if a value is an encrypted response.\n     */\n    isEncryptedResponse,\n  };\n}\n\n/**\n * Safe decryption wrapper that returns result or error.\n *\n * @param fn - Async function to execute\n * @returns Promise resolving to DecryptionResult or DecryptionError\n */\nexport async function safeDecrypt<T>(\n  fn: () => Promise<T>\n): Promise<DecryptionResult<T> | DecryptionError> {\n  try {\n    const data = await fn();\n    return { success: true, data };\n  } catch (error) {\n    const message = error instanceof Error ? error.message : 'Unknown error';\n\n    // Determine error code\n    let code: DecryptionError['code'] = 'DECRYPTION_FAILED';\n    if (message.includes('format') || message.includes('parse')) {\n      code = 'INVALID_FORMAT';\n    } else if (message.includes('auth') || message.includes('tag')) {\n      code = 'AUTH_FAILED';\n    } else if (message.includes('key')) {\n      code = 'KEY_ERROR';\n    }\n\n    return { success: false, message, code };\n  }\n}\n"],"mappings":"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","names":[]}