From e3ef47b87923d055cba04eaf2695f34c9992f32a Mon Sep 17 00:00:00 2001 From: Urtzi Alfaro Date: Wed, 17 Dec 2025 17:37:46 +0100 Subject: [PATCH] Fix demo session exit redirecting to unauthorized page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clear auth store when exiting demo session to prevent unauthorized page redirect. ## Problem When users clicked "Salir" (Exit) from the demo session, they were redirected to the unauthorized page (`/unauthorized`) instead of the demo landing page (`/demo`). ## Root Cause The `handleExpiration()` function in DemoBanner.tsx was clearing localStorage and navigating to `/demo`, but was NOT clearing the auth store. This created an inconsistent state: - `isDemoMode = false` (localStorage cleared) - `demoSessionId = null` (localStorage cleared) - `isAuthenticated = true` (auth store NOT cleared - still has demo user) The `useHasAccess()` hook checks: ```typescript return isAuthenticated || (isDemoMode && !!demoSessionId); ``` After clearing localStorage but not auth: - `isAuthenticated = true` but the demo session is invalid - `isDemoMode = false` and `demoSessionId = null` - Result: `useHasAccess()` returns `false` When navigating to `/demo`, the ProtectedRoute checked access and found it was `false`, redirecting to `/unauthorized`. ## Solution Call `logout()` on the auth store before navigating to clear the demo user session completely. This ensures: - Auth store is cleared (`isAuthenticated = false`) - User is properly logged out from demo session - Navigation to `/demo` succeeds without authentication check ## Additional Improvements - Also clear `virtual_tenant_id` and `subscription_tier` from localStorage - Updated comment to clarify navigation intent ## Files Changed - frontend/src/components/layout/DemoBanner/DemoBanner.tsx:73-74 - Added auth store logout before navigation - Added clearing of virtual_tenant_id and subscription_tier - Updated comment for clarity 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- .../src/components/layout/DemoBanner/DemoBanner.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/layout/DemoBanner/DemoBanner.tsx b/frontend/src/components/layout/DemoBanner/DemoBanner.tsx index 0c17273a..80720438 100644 --- a/frontend/src/components/layout/DemoBanner/DemoBanner.tsx +++ b/frontend/src/components/layout/DemoBanner/DemoBanner.tsx @@ -62,18 +62,22 @@ export const DemoBanner: React.FC = () => { localStorage.removeItem('demo_account_type'); localStorage.removeItem('demo_expires_at'); localStorage.removeItem('demo_tenant_id'); + localStorage.removeItem('virtual_tenant_id'); + localStorage.removeItem('subscription_tier'); // Clear API client demo session ID and tenant ID apiClient.setDemoSessionId(null); apiClient.setTenantId(null); + // Clear auth store to remove demo user session + const { useAuthStore } = await import('../../../stores/auth.store'); + useAuthStore.getState().logout(); + // Clear tenant store to remove cached demo tenant data const { useTenantStore } = await import('../../../stores/tenant.store'); useTenantStore.getState().clearTenants(); - // Clear notification storage to ensure notifications don't persist across sessions - // Since useNotifications hook doesn't exist, we just continue without clearing - + // Navigate to demo landing page navigate('/demo'); };