From e69ded4fed8d605e0384a3bfb1fe91e7bfbaff24 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Mon, 20 Jul 2026 15:13:33 +0000 Subject: [PATCH] =?UTF-8?q?web:=20www-Hosts=20l=C3=B6sen=20aufs=20Apex-Dom?= =?UTF-8?q?ain-Theme=20auf=20statt=20aufs=20Portal-Fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Die Domain-Auflösung matchte den Host exakt gegen domain_name — www.presseecho.de fiel dadurch aufs Portal-Default-Theme zurück, dessen theme-portal.css im Web-Build nicht existiert. Alle Route::view-Seiten ohne Controller (Impressum, Datenschutz, AGB, FAQ, …) antworteten auf www-Hosts mit 500 (ViteException, Dauereintrag im Live-Log); die Controller-Seiten traf es nicht, weil WebPortalContext den Host tolerant matcht. resolve() normalisiert Hosts jetzt (lowercase, www. entfernt) auf beiden Seiten des Vergleichs. Co-Authored-By: Claude Fable 5 --- app/Support/DomainAssetContext.php | 22 ++++++++++++++++++++-- tests/Feature/DomainAssetContextTest.php | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/app/Support/DomainAssetContext.php b/app/Support/DomainAssetContext.php index f410211b..25ee8a56 100644 --- a/app/Support/DomainAssetContext.php +++ b/app/Support/DomainAssetContext.php @@ -55,7 +55,13 @@ class DomainAssetContext return array_merge($defaults, $configuredDomains[$themeOverride]); } - $portalHost = (string) config('domains.domain_portal'); + // www-Varianten zählen als ihre Apex-Domain: Ohne Normalisierung + // fiele z. B. www.presseecho.de auf das Portal-Default-Theme zurück, + // dessen theme-portal.css im Web-Build nicht existiert → 500 + // (ViteException) auf allen Route::view-Seiten (Impressum, AGB, …). + $host = self::normalizedHost($host); + + $portalHost = self::normalizedHost((string) config('domains.domain_portal')); if ($host === $portalHost) { $request ??= request(); @@ -72,7 +78,9 @@ class DomainAssetContext continue; } - if (($config['domain_name'] ?? null) === $host) { + $domainName = $config['domain_name'] ?? null; + + if (is_string($domainName) && self::normalizedHost($domainName) === $host) { return array_merge($defaults, $config); } } @@ -80,6 +88,16 @@ class DomainAssetContext return $defaults; } + /** + * Kleingeschriebener Host ohne führendes "www.". + */ + private static function normalizedHost(string $host): string + { + $host = strtolower(trim($host)); + + return str_starts_with($host, 'www.') ? substr($host, 4) : $host; + } + public static function isBackendRequest(Request $request): bool { if ($request->routeIs( diff --git a/tests/Feature/DomainAssetContextTest.php b/tests/Feature/DomainAssetContextTest.php index b1a6f448..bd155375 100644 --- a/tests/Feature/DomainAssetContextTest.php +++ b/tests/Feature/DomainAssetContextTest.php @@ -50,6 +50,28 @@ test('presseecho resolves to its own web theme', function () { ->and($config['assets_dir'])->toBe('build/web'); }); +test('www hosts resolve like their apex domain instead of the portal fallback', function () { + $defaults = ['theme' => 'portal', 'assets_dir' => 'build/portal']; + $domains = config('domains.domains'); + + // Ohne www-Normalisierung fiele der Host aufs Portal-Default zurück, + // dessen theme-portal.css im Web-Build fehlt → 500 auf Route::view-Seiten. + $config = DomainAssetContext::resolve('www.presseecho.test', $defaults, $domains); + + expect($config['theme'])->toBe('presseecho') + ->and($config['assets_dir'])->toBe('build/web'); + + $hub = DomainAssetContext::resolve( + 'WWW.pressekonto.test', + $defaults, + $domains, + null, + Request::create('https://www.pressekonto.test/', 'GET'), + ); + + expect($hub['theme'])->toBe('pressekonto'); +}); + test('hot file path depends on asset bundle', function () { expect(DomainAssetContext::hotFilePath('build/web')) ->toEndWith('hot-web')