{"version":3,"sources":["../src/react/index.ts","../src/react/hooks.ts","../src/key-derivation.ts","../src/types.ts","../src/decryption.ts"],"sourcesContent":["/**\n * React integration for @djangocfg/crypto.\n *\n * @packageDocumentation\n */\n\nexport {\n  useDecrypt,\n  useDecryptionClient,\n  useLazyDecrypt,\n  useIsEncrypted,\n} from './hooks';\n\n// Re-export types for convenience\nexport type {\n  DecryptionConfig,\n  DecryptionResult,\n  DecryptionError,\n  EncryptedField,\n  EncryptedResponse,\n} from '../types';\n","/**\n * React hooks for Django-CFG encryption.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { createDecryptionClient, decryptObject } from '../decryption';\nimport { deriveKeyFromConfig } from '../key-derivation';\nimport { isEncryptedField } from '../types';\n\nimport type { DecryptionConfig, EncryptedField } from '../types';\n/**\n * Hook state for decryption operations.\n */\ninterface UseDecryptState<T> {\n  /** Decrypted data */\n  data: T | undefined;\n  /** Loading state */\n  isLoading: boolean;\n  /** Error if decryption failed */\n  error: Error | undefined;\n  /** Whether data has been decrypted */\n  isDecrypted: boolean;\n}\n\n/**\n * Hook to decrypt data on mount or when dependencies change.\n *\n * @param encryptedData - Data potentially containing encrypted fields\n * @param config - Decryption configuration\n * @returns Decrypted data state\n *\n * @example\n * ```typescript\n * function ProductPrice({ product }: { product: Product }) {\n *   const { data, isLoading, error } = useDecrypt(product, {\n *     secretKey: process.env.NEXT_PUBLIC_DECRYPT_KEY!,\n *     userId: user.id\n *   });\n *\n *   if (isLoading) return <Skeleton />;\n *   if (error) return <ErrorMessage error={error} />;\n *   return <span>{data.price}</span>;\n * }\n * ```\n */\nexport function useDecrypt<T>(\n  encryptedData: unknown,\n  config: DecryptionConfig\n): UseDecryptState<T> {\n  const [state, setState] = useState<UseDecryptState<T>>({\n    data: undefined,\n    isLoading: true,\n    error: undefined,\n    isDecrypted: false,\n  });\n\n  // Cache the key to avoid re-deriving on every render\n  const keyRef = useRef<CryptoKey | null>(null);\n  const configRef = useRef(config);\n\n  // Check if config changed\n  const configChanged =\n    configRef.current.secretKey !== config.secretKey ||\n    configRef.current.userId !== config.userId ||\n    configRef.current.sessionId !== config.sessionId;\n\n  if (configChanged) {\n    configRef.current = config;\n    keyRef.current = null;\n  }\n\n  useEffect(() => {\n    let cancelled = false;\n\n    async function decrypt() {\n      try {\n        setState((s) => ({ ...s, isLoading: true, error: undefined }));\n\n        // Get or derive key\n        if (!keyRef.current) {\n          keyRef.current = await deriveKeyFromConfig(config);\n        }\n\n        const decrypted = await decryptObject<T>(encryptedData, keyRef.current);\n\n        if (!cancelled) {\n          setState({\n            data: decrypted,\n            isLoading: false,\n            error: undefined,\n            isDecrypted: true,\n          });\n        }\n      } catch (err) {\n        if (!cancelled) {\n          setState({\n            data: undefined,\n            isLoading: false,\n            error: err instanceof Error ? err : new Error('Decryption failed'),\n            isDecrypted: false,\n          });\n        }\n      }\n    }\n\n    decrypt();\n\n    return () => {\n      cancelled = true;\n    };\n  }, [encryptedData, config.secretKey, config.userId, config.sessionId]);\n\n  return state;\n}\n\n/**\n * Hook to create a memoized decryption client.\n *\n * @param config - Decryption configuration\n * @returns Decryption client or undefined while loading\n *\n * @example\n * ```typescript\n * function App() {\n *   const crypto = useDecryptionClient({\n *     secretKey: process.env.NEXT_PUBLIC_DECRYPT_KEY!\n *   });\n *\n *   const handleFetch = async () => {\n *     const response = await fetch('/api/products/?encrypt=true');\n *     const data = await response.json();\n *     const decrypted = await crypto?.decryptObject(data);\n *   };\n * }\n * ```\n */\nexport function useDecryptionClient(config: DecryptionConfig) {\n  const [client, setClient] = useState<Awaited<\n    ReturnType<typeof createDecryptionClient>\n  > | null>(null);\n\n  useEffect(() => {\n    createDecryptionClient(config).then(setClient);\n  }, [config.secretKey, config.userId, config.sessionId]);\n\n  return client;\n}\n\n/**\n * Hook for lazy decryption with manual trigger.\n *\n * @param config - Decryption configuration\n * @returns Decrypt function and state\n *\n * @example\n * ```typescript\n * function LazyProduct({ product }: { product: Product }) {\n *   const { decrypt, data, isLoading } = useLazyDecrypt({\n *     secretKey: process.env.NEXT_PUBLIC_DECRYPT_KEY!\n *   });\n *\n *   return (\n *     <div>\n *       <button onClick={() => decrypt(product)}>Show Price</button>\n *       {isLoading && <Spinner />}\n *       {data && <span>{data.price}</span>}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useLazyDecrypt<T>(config: DecryptionConfig) {\n  const [state, setState] = useState<UseDecryptState<T>>({\n    data: undefined,\n    isLoading: false,\n    error: undefined,\n    isDecrypted: false,\n  });\n\n  const keyRef = useRef<CryptoKey | null>(null);\n\n  const decrypt = useCallback(\n    async (encryptedData: unknown): Promise<T | undefined> => {\n      try {\n        setState((s) => ({ ...s, isLoading: true, error: undefined }));\n\n        if (!keyRef.current) {\n          keyRef.current = await deriveKeyFromConfig(config);\n        }\n\n        const decrypted = await decryptObject<T>(encryptedData, keyRef.current);\n\n        setState({\n          data: decrypted,\n          isLoading: false,\n          error: undefined,\n          isDecrypted: true,\n        });\n\n        return decrypted;\n      } catch (err) {\n        const error =\n          err instanceof Error ? err : new Error('Decryption failed');\n        setState({\n          data: undefined,\n          isLoading: false,\n          error,\n          isDecrypted: false,\n        });\n        return undefined;\n      }\n    },\n    [config.secretKey, config.userId, config.sessionId]\n  );\n\n  const reset = useCallback(() => {\n    setState({\n      data: undefined,\n      isLoading: false,\n      error: undefined,\n      isDecrypted: false,\n    });\n  }, []);\n\n  return { ...state, decrypt, reset };\n}\n\n/**\n * Hook to check if a value needs decryption.\n *\n * @param value - Value to check\n * @returns Whether the value is encrypted\n */\nexport function useIsEncrypted(value: unknown): boolean {\n  return useMemo(() => isEncryptedField(value), [value]);\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 * 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 * 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":[]}