JWT key issue fix
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m24s
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m24s
This commit is contained in:
parent
e1fdbd9388
commit
07aad3b8d4
5 changed files with 103 additions and 40 deletions
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue