put(WorkspaceContext::INTENDED_URL_SESSION_KEY, $pathWithQuery); } /** * Store the intended URL derived from the current request. */ public static function storeFromRequest(Request $request): void { if (! $request->isMethod('GET')) { return; } $path = '/'.ltrim($request->path(), '/'); $queryString = $request->getQueryString(); $pathWithQuery = $queryString ? "{$path}?{$queryString}" : $path; self::store($pathWithQuery, $request); } /** * Consume (read + forget) the intended URL. Returns null if missing or unsafe. */ public static function consume(?Request $request = null): ?string { $session = self::session($request); if (! $session instanceof Store) { return null; } $value = $session->pull(WorkspaceContext::INTENDED_URL_SESSION_KEY); if (! is_string($value)) { return null; } $value = trim($value); if ($value === '' || ! self::isAllowed($value)) { return null; } return $value; } public static function clear(?Request $request = null): void { $session = self::session($request); if (! $session instanceof Store) { return; } $session->forget(WorkspaceContext::INTENDED_URL_SESSION_KEY); } private static function session(?Request $request = null): ?Store { $session = ($request && $request->hasSession()) ? $request->session() : session()->driver(); return $session instanceof Store ? $session : null; } private static function isAllowed(string $pathWithQuery): bool { if (str_contains($pathWithQuery, "\n") || str_contains($pathWithQuery, "\r")) { return false; } if (preg_match('#^https?://#i', $pathWithQuery) === 1) { return false; } if (str_starts_with($pathWithQuery, '//')) { return false; } if (! str_starts_with($pathWithQuery, '/admin')) { return false; } $path = parse_url($pathWithQuery, PHP_URL_PATH); $path = '/'.ltrim((string) ($path ?? ''), '/'); if (in_array($path, ['/admin/choose-workspace', '/admin/no-access'], true)) { return false; } return true; } }