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.
|
- **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.
|
- **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
|
## [0.10.0-alpha] - 2026-02-21
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||||
import { useRouter, useSearchParams } from 'next/navigation'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
|
import { setSessionAction } from '@/app/actions/auth'
|
||||||
import { useAuth } from '@/lib/auth/context'
|
import { useAuth } from '@/lib/auth/context'
|
||||||
import {
|
import {
|
||||||
deleteOrganization,
|
deleteOrganization,
|
||||||
@@ -418,7 +419,7 @@ export default function OrganizationSettings() {
|
|||||||
// * Switch to personal context explicitly
|
// * Switch to personal context explicitly
|
||||||
try {
|
try {
|
||||||
const { access_token } = await switchContext(null)
|
const { access_token } = await switchContext(null)
|
||||||
localStorage.setItem('token', access_token)
|
await setSessionAction(access_token)
|
||||||
window.location.href = '/'
|
window.location.href = '/'
|
||||||
} catch (switchErr) {
|
} catch (switchErr) {
|
||||||
console.error('Failed to switch to personal context after delete:', switchErr)
|
console.error('Failed to switch to personal context after delete:', switchErr)
|
||||||
|
|||||||
@@ -184,46 +184,5 @@ async function apiRequest<T>(
|
|||||||
return response.json()
|
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 const authFetch = apiRequest
|
||||||
export default apiRequest
|
export default apiRequest
|
||||||
|
|||||||
Reference in New Issue
Block a user