WebUI gibt keine Geheimnisse mehr heraus und aendert keine Zugangseinstellungen
Behebt #562. Entscheidung Richard, 13.09.2026: Geheimnisse verwalten wir ausschliesslich im Desktop. Bis dahin lieferte GET /api/settings/webui das Zugangs-Token im Klartext. Ueber das WebUI liessen sich ausserdem ein Token setzen, ein neues erzeugen und LocalOnly abschalten. Wer das Token hatte, konnte das WebUI damit ueber unverschluesseltes HTTP ins Netz oeffnen, sich den Zugang verlegen oder sich selbst aussperren. Jetzt: - GET /api/settings/webui liefert Enabled, Port, LocalOnly und vom Token nur hasToken. - POST /api/settings/webui und /webui/generate-token antworten mit 403 und protokollieren den Versuch. Sie bleiben als ausdrueckliche Ablehnung stehen: Ohne eigene Route faengt die Fallback-Route den POST ab und antwortet mit 200, ein altes Skript hielte das fuer einen Erfolg. - Die WebUI-Einstellungsansicht zeigt den Zugang nur noch an. Gepflegt wird er im Desktop unter Einstellungen -> WebUI. WebUiSecretsTests zaehlt alle GET-Routen selbst auf und prueft jede Antwort gegen Kanarienwerte. Geprueft werden ApiKey, ApiSecret, ApiPassphrase und PrivateKey eines Kontos, Mullvad-Account, Alchemy-Key, Watchdog-Token, Lizenzschluessel und das WebUI-Token. Eine neue Route, die ein Konto oder die Server-Einstellungen serialisiert, faellt damit auf, ohne dass jemand an diesen Test denken muss. Gegen die alte Route schlug er fehl ("GET /api/settings/webui liefert ein Geheimnis aus"), jetzt ist er gruen. Ausserdem festgehalten: /api/accounts kennt nur GET. Polymarket-Konten bleiben im WebUI lesbar und nicht aenderbar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -585,54 +585,17 @@ async function loadSettings() {
|
||||
if (!res.ok) return;
|
||||
const opt = await res.json();
|
||||
|
||||
document.getElementById('cfgEnabled').checked = opt.enabled;
|
||||
document.getElementById('cfgPort').value = opt.port;
|
||||
document.getElementById('cfgLocalOnly').checked = opt.localOnly;
|
||||
document.getElementById('cfgToken').value = opt.token || '';
|
||||
document.getElementById('cfgEnabled').textContent = opt.enabled ? 'aktiv' : 'deaktiviert';
|
||||
document.getElementById('cfgPort').textContent = opt.port;
|
||||
document.getElementById('cfgBind').textContent = opt.localOnly
|
||||
? 'nur lokal (127.0.0.1)'
|
||||
: 'im Netzwerk – alle Schnittstellen, unverschlüsseltes HTTP';
|
||||
document.getElementById('cfgTokenStatus').textContent = opt.hasToken
|
||||
? 'gesetzt'
|
||||
: 'nicht gesetzt – das WebUI ist gesperrt';
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function saveSettings(e) {
|
||||
e.preventDefault();
|
||||
const enabled = document.getElementById('cfgEnabled').checked;
|
||||
const port = parseInt(document.getElementById('cfgPort').value, 10);
|
||||
const localOnly = document.getElementById('cfgLocalOnly').checked;
|
||||
const token = document.getElementById('cfgToken').value.trim();
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/settings/webui', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled, port, localOnly, authToken: token })
|
||||
});
|
||||
if (res.ok) {
|
||||
const msg = document.getElementById('settingsStatusMsg');
|
||||
msg.style.display = 'inline';
|
||||
setTimeout(() => { msg.style.display = 'none'; }, 3000);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function generateNewToken() {
|
||||
if (!confirm('Neues Zugangs-Token generieren? Alle bestehenden Sessions müssen sich danach neu anmelden.')) return;
|
||||
try {
|
||||
const res = await fetch('/api/settings/webui/generate-token', { method: 'POST' });
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
document.getElementById('cfgToken').value = data.token;
|
||||
alert('Neues Token generiert und in appsettings.Local.json gespeichert:\n\n' + data.token);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function copyToken() {
|
||||
const input = document.getElementById('cfgToken');
|
||||
if (!input.value) return;
|
||||
navigator.clipboard.writeText(input.value).then(() => {
|
||||
alert('Token in Zwischenablage kopiert!');
|
||||
});
|
||||
}
|
||||
|
||||
// Auth
|
||||
async function logout() {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user