JWT key issue fix
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m24s

This commit is contained in:
Elijah 2026-05-24 11:26:55 -07:00
parent e1fdbd9388
commit 07aad3b8d4
5 changed files with 103 additions and 40 deletions

View file

@ -22,15 +22,75 @@ interface OnlyOfficeEditorProps {
export default function OnlyOfficeEditor({ file, type, onClose }: OnlyOfficeEditorProps) {
const [downloadToken, setDownloadToken] = useState<string | null>(null);
const [loadError, setLoadError] = useState<string | null>(null);
const [config, setConfig] = useState<any>(null);
useEffect(() => {
// We need a short-lived download token to pass to the Document Server
api.createDownloadToken()
.then((token: string) => setDownloadToken(token))
.catch(console.error);
.catch(err => {
setLoadError("Failed to get download token");
console.error(err);
});
}, [file.path]);
if (!downloadToken) {
useEffect(() => {
if (!downloadToken) return;
const getApiBase = () => {
if (process.env.NEXT_PUBLIC_API_URL) return process.env.NEXT_PUBLIC_API_URL;
if (typeof window !== 'undefined') return window.location.origin;
return 'http://localhost:8080';
};
const API_BASE = getApiBase();
// Use the internal backend URL for OnlyOffice server-to-server communication
// to avoid Hairpin NAT/DNS issues from inside the Docker network.
const INTERNAL_BACKEND_URL = 'http://192.168.50.81:5827';
// URL that OnlyOffice will use to download the file
const fileUrl = `${INTERNAL_BACKEND_URL}/api/files/download/?path=${encodeURIComponent(file.path)}&token=${downloadToken}`;
// Callback URL that OnlyOffice will post to when saving
const callbackUrl = `${INTERNAL_BACKEND_URL}/api/public/onlyoffice/callback?path=${encodeURIComponent(file.path)}&token=${downloadToken}`;
const baseConfig: any = {
document: {
fileType: file.name.split('.').pop() || 'docx',
key: `${file.path.replace(/[^a-zA-Z0-9\-_=]/g, '_')}_${new Date(file.mod_time).getTime()}`.substring(0, 128),
title: file.name,
url: fileUrl,
},
documentType: type,
editorConfig: {
callbackUrl: callbackUrl,
mode: 'edit',
customization: {
forcesave: true,
goback: {
url: '',
}
}
},
};
// Sign the config with our backend
api.signOnlyOfficeConfig(baseConfig)
.then((res: any) => {
if (res.token) {
baseConfig.token = res.token;
}
setConfig(baseConfig);
})
.catch((err) => {
console.warn("Failed to sign config (JWT secret might not be set). Falling back to unsigned config.", err);
setConfig(baseConfig);
});
}, [downloadToken, file, type]);
if (!config) {
return (
<div className="flex-1 flex flex-col items-center justify-center" style={{ backgroundColor: 'var(--color-bg-primary)' }}>
<div className="text-sm" style={{ color: 'var(--color-text-tertiary)' }}>Loading Editor...</div>
@ -39,41 +99,7 @@ export default function OnlyOfficeEditor({ file, type, onClose }: OnlyOfficeEdit
);
}
const getApiBase = () => {
if (process.env.NEXT_PUBLIC_API_URL) return process.env.NEXT_PUBLIC_API_URL;
if (typeof window !== 'undefined') return window.location.origin;
return 'http://localhost:8080';
};
const API_BASE = getApiBase();
const docServerUrl = 'https://office.elijahkuntz.com/';
// URL that OnlyOffice will use to download the file
const fileUrl = `${API_BASE}/api/files/download/?path=${encodeURIComponent(file.path)}&token=${downloadToken}`;
// Callback URL that OnlyOffice will post to when saving
const callbackUrl = `${API_BASE}/api/public/onlyoffice/callback?path=${encodeURIComponent(file.path)}&token=${downloadToken}`;
const config = {
document: {
fileType: file.name.split('.').pop() || 'docx',
key: `${file.path.replace(/[^a-zA-Z0-9\-_=]/g, '_')}_${new Date(file.mod_time).getTime()}`.substring(0, 128),
title: file.name,
url: fileUrl,
},
documentType: type,
editorConfig: {
callbackUrl: callbackUrl,
mode: 'edit',
customization: {
forcesave: true,
goback: {
url: '',
}
}
},
};
const onDocumentReady = function (event: any) {
console.log("Document is loaded");
@ -109,7 +135,7 @@ export default function OnlyOfficeEditor({ file, type, onClose }: OnlyOfficeEdit
<DocumentEditor
id="docxEditor"
documentServerUrl={docServerUrl}
config={config as any}
config={config}
events_onDocumentReady={onDocumentReady}
onLoadComponentError={onLoadComponentError}
/>

View file

@ -471,9 +471,17 @@ class ApiClient {
// --- OnlyOffice ---
async createOnlyOfficeFile(type: 'word' | 'slide') {
const res = await this.request('/api/onlyoffice/create', {
const res = await this.request('/onlyoffice/create', {
method: 'POST',
body: { type },
body: JSON.stringify({ type })
});
return res.json();
}
async signOnlyOfficeConfig(config: any) {
const res = await this.request('/onlyoffice/sign', {
method: 'POST',
body: JSON.stringify(config)
});
return res.json();
}