diff --git a/CHANGELOG.md b/CHANGELOG.md index b10f219..04dfd2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - **Better form experience.** Forms now auto-focus the first field when they open, text inputs enforce character limits with a visible counter when you're close, and the settings page warns you before navigating away with unsaved changes. - **Tighter name limits.** Site, funnel, and monitor names are now capped at 100 characters instead of 255 — long enough for any real name, short enough to not break the UI. +### Fixed + +- **Organization context switch.** Switching away from a deleted organization now stores the session correctly instead of using an insecure fallback. + ## [0.10.0-alpha] - 2026-02-21 ### Changed diff --git a/components/settings/OrganizationSettings.tsx b/components/settings/OrganizationSettings.tsx index 28bd657..6e22ce9 100644 --- a/components/settings/OrganizationSettings.tsx +++ b/components/settings/OrganizationSettings.tsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback, useRef } from 'react' import { useRouter, useSearchParams } from 'next/navigation' +import { setSessionAction } from '@/app/actions/auth' import { useAuth } from '@/lib/auth/context' import { deleteOrganization, @@ -418,7 +419,7 @@ export default function OrganizationSettings() { // * Switch to personal context explicitly try { const { access_token } = await switchContext(null) - localStorage.setItem('token', access_token) + await setSessionAction(access_token) window.location.href = '/' } catch (switchErr) { console.error('Failed to switch to personal context after delete:', switchErr) diff --git a/lib/api/client.ts b/lib/api/client.ts index e012341..c3734e7 100644 --- a/lib/api/client.ts +++ b/lib/api/client.ts @@ -184,46 +184,5 @@ async function apiRequest( return response.json() } -// * Legacy axios-style client for compatibility -export function getClient() { - return { - post: async (endpoint: string, body: any) => { - // Handle the case where endpoint might start with /api (remove it if our base client adds it, OR adjust usage) - // Our apiRequest adds /api/v1 prefix. - // If we pass /api/billing/checkout, apiRequest makes it /api/v1/api/billing/checkout -> Wrong. - // We should probably just expose apiRequest directly or wrap it properly. - - // Let's adapt the endpoint: - // If endpoint starts with /api/, strip it because apiRequest adds /api/v1 - // BUT WAIT: The backend billing endpoint is likely at /api/billing/checkout (not /api/v1/billing/checkout) if I registered it at root group? - // Let's check backend routing. - // In main.go: billingGroup := router.Group("/api/billing") -> so it is at /api/billing/... NOT /api/v1/billing... - - // So we need a raw fetch for this, or modify apiRequest to support non-v1 routes. - // For now, let's just implement a simple fetch wrapper that mimics axios - - const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null - const headers: any = { 'Content-Type': 'application/json' } - // Although we use cookies, sometimes we might fallback to token if cookies fail? - // Pulse uses cookies primarily now. - - const url = `${API_URL}${endpoint}` - const res = await fetch(url, { - method: 'POST', - headers, - body: JSON.stringify(body), - credentials: 'include' - }) - - if (!res.ok) { - const err = await res.json().catch(() => ({})) - throw new Error(err.error || 'Request failed') - } - - return { data: await res.json() } - } - } -} - export const authFetch = apiRequest export default apiRequest