{"version":3,"file":"useCSPNonce.mjs","sources":["../../../../src/lib/security/hooks/useCSPNonce.ts"],"sourcesContent":["/**\n * @fileoverview useCSPNonce Hook\n * @module @/lib/security/hooks/useCSPNonce\n *\n * React hook for accessing CSP nonce values for inline scripts and styles.\n * Provides formatted attributes ready for use in JSX.\n *\n * @author Harbor Security Team\n * @version 1.0.0\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport type { UseCSPNonceResult } from '../types';\nimport { CSPManager, generateNonce } from '../csp-manager';\n\n/**\n * Options for the useCSPNonce hook\n */\nexport interface UseCSPNonceOptions {\n  /** Auto-regenerate nonce at this interval (ms) */\n  regenerateInterval?: number;\n  /** Whether to initialize CSP Manager if not already */\n  autoInitialize?: boolean;\n}\n\n/**\n * Hook for accessing CSP nonce values\n *\n * Provides nonce values for inline scripts and styles that comply\n * with Content Security Policy requirements.\n *\n * @param options - Hook options\n * @returns CSP nonce operations and values\n *\n * @example\n * ```tsx\n * function ScriptLoader() {\n *   const { nonce, scriptNonce } = useCSPNonce();\n *\n *   return (\n *     <script nonce={nonce} dangerouslySetInnerHTML={{\n *       __html: 'console.log(\"Secure inline script\")'\n *     }} />\n *   );\n * }\n *\n * // Or with style\n * function InlineStyle() {\n *   const { nonce, styleNonce } = useCSPNonce();\n *\n *   return (\n *     <style nonce={nonce}>{`\n *       .secure-class { color: blue; }\n *     `}</style>\n *   );\n * }\n * ```\n */\nexport function useCSPNonce(options: UseCSPNonceOptions = {}): UseCSPNonceResult {\n  const { regenerateInterval, autoInitialize = true } = options;\n\n  // State for the current nonce\n  const [nonce, setNonce] = useState<string>(() => {\n    // Try to get existing nonce from CSP Manager\n    try {\n      if (CSPManager.isInitialized()) {\n        return CSPManager.getCurrentNonce();\n      }\n    } catch {\n      // Manager not initialized, generate a standalone nonce\n    }\n    return generateNonce();\n  });\n\n  // Initialize CSP Manager if needed\n  useEffect(() => {\n    if (autoInitialize && !CSPManager.isInitialized()) {\n      CSPManager.initialize();\n      // Schedule nonce update for next render to avoid cascading renders\n      Promise.resolve()\n        .then(() => {\n          try {\n            setNonce(CSPManager.getCurrentNonce());\n          } catch {\n            // Keep the generated nonce\n          }\n        })\n        .catch(() => {\n          // Ignore errors\n        });\n    }\n    return undefined;\n  }, [autoInitialize]);\n\n  // Regenerate nonce function\n  const regenerate = useCallback((): string => {\n    let newNonce: string;\n\n    if (CSPManager.isInitialized()) {\n      const nonceObj = CSPManager.regenerateNonce();\n      newNonce = nonceObj.value;\n    } else {\n      newNonce = generateNonce();\n    }\n\n    setNonce(newNonce);\n    return newNonce;\n  }, []);\n\n  // Set up auto-regeneration interval\n  useEffect(() => {\n    if (regenerateInterval !== undefined && regenerateInterval !== null && regenerateInterval > 0) {\n      const intervalId = setInterval(() => {\n        regenerate();\n      }, regenerateInterval);\n\n      return () => clearInterval(intervalId);\n    }\n    return undefined;\n  }, [regenerateInterval, regenerate]);\n\n  // Memoized nonce attributes\n  const scriptNonce = useMemo(() => nonce, [nonce]);\n  const styleNonce = useMemo(() => nonce, [nonce]);\n\n  return {\n    nonce,\n    scriptNonce,\n    styleNonce,\n    regenerate,\n  };\n}\n\n/**\n * Hook for creating nonce-protected inline script props\n *\n * @example\n * ```tsx\n * function TrackerScript() {\n *   const scriptProps = useNonceScript('console.log(\"tracked\")');\n *\n *   return <script {...scriptProps} />;\n * }\n * ```\n */\nexport function useNonceScript(scriptContent: string): {\n  nonce: string;\n  dangerouslySetInnerHTML: { __html: string };\n} {\n  const { nonce } = useCSPNonce();\n\n  return useMemo(\n    () => ({\n      nonce,\n      dangerouslySetInnerHTML: { __html: scriptContent },\n    }),\n    [nonce, scriptContent]\n  );\n}\n\n/**\n * Hook for creating nonce-protected inline style props\n *\n * @example\n * ```tsx\n * function CustomStyles() {\n *   const styleProps = useNonceStyle('.custom { color: red; }');\n *\n *   return <style {...styleProps} />;\n * }\n * ```\n */\nexport function useNonceStyle(styleContent: string): {\n  nonce: string;\n  dangerouslySetInnerHTML: { __html: string };\n} {\n  const { nonce } = useCSPNonce();\n\n  return useMemo(\n    () => ({\n      nonce,\n      dangerouslySetInnerHTML: { __html: styleContent },\n    }),\n    [nonce, styleContent]\n  );\n}\n"],"names":["useCSPNonce","options","regenerateInterval","autoInitialize","nonce","setNonce","useState","CSPManager","generateNonce","useEffect","regenerate","useCallback","newNonce","intervalId","scriptNonce","useMemo","styleNonce","useNonceScript","scriptContent","useNonceStyle","styleContent"],"mappings":";;AA0DO,SAASA,EAAYC,IAA8B,IAAuB;AAC/E,QAAM,EAAE,oBAAAC,GAAoB,gBAAAC,IAAiB,GAAA,IAASF,GAGhD,CAACG,GAAOC,CAAQ,IAAIC,EAAiB,MAAM;AAE/C,QAAI;AACF,UAAIC,EAAW;AACb,eAAOA,EAAW,gBAAA;AAAA,IAEtB,QAAQ;AAAA,IAER;AACA,WAAOC,EAAA;AAAA,EACT,CAAC;AAGD,EAAAC,EAAU,MAAM;AACd,IAAIN,KAAkB,CAACI,EAAW,oBAChCA,EAAW,WAAA,GAEX,QAAQ,UACL,KAAK,MAAM;AACV,UAAI;AACF,QAAAF,EAASE,EAAW,iBAAiB;AAAA,MACvC,QAAQ;AAAA,MAER;AAAA,IACF,CAAC,EACA,MAAM,MAAM;AAAA,IAEb,CAAC;AAAA,EAGP,GAAG,CAACJ,CAAc,CAAC;AAGnB,QAAMO,IAAaC,EAAY,MAAc;AAC3C,QAAIC;AAEJ,WAAIL,EAAW,kBAEbK,IADiBL,EAAW,gBAAA,EACR,QAEpBK,IAAWJ,EAAA,GAGbH,EAASO,CAAQ,GACVA;AAAA,EACT,GAAG,CAAA,CAAE;AAGL,EAAAH,EAAU,MAAM;AACd,QAAwCP,KAAuB,QAAQA,IAAqB,GAAG;AAC7F,YAAMW,IAAa,YAAY,MAAM;AACnC,QAAAH,EAAA;AAAA,MACF,GAAGR,CAAkB;AAErB,aAAO,MAAM,cAAcW,CAAU;AAAA,IACvC;AAAA,EAEF,GAAG,CAACX,GAAoBQ,CAAU,CAAC;AAGnC,QAAMI,IAAcC,EAAQ,MAAMX,GAAO,CAACA,CAAK,CAAC,GAC1CY,IAAaD,EAAQ,MAAMX,GAAO,CAACA,CAAK,CAAC;AAE/C,SAAO;AAAA,IACL,OAAAA;AAAA,IACA,aAAAU;AAAA,IACA,YAAAE;AAAA,IACA,YAAAN;AAAA,EAAA;AAEJ;AAcO,SAASO,EAAeC,GAG7B;AACA,QAAM,EAAE,OAAAd,EAAA,IAAUJ,EAAA;AAElB,SAAOe;AAAA,IACL,OAAO;AAAA,MACL,OAAAX;AAAA,MACA,yBAAyB,EAAE,QAAQc,EAAA;AAAA,IAAc;AAAA,IAEnD,CAACd,GAAOc,CAAa;AAAA,EAAA;AAEzB;AAcO,SAASC,EAAcC,GAG5B;AACA,QAAM,EAAE,OAAAhB,EAAA,IAAUJ,EAAA;AAElB,SAAOe;AAAA,IACL,OAAO;AAAA,MACL,OAAAX;AAAA,MACA,yBAAyB,EAAE,QAAQgB,EAAA;AAAA,IAAa;AAAA,IAElD,CAAChB,GAAOgB,CAAY;AAAA,EAAA;AAExB;"}