UNPKG

protect-scr

Version:

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

220 lines (218 loc) 7.29 kB
export class PrintProtector { constructor(config) { this.isActive = false; this.originalMethods = new Map(); this.config = config; } start() { if (this.isActive) return; this.isActive = true; if (this.config.preventPrinting) { this.blockPrinting(); } if (this.config.preventPDFGeneration) { this.blockPDFGeneration(); } this.setupMediaQueryDetection(); } stop() { if (!this.isActive) return; this.isActive = false; this.restoreOriginalMethods(); } blockPrinting() { // Store original print method this.originalPrint = window.print; // Override window.print window.print = () => { if (this.config.showWarning) { alert('Printing is disabled for security reasons.'); } return; }; // Block print media queries this.addPrintBlockingCSS(); // Block beforeprint event const beforePrintHandler = (e) => { e.preventDefault(); e.stopPropagation(); if (this.config.showWarning) { alert('Printing is disabled for security reasons.'); } return false; }; window.addEventListener('beforeprint', beforePrintHandler); this.originalMethods.set('beforeprint', () => { window.removeEventListener('beforeprint', beforePrintHandler); }); } blockPDFGeneration() { // Block common PDF generation libraries this.blockJsPDF(); this.blockPDFMake(); this.blockPuppeteer(); this.blockHtml2Canvas(); this.blockDomToPdf(); } blockJsPDF() { // Block jsPDF library Object.defineProperty(window, 'jsPDF', { get: () => { throw new Error('PDF generation is blocked for security reasons'); }, set: () => { throw new Error('PDF generation is blocked for security reasons'); }, configurable: false }); // Block jspdf import if (typeof window !== 'undefined') { window.jsPDF = undefined; } } blockPDFMake() { // Block pdfMake library Object.defineProperty(window, 'pdfMake', { get: () => { throw new Error('PDF generation is blocked for security reasons'); }, set: () => { throw new Error('PDF generation is blocked for security reasons'); }, configurable: false }); if (typeof window !== 'undefined') { window.pdfMake = undefined; } } blockPuppeteer() { // Block puppeteer (mainly for server-side, but defensive) if (typeof window !== 'undefined') { window.puppeteer = undefined; } } blockHtml2Canvas() { // Block html2canvas library Object.defineProperty(window, 'html2canvas', { get: () => { throw new Error('Canvas generation is blocked for security reasons'); }, set: () => { throw new Error('Canvas generation is blocked for security reasons'); }, configurable: false }); if (typeof window !== 'undefined') { window.html2canvas = undefined; } } blockDomToPdf() { // Block dom-to-pdf and similar libraries const blockedLibraries = [ 'domToPdf', 'dom-to-pdf', 'htmlToPdf', 'html-to-pdf', 'pageToPdf', 'page-to-pdf' ]; blockedLibraries.forEach(lib => { Object.defineProperty(window, lib, { get: () => { throw new Error('PDF generation is blocked for security reasons'); }, set: () => { throw new Error('PDF generation is blocked for security reasons'); }, configurable: false }); }); } addPrintBlockingCSS() { const styleId = 'secure-app-shield-print-block'; let styleElement = document.getElementById(styleId); if (!styleElement) { styleElement = document.createElement('style'); styleElement.id = styleId; document.head.appendChild(styleElement); } styleElement.textContent = ` @media print { * { display: none !important; visibility: hidden !important; } body::before { content: "Printing is not allowed for security reasons" !important; display: block !important; visibility: visible !important; position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; font-size: 24px !important; font-weight: bold !important; color: #000 !important; background: #fff !important; padding: 20px !important; border: 2px solid #000 !important; z-index: 9999999 !important; } } @page { margin: 0 !important; size: A4 !important; } `; this.originalMethods.set('printCSS', () => { if (styleElement) { styleElement.remove(); } }); } setupMediaQueryDetection() { // Detect when print media query becomes active const printMediaQuery = window.matchMedia('print'); const printHandler = (e) => { var _a; if (e.matches && this.config.preventPrinting) { // Print mode detected if (this.config.showWarning) { alert('Printing is disabled for security reasons.'); } // Try to cancel print dialog (_a = window.stop) === null || _a === void 0 ? void 0 : _a.call(window); } }; if (printMediaQuery.addEventListener) { printMediaQuery.addEventListener('change', printHandler); this.originalMethods.set('mediaQuery', () => { printMediaQuery.removeEventListener('change', printHandler); }); } else if (printMediaQuery.addListener) { // Fallback for older browsers printMediaQuery.addListener(printHandler); this.originalMethods.set('mediaQuery', () => { printMediaQuery.removeListener(printHandler); }); } } restoreOriginalMethods() { // Restore original print method if (this.originalPrint) { window.print = this.originalPrint; this.originalPrint = undefined; } // Remove all event listeners and styles this.originalMethods.forEach((cleanup) => { if (typeof cleanup === 'function') { cleanup(); } }); this.originalMethods.clear(); } } //# sourceMappingURL=PrintProtector.js.map