Commit Graph

312 Commits (190b627fd4fd2fa706b4e7f66de9074ceda5038d)

Author SHA1 Message Date
boban 190b627fd4 Fix: git-Ops als root, fix_permissions immer im Exit-Trap
- git_safe: chown -R APP_DIR immer (kein bedingter Check)
- git_dirty_check + alle git fetch/checkout: als root → kein
  "permission denied" / "dubious ownership" mehr
- _cleanup: fix_permissions() immer aufrufen (auch bei Fehler-Abbruch)
  → kein 404/500 nach fehlgeschlagenem Update mehr

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:30:57 +02:00
boban a119686bfa Fix: git_safe() korrigiert Eigentümer automatisch bei User-Wechsel
chown -R nur wenn APP_DIR nicht dem APP_USER gehört, sonst nur .git.
Verhindert "Your local changes would be overwritten" nach root-Läufen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:25:32 +02:00
boban b107e9a580 Feature: ClamAV-Verwaltung in Sicherheit-Sidebar
- Neue Seite /security/clamav: Status, Aktivieren/Deaktivieren,
  Signatur-Update, RAM-Hinweis, Info-Box
- Optionale Dienste (ClamAV) im Dashboard nur sichtbar wenn aktiv
- mailwolt-clamav sbin-Wrapper + sudoers-Regel in ensure_system

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:21:37 +02:00
boban a7f6d8e242 Add: ClamAV in Dashboard-Dienste-Liste
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:15:44 +02:00
boban 3e12d7fd70 Fix: Dashboard zeigt nur die 8 Kern-Dienste (woltguard.dashboard-Liste)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:11:44 +02:00
boban c16315711d Fix: git_safe() system-level safe.directory + chown .git für APP_USER-Wechsel
Nach APP_USER-Wechsel von mailwolt→www-data schlägt git mit "dubious
ownership" fehl. git config --system schreibt /etc/gitconfig (root),
gilt für alle User. Zusätzlich .git vollständig neu besitzen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:07:58 +02:00
boban 3c6325db32 Fix: Dashboard zeigt Dienste auch ohne Monit (Fallback auf systemd/tcp-Probes)
- loadServices() liest Monit-Cache, fällt zurück auf woltguard.php Karten
  mit direkten systemd/tcp-Probes wenn Cache leer ist
- Monit als Dienst in woltguard.php ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 19:02:51 +02:00
boban a51f271069 Fix: APP_USER default auf www-data – kein 404 mehr nach Update
Artisan-Befehle (config:cache, route:cache, optimize:clear) liefen als
'mailwolt'-User, PHP-FPM läuft als 'www-data' → Cache-Dateien nicht
lesbar → 404 nach jedem Update. Default auf www-data gesetzt damit
beide User übereinstimmen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:55:56 +02:00
boban e0128312cf Fix: fix_permissions baut Cache als www-data + setgid auf cache/storage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:51:30 +02:00
boban c834b5f85d Fix: fix_permissions läuft nach jedem Update-Pfad (kein 404 mehr nach Update)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:46:33 +02:00
boban 7454638506 Fix: bootstrap/cache Rechte nach artisan-Befehlen für www-data freigeben
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:43:38 +02:00
boban f49b92074e Fix: ensure_system installiert mailwolt-ws (Reverb) als systemd-Service
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:41:23 +02:00
boban 29566499f9 Fix: artisan cache-Befehle in apply-domains als App-User statt root
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:37:49 +02:00
boban 81f1c9512a Fix: apply-domains mit Backup/Restore + robuster Cert-Erkennung
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:27:36 +02:00
boban 1e053c2bb6 Fix: nginx /ws/ Reverb-Proxy in apply-domains + health:probe-disk --ttl entfernt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:20:03 +02:00
boban 2369a29161 Fix: migrate-env-reverb prüft auch REVERB_PORT beim Skip-Check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:15:56 +02:00
boban 26eb3abdcd Fix: Scheme-Erkennung via APP_URL + nginx-Config statt letsencrypt-Pfad
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:13:26 +02:00
boban 4fc31726be Fix: Cert-Prüfung via renewal/-Verzeichnis (www-data-lesbar) statt live/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:10:32 +02:00
boban 8fa28a4d84 Fix: migrate-env-reverb liest Domain aus DB-Setting ui_domain als Fallback
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 18:04:52 +02:00
boban 60ebd0ed16 Fix: mailwolt:migrate-env-reverb Command + Update führt Migration immer aus
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 11:01:57 +02:00
boban 093b5a9eea Fix: Update migriert REVERB .env-Werte automatisch auf Domain-Basis
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:58:06 +02:00
boban becc1bd737 Fix: apply-domains korrigiert alle VITE_REVERB_* und REVERB_* .env-Werte
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:55:40 +02:00
boban b59e4c53b4 Fix: mailwolt-apply-domains aktualisiert APP_HOST in .env und baut Assets neu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:50:04 +02:00
boban 29ef2b6a2c Fix: CheckUpdates liest Version-Datei vor git-describe (APP_ENV=local Bug)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:30:07 +02:00
boban 1b79454df5 Fix: Blade-Syntaxfehler in SSL-Seite (@if/@elseif/@endif inline)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:22:44 +02:00
boban 38d6fdba6f Fix: SSL-Seite zweispaltig (Tabelle links, Einrichten rechts) + Settings kompakt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:20:28 +02:00
boban 996c9c19fe Fix: Laravel Scheduler cron + sudoers für --check-only + CheckUpdates Fallback
- ensure_system() installiert /etc/cron.d/mailwolt für schedule:run
- sudoers: www-data darf mailwolt-update --check-only aufrufen
- CheckUpdates: if/elseif → echter Fallback auf mailwolt-fetch-tags

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:13:05 +02:00
boban 871d69cc2d Fix: Korrekte Route-Namen ui.security.ssl + ui.system.settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:09:25 +02:00
boban f12c412bbe Fix: Route-Name security.ssl + SSL-Seite zweispaltig
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:07:11 +02:00
boban 7f56926b70 Refactor: SSL-Verwaltung nach Security/SSL verschoben
- Zertifikate einrichten/erneuern nur noch unter Sicherheit → SSL/TLS
- SSL-Seite: Provisioning mit Fortschritt, Ablaufdatum + Tage in Tabelle
- Einstellungen: nur noch read-only Status + Link zu SSL-Seite

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 10:01:58 +02:00
boban 904d60ed2b Fix: 503 fetch-Interceptor + Auto-Update-Polling + SSL-Banner prüft echte Certs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 09:26:20 +02:00
boban 8fd9fccc70 Fix: Livewire 503 löst echten Page-Reload aus statt Modal-Rendering
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 09:17:00 +02:00
boban 227c623578 Feat: Wartungsseite beim Update statt roher 503
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 09:13:46 +02:00
boban d60d228012 Fix: mx-Domain bekommt LE-Zertifikat + Postfix/Dovecot werden konfiguriert
- mailwolt-apply-domains: MAIL_HOST wird in ACME-Challenge-Block aufgenommen,
  certbot wird auch für die Mail-Domain ausgeführt, Postfix + Dovecot erhalten
  danach automatisch das neue Zertifikat
- SslCertificatesTable: certbot-Ausgabe korrekt geparst (Einrückung mit Leerzeichen)
- settings-form: "kein Zertifikat nötig" entfernt (Mail-Domain braucht Zertifikat)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 09:04:02 +02:00
boban 96e2b4d5ab Fix: .git/objects-Rechte werden automatisch repariert (root-Läufe)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:57:29 +02:00
boban 5ec7084cbd Fix: mailwolt-update schreibt jetzt alle Ausgaben in Log-Datei
exec > >(tee -a LOG_FILE) leitet stdout an tee weiter:
- CLI: Ausgabe weiterhin im Terminal + in Log-Datei
- UI (nohup >/dev/null): stdout geht nach /dev/null aber tee
  schreibt trotzdem in die Log-Datei

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:54:09 +02:00
boban 240c672198 Fix: Update-UI zeigt alte Version / schließt sofort ab (Race Condition)
Problem: state-Datei vom letzten Update zeigte noch 'done'. pollUpdate()
las das direkt nach runUpdate() als "Update fertig" — bevor der neue
Prozess überhaupt startete. displayCurrent war dann noch die alte Version.

Fix:
- runUpdate() setzt state='starting' und löscht rc VOR dem Shell-Aufruf
- runUpdate() setzt rc=null, lowState='starting', postActionsDone=false zurück
- refreshLowLevelState(): Kommentar klärt dass 'starting' als running gilt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:50:44 +02:00
boban bd7bb50a52 Fix: SSL-Cert-Status robuster + Provisioning-State nach Reload erhalten
- loadSslStatus(): clearstatcache() + renewal-Conf als primärer Existenzcheck
  (renewal/ ist immer 755, zuverlässiger als is_dir auf live/ das 750 sein kann)
  + /usr/bin/openssl (voller Pfad für sudoers-Matching)
- restoreSslProvisioningState(): stellt letzten Provisioning-Zustand aus
  State-Dateien wieder her, so dass Status nach Page-Reload sichtbar bleibt
- Button zeigt nach Abschluss "Erneut einrichten" statt disabled zu bleiben

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:44:08 +02:00
boban 17ed5b18d9 Fix: ensure_system() läuft bei JEDER mailwolt-update Ausführung
Scripts, Sudoers-Regeln und sbin-Binaries werden jetzt immer
aktualisiert — auch wenn kein Update verfügbar ist. Damit entfällt
das manuelle Nachtragen von Sudoers-Regeln nach neuen Releases.

ensure_system() wird aufgerufen:
- Vor jedem "bereits aktuell"-Exit (tags + branch mode)
- Am Ende jedes erfolgreichen Updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:34:09 +02:00
boban 096e983313 Fix: SSL-Cert-Status zeigt 'Fehlt' obwohl Cert vorhanden
Problem: /etc/letsencrypt/archive/ ist chmod 700 (root only).
file_exists() auf Symlinks in live/ schlägt fehl weil Symlink-Ziel
in archive/ nicht lesbar ist. is_dir() auf live/domain/ funktioniert
da das Verzeichnis selbst 755 ist.

- SettingsForm: file_exists() → is_dir() für Existenzcheck
- SettingsForm: openssl-Aufruf via sudo -n (archive/ ist root-only)
- installer.sh + update.sh: sudoers-Regel für openssl auf LE-Cert-Pfade
  (www-data darf nur exakt diesen openssl-Aufruf, keine anderen Pfade)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:27:49 +02:00
boban 880b99f1e0 Fix: git_dirty_check bricht nicht mehr mit rc=2 ab
Auf Produktivservern gibt es fast immer kleine Änderungen (App-generierte
Dateien, Setup-Änderungen). Statt Abbruch: tracked Dateien via git reset
--hard zurücksetzen, untracked Nicht-Systemdateien via git clean entfernen.
.env, storage/ und node_modules/ werden dabei bewusst ausgespart.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:21:45 +02:00
boban 2688b2528b Fix: artisan down ohne --render=errors.503 (View existiert nicht)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:16:49 +02:00
boban ae3b1e6b14 Fix: Update-Check Bootstrap — --check-only Flag in mailwolt-update
Problem: Henne-Ei-Situation — alte Server haben alte CheckUpdates.php die
  git fetch als www-data aufruft (schlägt wegen fehlender Credentials fehl).
  Neue mailwolt-fetch-tags Helper sind noch nicht deployed.

Lösung:
- scripts/update.sh: --check-only Flag — ruft nur git ls-remote als App-User
  auf, schreibt version_remote, beendet sich sofort (kein Update)
- update.sh: schreibt version_remote auch nach normalem Tag-Fetch (damit es
  nach manuellen Updates aktuell bleibt)
- CheckUpdates.php: sichere Fallback-Kette:
  1. mailwolt-update --check-only (nur wenn Skript das Flag kennt — kein
     versehentliches Triggern auf alten Servern)
  2. mailwolt-fetch-tags (ab v1.1.268)
  3. lokale git tags (letzter Fallback)
  + version_remote wird nur verwendet wenn < 2h alt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:13:32 +02:00
boban f740ffc753 Feature: Dedizierter SSL-Abschnitt in Einstellungen mit Echtzeit-Fortschritt
- Neuer Abschnitt "SSL-Zertifikate" in den Einstellungen:
  · Zeigt pro Domain (UI, Webmail, Mailserver) ob LE-Cert vorhanden ist,
    Ablaufdatum und Status (OK / fehlt / läuft ab / abgelaufen)
  · Button "Let's Encrypt Zertifikate einrichten" startet Provisioning
    im Hintergrund (nohup, non-blocking)
  · Live-Fortschrittsanzeige per wire:poll.2s mit Status-Icons pro Domain
    (pending → running → done/error/skip)
- saveDomains() ruft apply-domains jetzt ohne certbot auf (--ssl-auto 0) —
  Domains speichern und SSL einrichten sind damit getrennte Aktionen
- loadSslStatus() liest Certbot-Zertifikat-Info direkt aus openssl
- spin-Keyframe für Spinner-Animation in app.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 08:04:58 +02:00
boban c4a2f33293 Fix: Update-Check via mailwolt-fetch-tags + Fehlerdetails in Settings-Toast
- Neu: scripts/mailwolt-fetch-tags ruft git ls-remote als App-User auf (hat Credentials),
  schreibt neuesten Tag nach /var/lib/mailwolt/version_remote
- CheckUpdates.php nutzt jetzt sudo mailwolt-fetch-tags statt direktem git fetch als www-data
  (www-data hat keine Git-Credentials für private Repos)
- SettingsForm.php zeigt tatsächliche Fehlerzeilen ([!], error, failed) im Toast statt
  generischer "fehlgeschlagen"-Meldung
- installer.sh + update.sh installieren mailwolt-fetch-tags nach /usr/local/sbin/
- update.sh trägt mailwolt-fetch-tags automatisch in sudoers nach (Upgrade-Pfad)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 07:46:18 +02:00
boban 831f656b54 Fix: mailwolt-apply-domains — dig-Fallback + fertig-Echo
- certbot_safe(): dig ist auf Ubuntu nicht immer installiert (kein dnsutils).
  Mit set -euo pipefail crashte die Funktion lautlos → certbot nie ausgeführt.
  Fallback auf getent ahostsv6 wenn dig fehlt; Zuweisung mit || has_aaaa=""
  damit set -e nicht greift falls beide Befehle scheitern.

- echo "mailwolt-apply-domains fertig" am Ende: SettingsForm.php prüft ob
  "fertig" im Output steht um ssl_configured=1 zu setzen — ohne diesen Echo
  wurde SSL nie als konfiguriert markiert, selbst wenn Zertifikate vorhanden.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 07:26:44 +02:00
boban 5511498200 Refactor: update.sh nach scripts/ verschoben
Alle Scripts zentral unter scripts/:
- scripts/update.sh (war update.sh)
- scripts/mailwolt-apply-domains

installer.sh und update.sh selbst auf neuen Pfad angepasst.

Update laufender Server (einmalig):
  sudo install -m 755 /var/www/mailwolt/scripts/update.sh /usr/local/sbin/mailwolt-update
  sudo install -m 755 /var/www/mailwolt/scripts/mailwolt-apply-domains /usr/local/sbin/mailwolt-apply-domains

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 07:04:37 +02:00
boban 3b0ebce1df Fix: update.sh aktualisiert sich selbst + scripts/ immer am Ende
Beide Scripts werden jetzt bei jedem erfolgreichen Update eingespielt,
unabhängig von CHANGED_FILES — löst den Bootstrap-Problem wo die alte
mailwolt-update Version die neue Logik nicht kannte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 06:58:15 +02:00
boban 22eee053a3 Fix: update.sh aktualisiert scripts/ automatisch nach git pull
Bei Änderungen unter scripts/ wird mailwolt-apply-domains automatisch
nach /usr/local/sbin/ kopiert — kein manueller Eingriff mehr nötig.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 18:23:15 +02:00
boban 05cc53ef49 Refactor: mailwolt-apply-domains als eigenständige Datei im Repo
Script aus installer.sh-Heredoc in scripts/mailwolt-apply-domains ausgelagert.
installer.sh kopiert es jetzt via install -m 755 statt Heredoc.

Vorteile:
- git pull + sudo cp reicht um das Script auf laufenden Servern zu aktualisieren
- Keine doppelte Pflege mehr (Heredoc vs. Datei)
- Änderungen direkt im Script-File sichtbar (git diff)

Update laufender Server:
  sudo install -m 755 /var/www/mailwolt/scripts/mailwolt-apply-domains \
    /usr/local/sbin/mailwolt-apply-domains

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 18:20:09 +02:00