fix: correct organization context switching to ensure secure session storage when switching away from deleted organizations
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -184,46 +184,5 @@ async function apiRequest<T>(
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user