| import { getLoginUrl } from "@/const"; | |
| import { trpc } from "@/lib/trpc"; | |
| import { TRPCClientError } from "@trpc/client"; | |
| import { useCallback, useEffect, useMemo } from "react"; | |
| type UseAuthOptions = { | |
| redirectOnUnauthenticated?: boolean; | |
| redirectPath?: string; | |
| }; | |
| export function useAuth(options?: UseAuthOptions) { | |
| const { redirectOnUnauthenticated = false, redirectPath = getLoginUrl() } = | |
| options ?? {}; | |
| const utils = trpc.useUtils(); | |
| const meQuery = trpc.auth.me.useQuery(undefined, { | |
| retry: false, | |
| refetchOnWindowFocus: false, | |
| }); | |
| const logoutMutation = trpc.auth.logout.useMutation({ | |
| onSuccess: () => { | |
| utils.auth.me.setData(undefined, null); | |
| }, | |
| }); | |
| const logout = useCallback(async () => { | |
| try { | |
| await logoutMutation.mutateAsync(); | |
| } catch (error: unknown) { | |
| if ( | |
| error instanceof TRPCClientError && | |
| error.data?.code === "UNAUTHORIZED" | |
| ) { | |
| return; | |
| } | |
| throw error; | |
| } finally { | |
| utils.auth.me.setData(undefined, null); | |
| await utils.auth.me.invalidate(); | |
| } | |
| }, [logoutMutation, utils]); | |
| const state = useMemo(() => { | |
| localStorage.setItem( | |
| "manus-runtime-user-info", | |
| JSON.stringify(meQuery.data) | |
| ); | |
| return { | |
| user: meQuery.data ?? null, | |
| loading: meQuery.isLoading || logoutMutation.isPending, | |
| error: meQuery.error ?? logoutMutation.error ?? null, | |
| isAuthenticated: Boolean(meQuery.data), | |
| }; | |
| }, [ | |
| meQuery.data, | |
| meQuery.error, | |
| meQuery.isLoading, | |
| logoutMutation.error, | |
| logoutMutation.isPending, | |
| ]); | |
| useEffect(() => { | |
| if (!redirectOnUnauthenticated) return; | |
| if (meQuery.isLoading || logoutMutation.isPending) return; | |
| if (state.user) return; | |
| if (typeof window === "undefined") return; | |
| if (window.location.pathname === redirectPath) return; | |
| window.location.href = redirectPath | |
| }, [ | |
| redirectOnUnauthenticated, | |
| redirectPath, | |
| logoutMutation.isPending, | |
| meQuery.isLoading, | |
| state.user, | |
| ]); | |
| return { | |
| ...state, | |
| refresh: () => meQuery.refetch(), | |
| logout, | |
| }; | |
| } | |