@greatapps/common 1.1.272 → 1.1.275

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.
@@ -11,8 +11,7 @@ function AppNavBar({
11
11
  showExpandButton = false,
12
12
  onExpandClick,
13
13
  menuItems = [],
14
- onNotificationsViewAll,
15
- logoutRedirect
14
+ onNotificationsViewAll
16
15
  }) {
17
16
  const router = useRouter();
18
17
  const handleLogoClick = onLogoClick ?? (() => router.push("/"));
@@ -27,13 +26,7 @@ function AppNavBar({
27
26
  onExpandClick,
28
27
  children: [
29
28
  /* @__PURE__ */ jsx(NotificationsPopover, { onViewAll: onNotificationsViewAll }),
30
- /* @__PURE__ */ jsx(
31
- ProfilePopover,
32
- {
33
- menuItems,
34
- logoutRedirect
35
- }
36
- )
29
+ /* @__PURE__ */ jsx(ProfilePopover, { menuItems })
37
30
  ]
38
31
  }
39
32
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/layouts/AppNavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { NavBar } from \"./NavBar\";\nimport { ProfilePopover } from \"./ProfilePopover\";\nimport { NotificationsPopover } from \"./NotificationsPopover\";\nimport type { ProfileMenuItem } from \"./ProfilePopover\";\n\nexport interface AppNavBarProps {\n onLogoClick?: () => void;\n /** Which app is currently active — controls which icon gets the indicator */\n activeApp?: \"gapps\" | \"gpages\";\n appIconHref?: string;\n showExpandButton?: boolean;\n onExpandClick?: () => void;\n menuItems?: ProfileMenuItem[];\n onNotificationsViewAll?: () => void;\n logoutRedirect?: string;\n}\n\nexport function AppNavBar({\n onLogoClick,\n activeApp,\n appIconHref = \"/\",\n showExpandButton = false,\n onExpandClick,\n menuItems = [],\n onNotificationsViewAll,\n logoutRedirect,\n}: AppNavBarProps) {\n const router = useRouter();\n\n const handleLogoClick = onLogoClick ?? (() => router.push(\"/\"));\n const handleAppIconClick = () => router.push(appIconHref);\n\n return (\n <NavBar\n onLogoClick={handleLogoClick}\n onAppIconClick={handleAppIconClick}\n activeApp={activeApp}\n showExpandButton={showExpandButton}\n onExpandClick={onExpandClick}\n >\n <NotificationsPopover onViewAll={onNotificationsViewAll} />\n <ProfilePopover\n menuItems={menuItems}\n logoutRedirect={logoutRedirect}\n />\n </NavBar>\n );\n}\n"],"mappings":";AAoCI,SAOE,KAPF;AAlCJ,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AAe9B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB;AAAA,EACA,YAAY,CAAC;AAAA,EACb;AAAA,EACA;AACF,GAAmB;AACjB,QAAM,SAAS,UAAU;AAEzB,QAAM,kBAAkB,gBAAgB,MAAM,OAAO,KAAK,GAAG;AAC7D,QAAM,qBAAqB,MAAM,OAAO,KAAK,WAAW;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MAEA;AAAA,4BAAC,wBAAqB,WAAW,wBAAwB;AAAA,QACzD;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/layouts/AppNavBar.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { NavBar } from \"./NavBar\";\nimport { ProfilePopover } from \"./ProfilePopover\";\nimport { NotificationsPopover } from \"./NotificationsPopover\";\nimport type { ProfileMenuItem } from \"./ProfilePopover\";\n\nexport interface AppNavBarProps {\n onLogoClick?: () => void;\n /** Which app is currently active — controls which icon gets the indicator */\n activeApp?: \"gapps\" | \"gpages\";\n appIconHref?: string;\n showExpandButton?: boolean;\n onExpandClick?: () => void;\n menuItems?: ProfileMenuItem[];\n onNotificationsViewAll?: () => void;\n}\n\nexport function AppNavBar({\n onLogoClick,\n activeApp,\n appIconHref = \"/\",\n showExpandButton = false,\n onExpandClick,\n menuItems = [],\n onNotificationsViewAll,\n}: AppNavBarProps) {\n const router = useRouter();\n\n const handleLogoClick = onLogoClick ?? (() => router.push(\"/\"));\n const handleAppIconClick = () => router.push(appIconHref);\n\n return (\n <NavBar\n onLogoClick={handleLogoClick}\n onAppIconClick={handleAppIconClick}\n activeApp={activeApp}\n showExpandButton={showExpandButton}\n onExpandClick={onExpandClick}\n >\n <NotificationsPopover onViewAll={onNotificationsViewAll} />\n <ProfilePopover menuItems={menuItems} />\n </NavBar>\n );\n}\n"],"mappings":";AAkCI,SAOE,KAPF;AAhCJ,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,4BAA4B;AAc9B,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,mBAAmB;AAAA,EACnB;AAAA,EACA,YAAY,CAAC;AAAA,EACb;AACF,GAAmB;AACjB,QAAM,SAAS,UAAU;AAEzB,QAAM,kBAAkB,gBAAgB,MAAM,OAAO,KAAK,GAAG;AAC7D,QAAM,qBAAqB,MAAM,OAAO,KAAK,WAAW;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MAEA;AAAA,4BAAC,wBAAqB,WAAW,wBAAwB;AAAA,QACzD,oBAAC,kBAAe,WAAsB;AAAA;AAAA;AAAA,EACxC;AAEJ;","names":[]}
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
- import { useRouter } from "next/navigation";
5
4
  import * as PopoverPrimitive from "@radix-ui/react-popover";
6
5
  import { Popover } from "../ui/overlay/Popover";
7
6
  import { Progress } from "../ui/feedback/Progress";
@@ -17,10 +16,8 @@ function ProfilePopover({
17
16
  side = "top",
18
17
  align = "start",
19
18
  contentClassName = "absolute bottom-2 left-[26px]",
20
- menuItems = [],
21
- logoutRedirect = "/login"
19
+ menuItems = []
22
20
  }) {
23
- const router = useRouter();
24
21
  const { user, logout } = useAuth();
25
22
  const [isLoggingOut, setIsLoggingOut] = useState(false);
26
23
  const { summary, subscription, isSubscriptionLoading, isCreditsLoading } = useIaCredits();
@@ -31,9 +28,6 @@ function ProfilePopover({
31
28
  await logout();
32
29
  } finally {
33
30
  setIsLoggingOut(false);
34
- if (logoutRedirect !== "/login") {
35
- router.push(logoutRedirect);
36
- }
37
31
  }
38
32
  };
39
33
  const hasSubscription = !isSubscriptionLoading && subscription !== null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/layouts/ProfilePopover.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { useRouter } from \"next/navigation\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Popover } from \"../ui/overlay/Popover\";\nimport { Progress } from \"../ui/feedback/Progress\";\nimport { Separator } from \"../ui/data-display/Separator\";\nimport { NavBarItem } from \"./NavBarItem\";\nimport { UserAvatar } from \"../ui/data-display/UserAvatar\";\nimport { LoadingOverlay } from \"../ui/feedback/LoadingOverlay\";\nimport { useAuth } from \"../../providers/auth.provider\";\nimport { cn } from \"../../infra/utils/clsx\";\nimport { useIaCredits } from \"../../modules/ia-credits/hooks/ia-credits.hook\";\nimport { useBuyCreditsModal } from \"../../store/useBuyCreditsModal\";\n\nexport interface ProfileMenuItem {\n icon?: React.ReactNode;\n label: string;\n onClick: () => void;\n}\n\nexport interface ProfilePopoverProps {\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n align?: \"start\" | \"center\" | \"end\";\n contentClassName?: string;\n menuItems?: ProfileMenuItem[];\n logoutRedirect?: string;\n}\n\nfunction ProfilePopover({\n side = \"top\",\n align = \"start\",\n contentClassName = \"absolute bottom-2 left-[26px]\",\n menuItems = [],\n logoutRedirect = \"/login\",\n}: ProfilePopoverProps) {\n const router = useRouter();\n const { user, logout } = useAuth();\n const [isLoggingOut, setIsLoggingOut] = useState(false);\n\n const { summary, subscription, isSubscriptionLoading, isCreditsLoading } =\n useIaCredits();\n const { openModal: openBuyCreditsModal } = useBuyCreditsModal();\n\n const handleLogout = async () => {\n try {\n setIsLoggingOut(true);\n await logout();\n } finally {\n setIsLoggingOut(false);\n if (logoutRedirect !== \"/login\") {\n router.push(logoutRedirect);\n }\n }\n };\n\n const hasSubscription = !isSubscriptionLoading && subscription !== null;\n\n const shouldShowCredits = hasSubscription && subscription.id_wl === 1;\n const creditsPercentage =\n shouldShowCredits && summary.totalCredits > 0\n ? (summary.usedCredits / summary.totalCredits) * 100\n : 0;\n\n return (\n <>\n <LoadingOverlay\n isLoading={isLoggingOut}\n message=\"Saindo da sua conta...\"\n />\n <Popover>\n <PopoverPrimitive.Trigger className=\"cursor-pointer\">\n {user && (\n <UserAvatar\n key={user.id}\n photo={user.photo}\n name={user.name}\n size={40}\n />\n )}\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n className={cn(\n \"w-64.75 p-0 bg-white rounded-2xl shadow-md border border-gray-200 z-99\",\n contentClassName,\n )}\n side={side}\n align={align}\n sideOffset={8}\n >\n <div className=\"grid grid-cols-[32px_1fr] items-center gap-3 p-3 w-full\">\n {user && (\n <UserAvatar\n key={user.id}\n photo={user.photo}\n name={user.name}\n size={32}\n />\n )}\n\n <div className=\"flex flex-col gap-0.5 min-w-0\">\n <span className=\"paragraph-small-semibold text-gray-950 truncate\">\n {user?.name || \"\"}\n </span>\n <span className=\"paragraph-xsmall-medium text-gray-500 truncate\">\n {user?.email || \"\"}\n </span>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-2 border-t border-gray-200 rounded-2xl p-1.5\">\n {shouldShowCredits && (\n <div\n className={cn(\n \"flex flex-col bg-gray-950 rounded-lg gap-4 w-full p-4 transition-colors\",\n \"cursor-pointer hover:bg-gray-900\",\n )}\n onClick={() => openBuyCreditsModal()}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"paragraph-xsmall-semibold text-white truncate\">\n Créditos usados\n </span>\n <span className=\"paragraph-xsmall-medium text-white/50\">\n {summary.usedCredits.toLocaleString(\"pt-BR\")}/\n {summary.totalCredits.toLocaleString(\"pt-BR\")}\n </span>\n </div>\n <Progress\n className=\"bg-white/10\"\n indicatorColor=\"bg-white\"\n value={creditsPercentage}\n />\n </div>\n )}\n\n <div className=\"flex flex-col gap-2\">\n {menuItems.length > 0 && (\n <div className=\"flex flex-col\">\n {menuItems.map((item, index) => (\n <NavBarItem\n key={index}\n icon={item.icon}\n label={item.label}\n onClick={item.onClick}\n />\n ))}\n </div>\n )}\n <Separator />\n <NavBarItem label=\"Sair\" onClick={handleLogout} />\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </Popover>\n </>\n );\n}\n\nexport { ProfilePopover };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/layouts/ProfilePopover.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { Popover } from \"../ui/overlay/Popover\";\nimport { Progress } from \"../ui/feedback/Progress\";\nimport { Separator } from \"../ui/data-display/Separator\";\nimport { NavBarItem } from \"./NavBarItem\";\nimport { UserAvatar } from \"../ui/data-display/UserAvatar\";\nimport { LoadingOverlay } from \"../ui/feedback/LoadingOverlay\";\nimport { useAuth } from \"../../providers/auth.provider\";\nimport { cn } from \"../../infra/utils/clsx\";\nimport { useIaCredits } from \"../../modules/ia-credits/hooks/ia-credits.hook\";\nimport { useBuyCreditsModal } from \"../../store/useBuyCreditsModal\";\n\nexport interface ProfileMenuItem {\n icon?: React.ReactNode;\n label: string;\n onClick: () => void;\n}\n\nexport interface ProfilePopoverProps {\n side?: \"top\" | \"bottom\" | \"left\" | \"right\";\n align?: \"start\" | \"center\" | \"end\";\n contentClassName?: string;\n menuItems?: ProfileMenuItem[];\n}\n\nfunction ProfilePopover({\n side = \"top\",\n align = \"start\",\n contentClassName = \"absolute bottom-2 left-[26px]\",\n menuItems = [],\n}: ProfilePopoverProps) {\n const { user, logout } = useAuth();\n const [isLoggingOut, setIsLoggingOut] = useState(false);\n\n const { summary, subscription, isSubscriptionLoading, isCreditsLoading } =\n useIaCredits();\n const { openModal: openBuyCreditsModal } = useBuyCreditsModal();\n\n const handleLogout = async () => {\n try {\n setIsLoggingOut(true);\n await logout();\n } finally {\n setIsLoggingOut(false);\n }\n };\n\n const hasSubscription = !isSubscriptionLoading && subscription !== null;\n\n const shouldShowCredits = hasSubscription && subscription.id_wl === 1;\n const creditsPercentage =\n shouldShowCredits && summary.totalCredits > 0\n ? (summary.usedCredits / summary.totalCredits) * 100\n : 0;\n\n return (\n <>\n <LoadingOverlay\n isLoading={isLoggingOut}\n message=\"Saindo da sua conta...\"\n />\n <Popover>\n <PopoverPrimitive.Trigger className=\"cursor-pointer\">\n {user && (\n <UserAvatar\n key={user.id}\n photo={user.photo}\n name={user.name}\n size={40}\n />\n )}\n </PopoverPrimitive.Trigger>\n\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n className={cn(\n \"w-64.75 p-0 bg-white rounded-2xl shadow-md border border-gray-200 z-99\",\n contentClassName,\n )}\n side={side}\n align={align}\n sideOffset={8}\n >\n <div className=\"grid grid-cols-[32px_1fr] items-center gap-3 p-3 w-full\">\n {user && (\n <UserAvatar\n key={user.id}\n photo={user.photo}\n name={user.name}\n size={32}\n />\n )}\n\n <div className=\"flex flex-col gap-0.5 min-w-0\">\n <span className=\"paragraph-small-semibold text-gray-950 truncate\">\n {user?.name || \"\"}\n </span>\n <span className=\"paragraph-xsmall-medium text-gray-500 truncate\">\n {user?.email || \"\"}\n </span>\n </div>\n </div>\n\n <div className=\"flex flex-col gap-2 border-t border-gray-200 rounded-2xl p-1.5\">\n {shouldShowCredits && (\n <div\n className={cn(\n \"flex flex-col bg-gray-950 rounded-lg gap-4 w-full p-4 transition-colors\",\n \"cursor-pointer hover:bg-gray-900\",\n )}\n onClick={() => openBuyCreditsModal()}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"paragraph-xsmall-semibold text-white truncate\">\n Créditos usados\n </span>\n <span className=\"paragraph-xsmall-medium text-white/50\">\n {summary.usedCredits.toLocaleString(\"pt-BR\")}/\n {summary.totalCredits.toLocaleString(\"pt-BR\")}\n </span>\n </div>\n <Progress\n className=\"bg-white/10\"\n indicatorColor=\"bg-white\"\n value={creditsPercentage}\n />\n </div>\n )}\n\n <div className=\"flex flex-col gap-2\">\n {menuItems.length > 0 && (\n <div className=\"flex flex-col\">\n {menuItems.map((item, index) => (\n <NavBarItem\n key={index}\n icon={item.icon}\n label={item.label}\n onClick={item.onClick}\n />\n ))}\n </div>\n )}\n <Separator />\n <NavBarItem label=\"Sair\" onClick={handleLogout} />\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </Popover>\n </>\n );\n}\n\nexport { ProfilePopover };\n"],"mappings":"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","names":[]}
@@ -4,14 +4,22 @@ class WhitelabelService {
4
4
  getApiUrl() {
5
5
  const apiUrl = process.env.GAPPS_R3_API_URL;
6
6
  if (!apiUrl) {
7
- throw new ApiError("GAPPS_R3_API_URL not configured", "CONFIG_ERROR", 500);
7
+ throw new ApiError(
8
+ "GAPPS_R3_API_URL not configured",
9
+ "CONFIG_ERROR",
10
+ 500
11
+ );
8
12
  }
9
13
  return apiUrl;
10
14
  }
11
15
  getToken() {
12
16
  const token = process.env.WHITELABEL_TOKEN_MASTER;
13
17
  if (!token) {
14
- throw new ApiError("WHITELABEL_TOKEN_MASTER not configured", "CONFIG_ERROR", 500);
18
+ throw new ApiError(
19
+ "WHITELABEL_TOKEN_MASTER not configured",
20
+ "CONFIG_ERROR",
21
+ 500
22
+ );
15
23
  }
16
24
  return token;
17
25
  }
@@ -38,7 +46,9 @@ class WhitelabelService {
38
46
  }
39
47
  });
40
48
  if (!response.ok) {
41
- console.error("[WhitelabelService] Failed to fetch whitelabel token", { response });
49
+ console.error("[WhitelabelService] Failed to fetch whitelabel token", {
50
+ response
51
+ });
42
52
  throw new ApiError(
43
53
  `Failed to fetch whitelabel token: ${response.status}`,
44
54
  "FETCH_ERROR",
@@ -67,11 +77,18 @@ class WhitelabelService {
67
77
  async getTokenByWhitelabelId(idWl) {
68
78
  const apiUrl = this.getApiUrl();
69
79
  const masterToken = this.getToken();
70
- const url = `${apiUrl}/pt-br/${idWl}/tokens?limit=1&page=1&sort=id:desc`;
80
+ const url = `${apiUrl}/v1/pt-br/${idWl}/tokens?limit=1&page=1&sort=id:desc`;
71
81
  const response = await fetch(url, {
72
82
  method: "GET",
73
83
  headers: { authorization: masterToken }
74
84
  });
85
+ console.debug("[WhitelabelService] Fetching token by whitelabel ID", {
86
+ url,
87
+ config: {
88
+ method: "GET",
89
+ headers: { authorization: masterToken }
90
+ }
91
+ });
75
92
  if (!response.ok) {
76
93
  throw new ApiError(
77
94
  `Failed to fetch whitelabel token: ${response.status}`,
@@ -81,7 +98,11 @@ class WhitelabelService {
81
98
  }
82
99
  const result = await response.json();
83
100
  if (result.status !== 1 || !result.data?.length) {
84
- throw new ApiError("Token do whitelabel n\xE3o encontrado", "WL_TOKEN_NOT_FOUND", 404);
101
+ throw new ApiError(
102
+ "Token do whitelabel n\xE3o encontrado",
103
+ "WL_TOKEN_NOT_FOUND",
104
+ 404
105
+ );
85
106
  }
86
107
  return result.data[0].token;
87
108
  }
@@ -89,11 +110,15 @@ class WhitelabelService {
89
110
  hostname = process.env.WHITELABEL_DOMAIN || hostname;
90
111
  const cache = this.createCache();
91
112
  const cacheKey = this.getCacheKey(hostname);
92
- console.log("[WhitelabelService] Revalidating cache for domain", { hostname });
113
+ console.log("[WhitelabelService] Revalidating cache for domain", {
114
+ hostname
115
+ });
93
116
  await cache.delete(cacheKey);
94
117
  const data = await this.fetchFromApi(hostname);
95
118
  await cache.insert(cacheKey, JSON.stringify(data), 604800);
96
- console.log("[WhitelabelService] Cache revalidated for domain", { hostname });
119
+ console.log("[WhitelabelService] Cache revalidated for domain", {
120
+ hostname
121
+ });
97
122
  return data;
98
123
  }
99
124
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/whitelabel/services/whitelabel.service.ts"],"sourcesContent":["\r\nimport greatCache from '@greatapps/cache';\r\nimport { ApiError } from '../../../infra/api/types';\r\nimport { WhitelabelTokenApiResponse, WhitelabelTokenData } from '../schema';\r\n\r\nclass WhitelabelService {\r\n private getApiUrl(): string {\r\n const apiUrl = process.env.GAPPS_R3_API_URL;\r\n if (!apiUrl) {\r\n throw new ApiError('GAPPS_R3_API_URL not configured', 'CONFIG_ERROR', 500);\r\n }\r\n return apiUrl;\r\n }\r\n\r\n private getToken(): string {\r\n const token = process.env.WHITELABEL_TOKEN_MASTER;\r\n if (!token) {\r\n throw new ApiError('WHITELABEL_TOKEN_MASTER not configured', 'CONFIG_ERROR', 500);\r\n }\r\n return token;\r\n }\r\n\r\n private createCache() {\r\n return new greatCache({\r\n service: 'whitelabel-service',\r\n version: '1.0',\r\n domain: 'whitelabel-cache.greatapps.com.br',\r\n ambient: process.env.NODE_ENV || 'development',\r\n });\r\n }\r\n\r\n private getCacheKey(hostname: string): string {\r\n return `whitelabel-token-${hostname}`;\r\n }\r\n\r\n private async fetchFromApi(hostname: string): Promise<WhitelabelTokenData> {\r\n const apiUrl = this.getApiUrl();\r\n const whitelabelMasterToken = this.getToken();\r\n const url = `${apiUrl}/v1/pt-br/1/whitelabel/${hostname}/token`;\r\n\r\n console.log('[WhitelabelService] Fetching token for domain', { url });\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: {\r\n authorization: whitelabelMasterToken,\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n console.error('[WhitelabelService] Failed to fetch whitelabel token', { response });\r\n throw new ApiError(\r\n `Failed to fetch whitelabel token: ${response.status}`,\r\n 'FETCH_ERROR',\r\n response.status\r\n );\r\n }\r\n\r\n const result: WhitelabelTokenApiResponse = await response.json();\r\n\r\n if (result.status !== 1 || !result.data?.length) {\r\n throw new ApiError('Whitelabel token not found', 'TOKEN_NOT_FOUND', 404);\r\n }\r\n\r\n return result.data[0];\r\n }\r\n\r\n async getTokenByDomain(hostname: string): Promise<WhitelabelTokenData> {\r\n hostname = process.env.WHITELABEL_DOMAIN || hostname;\r\n\r\n const cache = this.createCache();\r\n const cacheKey = this.getCacheKey(hostname);\r\n\r\n const cachedData = await cache.select(cacheKey);\r\n\r\n if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {\r\n console.log('[WhitelabelService] Cache hit for domain', { hostname });\r\n return JSON.parse(cachedData.data) as WhitelabelTokenData;\r\n }\r\n\r\n const data = await this.fetchFromApi(hostname);\r\n\r\n await cache.insert(cacheKey, JSON.stringify(data), 604800);\r\n\r\n return data;\r\n }\r\n\r\n async getTokenByWhitelabelId(idWl: number): Promise<string> {\r\n const apiUrl = this.getApiUrl();\r\n const masterToken = this.getToken();\r\n const url = `${apiUrl}/pt-br/${idWl}/tokens?limit=1&page=1&sort=id:desc`;\r\n\r\n const response = await fetch(url, {\r\n method: 'GET',\r\n headers: { authorization: masterToken },\r\n });\r\n\r\n if (!response.ok) {\r\n throw new ApiError(\r\n `Failed to fetch whitelabel token: ${response.status}`,\r\n 'WL_TOKEN_NOT_FOUND',\r\n response.status\r\n );\r\n }\r\n\r\n const result: WhitelabelTokenApiResponse = await response.json();\r\n\r\n if (result.status !== 1 || !result.data?.length) {\r\n throw new ApiError('Token do whitelabel não encontrado', 'WL_TOKEN_NOT_FOUND', 404);\r\n }\r\n\r\n return result.data[0].token;\r\n }\r\n\r\n async revalidateByDomain(hostname: string): Promise<WhitelabelTokenData> {\r\n hostname = process.env.WHITELABEL_DOMAIN || hostname;\r\n\r\n const cache = this.createCache();\r\n const cacheKey = this.getCacheKey(hostname);\r\n\r\n console.log('[WhitelabelService] Revalidating cache for domain', { hostname });\r\n\r\n await cache.delete(cacheKey);\r\n\r\n const data = await this.fetchFromApi(hostname);\r\n\r\n await cache.insert(cacheKey, JSON.stringify(data), 604800);\r\n\r\n console.log('[WhitelabelService] Cache revalidated for domain', { hostname });\r\n\r\n return data;\r\n }\r\n}\r\n\r\nexport const whitelabelService = new WhitelabelService();\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/whitelabel/services/whitelabel.service.ts"],"sourcesContent":["import greatCache from \"@greatapps/cache\";\r\nimport { ApiError } from \"../../../infra/api/types\";\r\nimport { WhitelabelTokenApiResponse, WhitelabelTokenData } from \"../schema\";\r\n\r\nclass WhitelabelService {\r\n private getApiUrl(): string {\r\n const apiUrl = process.env.GAPPS_R3_API_URL;\r\n if (!apiUrl) {\r\n throw new ApiError(\r\n \"GAPPS_R3_API_URL not configured\",\r\n \"CONFIG_ERROR\",\r\n 500,\r\n );\r\n }\r\n return apiUrl;\r\n }\r\n\r\n private getToken(): string {\r\n const token = process.env.WHITELABEL_TOKEN_MASTER;\r\n if (!token) {\r\n throw new ApiError(\r\n \"WHITELABEL_TOKEN_MASTER not configured\",\r\n \"CONFIG_ERROR\",\r\n 500,\r\n );\r\n }\r\n return token;\r\n }\r\n\r\n private createCache() {\r\n return new greatCache({\r\n service: \"whitelabel-service\",\r\n version: \"1.0\",\r\n domain: \"whitelabel-cache.greatapps.com.br\",\r\n ambient: process.env.NODE_ENV || \"development\",\r\n });\r\n }\r\n\r\n private getCacheKey(hostname: string): string {\r\n return `whitelabel-token-${hostname}`;\r\n }\r\n\r\n private async fetchFromApi(hostname: string): Promise<WhitelabelTokenData> {\r\n const apiUrl = this.getApiUrl();\r\n const whitelabelMasterToken = this.getToken();\r\n const url = `${apiUrl}/v1/pt-br/1/whitelabel/${hostname}/token`;\r\n\r\n console.log(\"[WhitelabelService] Fetching token for domain\", { url });\r\n\r\n const response = await fetch(url, {\r\n method: \"GET\",\r\n headers: {\r\n authorization: whitelabelMasterToken,\r\n },\r\n });\r\n\r\n if (!response.ok) {\r\n console.error(\"[WhitelabelService] Failed to fetch whitelabel token\", {\r\n response,\r\n });\r\n throw new ApiError(\r\n `Failed to fetch whitelabel token: ${response.status}`,\r\n \"FETCH_ERROR\",\r\n response.status,\r\n );\r\n }\r\n\r\n const result: WhitelabelTokenApiResponse = await response.json();\r\n\r\n if (result.status !== 1 || !result.data?.length) {\r\n throw new ApiError(\"Whitelabel token not found\", \"TOKEN_NOT_FOUND\", 404);\r\n }\r\n\r\n return result.data[0];\r\n }\r\n\r\n async getTokenByDomain(hostname: string): Promise<WhitelabelTokenData> {\r\n hostname = process.env.WHITELABEL_DOMAIN || hostname;\r\n\r\n const cache = this.createCache();\r\n const cacheKey = this.getCacheKey(hostname);\r\n\r\n const cachedData = await cache.select(cacheKey);\r\n\r\n if (cachedData.status == 1 && \"data\" in cachedData && cachedData.data) {\r\n console.log(\"[WhitelabelService] Cache hit for domain\", { hostname });\r\n return JSON.parse(cachedData.data) as WhitelabelTokenData;\r\n }\r\n\r\n const data = await this.fetchFromApi(hostname);\r\n\r\n await cache.insert(cacheKey, JSON.stringify(data), 604800);\r\n\r\n return data;\r\n }\r\n\r\n async getTokenByWhitelabelId(idWl: number): Promise<string> {\r\n const apiUrl = this.getApiUrl();\r\n const masterToken = this.getToken();\r\n const url = `${apiUrl}/v1/pt-br/${idWl}/tokens?limit=1&page=1&sort=id:desc`;\r\n\r\n const response = await fetch(url, {\r\n method: \"GET\",\r\n headers: { authorization: masterToken },\r\n });\r\n\r\n console.debug(\"[WhitelabelService] Fetching token by whitelabel ID\", {\r\n url,\r\n config: {\r\n method: \"GET\",\r\n headers: { authorization: masterToken },\r\n },\r\n });\r\n\r\n \r\n\r\n if (!response.ok) {\r\n throw new ApiError(\r\n `Failed to fetch whitelabel token: ${response.status}`,\r\n \"WL_TOKEN_NOT_FOUND\",\r\n response.status,\r\n );\r\n }\r\n\r\n const result: WhitelabelTokenApiResponse = await response.json();\r\n\r\n if (result.status !== 1 || !result.data?.length) {\r\n throw new ApiError(\r\n \"Token do whitelabel não encontrado\",\r\n \"WL_TOKEN_NOT_FOUND\",\r\n 404,\r\n );\r\n }\r\n\r\n return result.data[0].token;\r\n }\r\n\r\n async revalidateByDomain(hostname: string): Promise<WhitelabelTokenData> {\r\n hostname = process.env.WHITELABEL_DOMAIN || hostname;\r\n\r\n const cache = this.createCache();\r\n const cacheKey = this.getCacheKey(hostname);\r\n\r\n console.log(\"[WhitelabelService] Revalidating cache for domain\", {\r\n hostname,\r\n });\r\n\r\n await cache.delete(cacheKey);\r\n\r\n const data = await this.fetchFromApi(hostname);\r\n\r\n await cache.insert(cacheKey, JSON.stringify(data), 604800);\r\n\r\n console.log(\"[WhitelabelService] Cache revalidated for domain\", {\r\n hostname,\r\n });\r\n\r\n return data;\r\n }\r\n}\r\n\r\nexport const whitelabelService = new WhitelabelService();\r\n"],"mappings":"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","names":[]}
@@ -16,7 +16,7 @@ import { useLogin } from "../modules/auth/hooks/login.hook";
16
16
  import { useRegister } from "../modules/auth/hooks/register.hook";
17
17
  import { useLogout } from "../modules/auth/hooks/logout.hook";
18
18
  import { useCurrentAccount, ACCOUNT_QUERY_KEY } from "../modules/accounts/hooks/current-account.hook";
19
- import { useRouter } from "next/navigation";
19
+ import { useWhitelabelUrls } from "./whitelabel.provider";
20
20
  const AuthContext = createContext(
21
21
  void 0
22
22
  );
@@ -26,7 +26,7 @@ function AuthProvider({ children }) {
26
26
  const { isLoading: isSessionLoading } = useUserValidateSession();
27
27
  const queryClient = useQueryClient();
28
28
  const setUserData = useSetUserData();
29
- const router = useRouter();
29
+ const { accountsUrl, pagesUrl } = useWhitelabelUrls();
30
30
  const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();
31
31
  const { mutateAsync: registerMutate, isPending: isRegistering } = useRegister();
32
32
  const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();
@@ -62,15 +62,29 @@ function AuthProvider({ children }) {
62
62
  },
63
63
  [queryClient, setUserData]
64
64
  );
65
+ const resolveLogoutRedirect = useCallback(() => {
66
+ if (typeof window === "undefined") {
67
+ return "/login";
68
+ }
69
+ try {
70
+ const currentOrigin = window.location.origin;
71
+ const pagesOrigin = pagesUrl ? new URL(pagesUrl).origin : "";
72
+ if (pagesOrigin && currentOrigin === pagesOrigin) {
73
+ return accountsUrl || "/login";
74
+ }
75
+ } catch {
76
+ }
77
+ return "/login";
78
+ }, [accountsUrl, pagesUrl]);
65
79
  const logout = useCallback(async () => {
66
80
  try {
67
81
  await logoutMutate(void 0);
68
82
  } catch {
69
83
  } finally {
70
84
  queryClient.clear();
71
- router.push("/login");
85
+ window.location.assign(resolveLogoutRedirect());
72
86
  }
73
- }, [queryClient, router]);
87
+ }, [queryClient, logoutMutate, resolveLogoutRedirect]);
74
88
  const value = useMemo(
75
89
  () => ({
76
90
  user: user ?? null,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {\r\n createContext,\r\n ReactNode,\r\n useCallback,\r\n useContext,\r\n useMemo,\r\n} from \"react\";\r\nimport { useQueryClient } from \"@tanstack/react-query\";\r\nimport {\r\n useUserQuery,\r\n useSetUserData,\r\n useUserValidateSession,\r\n} from \"../modules/auth/hooks/useUserQuery\";\r\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\r\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\r\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\r\nimport {\r\n AuthState,\r\n LoginRequest,\r\n RegisterRequest,\r\n} from \"../modules/auth/schema\";\r\n\r\nexport type LoginResult =\r\n | { result: \"success\" }\r\n | { result: \"two_factor_required\"; cookie: string }\r\n | { result: \"error\"; message: string };\r\nimport { useCurrentAccount, ACCOUNT_QUERY_KEY } from \"../modules/accounts/hooks/current-account.hook\";\r\nimport { useRouter } from \"next/navigation\";\r\n\r\ninterface AuthContextProps extends AuthState {\r\n login: (credentials: LoginRequest) => Promise<LoginResult>;\r\n register: (data: RegisterRequest) => Promise<void>;\r\n logout: () => Promise<void>;\r\n}\r\n\r\nexport const AuthContext = createContext<AuthContextProps | undefined>(\r\n undefined\r\n);\r\n\r\ninterface AuthProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function AuthProvider({ children }: AuthProviderProps) {\r\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\r\n const { data: account, isLoading: isAccountLoading } = useCurrentAccount();\r\n const { isLoading: isSessionLoading } = useUserValidateSession();\r\n\r\n const queryClient = useQueryClient();\r\n const setUserData = useSetUserData();\r\n\r\n const router = useRouter();\r\n\r\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\r\n const { mutateAsync: registerMutate, isPending: isRegistering } =\r\n useRegister();\r\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\r\n\r\n const isAuthenticated = !!user;\r\n const isLoading =\r\n isLogging ||\r\n isRegistering ||\r\n isLoggingOut ||\r\n isQueryLoading ||\r\n isAccountLoading ||\r\n isSessionLoading;\r\n\r\n const login = useCallback(\r\n async (credentials: LoginRequest): Promise<LoginResult> => {\r\n try {\r\n const data = await loginMutate(credentials);\r\n\r\n if (data.result === \"two_factor_required\") {\r\n return { result: \"two_factor_required\", cookie: data.cookie };\r\n }\r\n\r\n queryClient.clear();\r\n setUserData(data.user);\r\n queryClient.setQueryData(ACCOUNT_QUERY_KEY, data.account);\r\n\r\n return { result: \"success\" };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : \"Ocorreu um erro ao fazer login. Tente novamente.\";\r\n return { result: \"error\", message };\r\n }\r\n },\r\n [queryClient, setUserData]\r\n );\r\n\r\n const register = useCallback(\r\n async (data: RegisterRequest): Promise<void> => {\r\n await registerMutate(data, {\r\n onSuccess: (data) => {\r\n queryClient.clear();\r\n setUserData(data.user);\r\n queryClient.setQueryData(ACCOUNT_QUERY_KEY, data.account);\r\n },\r\n });\r\n },\r\n [queryClient, setUserData]\r\n );\r\n\r\n const logout = useCallback(async (): Promise<void> => {\r\n try {\r\n await logoutMutate(undefined);\r\n } catch {\r\n // cookie já removido no servidor mesmo se a API falhou\r\n } finally {\r\n queryClient.clear();\r\n router.push(\"/login\");\r\n }\r\n }, [queryClient, router]);\r\n\r\n const value: AuthContextProps = useMemo(\r\n () => ({\r\n user: user ?? null,\r\n account: account ?? null,\r\n isAuthenticated,\r\n isLoading,\r\n login,\r\n register,\r\n logout,\r\n }),\r\n [user, account, isAuthenticated, isLoading, login, register, logout]\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n\r\nexport function useAuth(): AuthContextProps {\r\n const context = useContext(AuthContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\r\n }\r\n\r\n return context;\r\n}\r\n"],"mappings":";AAiIS;AA/HT;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAW1B,SAAS,mBAAmB,yBAAyB;AACrD,SAAS,iBAAiB;AAQnB,MAAM,cAAc;AAAA,EACzB;AACF;AAMO,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC5D,QAAM,EAAE,MAAM,MAAM,WAAW,eAAe,IAAI,aAAa;AAC/D,QAAM,EAAE,MAAM,SAAS,WAAW,iBAAiB,IAAI,kBAAkB;AACzE,QAAM,EAAE,WAAW,iBAAiB,IAAI,uBAAuB;AAE/D,QAAM,cAAc,eAAe;AACnC,QAAM,cAAc,eAAe;AAEnC,QAAM,SAAS,UAAU;AAEzB,QAAM,EAAE,aAAa,aAAa,WAAW,UAAU,IAAI,SAAS;AACpE,QAAM,EAAE,aAAa,gBAAgB,WAAW,cAAc,IAC5D,YAAY;AACd,QAAM,EAAE,aAAa,cAAc,WAAW,aAAa,IAAI,UAAU;AAEzE,QAAM,kBAAkB,CAAC,CAAC;AAC1B,QAAM,YACJ,aACA,iBACA,gBACA,kBACA,oBACA;AAEF,QAAM,QAAQ;AAAA,IACZ,OAAO,gBAAoD;AACzD,UAAI;AACF,cAAM,OAAO,MAAM,YAAY,WAAW;AAE1C,YAAI,KAAK,WAAW,uBAAuB;AACzC,iBAAO,EAAE,QAAQ,uBAAuB,QAAQ,KAAK,OAAO;AAAA,QAC9D;AAEA,oBAAY,MAAM;AAClB,oBAAY,KAAK,IAAI;AACrB,oBAAY,aAAa,mBAAmB,KAAK,OAAO;AAExD,eAAO,EAAE,QAAQ,UAAU;AAAA,MAC7B,SAAS,OAAO;AACd,cAAM,UACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,eAAO,EAAE,QAAQ,SAAS,QAAQ;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,EAC3B;AAEA,QAAM,WAAW;AAAA,IACf,OAAO,SAAyC;AAC9C,YAAM,eAAe,MAAM;AAAA,QACzB,WAAW,CAACA,UAAS;AACnB,sBAAY,MAAM;AAClB,sBAAYA,MAAK,IAAI;AACrB,sBAAY,aAAa,mBAAmBA,MAAK,OAAO;AAAA,QAC1D;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa,WAAW;AAAA,EAC3B;AAEA,QAAM,SAAS,YAAY,YAA2B;AACpD,QAAI;AACF,YAAM,aAAa,MAAS;AAAA,IAC9B,QAAQ;AAAA,IAER,UAAE;AACA,kBAAY,MAAM;AAClB,aAAO,KAAK,QAAQ;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,aAAa,MAAM,CAAC;AAExB,QAAM,QAA0B;AAAA,IAC9B,OAAO;AAAA,MACL,MAAM,QAAQ;AAAA,MACd,SAAS,WAAW;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,MAAM,SAAS,iBAAiB,WAAW,OAAO,UAAU,MAAM;AAAA,EACrE;AAEA,SAAO,oBAAC,YAAY,UAAZ,EAAqB,OAAe,UAAS;AACvD;AAEO,SAAS,UAA4B;AAC1C,QAAM,UAAU,WAAW,WAAW;AAEtC,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,SAAO;AACT;","names":["data"]}
1
+ {"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport {\r\n createContext,\r\n ReactNode,\r\n useCallback,\r\n useContext,\r\n useMemo,\r\n} from \"react\";\r\nimport { useQueryClient } from \"@tanstack/react-query\";\r\nimport {\n useUserQuery,\n useSetUserData,\n useUserValidateSession,\n} from \"../modules/auth/hooks/useUserQuery\";\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\r\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\r\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\r\nimport {\n AuthState,\n LoginRequest,\n RegisterRequest,\n} from \"../modules/auth/schema\";\n\r\nexport type LoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string }\n | { result: \"error\"; message: string };\nimport { useCurrentAccount, ACCOUNT_QUERY_KEY } from \"../modules/accounts/hooks/current-account.hook\";\nimport { useWhitelabelUrls } from \"./whitelabel.provider\";\n\ninterface AuthContextProps extends AuthState {\n login: (credentials: LoginRequest) => Promise<LoginResult>;\n register: (data: RegisterRequest) => Promise<void>;\n logout: () => Promise<void>;\n}\n\r\nexport const AuthContext = createContext<AuthContextProps | undefined>(\r\n undefined\r\n);\r\n\r\ninterface AuthProviderProps {\r\n children: ReactNode;\r\n}\r\n\r\nexport function AuthProvider({ children }: AuthProviderProps) {\r\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\r\n const { data: account, isLoading: isAccountLoading } = useCurrentAccount();\r\n const { isLoading: isSessionLoading } = useUserValidateSession();\r\n\r\n const queryClient = useQueryClient();\n const setUserData = useSetUserData();\n const { accountsUrl, pagesUrl } = useWhitelabelUrls();\n\r\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\n const { mutateAsync: registerMutate, isPending: isRegistering } =\r\n useRegister();\r\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\r\n\r\n const isAuthenticated = !!user;\r\n const isLoading =\r\n isLogging ||\r\n isRegistering ||\r\n isLoggingOut ||\r\n isQueryLoading ||\r\n isAccountLoading ||\r\n isSessionLoading;\r\n\r\n const login = useCallback(\r\n async (credentials: LoginRequest): Promise<LoginResult> => {\r\n try {\r\n const data = await loginMutate(credentials);\r\n\r\n if (data.result === \"two_factor_required\") {\r\n return { result: \"two_factor_required\", cookie: data.cookie };\r\n }\r\n\r\n queryClient.clear();\r\n setUserData(data.user);\r\n queryClient.setQueryData(ACCOUNT_QUERY_KEY, data.account);\r\n\r\n return { result: \"success\" };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : \"Ocorreu um erro ao fazer login. Tente novamente.\";\r\n return { result: \"error\", message };\r\n }\r\n },\r\n [queryClient, setUserData]\r\n );\r\n\r\n const register = useCallback(\r\n async (data: RegisterRequest): Promise<void> => {\r\n await registerMutate(data, {\r\n onSuccess: (data) => {\r\n queryClient.clear();\r\n setUserData(data.user);\r\n queryClient.setQueryData(ACCOUNT_QUERY_KEY, data.account);\r\n },\r\n });\r\n },\r\n [queryClient, setUserData]\r\n );\r\n\r\n const resolveLogoutRedirect = useCallback(() => {\n if (typeof window === \"undefined\") {\n return \"/login\";\n }\n\n try {\n const currentOrigin = window.location.origin;\n const pagesOrigin = pagesUrl ? new URL(pagesUrl).origin : \"\";\n\n if (pagesOrigin && currentOrigin === pagesOrigin) {\n return accountsUrl || \"/login\";\n }\n } catch {\n // fallback below\n }\n\n return \"/login\";\n }, [accountsUrl, pagesUrl]);\n\n const logout = useCallback(async (): Promise<void> => {\n try {\n await logoutMutate(undefined);\n } catch {\n // cookie já removido no servidor mesmo se a API falhou\n } finally {\n queryClient.clear();\n window.location.assign(resolveLogoutRedirect());\n }\n }, [queryClient, logoutMutate, resolveLogoutRedirect]);\n\r\n const value: AuthContextProps = useMemo(\r\n () => ({\r\n user: user ?? null,\r\n account: account ?? null,\r\n isAuthenticated,\r\n isLoading,\r\n login,\r\n register,\r\n logout,\r\n }),\r\n [user, account, isAuthenticated, isLoading, login, register, logout]\r\n );\r\n\r\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\r\n}\r\n\r\nexport function useAuth(): AuthContextProps {\r\n const context = useContext(AuthContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\r\n }\r\n\r\n return context;\r\n}\r\n"],"mappings":"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","names":["data"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.272",
3
+ "version": "1.1.275",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -15,7 +15,6 @@ export interface AppNavBarProps {
15
15
  onExpandClick?: () => void;
16
16
  menuItems?: ProfileMenuItem[];
17
17
  onNotificationsViewAll?: () => void;
18
- logoutRedirect?: string;
19
18
  }
20
19
 
21
20
  export function AppNavBar({
@@ -26,7 +25,6 @@ export function AppNavBar({
26
25
  onExpandClick,
27
26
  menuItems = [],
28
27
  onNotificationsViewAll,
29
- logoutRedirect,
30
28
  }: AppNavBarProps) {
31
29
  const router = useRouter();
32
30
 
@@ -42,10 +40,7 @@ export function AppNavBar({
42
40
  onExpandClick={onExpandClick}
43
41
  >
44
42
  <NotificationsPopover onViewAll={onNotificationsViewAll} />
45
- <ProfilePopover
46
- menuItems={menuItems}
47
- logoutRedirect={logoutRedirect}
48
- />
43
+ <ProfilePopover menuItems={menuItems} />
49
44
  </NavBar>
50
45
  );
51
46
  }
@@ -1,7 +1,6 @@
1
1
  "use client";
2
2
 
3
3
  import { useState } from "react";
4
- import { useRouter } from "next/navigation";
5
4
  import * as PopoverPrimitive from "@radix-ui/react-popover";
6
5
  import { Popover } from "../ui/overlay/Popover";
7
6
  import { Progress } from "../ui/feedback/Progress";
@@ -25,7 +24,6 @@ export interface ProfilePopoverProps {
25
24
  align?: "start" | "center" | "end";
26
25
  contentClassName?: string;
27
26
  menuItems?: ProfileMenuItem[];
28
- logoutRedirect?: string;
29
27
  }
30
28
 
31
29
  function ProfilePopover({
@@ -33,9 +31,7 @@ function ProfilePopover({
33
31
  align = "start",
34
32
  contentClassName = "absolute bottom-2 left-[26px]",
35
33
  menuItems = [],
36
- logoutRedirect = "/login",
37
34
  }: ProfilePopoverProps) {
38
- const router = useRouter();
39
35
  const { user, logout } = useAuth();
40
36
  const [isLoggingOut, setIsLoggingOut] = useState(false);
41
37
 
@@ -49,9 +45,6 @@ function ProfilePopover({
49
45
  await logout();
50
46
  } finally {
51
47
  setIsLoggingOut(false);
52
- if (logoutRedirect !== "/login") {
53
- router.push(logoutRedirect);
54
- }
55
48
  }
56
49
  };
57
50
 
@@ -1,13 +1,16 @@
1
-
2
- import greatCache from '@greatapps/cache';
3
- import { ApiError } from '../../../infra/api/types';
4
- import { WhitelabelTokenApiResponse, WhitelabelTokenData } from '../schema';
1
+ import greatCache from "@greatapps/cache";
2
+ import { ApiError } from "../../../infra/api/types";
3
+ import { WhitelabelTokenApiResponse, WhitelabelTokenData } from "../schema";
5
4
 
6
5
  class WhitelabelService {
7
6
  private getApiUrl(): string {
8
7
  const apiUrl = process.env.GAPPS_R3_API_URL;
9
8
  if (!apiUrl) {
10
- throw new ApiError('GAPPS_R3_API_URL not configured', 'CONFIG_ERROR', 500);
9
+ throw new ApiError(
10
+ "GAPPS_R3_API_URL not configured",
11
+ "CONFIG_ERROR",
12
+ 500,
13
+ );
11
14
  }
12
15
  return apiUrl;
13
16
  }
@@ -15,17 +18,21 @@ class WhitelabelService {
15
18
  private getToken(): string {
16
19
  const token = process.env.WHITELABEL_TOKEN_MASTER;
17
20
  if (!token) {
18
- throw new ApiError('WHITELABEL_TOKEN_MASTER not configured', 'CONFIG_ERROR', 500);
21
+ throw new ApiError(
22
+ "WHITELABEL_TOKEN_MASTER not configured",
23
+ "CONFIG_ERROR",
24
+ 500,
25
+ );
19
26
  }
20
27
  return token;
21
28
  }
22
29
 
23
30
  private createCache() {
24
31
  return new greatCache({
25
- service: 'whitelabel-service',
26
- version: '1.0',
27
- domain: 'whitelabel-cache.greatapps.com.br',
28
- ambient: process.env.NODE_ENV || 'development',
32
+ service: "whitelabel-service",
33
+ version: "1.0",
34
+ domain: "whitelabel-cache.greatapps.com.br",
35
+ ambient: process.env.NODE_ENV || "development",
29
36
  });
30
37
  }
31
38
 
@@ -38,28 +45,30 @@ class WhitelabelService {
38
45
  const whitelabelMasterToken = this.getToken();
39
46
  const url = `${apiUrl}/v1/pt-br/1/whitelabel/${hostname}/token`;
40
47
 
41
- console.log('[WhitelabelService] Fetching token for domain', { url });
48
+ console.log("[WhitelabelService] Fetching token for domain", { url });
42
49
 
43
50
  const response = await fetch(url, {
44
- method: 'GET',
51
+ method: "GET",
45
52
  headers: {
46
53
  authorization: whitelabelMasterToken,
47
54
  },
48
55
  });
49
56
 
50
57
  if (!response.ok) {
51
- console.error('[WhitelabelService] Failed to fetch whitelabel token', { response });
58
+ console.error("[WhitelabelService] Failed to fetch whitelabel token", {
59
+ response,
60
+ });
52
61
  throw new ApiError(
53
62
  `Failed to fetch whitelabel token: ${response.status}`,
54
- 'FETCH_ERROR',
55
- response.status
63
+ "FETCH_ERROR",
64
+ response.status,
56
65
  );
57
66
  }
58
67
 
59
68
  const result: WhitelabelTokenApiResponse = await response.json();
60
69
 
61
70
  if (result.status !== 1 || !result.data?.length) {
62
- throw new ApiError('Whitelabel token not found', 'TOKEN_NOT_FOUND', 404);
71
+ throw new ApiError("Whitelabel token not found", "TOKEN_NOT_FOUND", 404);
63
72
  }
64
73
 
65
74
  return result.data[0];
@@ -73,8 +82,8 @@ class WhitelabelService {
73
82
 
74
83
  const cachedData = await cache.select(cacheKey);
75
84
 
76
- if (cachedData.status == 1 && 'data' in cachedData && cachedData.data) {
77
- console.log('[WhitelabelService] Cache hit for domain', { hostname });
85
+ if (cachedData.status == 1 && "data" in cachedData && cachedData.data) {
86
+ console.log("[WhitelabelService] Cache hit for domain", { hostname });
78
87
  return JSON.parse(cachedData.data) as WhitelabelTokenData;
79
88
  }
80
89
 
@@ -88,25 +97,39 @@ class WhitelabelService {
88
97
  async getTokenByWhitelabelId(idWl: number): Promise<string> {
89
98
  const apiUrl = this.getApiUrl();
90
99
  const masterToken = this.getToken();
91
- const url = `${apiUrl}/pt-br/${idWl}/tokens?limit=1&page=1&sort=id:desc`;
100
+ const url = `${apiUrl}/v1/pt-br/${idWl}/tokens?limit=1&page=1&sort=id:desc`;
92
101
 
93
102
  const response = await fetch(url, {
94
- method: 'GET',
103
+ method: "GET",
95
104
  headers: { authorization: masterToken },
96
105
  });
97
106
 
107
+ console.debug("[WhitelabelService] Fetching token by whitelabel ID", {
108
+ url,
109
+ config: {
110
+ method: "GET",
111
+ headers: { authorization: masterToken },
112
+ },
113
+ });
114
+
115
+
116
+
98
117
  if (!response.ok) {
99
118
  throw new ApiError(
100
119
  `Failed to fetch whitelabel token: ${response.status}`,
101
- 'WL_TOKEN_NOT_FOUND',
102
- response.status
120
+ "WL_TOKEN_NOT_FOUND",
121
+ response.status,
103
122
  );
104
123
  }
105
124
 
106
125
  const result: WhitelabelTokenApiResponse = await response.json();
107
126
 
108
127
  if (result.status !== 1 || !result.data?.length) {
109
- throw new ApiError('Token do whitelabel não encontrado', 'WL_TOKEN_NOT_FOUND', 404);
128
+ throw new ApiError(
129
+ "Token do whitelabel não encontrado",
130
+ "WL_TOKEN_NOT_FOUND",
131
+ 404,
132
+ );
110
133
  }
111
134
 
112
135
  return result.data[0].token;
@@ -118,7 +141,9 @@ class WhitelabelService {
118
141
  const cache = this.createCache();
119
142
  const cacheKey = this.getCacheKey(hostname);
120
143
 
121
- console.log('[WhitelabelService] Revalidating cache for domain', { hostname });
144
+ console.log("[WhitelabelService] Revalidating cache for domain", {
145
+ hostname,
146
+ });
122
147
 
123
148
  await cache.delete(cacheKey);
124
149
 
@@ -126,7 +151,9 @@ class WhitelabelService {
126
151
 
127
152
  await cache.insert(cacheKey, JSON.stringify(data), 604800);
128
153
 
129
- console.log('[WhitelabelService] Cache revalidated for domain', { hostname });
154
+ console.log("[WhitelabelService] Cache revalidated for domain", {
155
+ hostname,
156
+ });
130
157
 
131
158
  return data;
132
159
  }
@@ -8,32 +8,32 @@ import {
8
8
  useMemo,
9
9
  } from "react";
10
10
  import { useQueryClient } from "@tanstack/react-query";
11
- import {
12
- useUserQuery,
13
- useSetUserData,
14
- useUserValidateSession,
15
- } from "../modules/auth/hooks/useUserQuery";
11
+ import {
12
+ useUserQuery,
13
+ useSetUserData,
14
+ useUserValidateSession,
15
+ } from "../modules/auth/hooks/useUserQuery";
16
16
  import { useLogin } from "../modules/auth/hooks/login.hook";
17
17
  import { useRegister } from "../modules/auth/hooks/register.hook";
18
18
  import { useLogout } from "../modules/auth/hooks/logout.hook";
19
- import {
20
- AuthState,
21
- LoginRequest,
22
- RegisterRequest,
23
- } from "../modules/auth/schema";
24
-
25
- export type LoginResult =
26
- | { result: "success" }
27
- | { result: "two_factor_required"; cookie: string }
28
- | { result: "error"; message: string };
29
- import { useCurrentAccount, ACCOUNT_QUERY_KEY } from "../modules/accounts/hooks/current-account.hook";
30
- import { useRouter } from "next/navigation";
31
-
32
- interface AuthContextProps extends AuthState {
33
- login: (credentials: LoginRequest) => Promise<LoginResult>;
34
- register: (data: RegisterRequest) => Promise<void>;
35
- logout: () => Promise<void>;
36
- }
19
+ import {
20
+ AuthState,
21
+ LoginRequest,
22
+ RegisterRequest,
23
+ } from "../modules/auth/schema";
24
+
25
+ export type LoginResult =
26
+ | { result: "success" }
27
+ | { result: "two_factor_required"; cookie: string }
28
+ | { result: "error"; message: string };
29
+ import { useCurrentAccount, ACCOUNT_QUERY_KEY } from "../modules/accounts/hooks/current-account.hook";
30
+ import { useWhitelabelUrls } from "./whitelabel.provider";
31
+
32
+ interface AuthContextProps extends AuthState {
33
+ login: (credentials: LoginRequest) => Promise<LoginResult>;
34
+ register: (data: RegisterRequest) => Promise<void>;
35
+ logout: () => Promise<void>;
36
+ }
37
37
 
38
38
  export const AuthContext = createContext<AuthContextProps | undefined>(
39
39
  undefined
@@ -48,12 +48,11 @@ export function AuthProvider({ children }: AuthProviderProps) {
48
48
  const { data: account, isLoading: isAccountLoading } = useCurrentAccount();
49
49
  const { isLoading: isSessionLoading } = useUserValidateSession();
50
50
 
51
- const queryClient = useQueryClient();
52
- const setUserData = useSetUserData();
53
-
54
- const router = useRouter();
51
+ const queryClient = useQueryClient();
52
+ const setUserData = useSetUserData();
53
+ const { accountsUrl, pagesUrl } = useWhitelabelUrls();
55
54
 
56
- const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();
55
+ const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();
57
56
  const { mutateAsync: registerMutate, isPending: isRegistering } =
58
57
  useRegister();
59
58
  const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();
@@ -103,16 +102,35 @@ export function AuthProvider({ children }: AuthProviderProps) {
103
102
  [queryClient, setUserData]
104
103
  );
105
104
 
106
- const logout = useCallback(async (): Promise<void> => {
107
- try {
108
- await logoutMutate(undefined);
109
- } catch {
110
- // cookie já removido no servidor mesmo se a API falhou
111
- } finally {
112
- queryClient.clear();
113
- router.push("/login");
114
- }
115
- }, [queryClient, router]);
105
+ const resolveLogoutRedirect = useCallback(() => {
106
+ if (typeof window === "undefined") {
107
+ return "/login";
108
+ }
109
+
110
+ try {
111
+ const currentOrigin = window.location.origin;
112
+ const pagesOrigin = pagesUrl ? new URL(pagesUrl).origin : "";
113
+
114
+ if (pagesOrigin && currentOrigin === pagesOrigin) {
115
+ return accountsUrl || "/login";
116
+ }
117
+ } catch {
118
+ // fallback below
119
+ }
120
+
121
+ return "/login";
122
+ }, [accountsUrl, pagesUrl]);
123
+
124
+ const logout = useCallback(async (): Promise<void> => {
125
+ try {
126
+ await logoutMutate(undefined);
127
+ } catch {
128
+ // cookie já removido no servidor mesmo se a API falhou
129
+ } finally {
130
+ queryClient.clear();
131
+ window.location.assign(resolveLogoutRedirect());
132
+ }
133
+ }, [queryClient, logoutMutate, resolveLogoutRedirect]);
116
134
 
117
135
  const value: AuthContextProps = useMemo(
118
136
  () => ({