shouldHandleRequest($request)) { return $next($request); } /** @var DomainContext $context */ $context = app(DomainContext::class); // Session-Domain für alle Subdomains setzen (wichtig für Cookie-Sharing) // Hinweis: DomainResolver läuft jetzt VOR StartSession - ideale Position! // Für User-Shops: Immer die korrekte Domain setzen if ($context->isUserShop()) { $userShopDomain = '.' . parse_url($context->host, PHP_URL_HOST); Config::set('session.domain', $userShopDomain); if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: User-Shop Session-Domain VOR StartSession gesetzt', [ 'user_shop_domain' => $userShopDomain, 'context_host' => $context->host, 'session_started' => Session::isStarted(), 'request_host' => $request->getHost(), 'solution' => 'Korrekte Kernel-Reihenfolge: DomainResolver → EncryptCookies → AddQueuedCookiesToResponse → StartSession' ]); } } else { // Für Main-Domain: Standard-Domain verwenden $mainDomain = '.' . config('app.domain') . config('app.tld_care'); Config::set('session.domain', $mainDomain); if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: Main-Domain Session-Domain VOR StartSession gesetzt', [ 'main_domain' => $mainDomain, 'session_started' => Session::isStarted(), 'request_host' => $request->getHost(), 'solution' => 'Korrekte Kernel-Reihenfolge: DomainResolver → EncryptCookies → AddQueuedCookiesToResponse → StartSession' ]); } } // Wenn der DomainServiceProvider die Domain nicht identifizieren konnte, // leiten wir sicher auf die Hauptdomain um. if ($context->isUnknown()) { // Detailliertes Logging für spätere Analyse if (config('app.debug')) { \Log::channel('domain')->warning('Unknown domain accessed', [ 'host' => $request->getHost(), 'subdomain' => $context->subdomain, 'user_agent' => $request->userAgent(), 'ip' => $request->ip(), 'referer' => $request->header('referer'), 'path' => $request->getPathInfo(), 'session_id_at_unknown_domain' => Session::isStarted() ? Session::getId() : 'session_not_started' ]); } // Holt die URL der Hauptdomain vom DomainService und leitet um. $mainUrl = app(\App\Services\DomainService::class)->buildUrl('main'); return redirect()->away($mainUrl, 301); } if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: context', [ 'context' => $context, 'subdomain' => $context->subdomain ]); } // Für User-Shop-Domains: Validierung und Route-Parameter-Bereinigung if ($context->isUserShop()) { // Validiere UserShop-Berechtigung (bereits im DomainServiceProvider geprüft, // aber zusätzliche Sicherheitsebene) if (!$context->userShop) { if (config('app.debug')) { \Log::channel('domain')->warning('UserShop not found', [ 'subdomain' => $context->subdomain, 'host' => $context->host ]); } abort(503, 'Shop not available'); } if (!$context->userShop->active) { if (config('app.debug')) { \Log::channel('domain')->info('UserShop inactive accessed', [ 'shop_id' => $context->userShop->id, 'subdomain' => $context->subdomain ]); } abort(503, 'Shop temporarily unavailable'); } if (!$context->userShop->user || !$context->userShop->user->isActiveShop()) { if (config('app.debug')) { \Log::channel('debug')->info('UserShop with expired payment accessed', [ 'shop_id' => $context->userShop->id, 'user_id' => $context->userShop->user_id ?? null, 'subdomain' => $context->subdomain ]); } abort(503, 'Shop access denied'); } // Route-Parameter-Bereinigung passiert in setupLegacyContext } // Richtet den Anwendungskontext für Abwärtskompatibilität ein. $this->setupLegacyContext($context, $request); // Session-ID in Request-Attributes speichern für Vergleich in anderen Middleware $currentSessionId = Session::isStarted() ? Session::getId() : null; $request->attributes->set('domain_resolver_session_id', $currentSessionId); // Debug-Logging für Session-Konsistenz vor dem nächsten Request if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: Middleware beendet - Session-Status VOR next()', [ 'current_session_id' => $currentSessionId, 'session_started' => Session::isStarted(), 'user_shop_id' => session('user_shop')?->id, 'user_shop_domain' => session('user_shop_domain'), 'context_type' => $context->type, 'session_domain_config' => config('session.domain'), 'request_host' => $request->getHost(), 'session_all_keys' => Session::isStarted() ? array_keys(Session::all()) : [], 'middleware_order' => 'DomainResolver → EncryptCookies → AddQueuedCookiesToResponse → StartSession → ...', 'domain_fix_applied' => $context->isUserShop() ? 'User-Shop Domain VOR StartSession gesetzt' : 'Main-Domain VOR StartSession gesetzt' ]); } return $next($request); } /** * Stellt die Kompatibilität mit älteren Teilen der Anwendung her, * die direkt auf Session-Daten oder dynamische Konfigurationen zugreifen. * * @param DomainContext $context * @param Request $request */ private function setupLegacyContext(DomainContext $context, Request $request): void { // TODO: [TECH-DEBT] Diese Methode sollte langfristig entfernt werden. // Alle Teile der Anwendung sollten den DomainContext direkt verwenden. if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: setupLegacyContext - Session ist jetzt verfügbar', [ 'session_user_shop_id' => session('user_shop')?->id, 'session_user_shop_name' => session('user_shop')?->name, 'context_user_shop_id' => $context->userShop?->id, 'context_user_shop_name' => $context->userShop?->name, 'context_type' => $context->type, 'session_id' => Session::getId(), 'session_started' => Session::isStarted(), 'session_domain' => config('session.domain'), 'request_host' => request()->getHost() ]); } if ($context->userShop) { // Setzt die alten Session-Variablen, die von einigen Views/Controllern erwartet werden. Session::put('user_shop', $context->userShop); Session::put('user_shop_domain', $context->host); // Session sofort speichern um Konsistenz sicherzustellen Session::save(); // Route-Parameter-Bereinigung passiert in separater Middleware // nachdem die Route vollständig aufgelöst wurde if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: user_shop gesetzt', [ 'user_id' => $context->userShop->user_id ?? null, 'context_user_shop_id' => $context->userShop->id, 'session_user_shop_id' => session('user_shop')?->id, 'session_user_shop_name' => session('user_shop')?->name, 'session_saved' => true, 'session_id' => Session::getId(), 'session_domain' => config('session.domain'), 'request_host' => request()->getHost(), 'route_cleanup_delegated' => true ]); } // Setzt die app.url zur Laufzeit, um URL-Generierung in alten Teilen zu ermöglichen. Config::set('app.url', $context->host); // Kompatibilität mit der Util-Klasse. Util::setPostRoute('user/'); } else { if ($context->type === 'main') { Session::forget('user_shop'); Session::forget('user_shop_domain'); // Session sofort speichern um Konsistenz sicherzustellen Session::save(); if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: user_shop entfernt (' . $context->type . ' domain)', ['user_shop' => session('user_shop')]); } Config::set('app.url', $context->host); } elseif ($context->type === 'shop') { Util::setPostRoute('user/'); $user_shop = UserShop::where('slug', 'aloevera')->first(); Session::put('user_shop', $user_shop); Session::put('user_shop_domain', $context->host); // Session sofort speichern um Konsistenz sicherzustellen Session::save(); if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: user_shop hinzugefügt (' . $context->type . ' domain)', ['user_shop' => session('user_shop')]); } Config::set('app.url', $context->host); } else { // Für Domains ohne UserShop: Session-Daten sofort löschen Session::forget('user_shop'); Session::put('user_shop_domain', $context->host); // Session sofort speichern um Konsistenz sicherzustellen Session::save(); \Log::debug('DomainResolver: user_shop_domain hinzugefügt (' . $context->type . ' domain)', ['user_shop' => session('user_shop')]); Config::set('app.url', $context->host); } } // Abschließendes Debug-Logging für Session-Konsistenz if (config('app.debug')) { \Log::channel('domain')->debug('DomainResolver: setupLegacyContext abgeschlossen', [ 'final_session_id' => Session::getId(), 'user_shop_id' => session('user_shop')?->id, 'user_shop_domain' => session('user_shop_domain'), 'context_type' => $context->type, 'session_domain' => config('session.domain'), 'request_host' => request()->getHost() ]); } } /** * Prüft, ob diese Middleware für den aktuellen Request ausgeführt werden soll. * * @param Request $request * @return bool */ private function shouldHandleRequest(Request $request): bool { // Überspringe API-Requests if ($request->is('api/*')) { return false; } // Überspringe Asset-Requests (CSS, JS, Bilder, etc.) if ($request->isMethod('GET') && preg_match('/\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/i', $request->path())) { return false; } // Überspringe Laravel-interne Requests if ($request->isMethod('GET') && in_array($request->path(), ['_debugbar/*'])) { return false; } // Überspringe Health-Check und Monitoring Requests if ($request->isMethod('GET') && in_array($request->path(), ['health', 'status', 'ping'])) { return false; } return true; } }