refactor: OnlyOffice Konfiguration nur ueber .env, nicht Admin-GUI

OnlyOffice URL und JWT Secret kommen jetzt ausschliesslich aus der
.env Datei (Umgebungsvariablen), nicht mehr aus der Admin-GUI:
- ONLYOFFICE_URL und ONLYOFFICE_JWT_SECRET in .env setzen
- docker-compose liest das gleiche Secret fuer den OnlyOffice-Container
- Eine Quelle der Wahrheit, kein Sync zwischen .env und DB noetig

Admin-GUI zeigt jetzt nur noch den Status an:
- Konfiguriert / Nicht konfiguriert (Tag)
- Aktuelle URL
- JWT Secret gesetzt / Fehlt (Tag)
- Setup-Anleitung mit .env Beispiel

Behebt: "Sicherheitstoken nicht korrekt" wenn OnlyOffice laeuft
aber JWT Secret nicht uebereinstimmt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker 2026-04-11 22:08:07 +02:00
parent 5bf98302e3
commit 0dbeef7cd9
3 changed files with 39 additions and 29 deletions

View File

@ -330,7 +330,7 @@ def onlyoffice_config(file_id):
if err:
return err
oo_url = AppSettings.get('onlyoffice_url', os.environ.get('ONLYOFFICE_URL', ''))
oo_url = os.environ.get('ONLYOFFICE_URL', '')
if not oo_url:
return jsonify({'error': 'OnlyOffice nicht konfiguriert', 'available': False}), 200
@ -381,7 +381,7 @@ def onlyoffice_config(file_id):
}
# Sign with JWT if secret is set
jwt_secret = AppSettings.get('onlyoffice_jwt_secret', '')
jwt_secret = os.environ.get('ONLYOFFICE_JWT_SECRET', '')
if jwt_secret:
import jwt as pyjwt
config['config']['token'] = pyjwt.encode(config['config'], jwt_secret, algorithm='HS256')
@ -448,7 +448,7 @@ def onlyoffice_callback():
@token_required
def onlyoffice_status():
"""Check if OnlyOffice is available."""
oo_url = AppSettings.get('onlyoffice_url', os.environ.get('ONLYOFFICE_URL', ''))
oo_url = os.environ.get('ONLYOFFICE_URL', '')
return jsonify({
'available': bool(oo_url),
'url': oo_url,

View File

@ -153,9 +153,9 @@ def get_settings():
'system_smtp_username': AppSettings.get('system_smtp_username', ''),
'system_smtp_password_set': bool(AppSettings.get('system_smtp_password', '')),
'system_email_from': AppSettings.get('system_email_from', ''),
'onlyoffice_url': AppSettings.get('onlyoffice_url', os.environ.get('ONLYOFFICE_URL', '')),
'onlyoffice_jwt_secret': AppSettings.get('onlyoffice_jwt_secret', ''),
'onlyoffice_jwt_secret_set': bool(AppSettings.get('onlyoffice_jwt_secret', '')),
'onlyoffice_url': os.environ.get('ONLYOFFICE_URL', ''),
'onlyoffice_configured': bool(os.environ.get('ONLYOFFICE_URL', '')),
'onlyoffice_jwt_set': bool(os.environ.get('ONLYOFFICE_JWT_SECRET', '')),
}), 200
@ -166,13 +166,11 @@ def update_settings():
if 'public_registration' in data:
AppSettings.set('public_registration', str(data['public_registration']).lower())
for key in ['system_smtp_host', 'system_smtp_port', 'system_smtp_ssl',
'system_smtp_username', 'system_email_from', 'onlyoffice_url']:
'system_smtp_username', 'system_email_from']:
if key in data:
AppSettings.set(key, str(data[key]))
if 'system_smtp_password' in data and data['system_smtp_password']:
AppSettings.set('system_smtp_password', data['system_smtp_password'])
if 'onlyoffice_jwt_secret' in data and data['onlyoffice_jwt_secret']:
AppSettings.set('onlyoffice_jwt_secret', data['onlyoffice_jwt_secret'])
return jsonify({'message': 'Einstellungen gespeichert'}), 200

View File

@ -80,28 +80,37 @@
<h3>OnlyOffice Document Server</h3>
<p class="hint">Fuer die Bearbeitung von Word, Excel und PowerPoint Dateien direkt im Browser.
Ohne OnlyOffice werden Dateien in einer einfachen Vorschau angezeigt.</p>
<div class="smtp-form">
<div class="field">
<label>OnlyOffice URL</label>
<InputText v-model="smtpForm.onlyoffice_url" placeholder="http://onlyoffice:80 oder https://office.example.com" fluid />
<div class="setting-row">
<div class="setting-info">
<strong>Status</strong>
</div>
<div class="field">
<label>JWT Secret {{ onlyofficeJwtSet ? '(gesetzt)' : '' }}</label>
<Password v-model="smtpForm.onlyoffice_jwt_secret" :feedback="false" toggle-mask fluid
placeholder="Muss mit JWT_SECRET in docker-compose uebereinstimmen" />
</div>
<Button label="Speichern" icon="pi pi-save" size="small" @click="saveSmtp" />
<Tag v-if="onlyofficeConfigured" value="Konfiguriert" severity="success" />
<Tag v-else value="Nicht konfiguriert" severity="warn" />
</div>
<div v-if="onlyofficeConfigured" class="settings-info" style="margin: 0.75rem 0">
<div class="info-row">
<span class="label">URL:</span>
<code>{{ onlyofficeUrl }}</code>
</div>
<div class="info-row">
<span class="label">JWT Secret:</span>
<Tag :value="onlyofficeJwtSet ? 'Gesetzt' : 'Fehlt!'" :severity="onlyofficeJwtSet ? 'success' : 'danger'" />
</div>
</div>
<div class="restore-instructions" style="margin-top: 1rem">
<strong>Setup:</strong>
<strong>Konfiguration ueber <code>.env</code>:</strong>
<pre style="background: var(--p-surface-100); padding: 0.75rem; border-radius: 4px; font-size: 0.85rem; margin: 0.5rem 0">ONLYOFFICE_URL=https://office.deine-domain.de
ONLYOFFICE_JWT_SECRET=dein-secret-hier</pre>
<strong>Setup-Schritte:</strong>
<ol>
<li>In <code>docker-compose.yml</code> den <code>onlyoffice</code>-Service auskommentieren</li>
<li>Nginx-Eintrag fuer OnlyOffice anlegen (z.B. <code>office.deine-domain.de</code>) - siehe <code>nginx.example.conf</code></li>
<li>Let's Encrypt Zertifikat fuer die OnlyOffice-Domain erstellen</li>
<li><code>docker-compose up -d</code></li>
<li>Hier die <strong>oeffentliche HTTPS-URL</strong> eintragen (z.B. <code>https://office.deine-domain.de</code>)<br/>
<em>Nicht</em> die interne Docker-URL - der Browser muss OnlyOffice erreichen koennen!</li>
<li>JWT Secret muss mit <code>ONLYOFFICE_JWT_SECRET</code> in <code>docker-compose.yml</code> uebereinstimmen</li>
<li>In <code>docker-compose.yml</code> den <code>onlyoffice</code>-Service aktivieren</li>
<li><code>ONLYOFFICE_URL</code> und <code>ONLYOFFICE_JWT_SECRET</code> in <code>.env</code> setzen</li>
<li>Nginx-Eintrag fuer die OnlyOffice-Domain anlegen (siehe <code>nginx.example.conf</code>)</li>
<li>Let's Encrypt: <code>certbot --nginx -d office.deine-domain.de</code></li>
<li><code>docker-compose up --build -d</code></li>
</ol>
</div>
</div>
@ -540,6 +549,8 @@ const smtpForm = ref({
system_smtp_username: '', system_smtp_password: '', system_email_from: '',
})
const smtpPasswordSet = ref(false)
const onlyofficeConfigured = ref(false)
const onlyofficeUrl = ref('')
const onlyofficeJwtSet = ref(false)
const smtpTesting = ref(false)
@ -648,8 +659,9 @@ async function loadSettings() {
smtpForm.value.system_smtp_username = res.data.system_smtp_username || ''
smtpForm.value.system_email_from = res.data.system_email_from || ''
smtpPasswordSet.value = res.data.system_smtp_password_set
smtpForm.value.onlyoffice_url = res.data.onlyoffice_url || ''
onlyofficeJwtSet.value = res.data.onlyoffice_jwt_secret_set
onlyofficeConfigured.value = res.data.onlyoffice_configured
onlyofficeUrl.value = res.data.onlyoffice_url || ''
onlyofficeJwtSet.value = res.data.onlyoffice_jwt_set
} catch { /* first load, defaults */ }
}