ultisuite-client/app/auth/complete/page.tsx
2026-05-25 13:52:40 +02:00

70 lines
1.8 KiB
TypeScript

"use client"
import { useEffect, Suspense } from "react"
import { useRouter, useSearchParams } from "next/navigation"
import { useAuthStore } from "@/lib/api/auth-store"
import type { PlatformUser } from "@/lib/auth/jwt-claims"
function AuthCompleteInner() {
const router = useRouter()
const searchParams = useSearchParams()
const login = useAuthStore((s) => s.login)
const returnTo = searchParams.get("returnTo") ?? "/mail/inbox"
const accountNotice = searchParams.get("accountNotice")
useEffect(() => {
let cancelled = false
async function finish() {
try {
const res = await fetch("/api/auth/session", { credentials: "include" })
const data = (await res.json()) as {
authenticated?: boolean
accessToken?: string
refreshToken?: string | null
expiresAt?: number
user?: PlatformUser | null
}
if (
data.authenticated &&
data.accessToken &&
data.expiresAt &&
!cancelled
) {
login(
data.accessToken,
data.refreshToken ?? "",
data.expiresAt,
data.user ?? null
)
if (accountNotice === "same") {
sessionStorage.setItem("ulti_account_notice", "same")
}
router.replace(returnTo.startsWith("/") ? returnTo : "/mail/inbox")
return
}
} catch {
// fall through
}
if (!cancelled) {
router.replace("/login?error=session_failed")
}
}
void finish()
return () => {
cancelled = true
}
}, [accountNotice, login, returnTo, router])
return null
}
export default function AuthCompletePage() {
return (
<Suspense fallback={null}>
<AuthCompleteInner />
</Suspense>
)
}