diff --git a/lib/Http/IntendedUrlService.php b/lib/Http/IntendedUrlService.php index 236900f..4631674 100644 --- a/lib/Http/IntendedUrlService.php +++ b/lib/Http/IntendedUrlService.php @@ -47,12 +47,22 @@ class IntendedUrlService /** * Retrieve the intended URL and remove it from the session. * Returns the fallback ('admin') if no valid URL is stored. + * + * The stored URL is a full REQUEST_URI (e.g. /de/admin/users?page=2) + * but Router::redirect() expects a route path without leading slash + * and without locale prefix (e.g. admin/users?page=2), because it + * prepends getBaseUrl() which already includes the base path. */ public function retrieveAndForget(SessionStoreInterface $session): string { $value = $this->retrieve($session); $session->remove(self::SESSION_KEY); - return $value ?? self::FALLBACK; + + if ($value === null) { + return self::FALLBACK; + } + + return $this->toRoutePath($value); } /** @@ -103,6 +113,25 @@ class IntendedUrlService return $url; } + /** + * Convert a full REQUEST_URI into a Router::redirect()-compatible route path. + * + * /de/admin/users?page=2 → admin/users?page=2 + * /admin/users → admin/users + */ + public function toRoutePath(string $url): string + { + // Remove leading slash + $path = ltrim($url, '/'); + + // Remove locale prefix (2-letter code followed by /) + if (preg_match('#^[a-z]{2}/#', $path)) { + $path = substr($path, 3); + } + + return $path !== '' ? $path : self::FALLBACK; + } + /** * Extract the path portion without query string and without locale prefix. */ diff --git a/lib/Support/helpers/app.php b/lib/Support/helpers/app.php index 8f352f0..7fb0d7d 100644 --- a/lib/Support/helpers/app.php +++ b/lib/Support/helpers/app.php @@ -450,6 +450,24 @@ function appLogoUrl(?int $size = null): string return asset('brand/logo.svg'); } +/** + * Resolve logo for auth pages: tenant avatar → global logo → default SVG. + * + * After logout the tenant context (`$_SESSION['current_tenant']`) is preserved, + * so the login page can show the tenant avatar instead of the generic app logo. + */ +function appAuthLogoUrl(?int $size = null): string +{ + $tenantUuid = $_SESSION['current_tenant']['uuid'] ?? ''; + if ($tenantUuid !== '' && class_exists('MintyPHP\\Service\\Tenant\\TenantAvatarService')) { + if (app(\MintyPHP\Service\Tenant\TenantAvatarService::class)->hasAvatar($tenantUuid)) { + $query = $size ? '&size=' . (int) $size : ''; + return lurl('auth/tenant-avatar-file?uuid=' . rawurlencode($tenantUuid) . $query); + } + } + return appLogoUrl($size); +} + /** * Resolve favicon path (tenant favicon with global fallback). */ diff --git a/pages/auth/login().php b/pages/auth/login().php index e36a5ee..68e2c7b 100644 --- a/pages/auth/login().php +++ b/pages/auth/login().php @@ -15,12 +15,21 @@ $requestRuntime = app(RequestRuntimeInterface::class); $sessionStore = app(SessionStoreInterface::class); $intendedUrlService = app(IntendedUrlService::class); -// Store return_to from query parameter (set by session timeout or auth guard redirect). +// Store return_to from query parameter (set by session timeout or auth guard redirect) +// or from hidden form field (preserved through multi-stage login POST flow). $returnTo = trim((string) (requestInput()->queryAll()['return_to'] ?? '')); +if ($returnTo === '') { + $returnTo = trim((string) (requestInput()->bodyAll()['return_to'] ?? '')); +} + if ($returnTo !== '') { $intendedUrlService->store($returnTo, $sessionStore); } +// Expose sanitized return_to for hidden form fields so it survives across +// POST stages even if the query string or session is lost. +$returnToSanitized = $intendedUrlService->sanitize($returnTo !== '' ? $returnTo : ($intendedUrlService->retrieve($sessionStore) ?? '')); + $session = $sessionStore->all(); if (!empty($session['user']['id'])) { diff --git a/pages/auth/login(login).phtml b/pages/auth/login(login).phtml index ca384be..5befa9c 100644 --- a/pages/auth/login(login).phtml +++ b/pages/auth/login(login).phtml @@ -58,6 +58,7 @@ $authLogoHref = lurl('login'); if ($tenantHint !== '') { $authLogoHref .= '?tenant=' . rawurlencode($tenantHint); } +$returnToSanitized = (string) ($returnToSanitized ?? ''); ?> @@ -85,6 +86,7 @@ if ($tenantHint !== '') {
+