8.6 KiB
8.6 KiB
Hilfe-Seite (In-Panel-Dokumentation) — Design
Goal: Eine eigene, bilinguale Hilfe-Seite im Panel, die alle Einstellungen und Abläufe erklärt — inklusive einer generischen Schritt-für-Schritt-Anleitung, wie man Clusev hinter einem externen Reverse-Proxy ("Proxy Manager") betreibt.
Architecture: Eine neue Full-Page-Livewire-Komponente unter /help mit linker Themen-Navigation (wie die Einstellungen). Kurze Chrome-Strings (Nav-Labels, Seitentitel) liegen in lang/{de,en}/help.php; der lange Fließtext liegt als Blade-Partials pro Sprache und wird nach aktiver Locale eingebunden. Keine neuen Tabellen, kein State außer dem gewählten Thema.
Tech Stack: Laravel 13, Livewire 3 (class-based), Tailwind v4 @theme-Tokens, bestehende Blade-Komponenten (x-panel, x-icon, …).
1. Platzierung & Navigation
- Komponente:
App\Livewire\Help\Index(Ordnerkarte R6), Viewresources/views/livewire/help/index.blade.php. - Route:
Route::get('/help', Help\Index::class)->name('help')in der onboarded-Gruppe vonroutes/web.php(gleiche Middleware-Gruppe wie Settings/System; hinter Auth +EnsureSecurityOnboarded). - Sidebar: neuer Eintrag „Hilfe" unten (nach „Version"), Icon z. B.
help-circle(Lucide, inline viax-icon). Label lokalisiert (__('shell.nav_help')). - Command-Palette: Eintrag in
resources/views/components/command-palette.blade.php($nav) + Chordg hinCMDK_GO(analog zu den bestehendeng <key>). - Layout:
layouts.app. - Route-Pfad englisch (R13), sichtbares Label deutsch/englisch (R9/R16).
2. Aufbau der Seite
- Öffentliche Property
public string $topic = 'overview';— der gewählte Themenschlüssel. mount()akzeptiert optional ein?topic-Query/Param, validiert gegen die bekannte Themenliste, fällt sonst aufoverviewzurück (kein Lockout, kein 404 für unbekannte Keys → Default).- Links: Themenliste (Buttons
wire:click="$set('topic', '<key>')", aktives Thema hervorgehoben — gleiche Optik wie die Settings-Tabs insettings/index.blade.php). - Rechts:
@include('livewire.help.content.'.app()->getLocale().'.'.$topic)mit Existenzprüfung; fehlt das Locale-Partial, Fallback aufde. - Responsive (R7): links Themen-Nav, die auf schmal über dem Inhalt als horizontale/aufklappbare Liste erscheint (gleiche Technik wie Settings-Tabs).
Themenliste (Reihenfolge)
| Key | Label (de) | Inhalt-Kurzfassung |
|---|---|---|
overview |
Überblick / Erste Schritte | Was Clusev ist, Erst-Login (admin@clusev.local / clusev, Zwangswechsel), Navigation, Bare-IP vs. Domain. |
domain-tls |
Domain, TLS & Reverse-Proxy | Drei Modi (Bare-IP, eingebautes TLS/Let's Encrypt, externer Proxy); Schritt-für-Schritt-Proxy-Anleitung; TRUSTED_PROXY_CIDR; Neustart-Boundary. |
security |
Sicherheit & 2FA | TOTP, Security-Keys (YubiKey), Backup-Codes; 2FA-Zugangspfad-Hinweis (s. u.); Passwort-Manager-Extension-Hinweis (Bitwarden/Kaspersky). |
updates |
Updates & Versionen | Auto-Check, „Jetzt aktualisieren"-Knopf, CLI sudo ./update.sh, was beim Update passiert (Build/Migrate). |
servers |
Server & SSH | Server hinzufügen, SSH-Credential-Vault, Hardening, SSH-Key-Provisioning. |
sessions |
Sitzungen & Mehrbenutzer | Aktive Sitzungen sehen/widerrufen, weitere Admins, Audit-Attribution. |
email |
E-Mail (SMTP) | SMTP für Passwort-Reset konfigurieren + Testmail. |
audit |
Audit-Log | Was protokolliert wird, Retention. |
recovery |
Konto-Wiederherstellung | Forgot-Password (E-Mail-Link / 2FA-Proof), Bare-IP-Recovery, clusev:reset-admin. |
3. Inhalt zweisprachig
- Chrome (kurz):
lang/de/help.php+lang/en/help.php— Seitentitel, Eyebrow, Untertitel, die Themen-Labels (topic_overview,topic_domain_tls, …),nav_helpinshell.php. - Lange Texte: Blade-Partials je Sprache:
resources/views/livewire/help/content/de/<topic>.blade.phpresources/views/livewire/help/content/en/<topic>.blade.php- Reines Markup mit Überschriften, Absätzen, Listen und Code-Blöcken (für Proxy-/CLI-Beispiele). Nur
@theme-Token-Utilities (R3), keine Inline-Styles (R4), kein Emoji (R9). Native Tokens (X-Forwarded-Proto,TRUSTED_PROXY_CIDR,sudo ./update.sh) bleiben alsfont-mono.
- Locale-Auflösung im View über
app()->getLocale(); Fallbackde, wenn das EN-Partial (noch) fehlt — so bricht nichts, falls eine Sprache nachgezogen wird.
4. Schlüssel-Inhalte (verbindlich)
4a. Proxy-Anleitung (in domain-tls) — generisch, OHNE Produktnamen
- Im Panel: System → Domain & TLS → Domain eintragen → TLS-Terminierung „Externer Reverse-Proxy" → speichern → Stack neu starten (Knopf).
- Im Proxy Manager: neuen Host/Eintrag anlegen:
- Eingehende Domain =
panel.<deine-domain> - Ziel/Backend =
http://<Clusev-Server-IP>:80(HTTP, nicht HTTPS) - Host-Header durchreichen und
X-Forwarded-Proto: httpssetzen - WebSocket-Weiterleitung aktivieren (für Realtime: Pfade
/app/*und/apps/*)
- Eingehende Domain =
- In der
.env(Clusev-Server):TRUSTED_PROXY_CIDRauf die Adresse/CIDR des Proxys setzen → korrekteSecure-Cookies + echte Besucher-IP im Audit-Log; danachsudo ./update.sh(oder Caddy-Neustart). - Firewall: den HTTP-Port (80) des Clusev-Servers so absichern, dass er nur vom Proxy erreichbar ist.
- Hinweis: In diesem Modus stellt Clusev kein eigenes Zertifikat aus — TLS kommt vom Proxy.
4b. 2FA-Zugangspfade (in security, Querverweis in recovery)
- Security-Key (YubiKey) funktioniert nur über die HTTPS-Domain (WebAuthn braucht einen sicheren Kontext + die Domain als rpId). Über die Domain wird die Security-Key-Anmeldung angeboten und funktioniert.
- Über den Bare-IP-/HTTP-Recovery-Pfad (
http://<Server-IP>) lässt sich nicht per Security-Key anmelden — dort muss ein Backup-Code verwendet werden. - TOTP / „Google Authenticator" funktioniert überall — auch über Bare-IP/HTTP. Wer TOTP nutzt, braucht für den Bare-IP-Pfad keinen Backup-Code.
- Praxis-Empfehlung: Wer ausschließlich einen Security-Key nutzt, sollte die Backup-Codes aufbewahren (einziger Weg über den Bare-IP-Recovery-Pfad). Wer zusätzlich/alternativ TOTP hat, ist auf allen Pfaden abgedeckt.
4c. Passwort-Manager-Extensions (in security)
- Browser-Erweiterungen wie Bitwarden/Kaspersky können die Security-Key-Registrierung abfangen („Passkey speichern"). Clusev signalisiert korrekt einen Hardware-Key (cross-platform, non-resident,
hints: ['security-key']), aber Erweiterungen lassen sich seitenseitig nicht abschalten. Lösung: die Passkey-Übernahme der Erweiterung für die Seite deaktivieren, oder die Registrierung in einem Browser/Fenster ohne diese Erweiterung durchführen (z. B. privates Fenster).
5. Komponenten-Logik (klein halten)
App\Livewire\Help\Index:
public string $topicmount(?string $topic = null): validiert gegenself::TOPICS(Liste der Keys), Defaultoverview.render(): übergibt die Themenliste (Keys + lokalisierte Labels) + den aktiven$topic; die View bindet das passende Locale-Partial ein.- Keine Persistenz, keine externen Aufrufe, keine Berechnungen — reine Anzeige.
6. Dateistruktur
- Neu:
app/Livewire/Help/Index.php - Neu:
resources/views/livewire/help/index.blade.php - Neu:
resources/views/livewire/help/content/{de,en}/{overview,domain-tls,security,updates,servers,sessions,email,audit,recovery}.blade.php(18 Partials) - Neu:
lang/de/help.php,lang/en/help.php - Ändern:
routes/web.php(Route),resources/views/partials/sidebar.blade.php(Nav-Eintrag),lang/{de,en}/shell.php(nav_help),resources/views/components/command-palette.blade.php+CMDK_GO(cmdk-Eintrag +g h).
7. Test & Verifizierung
- Livewire-Test (
tests/Feature/HelpPageTest.php): Default-Thema =overview;$set('topic', 'domain-tls')rendert den Proxy-Abschnitt (assertSee eines bekannten Strings, z. B.X-Forwarded-Proto); unbekannter Topic-Key fällt aufoverviewzurück; Seite lädt für einen eingeloggten Nutzer (HTTP 200). - R12 Browser (auf der Domain):
/helplädt mit HTTP 200, keine Konsolenfehler, keine geleakten{{ }}/group.key-Tokens; Themenwechsel funktioniert; DE/EN-Umschalter zeigt den jeweiligen Inhalt; 375/768/1280. - R15 Codex über den Diff.
8. Bewusst NICHT enthalten (YAGNI)
- Keine Volltextsuche in der Hilfe (Themen-Nav reicht).
- Keine kontextuellen „?"-Sprungmarken aus jeder Einstellung (kann später kommen).
- Keine aus Markdown gerenderte Doku-Engine — statische Blade-Partials genügen.
- Keine Versionierung/Changelog der Hilfe-Inhalte (das CHANGELOG deckt das ab).