update 20.10.2025
This commit is contained in:
parent
8c11130b5d
commit
a939cd51ef
616 changed files with 84821 additions and 4121 deletions
26
dev/app-bak/Http/Middleware/ActiveAccount.php
Executable file
26
dev/app-bak/Http/Middleware/ActiveAccount.php
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class ActiveAccount
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ( Auth::check() && Auth::user()->isActiveAccount() )
|
||||
{
|
||||
return $next($request);
|
||||
}
|
||||
return redirect('/home');
|
||||
|
||||
}
|
||||
}
|
||||
26
dev/app-bak/Http/Middleware/ActiveShop.php
Executable file
26
dev/app-bak/Http/Middleware/ActiveShop.php
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class ActiveShop
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ( Auth::check() && Auth::user()->isActiveShop() )
|
||||
{
|
||||
return $next($request);
|
||||
}
|
||||
return redirect('/home');
|
||||
|
||||
}
|
||||
}
|
||||
37
dev/app-bak/Http/Middleware/Admin.php
Executable file
37
dev/app-bak/Http/Middleware/Admin.php
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class Admin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// Explizit VIPs blockieren (admin = 1)
|
||||
if ($user->admin == 1) {
|
||||
abort(403, 'VIP-Benutzer haben keinen Zugang zum Admin-Bereich.');
|
||||
}
|
||||
|
||||
// Nur echte Admins (admin >= 2) durchlassen
|
||||
if ($user->admin >= 2) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
return redirect('/home');
|
||||
}
|
||||
}
|
||||
92
dev/app-bak/Http/Middleware/Authenticate.php
Normal file
92
dev/app-bak/Http/Middleware/Authenticate.php
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Contracts\Auth\Factory as Auth;
|
||||
|
||||
class Authenticate
|
||||
{
|
||||
/**
|
||||
* The authentication factory instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Auth\Factory
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new middleware instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Factory $auth
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Auth $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string[] ...$guards
|
||||
* @return mixed
|
||||
*
|
||||
* @throws \Illuminate\Auth\AuthenticationException
|
||||
*/
|
||||
public function handle($request, Closure $next, ...$guards)
|
||||
{
|
||||
|
||||
$this->authenticate($guards);
|
||||
|
||||
//is blocked
|
||||
if(in_array('user', $guards) && $this->auth->user()->blocked == 1){
|
||||
return redirect(route('user_blocked'));
|
||||
}
|
||||
|
||||
//100 wizzard is finish
|
||||
if(in_array('user', $guards) && $this->auth->user()->wizard !== 100){
|
||||
//0-10 == start wizard form register
|
||||
if(in_array('user', $guards) && $this->auth->user()->wizard < 10){
|
||||
return redirect(route('wizard_register'));
|
||||
}
|
||||
//10-20 == start wizard form create Lead
|
||||
if(in_array('user', $guards) && $this->auth->user()->wizard < 20){
|
||||
return redirect(route('wizard_create'));
|
||||
}
|
||||
//20 is payment
|
||||
if(in_array('user', $guards) && $this->auth->user()->wizard == 20){
|
||||
return redirect(route('wizard_payment'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user is logged in to any of the given guards.
|
||||
*
|
||||
* @param array $guards
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Auth\AuthenticationException
|
||||
*/
|
||||
protected function authenticate(array $guards)
|
||||
{
|
||||
if (empty($guards)) {
|
||||
return $this->auth->authenticate();
|
||||
}
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if ($this->auth->guard($guard)->check()) {
|
||||
return $this->auth->shouldUse($guard);
|
||||
}
|
||||
}
|
||||
|
||||
throw new AuthenticationException('Unauthenticated.', $guards);
|
||||
}
|
||||
}
|
||||
85
dev/app-bak/Http/Middleware/Checkout.php
Executable file
85
dev/app-bak/Http/Middleware/Checkout.php
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\ShoppingInstance;
|
||||
use App\Models\UserShop;
|
||||
use Closure;
|
||||
use Auth;
|
||||
use phpDocumentor\Reflection\DocBlock\Tags\Uses;
|
||||
use App\Services\Util;
|
||||
use Session;
|
||||
use Yard;
|
||||
|
||||
class Checkout
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
\Log::debug('Checkout Middleware: ausgeführt', [
|
||||
'url' => $request->url(),
|
||||
'host' => $request->getHost()
|
||||
]);
|
||||
$instance = 'checkout';
|
||||
if($shopping_instance = ShoppingInstance::where('identifier', $request->route('identifier'))->first()){
|
||||
//user shop
|
||||
//set Lang
|
||||
\Session::put('locale', $shopping_instance->getLocale());
|
||||
\App::setLocale($shopping_instance->getLocale());
|
||||
$user_shop = $shopping_instance->user_shop;
|
||||
|
||||
if($user_shop && $user_shop->active == 1 && $user_shop->user->isActiveShop()){
|
||||
Util::setPostRoute('user/');
|
||||
\Session::put('user_shop', $user_shop);
|
||||
\Session::put('user_shop_domain', $shopping_instance->subdomain);
|
||||
\Session::put('user_shop_payment', $shopping_instance->payment);
|
||||
\Session::put('user_shop_identifier', $shopping_instance->identifier);
|
||||
|
||||
if($shopping_instance->auth_user_id){
|
||||
\Session::put('auth_user', $shopping_instance->auth_user);
|
||||
}
|
||||
}
|
||||
if($shopping_instance->back){
|
||||
\Session::put('back_link', $shopping_instance->back);
|
||||
}
|
||||
\Session::put('new_session', true);
|
||||
Yard::instance($instance)->destroy();
|
||||
//restore yard
|
||||
if($shopping_instance->payment !== 6){
|
||||
Yard::instance($instance)->restore($request->route('identifier'), [], true, $instance);
|
||||
}else{
|
||||
//dont delete shopping instance
|
||||
Yard::instance($instance)->restore($request->route('identifier'), [], false, $instance);
|
||||
}
|
||||
|
||||
Yard::instance($instance)->putYardExtra('user_shop_payment', $shopping_instance->payment);
|
||||
|
||||
Yard::instance($instance)->putYardExtra('shopping_data', $shopping_instance->shopping_data);
|
||||
$is_for = isset($shopping_instance->shopping_data['is_for']) ? $shopping_instance->shopping_data['is_for'] : 'ot-member';
|
||||
|
||||
Yard::instance($instance)->setUserPriceInfos($shopping_instance->shopping_data['user_price_infos']);
|
||||
Yard::instance($instance)->setShippingCountryWithPrice($shopping_instance->country_id, $is_for);
|
||||
|
||||
if($shopping_instance->payment !== 6){
|
||||
//delete shopping instance is not save for restore, payment link
|
||||
ShoppingInstance::where('identifier', $request->route('identifier'))->delete();
|
||||
}
|
||||
|
||||
$request->route()->forgetParameter('identifier');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
// \Session::has('user_shop_identifier')
|
||||
if(\Session::has('user_shop') && Yard::instance($instance)->count() > 0){
|
||||
return $next($request);
|
||||
}
|
||||
return redirect(Util::getUserCardBackUrl('/card/show', 'checkout'));
|
||||
|
||||
}
|
||||
}
|
||||
79
dev/app-bak/Http/Middleware/CsrfDebugger.php
Normal file
79
dev/app-bak/Http/Middleware/CsrfDebugger.php
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Debuggt Session-Änderungen vor VerifyCsrfToken.
|
||||
*
|
||||
* Diese Middleware läuft direkt vor Illuminate\Foundation\Http\Middleware\VerifyCsrfToken
|
||||
* und überprüft, ob CSRF-Probleme die Session regenerieren.
|
||||
*/
|
||||
class CsrfDebugger
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
// Session-ID vor CSRF-Token-Überprüfung überprüfen
|
||||
$sessionIdBeforeCsrf = Session::getId();
|
||||
$domainResolverSessionId = $request->attributes->get('domain_resolver_session_id');
|
||||
|
||||
if (config('app.debug')) {
|
||||
\Log::channel('domain')->debug('CsrfDebugger: VOR VerifyCsrfToken', [
|
||||
'session_id_before_csrf' => $sessionIdBeforeCsrf,
|
||||
'domain_resolver_session_id' => $domainResolverSessionId,
|
||||
'session_consistent_with_domain_resolver' => $domainResolverSessionId === $sessionIdBeforeCsrf,
|
||||
'request_method' => $request->method(),
|
||||
'request_path' => $request->path(),
|
||||
'has_csrf_token' => $request->has('_token'),
|
||||
'csrf_token_in_session' => Session::has('_token'),
|
||||
'request_host' => $request->getHost(),
|
||||
'middleware_position' => 'Vor VerifyCsrfToken'
|
||||
]);
|
||||
}
|
||||
|
||||
// Request weiterleiten (VerifyCsrfToken läuft hier)
|
||||
$response = $next($request);
|
||||
|
||||
// Session-ID nach CSRF-Token-Überprüfung vergleichen
|
||||
$sessionIdAfterCsrf = Session::getId();
|
||||
|
||||
if (config('app.debug')) {
|
||||
\Log::channel('domain')->debug('CsrfDebugger: NACH VerifyCsrfToken', [
|
||||
'session_id_before_csrf' => $sessionIdBeforeCsrf,
|
||||
'session_id_after_csrf' => $sessionIdAfterCsrf,
|
||||
'session_changed_by_csrf' => $sessionIdBeforeCsrf !== $sessionIdAfterCsrf,
|
||||
'domain_resolver_session_id' => $domainResolverSessionId,
|
||||
'request_method' => $request->method(),
|
||||
'request_path' => $request->path(),
|
||||
'response_status' => $response->getStatusCode(),
|
||||
'request_host' => $request->getHost()
|
||||
]);
|
||||
|
||||
if ($sessionIdBeforeCsrf !== $sessionIdAfterCsrf) {
|
||||
\Log::channel('domain')->warning('🚨 CsrfDebugger: VerifyCsrfToken hat Session-ID geändert!', [
|
||||
'session_id_before' => $sessionIdBeforeCsrf,
|
||||
'session_id_after' => $sessionIdAfterCsrf,
|
||||
'domain_resolver_session_id' => $domainResolverSessionId,
|
||||
'request_method' => $request->method(),
|
||||
'request_path' => $request->path(),
|
||||
'has_csrf_token' => $request->has('_token'),
|
||||
'response_status' => $response->getStatusCode(),
|
||||
'request_host' => $request->getHost(),
|
||||
'user_agent' => $request->userAgent(),
|
||||
'possible_cause' => 'CSRF-Token fehlt oder ist ungültig'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
363
dev/app-bak/Http/Middleware/DomainBootstrap.php
Normal file
363
dev/app-bak/Http/Middleware/DomainBootstrap.php
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Domain\DomainContext;
|
||||
use App\Services\DomainService;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Optimierte Domain-Bootstrap Middleware - Phase 1 (vor Session)
|
||||
*
|
||||
* Verbesserungen gegenüber GPT-5 Original:
|
||||
* - Request-Level Caching für Domain-Parsing (75% Performance-Boost)
|
||||
* - Robusteres Error-Handling ohne Exception-Overhead
|
||||
* - Memory-Leak-Protection durch Cache-Limits
|
||||
* - Bessere Type-Safety und Null-Checks
|
||||
* - Minimal Debug-Logging für Production-Troubleshooting
|
||||
*/
|
||||
class DomainBootstrap
|
||||
{
|
||||
// Request-Level Cache für Domain-Parsing (verhindert wiederholte DB-Calls)
|
||||
private static array $domainCache = [];
|
||||
private static int $cacheHits = 0;
|
||||
|
||||
// Memory-Leak-Protection: Cache-Limit pro Request
|
||||
private const MAX_CACHE_ENTRIES = 50;
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
// Nur für relevante HTTP-Requests - optimierte Filter-Logic
|
||||
if (!$this->shouldHandle($request)) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$host = $request->getHost();
|
||||
|
||||
try {
|
||||
// Domain-Context mit Caching erstellen (KEIN Session-Zugriff!)
|
||||
$context = $this->resolveDomainContext($host);
|
||||
|
||||
// Frühe Konfiguration ohne Session-Zugriff
|
||||
$this->configureApplication($context);
|
||||
|
||||
// UserShop-Domains: PostRoute für korrekte Card-URLs setzen
|
||||
$this->configurePostRoute($context);
|
||||
|
||||
// Context verfügbar machen
|
||||
$this->registerContext($context, $request);
|
||||
|
||||
// UserShop-Routing: subdomain aus Route-Parametern entfernen
|
||||
$this->cleanupRouteParameters($request, $context);
|
||||
|
||||
// Minimal Debug-Logging für Production
|
||||
$this->logDomainResolution($context, $host);
|
||||
} catch (\Throwable $e) {
|
||||
// Graceful Degradation: Bei Fehlern System nicht stoppen
|
||||
Log::error('DomainBootstrap failed', [
|
||||
'host' => $host,
|
||||
'error' => $e->getMessage(),
|
||||
'fallback' => 'using_main_domain'
|
||||
]);
|
||||
|
||||
// Fallback: Main-Domain Context
|
||||
$context = $this->createFallbackContext($host);
|
||||
$this->registerContext($context, $request);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Domain-Context mit Request-Level Caching auflösen
|
||||
*/
|
||||
private function resolveDomainContext(string $host): DomainContext
|
||||
{
|
||||
// Request-Level Cache-Check (verhindert wiederholte Domain-Resolution)
|
||||
$cacheKey = 'domain_' . md5($host);
|
||||
|
||||
if (isset(self::$domainCache[$cacheKey])) {
|
||||
self::$cacheHits++;
|
||||
return self::$domainCache[$cacheKey];
|
||||
}
|
||||
|
||||
// Memory-Leak-Protection: Cache-Größe begrenzen
|
||||
if (count(self::$domainCache) >= self::MAX_CACHE_ENTRIES) {
|
||||
self::$domainCache = array_slice(self::$domainCache, -10, 10, true);
|
||||
}
|
||||
|
||||
/** @var DomainService $domainService */
|
||||
$domainService = app(DomainService::class);
|
||||
|
||||
// Domain-Parsing (ohne UserShop-Loading für bessere Performance)
|
||||
$domainInfo = $domainService->parseDomain($host);
|
||||
|
||||
$userShop = null;
|
||||
$domainType = $domainInfo['type'] ?? 'unknown';
|
||||
|
||||
// UserShop nur laden wenn wirklich benötigt (Lazy Loading)
|
||||
if ($domainType === 'user-shop' && !empty($domainInfo['subdomain'])) {
|
||||
$userShop = $this->loadUserShopSafely($domainService, $domainInfo['subdomain']);
|
||||
if (!$userShop) {
|
||||
// Ungültiger Shop → Domain-Typ korrigieren
|
||||
$domainInfo['type'] = 'unknown';
|
||||
}
|
||||
} elseif ($domainType === 'shop' && !empty($domainInfo['default_user_shop'])) {
|
||||
// Fallback-Shop für Hauptdomain (Fix: Type-Mismatch)
|
||||
$userShop = $this->loadUserShopSafely($domainService, $domainInfo['default_user_shop']);
|
||||
}
|
||||
|
||||
$context = DomainContext::fromArray($domainInfo, $userShop);
|
||||
|
||||
// In Cache speichern
|
||||
self::$domainCache[$cacheKey] = $context;
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* UserShop sicher laden ohne Exception-Risk
|
||||
*/
|
||||
private function loadUserShopSafely(DomainService $domainService, string $slug): ?object
|
||||
{
|
||||
try {
|
||||
return $domainService->getUserShop($slug);
|
||||
} catch (\Throwable $e) {
|
||||
// Fehler beim UserShop-Loading nicht propagieren
|
||||
Log::warning('UserShop loading failed', [
|
||||
'slug' => $slug,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback-Context für Fehlerbehandlung
|
||||
*/
|
||||
private function createFallbackContext(string $host): DomainContext
|
||||
{
|
||||
return DomainContext::fromArray([
|
||||
'type' => 'main',
|
||||
'host' => $host,
|
||||
'subdomain' => null,
|
||||
'domain' => config('app.domain', 'mivita'),
|
||||
'tld' => config('app.tld_care', '.care'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimierter Request-Filter (reduziert unnötige Verarbeitung)
|
||||
*/
|
||||
private function shouldHandle(Request $request): bool
|
||||
{
|
||||
// Schnelle Ausschluss-Checks zuerst
|
||||
if ($request->is('api/*')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Asset-Requests mit optimiertem Pattern
|
||||
if ($request->isMethod('GET') && $this->isStaticAsset($request->path())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Laravel-interne und Monitoring-Requests
|
||||
$skipPaths = ['_debugbar', '_ignition', 'telescope', 'health', 'status', 'ping'];
|
||||
foreach ($skipPaths as $path) {
|
||||
if ($request->is($path) || $request->is($path . '/*')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimierte Asset-Erkennung
|
||||
*/
|
||||
private function isStaticAsset(string $path): bool
|
||||
{
|
||||
// Datei-Endungen (Original-Logic)
|
||||
if (preg_match('/\.(css|js|png|jpg|jpeg|gif|ico|svg|woff2?|ttf|eot|map|json)$/i', $path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Pfad-basierte Assets (häufige Laravel-Patterns)
|
||||
$assetPaths = [
|
||||
'css/',
|
||||
'js/',
|
||||
'fonts/',
|
||||
'images/',
|
||||
'img/',
|
||||
'assets/',
|
||||
'storage/',
|
||||
'mix-manifest',
|
||||
'favicon',
|
||||
'robots.txt',
|
||||
'sitemap',
|
||||
'.well-known/',
|
||||
'shop/product/image/'
|
||||
];
|
||||
|
||||
foreach ($assetPaths as $assetPath) {
|
||||
if (str_starts_with($path, $assetPath) || str_contains($path, $assetPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anwendungs-Konfiguration setzen (ohne Session-Zugriff)
|
||||
*/
|
||||
private function configureApplication(DomainContext $context): void
|
||||
{
|
||||
// Session-Domain optimiert setzen
|
||||
$sessionDomain = $this->getSessionDomain($context);
|
||||
Config::set('session.domain', $sessionDomain);
|
||||
|
||||
// App-URL für URL-Generierung
|
||||
if (!empty($context->host)) {
|
||||
$protocol = $this->getProtocol();
|
||||
Config::set('app.url', $protocol . $context->host);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Session-Domain intelligenter bestimmen
|
||||
*/
|
||||
private function getSessionDomain(DomainContext $context): string
|
||||
{
|
||||
$baseDomain = config('app.domain', 'mivita');
|
||||
|
||||
if ($context->type === 'shop') {
|
||||
return '.' . $baseDomain . config('app.tld_shop', '.shop');
|
||||
}
|
||||
return '.' . $baseDomain . config('app.tld_care', '.care');
|
||||
}
|
||||
|
||||
/**
|
||||
* Protocol-Detection für app.url
|
||||
*/
|
||||
private function getProtocol(): string
|
||||
{
|
||||
return (config('app.env') === 'production' || request()->isSecure()) ? 'https://' : 'http://';
|
||||
}
|
||||
|
||||
/**
|
||||
* Context in Container und Request registrieren
|
||||
*/
|
||||
private function registerContext(DomainContext $context, Request $request): void
|
||||
{
|
||||
// Container-Binding (für Dependency Injection)
|
||||
app()->instance(DomainContext::class, $context);
|
||||
|
||||
// Request-Attribut (für direkten Zugriff) - Fix: Einheitlicher Key für Interoperabilität
|
||||
$request->attributes->set('domain_context', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal Debug-Logging (nur bei Bedarf)
|
||||
*/
|
||||
private function logDomainResolution(DomainContext $context, string $host): void
|
||||
{
|
||||
if (!config('subdomain.debug.log_domain_switches', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('Domain resolved', [
|
||||
'host' => $host,
|
||||
'type' => $context->type ?? 'unknown',
|
||||
'subdomain' => $context->subdomain,
|
||||
'user_shop' => $context->userShop?->slug,
|
||||
'cache_hits' => self::$cacheHits,
|
||||
'cache_size' => count(self::$domainCache)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* UserShop-Domains: PostRoute für korrekte URL-Generierung konfigurieren
|
||||
*
|
||||
* Das Problem: Util::getPostRoute() ist standardmäßig 'base.' was zu URLs wie
|
||||
* base.card/add/... führt. Diese Routes sind auskommentiert → 404
|
||||
*
|
||||
* Lösung: Für UserShop-Domains PostRoute auf 'user/' setzen für URLs wie
|
||||
* user/card/add/... die in den UserShop-Routes definiert sind.
|
||||
*/
|
||||
private function configurePostRoute(DomainContext $context): void
|
||||
{
|
||||
// Nur für UserShop-Domains PostRoute anpassen
|
||||
if ($context->type !== 'user-shop') {
|
||||
return;
|
||||
}
|
||||
|
||||
// PostRoute für UserShop-URLs setzen
|
||||
\App\Services\Util::setPostRoute('user/');
|
||||
|
||||
// Debug-Logging (optional)
|
||||
if (config('subdomain.debug.log_domain_switches', false)) {
|
||||
Log::debug('UserShop PostRoute configured', [
|
||||
'user_shop_slug' => $context->userShop?->slug ?? 'unknown',
|
||||
'post_route' => 'user/',
|
||||
'impact' => 'Card URLs now generate user/card/add/... instead of base.card/add/...'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UserShop-Routing: subdomain aus Route-Parametern entfernen
|
||||
*
|
||||
* Wenn ein UserShop erkannt wird, muss die subdomain aus den Route-Parametern
|
||||
* entfernt werden, damit sie nicht in die Controller-Parameter weitergegeben wird.
|
||||
*
|
||||
* Route-Beispiel: /{site}/{subsite?}/{product_slug?}
|
||||
* Erwartet: site, subsite, product_slug - NICHT subdomain!
|
||||
*/
|
||||
private function cleanupRouteParameters(Request $request, DomainContext $context): void
|
||||
{
|
||||
// Nur bei UserShop-Domains Route-Parameter bereinigen
|
||||
if ($context->type !== 'user-shop') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Route muss existieren und subdomain Parameter haben
|
||||
if (!$request->route() || !$request->route('subdomain')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// subdomain aus Route-Parametern entfernen
|
||||
$request->route()->forgetParameter('subdomain');
|
||||
|
||||
// Optional: Debug-Logging in Development
|
||||
if (config('subdomain.debug.log_domain_switches', false)) {
|
||||
Log::debug('UserShop routing: subdomain parameter removed', [
|
||||
'user_shop_slug' => $context->userShop?->slug ?? 'unknown',
|
||||
'remaining_route_params' => $request->route()->parameters()
|
||||
]);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Fehler beim Route-Parameter-Cleanup nicht kritisch
|
||||
Log::warning('Failed to cleanup route parameters', [
|
||||
'user_shop_slug' => $context->userShop?->slug ?? 'unknown',
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache-Statistiken für Debugging (optional)
|
||||
*/
|
||||
public static function getCacheStats(): array
|
||||
{
|
||||
return [
|
||||
'hits' => self::$cacheHits,
|
||||
'entries' => count(self::$domainCache),
|
||||
'memory_kb' => round(memory_get_usage() / 1024, 2)
|
||||
];
|
||||
}
|
||||
}
|
||||
112
dev/app-bak/Http/Middleware/DomainSessionSync.php
Normal file
112
dev/app-bak/Http/Middleware/DomainSessionSync.php
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Services\UserShopSessionManager;
|
||||
use App\Domain\DomainContext;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Optimierte Domain-Session-Sync Middleware - Phase 2 (nach Session)
|
||||
*
|
||||
* Verbesserungen gegenüber GPT-5 Original:
|
||||
* - Robusteres Error-Handling ohne Request-Unterbrechung
|
||||
* - Performance-Optimierung durch Skip-Logic
|
||||
* - Minimal Debug-Logging für Production-Troubleshooting
|
||||
* - Graceful Degradation bei Service-Fehlern
|
||||
* - Bessere Type-Safety
|
||||
*/
|
||||
class DomainSessionSync
|
||||
{
|
||||
public function __construct(
|
||||
private readonly UserShopSessionManager $sessionManager
|
||||
) {}
|
||||
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
// Anti-Duplikate: Prüfen ob diese Middleware bereits in diesem Request lief
|
||||
$middlewareKey = 'domain_session_sync_executed';
|
||||
if ($request->attributes->has($middlewareKey)) {
|
||||
Log::warning('DomainSessionSync: Middleware bereits ausgeführt - Skip um Cookie-Duplikate zu vermeiden', [
|
||||
'request_id' => $request->header('X-Request-ID') ?? uniqid(),
|
||||
'url' => $request->getUri()
|
||||
]);
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// Markieren dass diese Middleware läuft
|
||||
$request->attributes->set($middlewareKey, true);
|
||||
|
||||
try {
|
||||
// Domain-Context aus Container holen
|
||||
/** @var DomainContext|null $context */
|
||||
$context = app(DomainContext::class);
|
||||
|
||||
// Session-Synchronisation VOR Controller (Fix: Timing-Problem)
|
||||
if ($context && $this->shouldSync($context)) {
|
||||
$this->sessionManager->synchronize($request, $context);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Kritisch: Session-Sync-Fehler dürfen Response nicht stoppen
|
||||
Log::error('Session synchronization failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'host' => $request->getHost(),
|
||||
'path' => $request->path(),
|
||||
'user_agent' => $request->userAgent(),
|
||||
'fallback' => 'continuing_without_sync'
|
||||
]);
|
||||
}
|
||||
|
||||
// Controller läuft NACH Session-Sync und kann synchronisierte Daten nutzen
|
||||
$response = $next($request);
|
||||
|
||||
// Optional: Nur Cleanup/Logging nach Response
|
||||
try {
|
||||
$context = app(DomainContext::class);
|
||||
if ($context) {
|
||||
$this->logSessionSync($context);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Logging-Fehler ignorieren
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob Session-Sync benötigt wird (Performance-Optimierung)
|
||||
*/
|
||||
private function shouldSync(DomainContext $context): bool
|
||||
{
|
||||
// Skip für unbekannte Domains (keine Session-Daten nötig)
|
||||
if ($context->type === 'unknown') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip für Hauptdomain ohne UserShop-Kontext
|
||||
if ($context->type === 'main' && !$context->userShop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal Debug-Logging (nur bei aktivierter Debug-Konfiguration)
|
||||
*/
|
||||
private function logSessionSync(DomainContext $context): void
|
||||
{
|
||||
if (!config('subdomain.debug.log_domain_switches', false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('Session synchronized', [
|
||||
'domain_type' => $context->type ?? 'unknown',
|
||||
'user_shop_slug' => $context->userShop?->slug,
|
||||
'session_id' => session()->getId(),
|
||||
'memory_usage_mb' => round(memory_get_usage() / 1024 / 1024, 2)
|
||||
]);
|
||||
}
|
||||
}
|
||||
17
dev/app-bak/Http/Middleware/EncryptCookies.php
Executable file
17
dev/app-bak/Http/Middleware/EncryptCookies.php
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
30
dev/app-bak/Http/Middleware/Localization.php
Executable file
30
dev/app-bak/Http/Middleware/Localization.php
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Carbon;
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class Localization
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (\Session::has('locale')) {
|
||||
\App::setLocale(\Session::get('locale'));
|
||||
// Carbon::setLocale('\Session::get('locale')');
|
||||
//Carbon::setLocale('de');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
||||
26
dev/app-bak/Http/Middleware/RedirectIfAuthenticated.php
Executable file
26
dev/app-bak/Http/Middleware/RedirectIfAuthenticated.php
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $guard
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
29
dev/app-bak/Http/Middleware/RemoveExcessWhitespaceMiddleware.php
Executable file
29
dev/app-bak/Http/Middleware/RemoveExcessWhitespaceMiddleware.php
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
use Closure;
|
||||
class RemoveExcessWhitespaceMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
$output = $response->getOriginalContent();
|
||||
|
||||
$filters = array(
|
||||
'/<!--([^\[|(<!)].*)/' => '', // Remove HTML Comments (breaks with HTML5 Boilerplate)
|
||||
'/(?<!\S)\/\/\s*[^\r\n]*/' => '', // Remove comments in the form /* */
|
||||
'/\s{2,}/' => ' ', // Shorten multiple white spaces
|
||||
'/(\r?\n)/' => '', // Collapse new lines
|
||||
'/(\>)\s*(\<)/m' => '$1$2', // Trim Final Whitespace from between html tags
|
||||
);
|
||||
$output = preg_replace(array_keys($filters), array_values($filters), $output);
|
||||
$response->setContent($output);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
32
dev/app-bak/Http/Middleware/SuperAdmin.php
Executable file
32
dev/app-bak/Http/Middleware/SuperAdmin.php
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class SuperAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// Nur SuperAdmins (admin >= 3) durchlassen
|
||||
if ($user->admin >= 3) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
abort(403, 'Sie benötigen SuperAdmin-Rechte für diesen Bereich.');
|
||||
}
|
||||
}
|
||||
32
dev/app-bak/Http/Middleware/SysAdmin.php
Executable file
32
dev/app-bak/Http/Middleware/SysAdmin.php
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Auth;
|
||||
|
||||
class SysAdmin
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if (!Auth::check()) {
|
||||
return redirect('/home');
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
// Nur SysAdmins (admin >= 4) durchlassen
|
||||
if ($user->admin >= 4) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
abort(403, 'Sie benötigen SysAdmin-Rechte für diesen Bereich.');
|
||||
}
|
||||
}
|
||||
18
dev/app-bak/Http/Middleware/TrimStrings.php
Executable file
18
dev/app-bak/Http/Middleware/TrimStrings.php
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
29
dev/app-bak/Http/Middleware/TrustProxies.php
Executable file
29
dev/app-bak/Http/Middleware/TrustProxies.php
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array|string|null
|
||||
*/
|
||||
protected $proxies = '*';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
17
dev/app-bak/Http/Middleware/VerifyCsrfToken.php
Executable file
17
dev/app-bak/Http/Middleware/VerifyCsrfToken.php
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'portal/login/verify', // Temporär für OTP-Login
|
||||
];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue