shouldHandleRequest($request)) { return $next($request); } /** @var DomainContext $context */ $context = app(DomainContext::class); // Die Konfiguration der Session-Domain ist hier weiterhin sinnvoll. $this->configureSessionDomain($context); // 1. Umgang mit unbekannten Domains // Wenn der DomainContext nicht aufgelöst werden konnte, sicher umleiten. if ($context->isUnknown()) { \Log::channel('domain')->warning('Unknown domain accessed', [ 'host' => $request->getHost(), 'user_agent' => $request->userAgent(), 'ip' => $request->ip(), 'path' => $request->getPathInfo() ]); $mainUrl = app(\App\Services\DomainService::class)->buildUrl('main'); return redirect()->away($mainUrl, 301); } // 2. Validierung für User-Shop-Domains if ($context->isUserShop()) { $this->validateUserShop($context); // Der `RouteCleanup` sollte als eigene Middleware nach dem Routing laufen // und nicht mehr hier angedeutet werden. if ($request->route('subdomain')) { $request->route()->forgetParameter('subdomain'); } } // 3. Persistierung des Kontexts in der Session (vereinfachte Logik) $this->persistUserShopContext($context); return $next($request); } /** * Konfiguriert die `session.domain` basierend auf dem Domain-Typ. */ private function configureSessionDomain(DomainContext $context): void { if ($context->type === 'shop' || $context->type === 'main-shop' || $context->type === 'user-shop') { Config::set('session.domain', '.' . config('app.domain') . config('app.tld_shop')); } else { Config::set('session.domain', '.' . config('app.domain') . config('app.tld_care')); } } /** * Führt die notwendigen Validierungen für eine User-Shop-Domain durch. */ private function validateUserShop(DomainContext $context): void { if (!$context->userShop) { \Log::channel('domain')->warning('UserShop not found for subdomain', ['subdomain' => $context->subdomain]); abort(503, 'Shop not available'); } if (!$context->userShop->active) { \Log::channel('domain')->info('Inactive UserShop accessed', ['shop_id' => $context->userShop->id]); abort(503, 'Shop temporarily unavailable'); } if (!$context->userShop->user || !$context->userShop->user->isActiveShop()) { \Log::channel('domain')->info('UserShop with expired payment accessed', ['shop_id' => $context->userShop->id]); abort(503, 'Shop access denied'); } } /** * Speichert den User-Shop-Kontext in der Session. * * Diese Methode verfolgt eine einfachere, robustere Strategie: * - Wenn ein User-Shop-Kontext vorhanden ist (`user-shop` oder `main-shop`), * wird er in die Session geschrieben. * - Auf allen anderen Domains (`main`, `crm`, `portal` etc.) wird die * Session NICHT mehr angefasst. Ein einmal gesetzter `user_shop` bleibt * also erhalten, bis der Benutzer einen anderen Shop besucht. * Das `Session::forget('user_shop')` wird bewusst entfernt. */ private function persistUserShopContext(DomainContext $context): void { // Setze die `app.url` zur Laufzeit für korrekte URL-Generierung. Config::set('app.url', 'https://' . $context->host); if ($context->userShop) { // Ein UserShop ist im aktuellen Kontext aktiv (entweder via Subdomain oder als Fallback). // Wir aktualisieren die Session mit diesem Shop. Session::put('user_shop', $context->userShop); Session::put('user_shop_domain', $context->host); // Kompatibilität mit der alten Util-Klasse. Util::setPostRoute('user/'); } // WICHTIG: Es gibt keinen `else`-Block mehr. // Wenn kein `userShop` im Kontext ist (z.B. auf mivita.care, in.mivita.care), // wird ein eventuell vorhandener `user_shop` aus einem früheren Besuch // in der Session belassen. Dies löst das Problem des Kontextverlusts. } /** * Prüft, ob die Middleware für den Request relevant ist. * (Logik aus dem alten DomainResolver übernommen) */ private function shouldHandleRequest(Request $request): bool { if ($request->is('api/*')) { return false; } if ($request->isMethod('GET') && preg_match('/\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$/i', $request->path())) { return false; } if (in_array($request->path(), ['_debugbar/!*', 'health', 'status', 'ping'])) { return false; } return true; } }