Revert last 4 commits
All checks were successful
Automated Container Build / build-and-push (push) Successful in 46s
All checks were successful
Automated Container Build / build-and-push (push) Successful in 46s
This commit is contained in:
parent
e7a649d0d4
commit
c7d39144cd
5 changed files with 14 additions and 100 deletions
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Reference in a new issue