From f947ed60638c2fefc18c4b505b3d781dc8159ece Mon Sep 17 00:00:00 2001 From: Horus AI Date: Mon, 23 Mar 2026 22:17:23 +0100 Subject: [PATCH] fix(pdf-viewer): disable worker to bypass CSP, use Google Docs for URLs --- .../mission-control/PDFViewerClient.tsx | 59 ++++++++++++------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/components/mission-control/PDFViewerClient.tsx b/components/mission-control/PDFViewerClient.tsx index 607c962..7e3f40a 100644 --- a/components/mission-control/PDFViewerClient.tsx +++ b/components/mission-control/PDFViewerClient.tsx @@ -21,15 +21,16 @@ export default function PDFViewerClient() { const pdfDocRef = useRef(null); useEffect(() => { - // Load PDF.js from CDN with worker configured + // Load PDF.js from CDN const script = document.createElement("script"); script.src = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"; script.async = true; script.onload = () => { try { window.pdfjsLib = window.pdfjsLib; - // Use the CDN worker directly - no blob URL - window.pdfjsLib.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js"; + // Disable worker to avoid CSP issues + window.pdfjsLib.GlobalWorkerOptions.workerSrc = ""; + window.pdfjsLib.GlobalWorkerOptions.workerPort = null; setPdfjsLoaded(true); } catch (e) { setError("Failed to initialize PDF.js"); @@ -53,10 +54,14 @@ export default function PDFViewerClient() { canvas.height = viewport.height; canvas.width = viewport.width; - await page.render({ + // Use synchronous rendering to avoid worker + const renderContext = { canvasContext: context, viewport: viewport, - }).promise; + }; + + // For older pdf.js without worker, use direct render + await page.render(renderContext).promise; } catch (err) { console.error("Error rendering page:", err); } @@ -84,13 +89,19 @@ export default function PDFViewerClient() { try { const arrayBuffer = await file.arrayBuffer(); - const pdf = await window.pdfjsLib.getDocument({ data: arrayBuffer }).promise; + // Disable worker for this load + const loadingTask = window.pdfjsLib.getDocument({ + data: arrayBuffer, + disableWorker: true, + verbosity: 0 + }); + const pdf = await loadingTask.promise; pdfDocRef.current = pdf; setNumPages(pdf.numPages); setPdfData("local"); await renderPage(1); } catch (err) { - setError("Failed to load PDF"); + setError("Failed to load PDF. Try using 'Load from URL' instead."); console.error(err); } setLoading(false); @@ -108,16 +119,11 @@ export default function PDFViewerClient() { new URL(input); setPdfName(input.split("/").pop() || "document.pdf"); - const response = await fetch(input); - if (!response.ok) throw new Error("Failed to fetch"); - const arrayBuffer = await response.arrayBuffer(); - const pdf = await window.pdfjsLib.getDocument({ data: arrayBuffer }).promise; - pdfDocRef.current = pdf; - setNumPages(pdf.numPages); - setPdfData("url"); - await renderPage(1); + // Use Google Docs viewer for external URLs + setPdfData(`https://docs.google.com/gview?url=${encodeURIComponent(input)}&embedded=true`); + setNumPages(1); // We don't know the page count for external URLs } catch (err) { - setError("Failed to load PDF from URL. Make sure it's publicly accessible."); + setError("Failed to load PDF from URL."); console.error(err); } setLoading(false); @@ -202,6 +208,7 @@ export default function PDFViewerClient() {
📄

No PDF Loaded

Upload a PDF or enter a URL

+

💡 Tip: For best results, use "Load from URL" with a public PDF link

)} @@ -217,11 +224,21 @@ export default function PDFViewerClient() { {pdfData && !loading && (
- + {pdfData.startsWith("https://docs.google.com") ? ( + // Google Docs viewer for external URLs +