{"version":3,"file":"useSecureModule.mjs","sources":["../../../../src/lib/vdom/hooks/useSecureModule.ts"],"sourcesContent":["/**\n * @file useSecureModule Hook\n * @module vdom/hooks/useSecureModule\n * @description Hook for accessing module security context with content\n * validation, sanitization, and violation reporting capabilities.\n *\n * @author Agent 5 - PhD Virtual DOM Expert\n * @version 1.0.0\n */\n\nimport { useState, useCallback, useMemo, useEffect } from 'react';\nimport {\n  type UseSecureModuleReturn,\n  type SecurityViolation,\n  type SecurityNonce,\n  ModuleLifecycleEvent,\n} from '../types';\nimport { useModuleContext } from '../ModuleBoundary';\nimport { devWarn } from '@/lib/core/config/env-helper';\n\n/**\n * Hook for accessing module security context.\n * Provides content validation, sanitization, and security monitoring.\n *\n * @returns Security context and utilities\n * @throws Error if used outside a ModuleBoundary\n *\n * @example\n * ```tsx\n * function UserContent({ html }: { html: string }) {\n *   const {\n *     validateContent,\n *     sanitize,\n *     isSecure,\n *     nonce,\n *     violations,\n *   } = useSecureModule();\n *\n *   // Validate before rendering\n *   if (!validateContent(html)) {\n *     return <p>Invalid content detected</p>;\n *   }\n *\n *   // Sanitize for safe rendering\n *   const safeHtml = sanitize(html);\n *\n *   return (\n *     <div>\n *       {!isSecure && (\n *         <Warning>Security violations detected: {violations.length}</Warning>\n *       )}\n *       <div dangerouslySetInnerHTML={{ __html: safeHtml }} />\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useSecureModule(): UseSecureModuleReturn {\n  const context = useModuleContext();\n  const securityContext = context.security;\n\n  // Local violations state for tracking\n  const [violations, setViolations] = useState<SecurityViolation[]>(() => [\n    ...securityContext.violations,\n  ]);\n\n  // Sync with context violations using queueMicrotask to avoid synchronous setState\n  useEffect(() => {\n    queueMicrotask(() => {\n      setViolations([...securityContext.violations]);\n    });\n  }, [securityContext.violations]);\n\n  // Report a new violation\n  const reportViolation = useCallback((violation: Omit<SecurityViolation, 'timestamp'>) => {\n    const fullViolation: SecurityViolation = {\n      ...violation,\n      timestamp: Date.now(),\n    };\n\n    setViolations((prev) => [...prev, fullViolation]);\n\n    // Log in development\n    devWarn('[Security Violation]', fullViolation);\n  }, []);\n\n  // Memoize return value\n  return useMemo<UseSecureModuleReturn>(\n    () => ({\n      securityContext,\n      nonce: securityContext.nonce,\n      isSecure: securityContext.isSecure && violations.length === 0,\n      validateContent: securityContext.validateContent,\n      sanitize: securityContext.sanitize,\n      isEventAllowed: securityContext.isEventAllowed,\n      violations,\n      reportViolation,\n    }),\n    [securityContext, violations, reportViolation]\n  );\n}\n\n/**\n * Hook to get the security nonce.\n * @returns Security nonce or null\n */\nexport function useSecurityNonce(): SecurityNonce | null {\n  const { nonce } = useSecureModule();\n  return nonce;\n}\n\n/**\n * Hook to check if the module is in secure state.\n * @returns Whether module is secure\n */\nexport function useIsSecure(): boolean {\n  const { isSecure } = useSecureModule();\n  return isSecure;\n}\n\n/**\n * Hook to get a content sanitizer function.\n * @returns Sanitizer function\n *\n * @example\n * ```tsx\n * const sanitize = useSanitizer();\n * const safeContent = sanitize(userInput);\n * ```\n */\nexport function useSanitizer(): (content: string) => string {\n  const { sanitize } = useSecureModule();\n  return sanitize;\n}\n\n/**\n * Hook to get a content validator function.\n * @returns Validator function\n */\nexport function useContentValidator(): (content: string) => boolean {\n  const { validateContent } = useSecureModule();\n  return validateContent;\n}\n\n/**\n * Hook to get security violations.\n * @returns Array of violations\n */\nexport function useSecurityViolations(): ReadonlyArray<SecurityViolation> {\n  const { violations } = useSecureModule();\n  return violations;\n}\n\n/**\n * Hook for safely rendering user-provided HTML.\n * @param html - Raw HTML string\n * @returns Safe HTML and validation state\n *\n * @example\n * ```tsx\n * function RichText({ content }: { content: string }) {\n *   const { safeHtml, isValid, error } = useSafeHtml(content);\n *\n *   if (!isValid) {\n *     return <p>Invalid content: {error}</p>;\n *   }\n *\n *   return <div dangerouslySetInnerHTML={{ __html: safeHtml }} />;\n * }\n * ```\n */\nexport function useSafeHtml(html: string): {\n  safeHtml: string;\n  isValid: boolean;\n  error: string | null;\n} {\n  const { validateContent, sanitize, reportViolation } = useSecureModule();\n  const context = useModuleContext();\n\n  return useMemo(() => {\n    const isValid = validateContent(html);\n\n    if (!isValid) {\n      reportViolation({\n        type: 'xss',\n        message: 'Potentially dangerous HTML content detected',\n        moduleId: context.moduleId,\n        blockedContent: html.substring(0, 100),\n      });\n\n      return {\n        safeHtml: '',\n        isValid: false,\n        error: 'Content failed security validation',\n      };\n    }\n\n    const safeHtml = sanitize(html);\n\n    return {\n      safeHtml,\n      isValid: true,\n      error: null,\n    };\n  }, [html, validateContent, sanitize, reportViolation, context.moduleId]);\n}\n\n/**\n * Hook for secure URL validation.\n * @param url - URL to validate\n * @returns Whether URL is safe\n *\n * @example\n * ```tsx\n * function Link({ href }: { href: string }) {\n *   const isSafe = useSecureUrl(href);\n *\n *   if (!isSafe) {\n *     return <span>{href}</span>;\n *   }\n *\n *   return <a href={href}>{href}</a>;\n * }\n * ```\n */\nexport function useSecureUrl(url: string): boolean {\n  return useMemo(() => {\n    try {\n      const parsed = new URL(url, window.location.origin);\n      const safeProtocols = ['http:', 'https:', 'mailto:', 'tel:'];\n      return safeProtocols.includes(parsed.protocol);\n    } catch {\n      return false;\n    }\n  }, [url]);\n}\n\n/**\n * Hook for CSP nonce injection in style tags.\n * @returns Props to spread on style elements\n *\n * @example\n * ```tsx\n * function InlineStyles() {\n *   const styleProps = useSecureStyleProps();\n *\n *   return (\n *     <style {...styleProps}>\n *       {`.my-class { color: blue; }`}\n *     </style>\n *   );\n * }\n * ```\n */\nexport function useSecureStyleProps(): { nonce?: string } {\n  const { nonce } = useSecureModule();\n\n  return useMemo(() => (nonce ? { nonce } : {}), [nonce]);\n}\n\n/**\n * Hook for CSP nonce injection in script tags.\n * @returns Props to spread on script elements\n */\nexport function useSecureScriptProps(): { nonce?: string } {\n  const { nonce } = useSecureModule();\n\n  return useMemo(() => (nonce ? { nonce } : {}), [nonce]);\n}\n\n/**\n * Hook for event permission checking.\n * @param eventName - Event name to check\n * @returns Whether event is allowed\n */\nexport function useIsEventAllowed(eventName: string): boolean {\n  const { isEventAllowed } = useSecureModule();\n  return isEventAllowed(eventName);\n}\n\n/**\n * Hook for secure cross-module messaging.\n * Validates and sanitizes messages before sending.\n *\n * @returns Secure messaging utilities\n *\n * @example\n * ```tsx\n * function SecureMessenger() {\n *   const { sendSecure, onSecureMessage } = useSecureMessaging();\n *\n *   const handleSend = () => {\n *     sendSecure('data:update', { value: 'safe data' });\n *   };\n *\n *   useEffect(() => {\n *     return onSecureMessage('data:received', (payload) => {\n *       console.log('Received:', payload);\n *     });\n *   }, [onSecureMessage]);\n *\n *   return <button onClick={handleSend}>Send</button>;\n * }\n * ```\n */\nexport function useSecureMessaging(): {\n  sendSecure: <T>(eventName: string, payload: T) => boolean;\n  onSecureMessage: <T>(eventName: string, handler: (payload: T) => void) => () => void;\n} {\n  const { isEventAllowed, sanitize, reportViolation } = useSecureModule();\n  const context = useModuleContext();\n\n  const sendSecure = useCallback(\n    <T>(eventName: string, payload: T): boolean => {\n      // Validate event is allowed\n      if (!isEventAllowed(eventName)) {\n        reportViolation({\n          type: 'origin',\n          message: `Event not allowed: ${eventName}`,\n          moduleId: context.moduleId,\n        });\n        return false;\n      }\n\n      // Sanitize string payloads\n      let safePayload = payload;\n      if (typeof payload === 'string') {\n        safePayload = sanitize(payload) as unknown as T;\n      } else if (typeof payload === 'object' && payload !== null) {\n        // Deep sanitize object strings\n        safePayload = JSON.parse(sanitize(JSON.stringify(payload))) as T;\n      }\n\n      // Emit through context\n      context.dispatch({\n        type: 'SET_STATE',\n        key: `__event_${eventName}_${Date.now()}`,\n        value: safePayload,\n      });\n\n      return true;\n    },\n    [isEventAllowed, sanitize, reportViolation, context]\n  );\n\n  const onSecureMessage = useCallback(\n    <T>(eventName: string, _handler: (payload: T) => void): (() => void) => {\n      if (!isEventAllowed(eventName)) {\n        return () => {};\n      }\n\n      // Subscribe to lifecycle events as a proxy for secure messaging\n      return context.subscribe(ModuleLifecycleEvent.AFTER_UPDATE, () => {\n        // This is a simplified implementation\n        // Real implementation would use the event bus with validation\n      });\n    },\n    [isEventAllowed, context]\n  );\n\n  return useMemo(\n    () => ({\n      sendSecure,\n      onSecureMessage,\n    }),\n    [sendSecure, onSecureMessage]\n  );\n}\n"],"names":["useSecureModule","securityContext","useModuleContext","violations","setViolations","useState","useEffect","reportViolation","useCallback","violation","fullViolation","prev","devWarn","useMemo","useSecurityNonce","nonce","useIsSecure","isSecure","useSanitizer","sanitize","useContentValidator","validateContent","useSecurityViolations","useSafeHtml","html","context","useSecureUrl","url","parsed","useSecureStyleProps","useSecureScriptProps","useIsEventAllowed","eventName","isEventAllowed","useSecureMessaging","sendSecure","payload","safePayload","onSecureMessage","_handler","ModuleLifecycleEvent"],"mappings":"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"}