Eigenes HTML-Layout ohne Sidebar, mw-* CSS-Klassen, gleiches Logo
und Karten-Design wie der Setup-Wizard. Icons als Inline-SVG da
app.js (Phosphor) auf der Login-Seite nicht geladen wird.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
route('login') nutzt die gecachte Config (alte IP/URL). Stattdessen
direkt auf https://{ui_domain}/login umleiten, da APP_URL erst nach
dem Prozess-Neustart greift.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vor SSL-Zertifikaten schlägt Livewires AJAX über HTTPS fehl.
mount() leitet automatisch auf http:// um damit der Wizard funktioniert.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ls-remote fragt den Remote direkt — funktioniert mit shallow clone ohne
History-Download. Kein --unshallow, kein Fehler mehr.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shallow clones (--depth=1) kennen keine Tag-Historie. --unshallow
konvertiert zuerst zum vollständigen Clone, danach sind alle Tags erreichbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Spinner (⠋⠙⠹…) läuft während quietly() auf Abschluss wartet
- stop_spin() in ok/warn/err integriert, EXIT-Trap sichert Cleanup
- Smoke-Test: kein eval, separate Funktionen pro Protokoll (smtp/tls/imap/pop3)
- Service-Namen neben Port, Zusammenfassung X/7 Dienste erreichbar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Nur Hauptschritte mit Zeitschätzung sichtbar (~Pakete 2-5 Min, etc.)
- Alle verbose Ausgaben (apt/composer/npm/git) gehen in /var/log/mailwolt-install.log
- Bei Fehler: letzte 20 Log-Zeilen werden angezeigt + Log-Pfad
- quietly()/try_quiet() Helper für stille Ausführung
- Smoke-Test zeigt nur OK/⚠ pro Port ohne verbose openssl-Output
- Node/npm wird nach Git-Clone installiert (package.json bereits vorhanden)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- installer.sh: mailwolt-apply-domains mit 3-Phasen certbot (HTTP → LE → SSL),
IPv6-Check vor certbot, Zertifikat-Ablauf-Check (10 Tage), Version-Datei schreiben
- WizardDomains: noipv6-Status aus Helper-Output erkennen
- Wizard: retryDomains()-Methode für Wiederholung ohne neuen Wizard-Durchlauf
- Step 5 Blade: Hints pro Fehlerstatus, Retry-Button, "Trotzdem zum Login"
- UpdatePage: Version aus Datei, Fallback auf git describe (kein "dev" mehr)
- UpdatePage: refreshLowLevelState behandelt fehlende State-Datei als idle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Kein certbot --nginx mehr im Wizard (scheitert an catch-all server_name)
- mailwolt-apply-domains erstellt Vhosts zuerst, dann certbot --webroot
- sudoers-Eintrag für certbot im Installer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PHPV-Erkennung vor nginx-Config verschoben, Socket-Pfad dynamisch
- Argument-Parsing (-dev/-stag) ganz an den Anfang
- APP_PW früh generieren damit es überall verfügbar ist
- Doppelten setfacl-Block entfernt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- composer create-project entfernt (wir klonen das eigene Repo)
- .env wird nach dem Clone auf dem echten Codebase gesetzt
- composer install, key:generate, migrate und storage:link nach Clone
- nodesource curl|bash durch Datei-Download ersetzt (stdin-safe)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
trap EXIT/INT/TERM feuert auch bei Ctrl+C — vorheriges node-Cleanup
lief nur beim Start, nicht beim Beenden.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wenn Port 5173 belegt ist schlägt npm run dev sofort fehl statt
still auf 5174 zu wechseln — nginx würde dann ins Leere proxyen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Webmail-Layouts laden jetzt app-webmail.js statt app.js.
websocket.js, ui/command.js und sidebar.js werden im Webmail nicht
mehr geladen — kein /ui/tasks/active Aufruf mehr möglich.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
type=module Scripts haben kein garantiertes Timing mit inline Scripts.
<meta name="mw-context" content="webmail"> im <head> ist vor Modulausführung
garantiert im DOM verfügbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
window.MW_CONTEXT='webmail' in beiden Webmail-Layouts gesetzt.
bootstrapToasts() prüft diesen Context und bricht früh ab um
den 401-Fehler auf der Webmail-Domain zu vermeiden.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Path-based Fallback /webmail/* mit ->name('webmail.') re-added — kein
Namenskonflikt mehr mit web.php 'login'. Behebt gecachte 301-Redirects
im Browser. npm dev-script räumt public/hot vor dem Start auf damit
Vite-Stop nie mehr die App kaputt macht.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SVG paths in domain-list und installer-page hatten kein führendes 'M' im
d-Attribut — Browser-Fehler behoben. Nginx UI-Vhost bekommt Proxy-Locations
für /@vite/, /node_modules/, /resources/ und WebSocket /vite-hmr (Port 5173)
damit npm run dev durch nginx funktioniert.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Path-based Fallback (/webmail/*) wird nicht mehr registriert wenn eine
dedizierte Webmail-Subdomain konfiguriert ist. Sonst kollidiert das nackte
->name('login') aus webmail.php mit dem login-Route aus web.php.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mit dedizierter Webmail-Subdomain ist kein /webmail/-Präfix nötig —
Laravel's domain()-Routing in bootstrap/app.php übernimmt die Isolation.
Nur / leitet auf /login um, alle anderen Pfade gehen direkt an Laravel.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- build_webmail_http_only / build_webmail_tls als eigene Funktionen
- Webmail-Domain: / und /login → redirect auf /webmail/login
- Webmail-Domain: nur /webmail/* wird an Laravel weitergeleitet
- Alles andere auf Webmail-Domain → 403
- UI-Domain bleibt unverändert (voller Laravel-Zugriff)
- mailwolt-apply-domains deployed aktualisiert (write_webmail_vhost)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Installer legt das Wizard-State-Verzeichnis jetzt mit chown www-data an
damit finish() im Wizard die Status-Dateien schreiben kann.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Wizard Schritt 2: leere Domain-Felder werden beim Tippen auto-gefüllt
(wer nur eine Domain nutzt muss sie nur einmal eingeben)
- Wizard Schritt 4: Checkbox "SSL jetzt überspringen" mit Hinweistext
- Wizard Schritt 5: skip-Status wird pro Domain angezeigt
- WizardDomains schreibt ssl_configured=0/1 in Settings
- SettingsForm: setzt ssl_configured=1 nach erfolgreichem applyDomains
- Dashboard: gelber Banner wenn ssl_configured != 1, Link zu Einstellungen
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- perPage (#[Url as:'limit']) bleibt nach Reload erhalten (25/50/100)
- Pagination zeigt max 5 Seiten (±2 um aktuelle) + 1/letzte mit ...
- Per-Seite-Select in Quarantäne und Queue eingefügt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Quarantäne und Queue zeigen je 25 Einträge pro Seite
- Pagination-Bar mit Seitenanzeige (X-Y von Z) und Blätter-Buttons
- Seite wird bei Filter- oder Suchwechsel auf 1 zurückgesetzt
- Quarantäne: rows-Select entfernt (API holt intern 500, UI paginiert)
- CSS-Klassen mq-pagination, mq-pag-btn passend zum Dark-Design
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auf APP_ENV=local wird die aktuelle Version direkt aus git describe
gelesen statt aus /var/lib/mailwolt/version — verhindert falschen
"Update verfügbar" Hinweis auf der Entwicklungsmaschine.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- checkForUpdates() läuft jetzt synchron (nicht im Hintergrund), damit
das Ergebnis sofort angezeigt wird ohne Seite neu laden zu müssen
- Log-Viewer: white-space:pre-wrap + <br> entfernt durch display:block
pro Span — kein doppelter Zeilenabstand mehr
- Auto-Scroll Checkbox nutzt jetzt mw-modal-check Klassen (passend zum Design)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>