@vtex/faststore-plugin-buyer-portal 1.1.113 → 1.1.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/faststore-plugin-buyer-portal",
3
- "version": "1.1.113",
3
+ "version": "1.1.115",
4
4
  "description": "A plugin for faststore with buyer portal",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,6 +12,7 @@ import { AUT_COOKIE_KEY } from "../utils/constants";
12
12
  */
13
13
  export const useCookieMonitor = () => {
14
14
  const [hasCookie, setHasCookie] = useState(false);
15
+ const [timedOut, setTimedOut] = useState(false);
15
16
 
16
17
  useEffect(() => {
17
18
  const checkCookie = () => {
@@ -24,19 +25,33 @@ export const useCookieMonitor = () => {
24
25
  cookie.trim().startsWith(`${cookieName}=`)
25
26
  );
26
27
 
27
- return !!authCookie && authCookie.split("=")[1]?.trim() !== "";
28
+ const hasCookieValue =
29
+ !!authCookie && authCookie.split("=")[1]?.trim() !== "";
30
+
31
+ console.log("[useCookieMonitor] Checking cookie:", {
32
+ cookieName,
33
+ hasCookie: hasCookieValue,
34
+ cookieValue: authCookie
35
+ ? authCookie.split("=")[1]?.substring(0, 10) + "..."
36
+ : "none",
37
+ });
38
+
39
+ return hasCookieValue;
28
40
  };
29
41
 
30
42
  // Check immediately
31
43
  const initialCheck = checkCookie();
44
+ console.log("[useCookieMonitor] Initial check:", initialCheck);
32
45
  setHasCookie(initialCheck);
33
46
 
34
47
  // If no cookie yet, poll for it
35
48
  if (!initialCheck) {
49
+ console.log("[useCookieMonitor] Starting cookie polling...");
36
50
  const interval = setInterval(() => {
37
51
  const hasAuthCookie = checkCookie();
38
52
 
39
53
  if (hasAuthCookie) {
54
+ console.log("[useCookieMonitor] Cookie found! Stopping poll.");
40
55
  setHasCookie(true);
41
56
  clearInterval(interval);
42
57
  }
@@ -44,6 +59,10 @@ export const useCookieMonitor = () => {
44
59
 
45
60
  // Cleanup after 5 seconds max
46
61
  const timeout = setTimeout(() => {
62
+ console.log(
63
+ "[useCookieMonitor] Polling timeout reached (5s) - cookie never appeared"
64
+ );
65
+ setTimedOut(true);
47
66
  clearInterval(interval);
48
67
  }, 5000);
49
68
 
@@ -54,5 +73,5 @@ export const useCookieMonitor = () => {
54
73
  }
55
74
  }, []);
56
75
 
57
- return hasCookie;
76
+ return { hasCookie, timedOut };
58
77
  };
@@ -3,4 +3,9 @@ import { ClientContext } from "../utils";
3
3
  export type AuthRouteProps<T> =
4
4
  | { authorized: true; data: T; clientContext: ClientContext; loading: false }
5
5
  | { authorized: false; loading: false }
6
- | { authorized: false; loading: true };
6
+ | {
7
+ authorized: false;
8
+ loading: true;
9
+ data?: Partial<T>;
10
+ clientContext?: ClientContext;
11
+ };
@@ -1,8 +1,7 @@
1
- import { useEffect, type ComponentType } from "react";
1
+ import { useEffect, useRef, type ComponentType } from "react";
2
2
 
3
3
  import { useRouter } from "next/router";
4
4
 
5
- import { PageLoader } from "../components";
6
5
  import { useCookieMonitor } from "../hooks/useCookieMonitor";
7
6
 
8
7
  import type { AuthRouteProps } from "../types";
@@ -16,29 +15,69 @@ export const withAuth = <T extends Record<string, unknown>>(
16
15
  ) => {
17
16
  return function AuthenticatedComponent(props: AuthRouteProps<T>) {
18
17
  const router = useRouter();
19
- const hasCookie = useCookieMonitor();
18
+ const { hasCookie, timedOut } = useCookieMonitor();
19
+ const reloadAttemptedRef = useRef(false);
20
+
21
+ // Debug logging
22
+ useEffect(() => {
23
+ console.log("[withAuth] Props state:", {
24
+ authorized: props?.authorized,
25
+ loading: props?.loading,
26
+ hasCookie,
27
+ timedOut,
28
+ reloadAttempted: reloadAttemptedRef.current,
29
+ });
30
+ }, [props?.authorized, props?.loading, hasCookie, timedOut]);
20
31
 
21
32
  useEffect(() => {
22
33
  // If not authorized and not loading, reload the page
23
- if (!props?.authorized && !props?.loading) {
24
- router.reload();
34
+ if (
35
+ !props?.authorized &&
36
+ !props?.loading &&
37
+ !reloadAttemptedRef.current
38
+ ) {
39
+ console.log("[withAuth] Reloading: not authorized and not loading");
40
+ reloadAttemptedRef.current = true;
41
+ // Use replace to bypass Next.js data cache
42
+ router.replace(router.asPath);
25
43
  }
26
44
  }, [props?.authorized, props?.loading, router]);
27
45
 
28
46
  useEffect(() => {
29
- if (props?.loading && hasCookie) {
30
- router.reload();
47
+ if (props?.loading && hasCookie && !reloadAttemptedRef.current) {
48
+ console.log(
49
+ "[withAuth] Cookie available, performing hard reload to bypass cache"
50
+ );
51
+ reloadAttemptedRef.current = true;
52
+ // Hard reload to completely bypass Next.js cache
53
+ if (typeof window !== "undefined") {
54
+ window.location.href = router.asPath;
55
+ }
31
56
  }
32
57
  }, [props?.loading, hasCookie, router]);
33
58
 
34
- if (!props?.authorized) {
35
- if (props?.loading) {
36
- return <PageLoader />;
59
+ useEffect(() => {
60
+ // If we're in loading state and timeout reached, redirect to home
61
+ if (props?.loading && timedOut && !reloadAttemptedRef.current) {
62
+ console.log("[withAuth] Cookie timeout - redirecting to home page");
63
+ reloadAttemptedRef.current = true;
64
+ router.push("/");
37
65
  }
66
+ }, [props?.loading, timedOut, router]);
67
+
68
+ // Always render the component, but pass loading state
69
+ // This allows components to handle their own loading states
70
+ if (!props?.authorized && !props?.loading) {
71
+ // Not authorized and not loading = permanently denied
38
72
  return null;
39
73
  }
40
74
 
41
- // If authorized, render the component with the data
42
- return <Component {...(props.data as T)} />;
75
+ // Render with whatever data we have (might be empty/partial if loading)
76
+ const componentProps = {
77
+ ...(props?.data || ({} as T)),
78
+ loading: props?.loading || false,
79
+ } as T & { loading: boolean };
80
+
81
+ return <Component {...componentProps} />;
43
82
  };
44
83
  };
@@ -20,7 +20,13 @@ export const withAuthLoader = async <T>(
20
20
  // Check if auth cookie exists before proceeding
21
21
  const authCookie = getAuthCookie(data);
22
22
 
23
+ console.log("[withAuthLoader] Cookie check:", {
24
+ hasCookie: !!authCookie,
25
+ cookieLength: authCookie?.length,
26
+ });
27
+
23
28
  if (!authCookie || authCookie === "") {
29
+ console.log("[withAuthLoader] Returning loading state (no cookie)");
24
30
  return {
25
31
  authorized: false,
26
32
  loading: true,
@@ -31,7 +37,10 @@ export const withAuthLoader = async <T>(
31
37
 
32
38
  const hasAccess = await validateAccessService({ cookie });
33
39
 
40
+ console.log("[withAuthLoader] Access validation result:", hasAccess);
41
+
34
42
  if (!hasAccess) {
43
+ console.log("[withAuthLoader] Access denied, redirecting to /");
35
44
  data.res?.writeHead(302, { Location: "/" });
36
45
  data.res?.end();
37
46
 
@@ -43,6 +52,9 @@ export const withAuthLoader = async <T>(
43
52
 
44
53
  const pageData = await dataLoader({ cookie, userId, ...clientContext });
45
54
 
55
+ console.log(
56
+ "[withAuthLoader] Successfully loaded data, returning authorized"
57
+ );
46
58
  return {
47
59
  authorized: true,
48
60
  data: pageData,
@@ -50,7 +62,7 @@ export const withAuthLoader = async <T>(
50
62
  loading: false,
51
63
  };
52
64
  } catch (error) {
53
- console.error("Auth validation failed:", error);
65
+ console.error("[withAuthLoader] Auth validation failed:", error);
54
66
 
55
67
  data.res?.writeHead(302, { Location: "/" });
56
68
  data.res?.end();
@@ -1,8 +1,8 @@
1
- import { useEffect, type ComponentType } from "react";
1
+ import { useEffect, useRef, type ComponentType } from "react";
2
2
 
3
3
  import { useRouter } from "next/router";
4
4
 
5
- import { BuyerPortalProvider, PageLoader } from "../components";
5
+ import { BuyerPortalProvider } from "../components";
6
6
  import { useCookieMonitor } from "../hooks/useCookieMonitor";
7
7
 
8
8
  import type { AuthRouteProps } from "../types";
@@ -18,32 +18,90 @@ export const withAuthProvider = <T,>(
18
18
  ) => {
19
19
  return function WrappedPage(props: AuthRouteProps<T>) {
20
20
  const router = useRouter();
21
- const hasCookie = useCookieMonitor();
21
+ const { hasCookie, timedOut } = useCookieMonitor();
22
+ const reloadAttemptedRef = useRef(false);
23
+ const isProduction = process.env.NODE_ENV === "production";
24
+
25
+ // Debug logging (only in development or when needed)
26
+ useEffect(() => {
27
+ if (!isProduction) {
28
+ console.log("[withAuthProvider] Props state:", {
29
+ authorized: props?.authorized,
30
+ loading: props?.loading,
31
+ hasCookie,
32
+ timedOut,
33
+ reloadAttempted: reloadAttemptedRef.current,
34
+ routerPath: router.asPath,
35
+ });
36
+ }
37
+ }, [
38
+ props?.authorized,
39
+ props?.loading,
40
+ hasCookie,
41
+ timedOut,
42
+ router.asPath,
43
+ isProduction,
44
+ ]);
22
45
 
23
46
  useEffect(() => {
24
47
  // Se não está autorizado e não está carregando, recarrega a página
25
- if (!props?.authorized && !props?.loading) {
26
- router.reload();
48
+ if (
49
+ !props?.authorized &&
50
+ !props?.loading &&
51
+ !reloadAttemptedRef.current
52
+ ) {
53
+ console.log(
54
+ "[withAuthProvider] Reloading: not authorized and not loading"
55
+ );
56
+ reloadAttemptedRef.current = true;
57
+ // Use replace to bypass Next.js data cache
58
+ router.replace(router.asPath);
27
59
  }
28
60
  }, [props?.authorized, props?.loading, router]);
29
61
 
30
62
  useEffect(() => {
31
- // If we're in loading state and cookie becomes available, reload to fetch data
32
- if (props?.loading && hasCookie) {
33
- router.reload();
63
+ // If we're in loading state and cookie becomes available, do hard reload
64
+ if (props?.loading && hasCookie && !reloadAttemptedRef.current) {
65
+ console.log(
66
+ "[withAuthProvider] Cookie available, performing hard reload to bypass cache"
67
+ );
68
+ reloadAttemptedRef.current = true;
69
+ // Hard reload to completely bypass Next.js cache
70
+ if (typeof window !== "undefined") {
71
+ window.location.href = router.asPath;
72
+ }
34
73
  }
35
74
  }, [props?.loading, hasCookie, router]);
36
75
 
37
- if (!props?.authorized) {
38
- if (props?.loading) {
39
- return <PageLoader />;
76
+ useEffect(() => {
77
+ // If we're in loading state and timeout reached, redirect to home
78
+ if (props?.loading && timedOut && !reloadAttemptedRef.current) {
79
+ console.log(
80
+ "[withAuthProvider] Cookie timeout - redirecting to home page"
81
+ );
82
+ reloadAttemptedRef.current = true;
83
+ router.push("/");
40
84
  }
85
+ }, [props?.loading, timedOut, router]);
86
+
87
+ // Always render the component, but pass loading state
88
+ // This allows components to handle their own loading states
89
+ if (!props?.authorized && !props?.loading) {
90
+ // Not authorized and not loading = permanently denied
41
91
  return null;
42
92
  }
43
93
 
94
+ // Render with whatever data we have (might be empty/partial if loading)
95
+ const componentProps = {
96
+ ...(props?.data || ({} as T)),
97
+ loading: props?.loading || false,
98
+ } as T & { loading: boolean };
99
+
100
+ const clientContext = props?.clientContext || ({} as ClientContext);
101
+
44
102
  return (
45
- <BuyerPortalProvider clientContext={props?.clientContext}>
46
- <Component {...props.data} clientContext={props?.clientContext} />
103
+ <BuyerPortalProvider clientContext={clientContext}>
104
+ <Component {...componentProps} clientContext={clientContext} />
47
105
  </BuyerPortalProvider>
48
106
  );
49
107
  };