From 8ff1aeac2aba117a0661ee0420520e5bff25b138 Mon Sep 17 00:00:00 2001 From: boban Date: Sat, 25 Apr 2026 12:54:11 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20Wizard=20Step=205=20=E2=80=94=20per-Doma?= =?UTF-8?q?in-Fortschritt,=20Cert-Fallback,=20ssl=5Fconfigured?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mailwolt-apply-domains schreibt jetzt pro Domain running/done/error/nodns in die State-Dateien während certbot läuft (statt alles auf einmal am Ende) - get_cert_dir() erstellt fullchain.pem/privkey.pem Symlinks auf cert.pem/key.pem wenn kein LE-Zertifikat vorhanden — verhindert nginx-t-Fehler und kaputten Redirect - WizardDomains.php: ssl_configured wird jetzt anhand /etc/letsencrypt/live/ geprüft statt per Shell-Output (der wegen exec>>LOG immer leer war) - Shell-Script schreibt done-Datei selbst; PHP nur noch als Absturz-Fallback Co-Authored-By: Claude Sonnet 4.6 --- app/Console/Commands/WizardDomains.php | 40 +++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/app/Console/Commands/WizardDomains.php b/app/Console/Commands/WizardDomains.php index 9ba2980..7ac4775 100644 --- a/app/Console/Commands/WizardDomains.php +++ b/app/Console/Commands/WizardDomains.php @@ -59,7 +59,7 @@ class WizardDomains extends Command // Das Script erstellt erst die Vhosts (mit ACME-Location), dann certbot --webroot $helper = '/usr/local/sbin/mailwolt-apply-domains'; $out = shell_exec(sprintf( - 'sudo -n %s --ui-host %s --webmail-host %s --mail-host %s --ssl-auto %d 2>&1', + 'sudo -n %s --ui-host %s --webmail-host %s --mail-host %s --ssl-auto %d', escapeshellarg($helper), escapeshellarg($ui), escapeshellarg($webmail), @@ -67,31 +67,31 @@ class WizardDomains extends Command $ssl ? 1 : 0, )); - $outStr = (string) $out; - $helperOk = $out !== null - && !str_contains($outStr, '[x]') - && !str_contains($outStr, 'command not found') - && !str_contains($outStr, 'No such file') - && trim($outStr) !== ''; - + // Shell-Script schreibt per-Domain-Status selbst in die State-Dateien. + // Fallback: Domains die noch auf running/pending stehen auf error setzen. foreach (['ui', 'mail', 'webmail'] as $key) { - $status = file_get_contents(self::STATE_DIR . "/{$key}"); + $status = trim((string) @file_get_contents(self::STATE_DIR . "/{$key}")); if ($status === 'running' || $status === 'pending') { - $domain = $domains[$key] ?? ''; - if ($domain && str_contains($outStr, "[!] {$domain}:")) { - file_put_contents(self::STATE_DIR . "/{$key}", 'noipv6'); - } else { - file_put_contents(self::STATE_DIR . "/{$key}", $helperOk ? 'done' : 'error'); - } + file_put_contents(self::STATE_DIR . "/{$key}", 'error'); } } - // Shell-Script schreibt done bereits vor dem nginx-Switch — nicht überschreiben - $alreadyDone = trim((string) @file_get_contents(self::STATE_DIR . '/done')) === '1'; - if (!$alreadyDone) { - file_put_contents(self::STATE_DIR . '/done', $helperOk ? '1' : '0'); + // done-Datei: Shell-Script schreibt "1"/"0"; Fallback wenn Script abstürzte. + $doneVal = trim((string) @file_get_contents(self::STATE_DIR . '/done')); + if ($doneVal === '') { + file_put_contents(self::STATE_DIR . '/done', '0'); + $doneVal = '0'; } - Setting::set('ssl_configured', ($helperOk || $alreadyDone) ? '1' : '0'); + + // ssl_configured anhand tatsächlich ausgestellter LE-Zertifikate bestimmen + $hasAnyCert = false; + foreach ($domains as $domain) { + if ($domain && is_dir("/etc/letsencrypt/live/{$domain}")) { + $hasAnyCert = true; + break; + } + } + Setting::set('ssl_configured', $hasAnyCert ? '1' : '0'); // SESSION_SECURE_COOKIE wird nicht automatisch gesetzt — // nginx leitet HTTP→HTTPS weiter, Secure-Flag wird im Admin gesetzt