fix: OnlyOffice nutzt internes Docker-Netzwerk + langlebigen Token

Problem: OnlyOffice versuchte Dateien ueber die oeffentliche URL
herunterzuladen (http://selftestcloud...) und bekam 401 weil der
Access-Token nach 15 Min. ablief.

Fix:
- Download-URL und Callback-URL nutzen jetzt die interne Docker-URL
  (http://minicloud:5000) statt die oeffentliche URL
- Eigener 24h-Token fuer OnlyOffice Datei-Zugriff (statt des
  kurzlebigen User-Access-Tokens)
- ONLYOFFICE_INTERNAL_URL konfigurierbar (Default: http://minicloud:5000)

So bleibt der gesamte Dateizugriff zwischen OnlyOffice und Mini-Cloud
im Docker-Netzwerk - schneller und kein externer Roundtrip.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker
2026-04-11 22:19:30 +02:00
parent 35fddbfcbc
commit c3c0610750
+19 -6
View File
@@ -1,7 +1,7 @@
import io import io
import os import os
import hashlib import hashlib
from datetime import datetime, timezone from datetime import datetime, timezone, timedelta
from pathlib import Path from pathlib import Path
from flask import request, jsonify, current_app, send_file from flask import request, jsonify, current_app, send_file
@@ -353,9 +353,22 @@ def onlyoffice_config(file_id):
AppSettings.set(f'oo_callback_{callback_key}', str(file_id)) AppSettings.set(f'oo_callback_{callback_key}', str(file_id))
# Build the config # Build the config
# The URLs must be reachable by OnlyOffice server (not the browser) # Internal URL for OnlyOffice to reach our backend (Docker network)
base_url = request.host_url.rstrip('/') internal_url = os.environ.get('ONLYOFFICE_INTERNAL_URL', 'http://minicloud:5000')
token = request.args.get('token', '') or request.headers.get('Authorization', '').replace('Bearer ', '')
# Generate a long-lived token for OnlyOffice file access (24h)
from app.api.auth import create_access_token
import jwt as pyjwt
oo_file_token = pyjwt.encode(
{
'user_id': user.id,
'type': 'access',
'exp': datetime.now(timezone.utc) + timedelta(hours=24),
'iat': datetime.now(timezone.utc),
},
current_app.config['JWT_SECRET_KEY'],
algorithm='HS256',
)
config = { config = {
'available': True, 'available': True,
@@ -365,11 +378,11 @@ def onlyoffice_config(file_id):
'fileType': ext, 'fileType': ext,
'key': f'{file_id}_{f.checksum or "0"}_{callback_key[:8]}', 'key': f'{file_id}_{f.checksum or "0"}_{callback_key[:8]}',
'title': f.name, 'title': f.name,
'url': f'{base_url}/api/files/{file_id}/download?token={token}', 'url': f'{internal_url}/api/files/{file_id}/download?token={oo_file_token}',
}, },
'documentType': doc_type, 'documentType': doc_type,
'editorConfig': { 'editorConfig': {
'callbackUrl': f'{base_url}/api/files/onlyoffice-callback?key={callback_key}', 'callbackUrl': f'{internal_url}/api/files/onlyoffice-callback?key={callback_key}',
'mode': 'edit' if can_write else 'view', 'mode': 'edit' if can_write else 'view',
'lang': 'de', 'lang': 'de',
'user': { 'user': {