File size: 3,969 Bytes
c10f8f8
 
 
 
 
 
 
 
 
c2bb873
 
 
 
 
 
c10f8f8
 
 
 
 
 
 
 
 
 
 
 
 
 
c2bb873
 
 
 
 
 
 
 
c10f8f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2bb873
 
 
 
 
 
c10f8f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2bb873
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c10f8f8
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useCookie } from "react-use";
import { useRouter } from "next/navigation";

import { User } from "@/types";
import { api } from "@/lib/api";
import { toast } from "sonner";
import { 
  storeAuthDataFallback, 
  getAuthDataFallback, 
  clearAuthDataFallback,
  isInIframe 
} from "@/lib/iframe-storage";


export const useUser = (initialData?: {
  user: User | null;
  errCode: number | null;
}) => {
  const client = useQueryClient();
  const router = useRouter();
  const [currentRoute, setCurrentRoute, removeCurrentRoute] = useCookie("deepsite-currentRoute");

  const { data: { user, errCode } = { user: null, errCode: null }, isLoading } =
    useQuery({
      queryKey: ["user.me"],
      queryFn: async () => {
        // Check for fallback data if no initial data provided and we're in iframe
        if (!initialData && isInIframe()) {
          const fallbackData = getAuthDataFallback();
          if (fallbackData.user && fallbackData.token) {
            return { user: fallbackData.user, errCode: null };
          }
        }
        return { user: initialData?.user || null, errCode: initialData?.errCode || null };
      },
      refetchOnWindowFocus: false,
      refetchOnReconnect: false,
      refetchOnMount: false,
      retry: false,
      initialData: initialData
        ? { user: initialData?.user, errCode: initialData?.errCode }
        : undefined,
      enabled: false,
    });

  const { data: loadingAuth } = useQuery({
    queryKey: ["loadingAuth"],
    queryFn: async () => false,
    refetchOnWindowFocus: false,
    refetchOnReconnect: false,
    refetchOnMount: false,
  });
  const setLoadingAuth = (value: boolean) => {
    client.setQueryData(["setLoadingAuth"], value);
  };

  const openLoginWindow = async () => {
    setCurrentRoute(window.location.pathname);
    return router.push("/auth");
  };

  const loginFromCode = async (code: string) => {
    setLoadingAuth(true);
    if (loadingAuth) return;
    await api
      .post("/auth", { code })
      .then(async (res: any) => {
        if (res.data) {
          // Cookie is now set server-side with proper iframe attributes
          // Also store fallback data for iframe contexts
          if (res.data.useLocalStorageFallback) {
            storeAuthDataFallback(res.data.access_token, res.data.user);
          }
          
          client.setQueryData(["user.me"], {
            user: res.data.user,
            errCode: null,
          });
          if (currentRoute) {
            router.push(currentRoute);
            removeCurrentRoute();
          } else {
            router.push("/projects");
          }
          toast.success("Login successful");
        }
      })
      .catch((err: any) => {
        toast.error(err?.data?.message ?? err.message ?? "An error occurred");
      })
      .finally(() => {
        setLoadingAuth(false);
      });
  };

  const logout = async () => {
    try {
      // Call server endpoint to clear the HTTP-only cookie
      await api.post("/auth/logout");
      // Clear fallback storage
      clearAuthDataFallback();
      removeCurrentRoute();
      client.setQueryData(["user.me"], { user: null, errCode: null });
      router.push("/");
      toast.success("Logout successful");
      client.invalidateQueries({ queryKey: ["user.me"] });
      window.location.reload();
    } catch (error) {
      console.error("Logout error:", error);
      // Even if server call fails, clear client state
      clearAuthDataFallback();
      removeCurrentRoute();
      client.setQueryData(["user.me"], { user: null, errCode: null });
      router.push("/");
      toast.success("Logout successful");
      window.location.reload();
    }
  };

  return {
    user,
    errCode,
    loading: isLoading || loadingAuth,
    openLoginWindow,
    loginFromCode,
    logout,
  };
};