Revert last 4 commits
All checks were successful
Automated Container Build / build-and-push (push) Successful in 46s

This commit is contained in:
Elijah Kuntz 2026-06-11 16:24:34 -07:00
parent e7a649d0d4
commit c7d39144cd
5 changed files with 14 additions and 100 deletions

View file

@ -335,20 +335,16 @@ func (h *OnlyOfficeHandler) ListOfficeFiles(c *fiber.Ctx) error {
var results []OfficeFile
checksums := make(map[string]string)
dbPaths := []string{}
rows, err := h.DB.Query("SELECT path, checksum FROM files WHERE checksum IS NOT NULL AND checksum != ''")
rows, err := h.DB.Query("SELECT path, checksum FROM files WHERE checksum != '' AND is_trashed = 0")
if err == nil {
defer rows.Close()
for rows.Next() {
var p, c string
if rows.Scan(&p, &c) == nil {
checksums[p] = c
dbPaths = append(dbPaths, p)
}
}
}
walkPaths := []string{}
filepath.Walk(h.Config.StorageDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
@ -366,16 +362,12 @@ func (h *OnlyOfficeHandler) ListOfficeFiles(c *fiber.Ctx) error {
if strings.HasSuffix(strings.ToLower(info.Name()), ext) {
relPath, _ := filepath.Rel(h.Config.StorageDir, path)
relPathSlash := filepath.ToSlash(relPath)
chk := checksums[relPathSlash]
walkPaths = append(walkPaths, relPathSlash)
results = append(results, OfficeFile{
Name: info.Name(),
Path: relPathSlash,
Size: info.Size(),
ModTime: info.ModTime().UTC().Format("2006-01-02T15:04:05Z"),
Checksum: chk,
Checksum: checksums[relPathSlash],
})
}
return nil
@ -388,8 +380,6 @@ func (h *OnlyOfficeHandler) ListOfficeFiles(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"files": results,
"count": len(results),
"debug_db": dbPaths,
"debug_walk": walkPaths,
})
}

View file

@ -103,21 +103,9 @@ func main() {
c.Set("Cache-Control", "no-store, no-cache, must-revalidate")
return c.Next()
})
app.Use(helmet.New(helmet.Config{
// Relax cross-origin policies to allow OnlyOffice Document Server
// iframe embedding from a different origin (e.g. office.elijahkuntz.com)
CrossOriginEmbedderPolicy: "unsafe-none",
CrossOriginResourcePolicy: "cross-origin",
}))
// Build CSP with dynamic frame-src for the OnlyOffice Document Server
onlyOfficeFrameSrc := "https://" + cfg.OnlyOfficeHost
cspHeader := fmt.Sprintf(
"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self' wss: https: http:; frame-src 'self' %s;",
onlyOfficeFrameSrc,
)
app.Use(helmet.New())
app.Use(func(c *fiber.Ctx) error {
c.Set("Content-Security-Policy", cspHeader)
c.Set("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self' wss: https: http:;")
return c.Next()
})
allowedOrigins := os.Getenv("ALLOWED_ORIGINS")

View file

@ -92,8 +92,6 @@ export default function OfficeHome({ type, onFileSelect, onCreateBlank, onPinCha
// Fetch ALL office files recursively
api.listOfficeFiles(fileTypeParam)
.then(data => {
console.log("ListOfficeFiles Debug DB:", data.debug_db);
console.log("ListOfficeFiles Debug Walk:", data.debug_walk);
const files = (data.files || []).map((f: any) => ({
...f,
is_dir: false,

View file

@ -1,6 +1,6 @@
import React, { useEffect, useState, useRef, useCallback } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import { DocumentEditor } from '@onlyoffice/document-editor-react';
import { Sun, Moon, Loader2, ArrowLeft, RefreshCw, Download, ShieldAlert, X } from 'lucide-react';
import { Sun, Moon, Loader2, ArrowLeft, RefreshCw, Download } from 'lucide-react';
import api from '@/lib/api';
import { FileItem } from '@/types/files';
@ -18,10 +18,6 @@ export default function OnlyOfficeEditor({ file, type, onClose, onRename, theme,
const [loadError, setLoadError] = useState<string | null>(null);
const [config, setConfig] = useState<any>(null);
const [isRenaming, setIsRenaming] = useState(false);
const [adblockWarning, setAdblockWarning] = useState(false);
const [documentReady, setDocumentReady] = useState(false);
const documentReadyRef = useRef(false);
const loadTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const extMatch = file.name.match(/\.[^.]+$/);
const ext = extMatch ? extMatch[0] : '';
@ -134,39 +130,9 @@ export default function OnlyOfficeEditor({ file, type, onClose, onRename, theme,
const docServerUrl = process.env.NEXT_PUBLIC_ONLYOFFICE_URL || 'https://office.elijahkuntz.com/';
// Proactively detect if an adblocker is blocking OnlyOffice resources
useEffect(() => {
if (!config) return;
// Test fetch for a resource commonly blocked by adblockers (Brave Shields, uBlock, etc.)
const testUrl = `${docServerUrl}web-apps/apps/common/Analytics.js`;
fetch(testUrl, { method: 'HEAD', mode: 'no-cors' })
.then(() => {
// mode: 'no-cors' always resolves — check with a timeout fallback instead
})
.catch(() => {
setAdblockWarning(true);
});
// Fallback: if onDocumentReady hasn't fired in 8s, show the warning
loadTimeoutRef.current = setTimeout(() => {
if (!documentReadyRef.current) {
setAdblockWarning(true);
}
}, 8000);
return () => {
if (loadTimeoutRef.current) clearTimeout(loadTimeoutRef.current);
};
}, [config, docServerUrl]);
const onDocumentReady = useCallback(function (event: any) {
const onDocumentReady = function (event: any) {
console.log("Document is loaded");
documentReadyRef.current = true;
setDocumentReady(true);
setAdblockWarning(false);
if (loadTimeoutRef.current) clearTimeout(loadTimeoutRef.current);
}, []);
};
const onLoadComponentError = function (errorCode: number, errorDescription: string) {
setLoadError(`${errorCode}: ${errorDescription}`);
@ -226,44 +192,16 @@ export default function OnlyOfficeEditor({ file, type, onClose, onRename, theme,
</div>
<div className="flex-1 relative">
{loadError ? (
<div className="absolute inset-0 flex items-center justify-center bg-gray-50 dark:bg-[#1a1a1a] p-8 text-center flex-col">
<div className="absolute inset-0 flex items-center justify-center bg-gray-50 text-red-600 p-8 text-center flex-col">
<svg className="w-12 h-12 mb-4 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<h3 className="font-bold text-lg mb-2 text-red-600 dark:text-red-400">Failed to load OnlyOffice Editor</h3>
<p className="text-sm text-red-600 dark:text-red-400">{loadError}</p>
<p className="mt-4 text-xs text-gray-500 dark:text-gray-400">Check if your OnlyOffice server is running and accessible at the configured URL.</p>
<h3 className="font-bold text-lg mb-2">Failed to load OnlyOffice Editor</h3>
<p className="text-sm">{loadError}</p>
<p className="mt-4 text-xs text-gray-500">Check if your OnlyOffice server is running and accessible at the configured URL.</p>
</div>
) : (
<div className="absolute inset-0">
{/* Adblocker / Brave Shields warning banner */}
{adblockWarning && !documentReady && (
<div className="absolute top-0 left-0 right-0 z-50 flex items-start gap-3 px-5 py-4 bg-amber-50 dark:bg-amber-950/80 border-b border-amber-200 dark:border-amber-800 shadow-lg animate-in slide-in-from-top">
<ShieldAlert className="w-6 h-6 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" />
<div className="flex-1 min-w-0">
<h4 className="font-semibold text-sm text-amber-800 dark:text-amber-200">Ad Blocker Detected</h4>
<p className="text-xs text-amber-700 dark:text-amber-300 mt-1 leading-relaxed">
Your ad blocker or browser shield is blocking resources required by the document editor.
The editor may not load or function correctly.
</p>
<div className="mt-2 text-xs text-amber-600 dark:text-amber-400 space-y-1">
<p className="font-medium">To fix this:</p>
<ul className="list-disc list-inside space-y-0.5 ml-1">
<li><strong>Brave:</strong> Click the Shields icon (lion) in the address bar set Shields to <em>Down</em> for this site</li>
<li><strong>uBlock / AdBlock:</strong> Click the extension icon disable for this site</li>
</ul>
<p className="mt-1.5">Then refresh the page.</p>
</div>
</div>
<button
onClick={() => setAdblockWarning(false)}
className="p-1 rounded-md hover:bg-amber-200/50 dark:hover:bg-amber-800/50 transition-colors flex-shrink-0"
title="Dismiss"
>
<X className="w-4 h-4 text-amber-600 dark:text-amber-400" />
</button>
</div>
)}
<DocumentEditor
id="docxEditor"
documentServerUrl={docServerUrl}

View file

@ -20,7 +20,7 @@ export default function ThumbnailImage({ checksum, fallbackIcon, downloadToken,
}, [checksum]);
const docStyle = docType === 'docs'
? `h-[85%] max-w-[85%] ${showFallback ? 'aspect-[1/1.4]' : 'aspect-auto'} bg-white border border-gray-300 dark:border-gray-600 shadow-md`
? 'h-[85%] max-w-[85%] aspect-[1/1.4] bg-white border border-gray-300 dark:border-gray-600 shadow-md'
: docType === 'slides'
? 'w-[85%] max-h-[85%] aspect-[16/9] bg-white border border-gray-300 dark:border-gray-600 shadow-md'
: docType === 'sheets'
@ -32,7 +32,7 @@ export default function ThumbnailImage({ checksum, fallbackIcon, downloadToken,
key={key}
src={downloadToken ? `${api.getThumbnailUrl(checksum, downloadToken)}${errorCount > 0 ? `&t=${key}` : ''}` : ''}
alt=""
className={`object-contain ${docType ? 'w-full h-full mix-blend-multiply' : 'w-full h-full'}`}
className={`object-contain ${docType ? 'w-full h-full object-cover mix-blend-multiply' : 'w-full h-full'}`}
style={{ display: showFallback ? 'none' : 'block' }}
onError={(e) => {
if (errorCount < 20) {