@greatapps/common 1.1.286 → 1.1.287

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.
@@ -2,6 +2,7 @@ import { cookies } from "next/headers";
2
2
  import { api } from "../../../infra/api/client";
3
3
  import { ApiError } from "../../../infra/api/types";
4
4
  import { whitelabelService } from "../../whitelabel/services/whitelabel.service";
5
+ import { buildWlOverrideFromJwt } from "../utils/build-wl-override";
5
6
  import { findWhitelabel } from "../../../server";
6
7
  const AUTH_COOKIE_NAME = "greatapps";
7
8
  const COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
@@ -237,6 +238,7 @@ class AuthService {
237
238
  return false;
238
239
  }
239
240
  try {
241
+ const requestConfig = await buildWlOverrideFromJwt(cookie);
240
242
  const payload = {
241
243
  location: clientInfo.location,
242
244
  ip: clientInfo.ip,
@@ -246,7 +248,8 @@ class AuthService {
246
248
  };
247
249
  const response = await api.apps.post(
248
250
  "/auth/keep",
249
- payload
251
+ payload,
252
+ requestConfig
250
253
  );
251
254
  return response.status === 1;
252
255
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/auth/services/auth.service.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\r\n\r\nimport { api } from \"../../../infra/api/client\";\r\nimport { ApiError } from \"../../../infra/api/types\";\r\nimport { whitelabelService } from \"../../whitelabel/services/whitelabel.service\";\r\nimport {\r\n ClientInfo,\r\n ForgotPasswordRequest,\r\n ForgotPasswordResponse,\r\n GeoLocation,\r\n LoginApiResponse,\r\n LoginRequest,\r\n LoginResponse,\r\n LogoutApiResponse,\r\n LogoutRequest,\r\n LogoutResponse,\r\n RegisterApiRequest,\r\n RegisterApiResponse,\r\n RegisterRequest,\r\n RegisterResponse,\r\n ResendVerificationRequest,\r\n ResendVerificationResponse,\r\n ResetPasswordRequest,\r\n ResetPasswordResponse,\r\n SearchPlansApiResponse,\r\n SessionKeepRequest,\r\n SessionKeepResponse,\r\n TwoFactorApiResponse,\r\n TwoFactorRequest,\r\n TwoFactorResponse,\r\n VerifyEmailRequest,\r\n VerifyEmailResponse,\r\n} from \"../schema\";\r\nimport { findWhitelabel } from \"../../../server\";\r\n\r\nconst AUTH_COOKIE_NAME = \"greatapps\";\r\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 30;\r\n\r\nconst COOKIE_OPTIONS = {\r\n httpOnly: true,\r\n secure: process.env.NODE_ENV === \"production\",\r\n sameSite: \"lax\" as const,\r\n path: \"/\",\r\n domain: process.env.DOMAIN_COOKIE,\r\n};\r\n\r\nclass AuthService {\r\n \r\n async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo\r\n ): Promise<LoginResponse> {\r\n let requestConfig: import(\"../../../infra/api/client\").RequestConfig | undefined;\r\n if (credentials.id_wl) {\r\n const wlToken = await whitelabelService.getTokenByWhitelabelId(credentials.id_wl);\r\n requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };\r\n \r\n }\r\n\r\n const response = await api.apps.post<LoginApiResponse>(\"/auth/login\", {\r\n email: credentials.email,\r\n password: credentials.password,\r\n source: credentials?.source,\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n }, requestConfig);\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"E-mail ou senha incorretos\",\r\n response.code || \"LOGIN_FAILED\",\r\n 401\r\n );\r\n }\r\n\r\n if (!response.cookie) {\r\n throw new ApiError(\r\n \"Resposta de autenticação inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n if (response.two_factor_required) {\r\n return { result: 'two_factor_required', cookie: response.cookie };\r\n }\r\n\r\n await this.setAuthCookie(response.cookie);\r\n\r\n const [{ userService }, { accountService }] = await Promise.all([\r\n import('../../users/services/user.service'),\r\n import('../../accounts/services/account.service'),\r\n ]);\r\n const [user, account] = await Promise.all([\r\n userService.findById(requestConfig ? { authToken: requestConfig.authToken } : undefined),\r\n accountService.findCurrentAccount(requestConfig),\r\n ]);\r\n\r\n return {\r\n result: 'success',\r\n user,\r\n account,\r\n accessToken: response.cookie,\r\n refreshToken: \"\",\r\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\r\n };\r\n }\r\n\r\n async verifyTwoFactor(\r\n cookie: string,\r\n code: string,\r\n clientInfo: ClientInfo\r\n ): Promise<TwoFactorResponse> {\r\n const payload: TwoFactorRequest = {\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n cookie,\r\n code,\r\n };\r\n\r\n const response = await api.apps.post<TwoFactorApiResponse>(\r\n \"/auth/code\",\r\n payload\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\"Código 2FA inválido\", \"TWO_FACTOR_FAILED\", 401);\r\n }\r\n\r\n if (!response?.data?.cookie) {\r\n throw new ApiError(\r\n \"Resposta de autenticação inválida após 2FA\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n await this.setAuthCookie(response.data.cookie);\r\n\r\n return { status: 1 };\r\n }\r\n async register(data: RegisterRequest, clientInfo: ClientInfo): Promise<RegisterResponse> {\r\n const today = new Date();\r\n const trialEndDate = new Date(today);\r\n trialEndDate.setDate(today.getDate() + 7); // 7 dias de trial\r\n\r\n const idPlan = await this.resolvePlanId(data.idPlan);\r\n\r\n const payload: RegisterApiRequest = {\r\n name: data.accountName,\r\n bussiness_type: data.businessType ?? 0,\r\n language: \"pt-br\",\r\n timezone: \"America/Sao_Paulo\",\r\n currency: \"BRL\",\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n agent: clientInfo.agent,\r\n user: {\r\n id_api: \"\",\r\n name: data.name,\r\n last_name: data.lastName || \"\",\r\n rg: data.rg || \"\",\r\n cpf: data.cpf || \"\",\r\n gender: data.gender,\r\n email: data.email,\r\n phone: data.phone,\r\n password: data.password,\r\n profile: \"owner\",\r\n language: \"pt-br\",\r\n },\r\n subscription: {\r\n type: \"trial\",\r\n id_cupom: data.couponCode || \"\",\r\n id_plan: idPlan,\r\n due_date: trialEndDate.toISOString().split(\"T\")[0],\r\n id_product: 1,\r\n },\r\n };\r\n\r\n const response = await api.apps.post<RegisterApiResponse>(\r\n \"/accounts\",\r\n payload\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao criar conta\",\r\n \"REGISTER_FAILED\",\r\n 400\r\n );\r\n }\r\n\r\n if (!response.data || response.data.length === 0) {\r\n throw new ApiError(\r\n \"Resposta de registro inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n if (!response.cookie) {\r\n throw new ApiError(\r\n \"Resposta de autenticação inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n const accountData = response.data[0];\r\n\r\n await this.setAuthCookie(response.cookie);\r\n\r\n const [{ userService }, { accountService }] = await Promise.all([\r\n import('../../users/services/user.service'),\r\n import('../../accounts/services/account.service'),\r\n ]);\r\n const [user, account] = await Promise.all([\r\n userService.findById(),\r\n accountService.findCurrentAccount(),\r\n ]);\r\n\r\n return {\r\n user,\r\n account,\r\n accessToken: response.cookie,\r\n refreshToken: \"\",\r\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\r\n requiresEmailVerification: !accountData.verified,\r\n };\r\n }\r\n\r\n async logout(clientInfo: ClientInfo): Promise<LogoutResponse> {\r\n const cookie = await this.getToken();\r\n\r\n if (!cookie) {\r\n throw new ApiError(\r\n \"Usuário não autenticado\",\r\n \"NOT_AUTHENTICATED_LOGOUT\",\r\n 401\r\n );\r\n }\r\n\r\n const payload: LogoutRequest = {\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n cookie,\r\n };\r\n\r\n try {\r\n const response = await api.apps.post<LogoutApiResponse>(\r\n \"/auth/logout\",\r\n payload\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao realizar logout\",\r\n response.code || \"LOGOUT_FAILED\",\r\n 400\r\n );\r\n }\r\n } finally {\r\n await this.removeAuthCookie();\r\n }\r\n\r\n return {\r\n success: true,\r\n };\r\n }\r\n\r\n async forgotPassword(\r\n _data: ForgotPasswordRequest\r\n ): Promise<ForgotPasswordResponse> {\r\n throw new ApiError(\r\n \"Recuperação de senha não implementada\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async resetPassword(\r\n _data: ResetPasswordRequest\r\n ): Promise<ResetPasswordResponse> {\r\n throw new ApiError(\r\n \"Redefinição de senha não implementada\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async verifyEmail(_data: VerifyEmailRequest): Promise<VerifyEmailResponse> {\r\n throw new ApiError(\r\n \"Verificação de email não implementada\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async resendVerification(\r\n _data: ResendVerificationRequest\r\n ): Promise<ResendVerificationResponse> {\r\n throw new ApiError(\r\n \"Reenvio de verificação não implementado\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async validateSession(clientInfo: ClientInfo): Promise<boolean> {\r\n const cookie = await this.getToken();\r\n\r\n if (!cookie) {\r\n return false;\r\n }\r\n\r\n try {\r\n const payload: SessionKeepRequest = {\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n cookie,\r\n };\r\n\r\n const response = await api.apps.post<SessionKeepResponse>(\r\n \"/auth/keep\",\r\n payload\r\n );\r\n\r\n return response.status === 1;\r\n } catch (error) {\r\n console.error(\"[AuthService] validateSession error\", error);\r\n return false;\r\n }\r\n }\r\n\r\n async isAuthenticated(): Promise<boolean> {\r\n const token = await this.getToken();\r\n return !!token;\r\n }\r\n\r\n async getToken(): Promise<string | undefined> {\r\n if (process.env.DUMMY_AUTH_TOKEN) return process.env.DUMMY_AUTH_TOKEN;\r\n const cookieStore = await cookies();\r\n return cookieStore.get(AUTH_COOKIE_NAME)?.value;\r\n }\r\n\r\n private async resolvePlanId(idPlan?: number | string): Promise<number> {\r\n if (idPlan === undefined || idPlan === null) return 1;\r\n if (typeof idPlan === 'number') return idPlan;\r\n\r\n const response = await api.apps.get<SearchPlansApiResponse>(\r\n `/plans?search=${encodeURIComponent(idPlan)}`\r\n );\r\n\r\n if (response.status === 0 || !response.data || response.data.length === 0) {\r\n throw new ApiError(\r\n `Plano \"${idPlan}\" não encontrado`,\r\n \"PLAN_NOT_FOUND\",\r\n 404\r\n );\r\n }\r\n\r\n return response.data[0].id;\r\n }\r\n\r\n private async setAuthCookie(token: string): Promise<void> {\r\n const cookieStore = await cookies();\r\n const whitelabel = await findWhitelabel().catch(() => null);\r\n const cookieDomain =\r\n this.normalizeCookieDomain(whitelabel?.domain) ??\r\n this.normalizeCookieDomain(process.env.DOMAIN_COOKIE);\r\n\r\n cookieStore.set(AUTH_COOKIE_NAME, token, {\r\n ...COOKIE_OPTIONS,\r\n ...(cookieDomain ? { domain: cookieDomain } : {}),\r\n maxAge: COOKIE_MAX_AGE,\r\n });\r\n }\r\n\r\n async removeAuthCookie(): Promise<void> {\r\n const cookieStore = await cookies();\r\n const whitelabel = await findWhitelabel().catch(() => null);\r\n const cookieDomain =\r\n this.normalizeCookieDomain(whitelabel?.domain) ??\r\n this.normalizeCookieDomain(process.env.DOMAIN_COOKIE);\r\n\r\n cookieStore.delete({\r\n name: AUTH_COOKIE_NAME,\r\n ...COOKIE_OPTIONS,\r\n ...(cookieDomain ? { domain: cookieDomain } : {}),\r\n });\r\n }\r\n\r\n private normalizeCookieDomain(domain?: string | null): string | undefined {\r\n if (!domain) return undefined;\r\n\r\n const normalized = domain.trim();\r\n if (!normalized) return undefined;\r\n\r\n const rawHost = (() => {\r\n try {\r\n return new URL(normalized).hostname;\r\n } catch {\r\n return normalized\r\n .replace(/^https?:\\/\\//i, \"\")\r\n .replace(/^www\\./i, \"\")\r\n .split(\"/\")[0]\r\n .split(\":\")[0];\r\n }\r\n })();\r\n\r\n if (!rawHost || rawHost === \"localhost\") {\r\n return undefined;\r\n }\r\n\r\n return rawHost.startsWith(\".\") ? rawHost : `.${rawHost}`;\r\n }\r\n}\r\n\r\nexport const authService = new AuthService();\r\n\r\nexport type { ClientInfo, GeoLocation };\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/auth/services/auth.service.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\r\n\r\nimport { api, type RequestConfig } from \"../../../infra/api/client\";\r\nimport { ApiError } from \"../../../infra/api/types\";\r\nimport { whitelabelService } from \"../../whitelabel/services/whitelabel.service\";\r\nimport { buildWlOverrideFromJwt } from \"../utils/build-wl-override\";\r\nimport {\r\n ClientInfo,\r\n ForgotPasswordRequest,\r\n ForgotPasswordResponse,\r\n GeoLocation,\r\n LoginApiResponse,\r\n LoginRequest,\r\n LoginResponse,\r\n LogoutApiResponse,\r\n LogoutRequest,\r\n LogoutResponse,\r\n RegisterApiRequest,\r\n RegisterApiResponse,\r\n RegisterRequest,\r\n RegisterResponse,\r\n ResendVerificationRequest,\r\n ResendVerificationResponse,\r\n ResetPasswordRequest,\r\n ResetPasswordResponse,\r\n SearchPlansApiResponse,\r\n SessionKeepRequest,\r\n SessionKeepResponse,\r\n TwoFactorApiResponse,\r\n TwoFactorRequest,\r\n TwoFactorResponse,\r\n VerifyEmailRequest,\r\n VerifyEmailResponse,\r\n} from \"../schema\";\r\nimport { findWhitelabel } from \"../../../server\";\r\n\r\nconst AUTH_COOKIE_NAME = \"greatapps\";\r\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 30;\r\n\r\nconst COOKIE_OPTIONS = {\r\n httpOnly: true,\r\n secure: process.env.NODE_ENV === \"production\",\r\n sameSite: \"lax\" as const,\r\n path: \"/\",\r\n domain: process.env.DOMAIN_COOKIE,\r\n};\r\n\r\nclass AuthService {\r\n \r\n async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo\r\n ): Promise<LoginResponse> {\r\n let requestConfig: RequestConfig | undefined;\r\n if (credentials.id_wl) {\r\n const wlToken = await whitelabelService.getTokenByWhitelabelId(credentials.id_wl);\r\n requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };\r\n \r\n }\r\n\r\n const response = await api.apps.post<LoginApiResponse>(\"/auth/login\", {\r\n email: credentials.email,\r\n password: credentials.password,\r\n source: credentials?.source,\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n }, requestConfig);\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"E-mail ou senha incorretos\",\r\n response.code || \"LOGIN_FAILED\",\r\n 401\r\n );\r\n }\r\n\r\n if (!response.cookie) {\r\n throw new ApiError(\r\n \"Resposta de autenticação inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n if (response.two_factor_required) {\r\n return { result: 'two_factor_required', cookie: response.cookie };\r\n }\r\n\r\n await this.setAuthCookie(response.cookie);\r\n\r\n const [{ userService }, { accountService }] = await Promise.all([\r\n import('../../users/services/user.service'),\r\n import('../../accounts/services/account.service'),\r\n ]);\r\n const [user, account] = await Promise.all([\r\n userService.findById(requestConfig ? { authToken: requestConfig.authToken } : undefined),\r\n accountService.findCurrentAccount(requestConfig),\r\n ]);\r\n\r\n return {\r\n result: 'success',\r\n user,\r\n account,\r\n accessToken: response.cookie,\r\n refreshToken: \"\",\r\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\r\n };\r\n }\r\n\r\n async verifyTwoFactor(\r\n cookie: string,\r\n code: string,\r\n clientInfo: ClientInfo\r\n ): Promise<TwoFactorResponse> {\r\n const payload: TwoFactorRequest = {\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n cookie,\r\n code,\r\n };\r\n\r\n const response = await api.apps.post<TwoFactorApiResponse>(\r\n \"/auth/code\",\r\n payload\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\"Código 2FA inválido\", \"TWO_FACTOR_FAILED\", 401);\r\n }\r\n\r\n if (!response?.data?.cookie) {\r\n throw new ApiError(\r\n \"Resposta de autenticação inválida após 2FA\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n await this.setAuthCookie(response.data.cookie);\r\n\r\n return { status: 1 };\r\n }\r\n async register(data: RegisterRequest, clientInfo: ClientInfo): Promise<RegisterResponse> {\r\n const today = new Date();\r\n const trialEndDate = new Date(today);\r\n trialEndDate.setDate(today.getDate() + 7); // 7 dias de trial\r\n\r\n const idPlan = await this.resolvePlanId(data.idPlan);\r\n\r\n const payload: RegisterApiRequest = {\r\n name: data.accountName,\r\n bussiness_type: data.businessType ?? 0,\r\n language: \"pt-br\",\r\n timezone: \"America/Sao_Paulo\",\r\n currency: \"BRL\",\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n agent: clientInfo.agent,\r\n user: {\r\n id_api: \"\",\r\n name: data.name,\r\n last_name: data.lastName || \"\",\r\n rg: data.rg || \"\",\r\n cpf: data.cpf || \"\",\r\n gender: data.gender,\r\n email: data.email,\r\n phone: data.phone,\r\n password: data.password,\r\n profile: \"owner\",\r\n language: \"pt-br\",\r\n },\r\n subscription: {\r\n type: \"trial\",\r\n id_cupom: data.couponCode || \"\",\r\n id_plan: idPlan,\r\n due_date: trialEndDate.toISOString().split(\"T\")[0],\r\n id_product: 1,\r\n },\r\n };\r\n\r\n const response = await api.apps.post<RegisterApiResponse>(\r\n \"/accounts\",\r\n payload\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao criar conta\",\r\n \"REGISTER_FAILED\",\r\n 400\r\n );\r\n }\r\n\r\n if (!response.data || response.data.length === 0) {\r\n throw new ApiError(\r\n \"Resposta de registro inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n if (!response.cookie) {\r\n throw new ApiError(\r\n \"Resposta de autenticação inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500\r\n );\r\n }\r\n\r\n const accountData = response.data[0];\r\n\r\n await this.setAuthCookie(response.cookie);\r\n\r\n const [{ userService }, { accountService }] = await Promise.all([\r\n import('../../users/services/user.service'),\r\n import('../../accounts/services/account.service'),\r\n ]);\r\n const [user, account] = await Promise.all([\r\n userService.findById(),\r\n accountService.findCurrentAccount(),\r\n ]);\r\n\r\n return {\r\n user,\r\n account,\r\n accessToken: response.cookie,\r\n refreshToken: \"\",\r\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\r\n requiresEmailVerification: !accountData.verified,\r\n };\r\n }\r\n\r\n async logout(clientInfo: ClientInfo): Promise<LogoutResponse> {\r\n const cookie = await this.getToken();\r\n\r\n if (!cookie) {\r\n throw new ApiError(\r\n \"Usuário não autenticado\",\r\n \"NOT_AUTHENTICATED_LOGOUT\",\r\n 401\r\n );\r\n }\r\n\r\n const payload: LogoutRequest = {\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n cookie,\r\n };\r\n\r\n try {\r\n const response = await api.apps.post<LogoutApiResponse>(\r\n \"/auth/logout\",\r\n payload\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao realizar logout\",\r\n response.code || \"LOGOUT_FAILED\",\r\n 400\r\n );\r\n }\r\n } finally {\r\n await this.removeAuthCookie();\r\n }\r\n\r\n return {\r\n success: true,\r\n };\r\n }\r\n\r\n async forgotPassword(\r\n _data: ForgotPasswordRequest\r\n ): Promise<ForgotPasswordResponse> {\r\n throw new ApiError(\r\n \"Recuperação de senha não implementada\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async resetPassword(\r\n _data: ResetPasswordRequest\r\n ): Promise<ResetPasswordResponse> {\r\n throw new ApiError(\r\n \"Redefinição de senha não implementada\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async verifyEmail(_data: VerifyEmailRequest): Promise<VerifyEmailResponse> {\r\n throw new ApiError(\r\n \"Verificação de email não implementada\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async resendVerification(\r\n _data: ResendVerificationRequest\r\n ): Promise<ResendVerificationResponse> {\r\n throw new ApiError(\r\n \"Reenvio de verificação não implementado\",\r\n \"NOT_IMPLEMENTED\",\r\n 501\r\n );\r\n }\r\n\r\n async validateSession(clientInfo: ClientInfo): Promise<boolean> {\r\n const cookie = await this.getToken();\r\n\r\n if (!cookie) {\r\n return false;\r\n }\r\n\r\n try {\r\n const requestConfig = await buildWlOverrideFromJwt(cookie);\r\n\r\n const payload: SessionKeepRequest = {\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n cookie,\r\n };\r\n\r\n const response = await api.apps.post<SessionKeepResponse>(\r\n \"/auth/keep\",\r\n payload,\r\n requestConfig\r\n );\r\n\r\n return response.status === 1;\r\n } catch (error) {\r\n console.error(\"[AuthService] validateSession error\", error);\r\n return false;\r\n }\r\n }\r\n\r\n async isAuthenticated(): Promise<boolean> {\r\n const token = await this.getToken();\r\n return !!token;\r\n }\r\n\r\n async getToken(): Promise<string | undefined> {\r\n if (process.env.DUMMY_AUTH_TOKEN) return process.env.DUMMY_AUTH_TOKEN;\r\n const cookieStore = await cookies();\r\n return cookieStore.get(AUTH_COOKIE_NAME)?.value;\r\n }\r\n\r\n private async resolvePlanId(idPlan?: number | string): Promise<number> {\r\n if (idPlan === undefined || idPlan === null) return 1;\r\n if (typeof idPlan === 'number') return idPlan;\r\n\r\n const response = await api.apps.get<SearchPlansApiResponse>(\r\n `/plans?search=${encodeURIComponent(idPlan)}`\r\n );\r\n\r\n if (response.status === 0 || !response.data || response.data.length === 0) {\r\n throw new ApiError(\r\n `Plano \"${idPlan}\" não encontrado`,\r\n \"PLAN_NOT_FOUND\",\r\n 404\r\n );\r\n }\r\n\r\n return response.data[0].id;\r\n }\r\n\r\n private async setAuthCookie(token: string): Promise<void> {\r\n const cookieStore = await cookies();\r\n const whitelabel = await findWhitelabel().catch(() => null);\r\n const cookieDomain =\r\n this.normalizeCookieDomain(whitelabel?.domain) ??\r\n this.normalizeCookieDomain(process.env.DOMAIN_COOKIE);\r\n\r\n cookieStore.set(AUTH_COOKIE_NAME, token, {\r\n ...COOKIE_OPTIONS,\r\n ...(cookieDomain ? { domain: cookieDomain } : {}),\r\n maxAge: COOKIE_MAX_AGE,\r\n });\r\n }\r\n\r\n async removeAuthCookie(): Promise<void> {\r\n const cookieStore = await cookies();\r\n const whitelabel = await findWhitelabel().catch(() => null);\r\n const cookieDomain =\r\n this.normalizeCookieDomain(whitelabel?.domain) ??\r\n this.normalizeCookieDomain(process.env.DOMAIN_COOKIE);\r\n\r\n cookieStore.delete({\r\n name: AUTH_COOKIE_NAME,\r\n ...COOKIE_OPTIONS,\r\n ...(cookieDomain ? { domain: cookieDomain } : {}),\r\n });\r\n }\r\n\r\n private normalizeCookieDomain(domain?: string | null): string | undefined {\r\n if (!domain) return undefined;\r\n\r\n const normalized = domain.trim();\r\n if (!normalized) return undefined;\r\n\r\n const rawHost = (() => {\r\n try {\r\n return new URL(normalized).hostname;\r\n } catch {\r\n return normalized\r\n .replace(/^https?:\\/\\//i, \"\")\r\n .replace(/^www\\./i, \"\")\r\n .split(\"/\")[0]\r\n .split(\":\")[0];\r\n }\r\n })();\r\n\r\n if (!rawHost || rawHost === \"localhost\") {\r\n return undefined;\r\n }\r\n\r\n return rawHost.startsWith(\".\") ? rawHost : `.${rawHost}`;\r\n }\r\n}\r\n\r\nexport const authService = new AuthService();\r\n\r\nexport type { ClientInfo, GeoLocation };\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,20 @@
1
+ import "server-only";
2
+ import { findWhitelabel } from "../../whitelabel/actions/find-whitelabel.action";
3
+ import { whitelabelService } from "../../whitelabel/services/whitelabel.service";
4
+ async function buildWlOverrideFromJwt(cookie) {
5
+ try {
6
+ const payload = JSON.parse(atob(cookie.split(".")[1]));
7
+ const jwtWlId = Number(payload.id_wl);
8
+ const { id: hostWlId } = await findWhitelabel();
9
+ if (jwtWlId !== hostWlId) {
10
+ const wlToken = await whitelabelService.getTokenByWhitelabelId(jwtWlId);
11
+ return { whiteLabelId: jwtWlId, authToken: wlToken };
12
+ }
13
+ } catch {
14
+ }
15
+ return void 0;
16
+ }
17
+ export {
18
+ buildWlOverrideFromJwt
19
+ };
20
+ //# sourceMappingURL=build-wl-override.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/auth/utils/build-wl-override.ts"],"sourcesContent":["import 'server-only';\n\nimport type { RequestConfig } from '../../../infra/api/client';\nimport type { JWTPayload } from '../../users/schema';\nimport { findWhitelabel } from '../../whitelabel/actions/find-whitelabel.action';\nimport { whitelabelService } from '../../whitelabel/services/whitelabel.service';\n\n/**\n * Compara o `id_wl` do JWT com o whitelabel resolvido pelo hostname.\n * Se forem diferentes (ex: admin logando com id_wl=1 num domínio de id_wl=30),\n * retorna um RequestConfig com o override correto.\n * Se forem iguais, retorna undefined (sem custo extra).\n */\nexport async function buildWlOverrideFromJwt(\n cookie: string,\n): Promise<RequestConfig | undefined> {\n try {\n const payload = JSON.parse(atob(cookie.split('.')[1])) as JWTPayload;\n const jwtWlId = Number(payload.id_wl);\n const { id: hostWlId } = await findWhitelabel();\n\n if (jwtWlId !== hostWlId) {\n const wlToken = await whitelabelService.getTokenByWhitelabelId(jwtWlId);\n return { whiteLabelId: jwtWlId, authToken: wlToken };\n }\n } catch {\n // Fallback to default whitelabel resolution\n }\n\n return undefined;\n}\n"],"mappings":"AAAA,OAAO;AAIP,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAQlC,eAAsB,uBACpB,QACoC;AACpC,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,KAAK,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AACrD,UAAM,UAAU,OAAO,QAAQ,KAAK;AACpC,UAAM,EAAE,IAAI,SAAS,IAAI,MAAM,eAAe;AAE9C,QAAI,YAAY,UAAU;AACxB,YAAM,UAAU,MAAM,kBAAkB,uBAAuB,OAAO;AACtE,aAAO,EAAE,cAAc,SAAS,WAAW,QAAQ;AAAA,IACrD;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;","names":[]}
@@ -11,6 +11,7 @@ async function getUserContext() {
11
11
  try {
12
12
  const payload = JSON.parse(atob(token.split(".")[1]));
13
13
  return {
14
+ id_wl: Number(payload.id_wl),
14
15
  id_account: payload.id_account,
15
16
  id_user: payload.id_user
16
17
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/auth/utils/get-user-context.ts"],"sourcesContent":["import 'server-only';\r\n\r\nimport { cookies } from 'next/headers';\r\nimport { ApiError } from '../../../infra/api/types';\r\nimport { JWTPayload } from '../../users/schema';\r\n\r\nconst AUTH_COOKIE_NAME = 'greatapps';\r\n\r\nexport async function getUserContext(): Promise<{\r\n id_account: number;\r\n id_user: number;\r\n}> {\r\n const cookieStore = await cookies();\r\n const token = process.env.DUMMY_AUTH_TOKEN || cookieStore.get(AUTH_COOKIE_NAME)?.value;\r\n\r\n if (!token) {\r\n throw new ApiError('Usuário não autenticado', 'NOT_AUTHENTICATED_GUC', 401);\r\n }\r\n\r\n try {\r\n const payload = JSON.parse(atob(token.split('.')[1])) as JWTPayload;\r\n\r\n return {\r\n id_account: payload.id_account,\r\n id_user: payload.id_user,\r\n };\r\n } catch {\r\n throw new ApiError('Token inválido', 'INVALID_TOKEN', 401);\r\n }\r\n}\r\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,eAAe;AACxB,SAAS,gBAAgB;AAGzB,MAAM,mBAAmB;AAEzB,eAAsB,iBAGnB;AACD,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,QAAQ,QAAQ,IAAI,oBAAoB,YAAY,IAAI,gBAAgB,GAAG;AAEjF,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,SAAS,iCAA2B,yBAAyB,GAAG;AAAA,EAC5E;AAEA,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AAEpD,WAAO;AAAA,MACL,YAAY,QAAQ;AAAA,MACpB,SAAS,QAAQ;AAAA,IACnB;AAAA,EACF,QAAQ;AACN,UAAM,IAAI,SAAS,qBAAkB,iBAAiB,GAAG;AAAA,EAC3D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/auth/utils/get-user-context.ts"],"sourcesContent":["import 'server-only';\r\n\r\nimport { cookies } from 'next/headers';\r\nimport { ApiError } from '../../../infra/api/types';\r\nimport { JWTPayload } from '../../users/schema';\r\n\r\nconst AUTH_COOKIE_NAME = 'greatapps';\r\n\r\nexport async function getUserContext(): Promise<{\r\n id_wl: number;\r\n id_account: number;\r\n id_user: number;\r\n}> {\r\n const cookieStore = await cookies();\r\n const token = process.env.DUMMY_AUTH_TOKEN || cookieStore.get(AUTH_COOKIE_NAME)?.value;\r\n\r\n if (!token) {\r\n throw new ApiError('Usuário não autenticado', 'NOT_AUTHENTICATED_GUC', 401);\r\n }\r\n\r\n try {\r\n const payload = JSON.parse(atob(token.split('.')[1])) as JWTPayload;\r\n\r\n return {\r\n id_wl: Number(payload.id_wl),\r\n id_account: payload.id_account,\r\n id_user: payload.id_user,\r\n };\r\n } catch {\r\n throw new ApiError('Token inválido', 'INVALID_TOKEN', 401);\r\n }\r\n}\r\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,eAAe;AACxB,SAAS,gBAAgB;AAGzB,MAAM,mBAAmB;AAEzB,eAAsB,iBAInB;AACD,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,QAAQ,QAAQ,IAAI,oBAAoB,YAAY,IAAI,gBAAgB,GAAG;AAEjF,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,SAAS,iCAA2B,yBAAyB,GAAG;AAAA,EAC5E;AAEA,MAAI;AACF,UAAM,UAAU,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC;AAEpD,WAAO;AAAA,MACL,OAAO,OAAO,QAAQ,KAAK;AAAA,MAC3B,YAAY,QAAQ;AAAA,MACpB,SAAS,QAAQ;AAAA,IACnB;AAAA,EACF,QAAQ;AACN,UAAM,IAAI,SAAS,qBAAkB,iBAAiB,GAAG;AAAA,EAC3D;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.286",
3
+ "version": "1.1.287",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -1,8 +1,9 @@
1
1
  import { cookies } from "next/headers";
2
2
 
3
- import { api } from "../../../infra/api/client";
3
+ import { api, type RequestConfig } from "../../../infra/api/client";
4
4
  import { ApiError } from "../../../infra/api/types";
5
5
  import { whitelabelService } from "../../whitelabel/services/whitelabel.service";
6
+ import { buildWlOverrideFromJwt } from "../utils/build-wl-override";
6
7
  import {
7
8
  ClientInfo,
8
9
  ForgotPasswordRequest,
@@ -50,7 +51,7 @@ class AuthService {
50
51
  credentials: LoginRequest,
51
52
  clientInfo: ClientInfo
52
53
  ): Promise<LoginResponse> {
53
- let requestConfig: import("../../../infra/api/client").RequestConfig | undefined;
54
+ let requestConfig: RequestConfig | undefined;
54
55
  if (credentials.id_wl) {
55
56
  const wlToken = await whitelabelService.getTokenByWhitelabelId(credentials.id_wl);
56
57
  requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };
@@ -320,6 +321,8 @@ class AuthService {
320
321
  }
321
322
 
322
323
  try {
324
+ const requestConfig = await buildWlOverrideFromJwt(cookie);
325
+
323
326
  const payload: SessionKeepRequest = {
324
327
  location: clientInfo.location,
325
328
  ip: clientInfo.ip,
@@ -330,7 +333,8 @@ class AuthService {
330
333
 
331
334
  const response = await api.apps.post<SessionKeepResponse>(
332
335
  "/auth/keep",
333
- payload
336
+ payload,
337
+ requestConfig
334
338
  );
335
339
 
336
340
  return response.status === 1;
@@ -0,0 +1,31 @@
1
+ import 'server-only';
2
+
3
+ import type { RequestConfig } from '../../../infra/api/client';
4
+ import type { JWTPayload } from '../../users/schema';
5
+ import { findWhitelabel } from '../../whitelabel/actions/find-whitelabel.action';
6
+ import { whitelabelService } from '../../whitelabel/services/whitelabel.service';
7
+
8
+ /**
9
+ * Compara o `id_wl` do JWT com o whitelabel resolvido pelo hostname.
10
+ * Se forem diferentes (ex: admin logando com id_wl=1 num domínio de id_wl=30),
11
+ * retorna um RequestConfig com o override correto.
12
+ * Se forem iguais, retorna undefined (sem custo extra).
13
+ */
14
+ export async function buildWlOverrideFromJwt(
15
+ cookie: string,
16
+ ): Promise<RequestConfig | undefined> {
17
+ try {
18
+ const payload = JSON.parse(atob(cookie.split('.')[1])) as JWTPayload;
19
+ const jwtWlId = Number(payload.id_wl);
20
+ const { id: hostWlId } = await findWhitelabel();
21
+
22
+ if (jwtWlId !== hostWlId) {
23
+ const wlToken = await whitelabelService.getTokenByWhitelabelId(jwtWlId);
24
+ return { whiteLabelId: jwtWlId, authToken: wlToken };
25
+ }
26
+ } catch {
27
+ // Fallback to default whitelabel resolution
28
+ }
29
+
30
+ return undefined;
31
+ }
@@ -7,6 +7,7 @@ import { JWTPayload } from '../../users/schema';
7
7
  const AUTH_COOKIE_NAME = 'greatapps';
8
8
 
9
9
  export async function getUserContext(): Promise<{
10
+ id_wl: number;
10
11
  id_account: number;
11
12
  id_user: number;
12
13
  }> {
@@ -21,6 +22,7 @@ export async function getUserContext(): Promise<{
21
22
  const payload = JSON.parse(atob(token.split('.')[1])) as JWTPayload;
22
23
 
23
24
  return {
25
+ id_wl: Number(payload.id_wl),
24
26
  id_account: payload.id_account,
25
27
  id_user: payload.id_user,
26
28
  };