UNPKG

protect-scr

Version:

Comprehensive client-side security protection for React applications against screenshots, printing, and unauthorized access

152 lines 4.96 kB
// src/react/hooks.ts import { useEffect, useRef, useState, useCallback } from 'react'; import { SecurityManager } from '../core/SecurityManager'; import { getPresetConfig } from '../presets'; export function useSecurityShield(config) { const securityManagerRef = useRef(null); const [isEnabled, setIsEnabled] = useState(false); const configRef = useRef(config); // Update config ref when config changes useEffect(() => { configRef.current = config; }, [config]); // Initialize security manager only once useEffect(() => { if (securityManagerRef.current) return; // Already initialized try { let finalConfig = {}; if (typeof configRef.current === 'string') { finalConfig = getPresetConfig(configRef.current); } else if (configRef.current) { finalConfig = configRef.current; } securityManagerRef.current = new SecurityManager(finalConfig); console.log('SecurityManager initialized'); } catch (error) { console.error('Failed to initialize SecurityManager:', error); } // Cleanup function return () => { if (securityManagerRef.current) { try { securityManagerRef.current.disable(); securityManagerRef.current = null; } catch (error) { console.error('Cleanup error:', error); } } }; }, []); // Empty dependency array - only run once const enable = useCallback(() => { if (securityManagerRef.current && !isEnabled) { try { securityManagerRef.current.enable(); setIsEnabled(true); } catch (error) { console.error('Failed to enable security:', error); } } }, [isEnabled]); const disable = useCallback(() => { if (securityManagerRef.current && isEnabled) { try { securityManagerRef.current.disable(); setIsEnabled(false); } catch (error) { console.error('Failed to disable security:', error); } } }, [isEnabled]); const updateConfig = useCallback((newConfig) => { if (securityManagerRef.current) { try { securityManagerRef.current.updateConfig(newConfig); } catch (error) { console.error('Failed to update config:', error); } } }, []); return { isEnabled, enable, disable, updateConfig }; } // Simplified version for other hooks to prevent dependency issues export function useRouteSecurityShield(routes, config) { const [currentPath, setCurrentPath] = useState(() => { if (typeof window !== 'undefined') { return window.location.pathname; } return '/'; }); const [shouldProtect, setShouldProtect] = useState(false); const { isEnabled, enable, disable } = useSecurityShield(config); // Monitor route changes useEffect(() => { if (typeof window === 'undefined') return; const handleRouteChange = () => { setCurrentPath(window.location.pathname); }; window.addEventListener('popstate', handleRouteChange); return () => { window.removeEventListener('popstate', handleRouteChange); }; }, []); // Check if current route should be protected useEffect(() => { const isProtectedRoute = routes.some(route => { if (route.endsWith('*')) { return currentPath.startsWith(route.slice(0, -1)); } return currentPath === route || currentPath.startsWith(route + '/'); }); setShouldProtect(isProtectedRoute); if (isProtectedRoute) { enable(); } else { disable(); } }, [currentPath, routes, enable, disable]); return { isEnabled: isEnabled && shouldProtect, shouldProtect }; } export function useConditionalSecurityShield(condition, config) { const { isEnabled, enable: baseEnable, disable: baseDisable } = useSecurityShield(config); useEffect(() => { if (condition) { baseEnable(); } else { baseDisable(); } }, [condition, baseEnable, baseDisable]); return { isEnabled: isEnabled && condition, enable: baseEnable, disable: baseDisable }; } export function useSecurityEvents() { const [events, setEvents] = useState([]); const clearEvents = useCallback(() => { setEvents([]); }, []); return { events, clearEvents }; } //# sourceMappingURL=hooks.js.map