From d1fb93ffe30f72990db7bd4050701d6f5d56bfff Mon Sep 17 00:00:00 2001 From: boban Date: Fri, 19 Jun 2026 22:20:58 +0200 Subject: [PATCH] feat(help): remaining topics (updates, servers, sessions, email, audit, recovery) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../livewire/help/content/de/audit.blade.php | 15 ++++++++++++ .../livewire/help/content/de/email.blade.php | 15 ++++++++++++ .../help/content/de/recovery.blade.php | 24 +++++++++++++++++++ .../help/content/de/servers.blade.php | 17 +++++++++++++ .../help/content/de/sessions.blade.php | 16 +++++++++++++ .../help/content/de/updates.blade.php | 16 +++++++++++++ .../livewire/help/content/en/audit.blade.php | 15 ++++++++++++ .../livewire/help/content/en/email.blade.php | 15 ++++++++++++ .../help/content/en/recovery.blade.php | 24 +++++++++++++++++++ .../help/content/en/servers.blade.php | 17 +++++++++++++ .../help/content/en/sessions.blade.php | 15 ++++++++++++ .../help/content/en/updates.blade.php | 16 +++++++++++++ tests/Feature/HelpPageTest.php | 20 ++++++++++++++++ 13 files changed, 225 insertions(+) create mode 100644 resources/views/livewire/help/content/de/audit.blade.php create mode 100644 resources/views/livewire/help/content/de/email.blade.php create mode 100644 resources/views/livewire/help/content/de/recovery.blade.php create mode 100644 resources/views/livewire/help/content/de/servers.blade.php create mode 100644 resources/views/livewire/help/content/de/sessions.blade.php create mode 100644 resources/views/livewire/help/content/de/updates.blade.php create mode 100644 resources/views/livewire/help/content/en/audit.blade.php create mode 100644 resources/views/livewire/help/content/en/email.blade.php create mode 100644 resources/views/livewire/help/content/en/recovery.blade.php create mode 100644 resources/views/livewire/help/content/en/servers.blade.php create mode 100644 resources/views/livewire/help/content/en/sessions.blade.php create mode 100644 resources/views/livewire/help/content/en/updates.blade.php diff --git a/resources/views/livewire/help/content/de/audit.blade.php b/resources/views/livewire/help/content/de/audit.blade.php new file mode 100644 index 0000000..a51b621 --- /dev/null +++ b/resources/views/livewire/help/content/de/audit.blade.php @@ -0,0 +1,15 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; +@endphp + +
+

Audit-Log

+

Das Audit-Log protokolliert sicherheits- und konfigurationsrelevante Aktionen — wer, wann, was, von welcher IP. So bleibt jede Änderung nachvollziehbar und einem Benutzer zugeordnet.

+
    +
  • Erfasst u. a.: Logins, 2FA-Änderungen, Domain-/TLS-Änderungen, Update-Anstöße, Server-Hardening und SSH-Aktionen.
  • +
  • Aufbewahrung: die Vorhaltedauer lässt sich konfigurieren; ältere Einträge werden danach automatisch bereinigt.
  • +
+

Hinweis: Hinter einem externen Proxy zeigt das Audit-Log nur dann die echte Besucher-IP, wenn TRUSTED_PROXY_CIDR gesetzt ist (siehe „Domain, TLS & Reverse-Proxy").

+
diff --git a/resources/views/livewire/help/content/de/email.blade.php b/resources/views/livewire/help/content/de/email.blade.php new file mode 100644 index 0000000..3f13a25 --- /dev/null +++ b/resources/views/livewire/help/content/de/email.blade.php @@ -0,0 +1,15 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; +@endphp + +
+

E-Mail (SMTP)

+

Unter Einstellungen → E-Mail hinterlegst du einen SMTP-Server. Damit kann das Panel E-Mails versenden — vor allem den Passwort-Reset-Link über die „Passwort vergessen"-Seite.

+
    +
  • Host, Port, Verschlüsselung, Benutzer/Passwort und die Absenderadresse eintragen.
  • +
  • Mit „Testmail senden" prüfst du die Konfiguration sofort.
  • +
+

Ohne SMTP funktioniert die Wiederherstellung weiterhin über den 2FA-Nachweis (E-Mail + TOTP oder Backup-Code) oder über die Host-Konsole — siehe „Konto-Wiederherstellung".

+
diff --git a/resources/views/livewire/help/content/de/recovery.blade.php b/resources/views/livewire/help/content/de/recovery.blade.php new file mode 100644 index 0000000..34c74ea --- /dev/null +++ b/resources/views/livewire/help/content/de/recovery.blade.php @@ -0,0 +1,24 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; + $pre = 'overflow-x-auto rounded-md border border-line bg-inset p-3 font-mono text-[11px] leading-relaxed text-ink-2'; +@endphp + +
+

Konto-Wiederherstellung

+

Mehrere Wege, falls du nicht mehr reinkommst — vom bequemsten zum letzten Ausweg:

+
    +
  • Passwort vergessen: die „Passwort vergessen"-Seite bietet einen E-Mail-Reset-Link (wenn SMTP konfiguriert ist, gültig 15 Min) oder einen 2FA-Nachweis-Reset (E-Mail + TOTP oder Backup-Code → neues Passwort).
  • +
  • Bare-IP-Zugang: http://<Server-IP> bleibt immer erreichbar — falls die Domain (DNS/Zertifikat/Proxy) gerade nicht geht. Beachte: über diesen Weg kein Security-Key, nur TOTP oder Backup-Code (siehe „Sicherheit & 2FA").
  • +
+
+ +
+

Komplett ausgesperrt (letzter Ausweg)

+

Passwort und 2FA verloren, kein SMTP? Vom Host wiederherstellen — per SSH auf den Server einloggen und im Projektverzeichnis ausführen:

+
cd clusev
+docker compose -f docker-compose.prod.yml exec app php artisan clusev:reset-admin
+

clusev:reset-admin entfernt den zweiten Faktor, sodass du beim nächsten Login ein neues Passwort setzen kannst.

+
diff --git a/resources/views/livewire/help/content/de/servers.blade.php b/resources/views/livewire/help/content/de/servers.blade.php new file mode 100644 index 0000000..a9d4b2c --- /dev/null +++ b/resources/views/livewire/help/content/de/servers.blade.php @@ -0,0 +1,17 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; +@endphp + +
+

Server & SSH

+

Clusev verwaltet die Flotte agentenlos über SSH — auf den Zielservern wird nichts installiert. Du fügst Server mit Host/IP, Port und Zugangsdaten hinzu; im Dashboard und auf der Server-Detailseite siehst du Metriken, Dienste, Dateien und mehr.

+
    +
  • Zugangsdaten-Tresor: SSH-Passwörter/Schlüssel werden verschlüsselt gespeichert (App-Key), nie im Klartext.
  • +
  • Hardening: auf der Server-Detailseite — UFW/firewalld-Regeln, fail2ban-Status, und ein Ein-Klick-Ablauf „SSH-Schlüssel erzeugen und Passwort-Login sicher abschalten".
  • +
  • SSH-Key-Provisioning: erzeugt ein Schlüsselpaar, hinterlegt den öffentlichen Schlüssel auf dem Zielserver und stellt die Verbindung danach auf Key-Auth um.
  • +
+

Jede Aktion über SSH wird im Audit-Log dem ausführenden Benutzer zugeordnet.

+
diff --git a/resources/views/livewire/help/content/de/sessions.blade.php b/resources/views/livewire/help/content/de/sessions.blade.php new file mode 100644 index 0000000..0076ada --- /dev/null +++ b/resources/views/livewire/help/content/de/sessions.blade.php @@ -0,0 +1,16 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; +@endphp + +
+

Sitzungen

+

Unter Einstellungen → Sitzungen siehst du alle aktiven Sitzungen deines Kontos (Gerät, Browser, IP, letzte Aktivität). Du kannst eine einzelne Sitzung beenden oder alle anderen außer der aktuellen abmelden.

+

Ein Passwortwechsel macht jede andere Sitzung automatisch ungültig — die aktive Sitzung bleibt bestehen.

+
+ +
+

Mehrere Administratoren

+

Unter Einstellungen → Benutzer legst du weitere Admin-Konten an. Jede Aktion wird im Audit-Log dem jeweiligen Benutzer zugeordnet, und du kannst aktive Sitzungen pro Gerät, pro Benutzer oder global widerrufen.

+
diff --git a/resources/views/livewire/help/content/de/updates.blade.php b/resources/views/livewire/help/content/de/updates.blade.php new file mode 100644 index 0000000..48ab3dd --- /dev/null +++ b/resources/views/livewire/help/content/de/updates.blade.php @@ -0,0 +1,16 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; +@endphp + +
+

Updates

+

Unter Version & Releases prüft das Panel beim Öffnen automatisch, ob eine neuere Version im Kanal verfügbar ist (Vergleich mit dem neuesten getaggten Release). Ist eines verfügbar, erscheint der Knopf „Jetzt aktualisieren".

+
    +
  • Per Knopf: „Jetzt aktualisieren" anstoßen. Das Panel ist während des Neubaus ein bis zwei Minuten kurz nicht erreichbar; danach springt die Anzeige selbst auf „Aktuell".
  • +
  • Per SSH: auf dem Host cd clusev und sudo ./update.sh ausführen.
  • +
+

Beim Update wird das Image neu gebaut (inkl. npm run build für CSS/JS) und es werden Datenbank-Migrationen angewendet. Stil-Änderungen und Schema-Updates greifen also automatisch. Secrets und die konfigurierte Domain bleiben erhalten.

+
diff --git a/resources/views/livewire/help/content/en/audit.blade.php b/resources/views/livewire/help/content/en/audit.blade.php new file mode 100644 index 0000000..18d712f --- /dev/null +++ b/resources/views/livewire/help/content/en/audit.blade.php @@ -0,0 +1,15 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; +@endphp + +
+

Audit log

+

The Audit log records security- and configuration-relevant actions — who, when, what, from which IP. Every change stays traceable and attributed to a user.

+
    +
  • Captures, among others: logins, 2FA changes, domain/TLS changes, update triggers, server hardening and SSH actions.
  • +
  • Retention: the keep duration is configurable; older entries are pruned automatically afterwards.
  • +
+

Note: behind an external proxy the audit log shows the real visitor IP only when TRUSTED_PROXY_CIDR is set (see "Domain, TLS & reverse proxy").

+
diff --git a/resources/views/livewire/help/content/en/email.blade.php b/resources/views/livewire/help/content/en/email.blade.php new file mode 100644 index 0000000..0f9398b --- /dev/null +++ b/resources/views/livewire/help/content/en/email.blade.php @@ -0,0 +1,15 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; +@endphp + +
+

Email (SMTP)

+

Under Settings → Email you configure an SMTP server. This lets the panel send e-mail — primarily the password-reset link from the "Forgot password" screen.

+
    +
  • Enter host, port, encryption, username/password and the sender address.
  • +
  • Use "Send test email" to verify the configuration right away.
  • +
+

Without SMTP, recovery still works via the 2FA proof (e-mail + TOTP or a backup code) or via the host console — see "Account recovery".

+
diff --git a/resources/views/livewire/help/content/en/recovery.blade.php b/resources/views/livewire/help/content/en/recovery.blade.php new file mode 100644 index 0000000..1491d19 --- /dev/null +++ b/resources/views/livewire/help/content/en/recovery.blade.php @@ -0,0 +1,24 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; + $pre = 'overflow-x-auto rounded-md border border-line bg-inset p-3 font-mono text-[11px] leading-relaxed text-ink-2'; +@endphp + +
+

Account recovery

+

Several ways back in if you are locked out — from most convenient to last resort:

+
    +
  • Forgot password: the "Forgot password" screen offers an e-mail reset link (when SMTP is configured, valid 15 min) or a 2FA-proof reset (e-mail + TOTP or a backup code → new password).
  • +
  • Bare-IP access: http://<server-ip> always stays reachable — in case the domain (DNS/cert/proxy) is currently down. Note: no security key over this path, only TOTP or a backup code (see "Security & 2FA").
  • +
+
+ +
+

Completely locked out (last resort)

+

Lost password and 2FA, no SMTP? Recover from the host — SSH into the server and run in the project directory:

+
cd clusev
+docker compose -f docker-compose.prod.yml exec app php artisan clusev:reset-admin
+

clusev:reset-admin clears the second factor so you can set a new password on the next login.

+
diff --git a/resources/views/livewire/help/content/en/servers.blade.php b/resources/views/livewire/help/content/en/servers.blade.php new file mode 100644 index 0000000..15b41d4 --- /dev/null +++ b/resources/views/livewire/help/content/en/servers.blade.php @@ -0,0 +1,17 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; +@endphp + +
+

Servers & SSH

+

Clusev manages the fleet agentless over SSH — nothing is installed on the target servers. You add servers with host/IP, port and credentials; the dashboard and the server detail page show metrics, services, files and more.

+
    +
  • Credential vault: SSH passwords/keys are stored encrypted (app key), never in plaintext.
  • +
  • Hardening: on the server detail page — UFW/firewalld rules, fail2ban status, and a one-click "generate an SSH key and safely disable password login" flow.
  • +
  • SSH key provisioning: generates a key pair, installs the public key on the target server and switches the connection to key auth afterwards.
  • +
+

Every action over SSH is attributed to the acting user in the audit log.

+
diff --git a/resources/views/livewire/help/content/en/sessions.blade.php b/resources/views/livewire/help/content/en/sessions.blade.php new file mode 100644 index 0000000..9286c89 --- /dev/null +++ b/resources/views/livewire/help/content/en/sessions.blade.php @@ -0,0 +1,15 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; +@endphp + +
+

Sessions (Sitzungen)

+

Under Settings → Sessions you see all active sessions of your account (device, browser, IP, last activity). You can end a single session or sign out all others except the current one.

+

A password change automatically invalidates every other session — the active session stays.

+
+ +
+

Multiple administrators

+

Under Settings → Users you add further admin accounts. Every action is attributed to the respective user in the audit log, and you can revoke active sessions per device, per user, or globally.

+
diff --git a/resources/views/livewire/help/content/en/updates.blade.php b/resources/views/livewire/help/content/en/updates.blade.php new file mode 100644 index 0000000..663fc39 --- /dev/null +++ b/resources/views/livewire/help/content/en/updates.blade.php @@ -0,0 +1,16 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; +@endphp + +
+

Updates

+

Under Version & Releases the panel checks on open whether a newer release is available in the channel (compared against the newest tagged release). When one is available, the "Update now" button appears.

+
    +
  • From the button: trigger "Update now". The panel is briefly unreachable for a minute or two during the rebuild; afterwards the card flips to "Current" on its own.
  • +
  • Over SSH: on the host run cd clusev and sudo ./update.sh.
  • +
+

An update rebuilds the image (including npm run build for CSS/JS) and applies database migrations. So style changes and schema updates take effect automatically. Secrets and the configured domain are preserved.

+
diff --git a/tests/Feature/HelpPageTest.php b/tests/Feature/HelpPageTest.php index 9c06098..36b58bd 100644 --- a/tests/Feature/HelpPageTest.php +++ b/tests/Feature/HelpPageTest.php @@ -6,6 +6,7 @@ use App\Livewire\Help\Index; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Livewire\Livewire; +use PHPUnit\Framework\Attributes\DataProvider; use Tests\TestCase; class HelpPageTest extends TestCase @@ -55,4 +56,23 @@ class HelpPageTest extends TestCase ->assertSee('Backup-Code') ->assertSee('TOTP'); } + + #[DataProvider('topicProvider')] + public function test_each_topic_renders_its_own_partial(string $topic, string $marker): void + { + $this->actAsAdmin(); + Livewire::test(Index::class)->set('topic', $topic)->assertSee($marker); + } + + public static function topicProvider(): array + { + return [ + ['updates', 'update.sh'], + ['servers', 'SSH'], + ['sessions', 'Sitzung'], + ['email', 'SMTP'], + ['audit', 'Audit'], + ['recovery', 'clusev:reset-admin'], + ]; + } }