fix stale session cookie (#823)

- redirect to login when session is gone instead of blank screen
- show cached username while session restores so header doesn't flicker
- cleaned up redundant type casts and unused vars
This commit is contained in:
Prasanna721 2026-04-03 01:55:24 +00:00
parent 5fd7f1d7dd
commit c012f3b5c4
3 changed files with 19 additions and 13 deletions

View file

@ -10,8 +10,14 @@ export function EnsureWorkspace({ children }: { children: React.ReactNode }) {
const { session, organizations, isRestoring } = useAuth()
useEffect(() => {
if (!session) return
if (isRestoring || organizations === null) return
if (isRestoring) return
if (!session) {
router.replace(
`/login?redirect=${encodeURIComponent(window.location.href)}`,
)
return
}
if (organizations === null) return
if (organizations.length > 0) return
if (pathname.startsWith("/onboarding")) return
router.replace("/onboarding/welcome?step=input")

View file

@ -34,7 +34,7 @@ import { useIsMobile } from "@hooks/use-mobile"
import { useLocalStorageUsername } from "@hooks/use-local-storage-username"
import { UserProfileMenu } from "@/components/user-profile-menu"
import { FeedbackModal } from "./feedback-modal"
import { useViewMode } from "@/lib/view-mode-context"
import { useViewMode, type ViewMode } from "@/lib/view-mode-context"
import { useQueryState } from "nuqs"
import { feedbackParam } from "@/lib/search-params"
@ -45,7 +45,7 @@ interface HeaderProps {
}
export function Header({ onAddMemory, onOpenChat, onOpenSearch }: HeaderProps) {
const { user } = useAuth()
const { user, isRestoring } = useAuth()
const { selectedProjects, setSelectedProjects } = useProject()
const router = useRouter()
const isMobile = useIsMobile()
@ -53,14 +53,16 @@ export function Header({ onAddMemory, onOpenChat, onOpenSearch }: HeaderProps) {
"feedback",
feedbackParam,
)
const isFeedbackOpen = feedbackOpen ?? false
const { viewMode, setViewMode } = useViewMode()
const handleFeedback = () => setFeedbackOpen(true)
const localStorageUsername = useLocalStorageUsername()
const displayName =
user?.displayUsername || localStorageUsername || user?.name || ""
user?.displayUsername ||
(isRestoring ? localStorageUsername : "") ||
user?.name ||
""
const userName = displayName ? `${displayName.split(" ")[0]}'s` : "My"
return (
<div className="flex p-3 md:p-4 justify-between items-center gap-2">
@ -141,7 +143,7 @@ export function Header({ onAddMemory, onOpenChat, onOpenSearch }: HeaderProps) {
<Tabs
value={viewMode === "list" ? "grid" : viewMode}
onValueChange={(v) =>
setViewMode(v === "grid" ? "list" : (v as "graph" | "integrations"))
setViewMode(v === "grid" ? "list" : (v as ViewMode))
}
>
<TabsList className="rounded-full border border-[#161F2C] h-11! z-10!">
@ -307,7 +309,7 @@ export function Header({ onAddMemory, onOpenChat, onOpenSearch }: HeaderProps) {
<UserProfileMenu />
</div>
<FeedbackModal
isOpen={isFeedbackOpen}
isOpen={feedbackOpen}
onClose={() => setFeedbackOpen(false)}
/>
</div>

View file

@ -42,7 +42,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
isPending: orgsPending,
} = authClient.useListOrganizations()
const organizations: OrganizationListItem[] | null =
const organizations =
session?.session == null ? null : orgsPending ? null : (orgsData ?? [])
const refetchOrganizations = useCallback(
@ -74,9 +74,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
}, [])
useEffect(() => {
if (isSessionPending) {
return
}
if (isSessionPending) return
if (!session?.session) {
setIsRestoring(false)
@ -150,7 +148,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
return () => {
cancelled = true
}
}, [session, isSessionPending, orgsData, orgsPending, setActiveOrg])
}, [isSessionPending, session, orgsData, orgsPending, setActiveOrg])
useEffect(() => {
if (typeof window === "undefined") return