Files
sim/apps/sim/app/_shell/providers/session-provider.tsx
Jay Prajapati 9e817bc5b0 fix(auth): make DISABLE_AUTH work in web app (#3297)
Return an anonymous session using the same response envelope as Better Auth's get-session endpoint, and make the session provider tolerant to both wrapped and raw session payloads.

Fixes #2524
2026-02-24 09:52:44 -08:00

105 lines
3.0 KiB
TypeScript

'use client'
import type React from 'react'
import { createContext, useCallback, useEffect, useMemo, useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
import posthog from 'posthog-js'
import { client } from '@/lib/auth/auth-client'
import { extractSessionDataFromAuthClientResult } from '@/lib/auth/session-response'
export type AppSession = {
user: {
id: string
email: string
emailVerified?: boolean
name?: string | null
image?: string | null
createdAt?: Date
updatedAt?: Date
} | null
session?: {
id?: string
userId?: string
activeOrganizationId?: string
}
} | null
export type SessionHookResult = {
data: AppSession
isPending: boolean
error: Error | null
refetch: () => Promise<void>
}
export const SessionContext = createContext<SessionHookResult | null>(null)
export function SessionProvider({ children }: { children: React.ReactNode }) {
const [data, setData] = useState<AppSession>(null)
const [isPending, setIsPending] = useState(true)
const [error, setError] = useState<Error | null>(null)
const queryClient = useQueryClient()
const loadSession = useCallback(async (bypassCache = false) => {
try {
setIsPending(true)
setError(null)
const res = bypassCache
? await client.getSession({ query: { disableCookieCache: true } })
: await client.getSession()
const session = extractSessionDataFromAuthClientResult(res) as AppSession
setData(session)
} catch (e) {
setError(e instanceof Error ? e : new Error('Failed to fetch session'))
} finally {
setIsPending(false)
}
}, [])
useEffect(() => {
// Check if user was redirected after plan upgrade
const params = new URLSearchParams(window.location.search)
const wasUpgraded = params.get('upgraded') === 'true'
if (wasUpgraded) {
params.delete('upgraded')
const newUrl = params.toString()
? `${window.location.pathname}?${params.toString()}`
: window.location.pathname
window.history.replaceState({}, '', newUrl)
}
loadSession(wasUpgraded).then(() => {
if (wasUpgraded) {
queryClient.invalidateQueries({ queryKey: ['organizations'] })
queryClient.invalidateQueries({ queryKey: ['subscription'] })
}
})
}, [loadSession, queryClient])
useEffect(() => {
if (isPending || typeof posthog.identify !== 'function') {
return
}
try {
if (data?.user) {
posthog.identify(data.user.id, {
email: data.user.email,
name: data.user.name,
email_verified: data.user.emailVerified,
created_at: data.user.createdAt,
})
} else {
posthog.reset()
}
} catch {}
}, [data, isPending])
const value = useMemo<SessionHookResult>(
() => ({ data, isPending, error, refetch: loadSession }),
[data, isPending, error, loadSession]
)
return <SessionContext.Provider value={value}>{children}</SessionContext.Provider>
}