@greatapps/common 1.1.633 → 1.1.635
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/dist/components/account/sections/SecuritySection.mjs +38 -2
- package/dist/components/account/sections/SecuritySection.mjs.map +1 -1
- package/dist/components/navigation/SubscriptionBanner.mjs +12 -4
- package/dist/components/navigation/SubscriptionBanner.mjs.map +1 -1
- package/dist/index.mjs +6 -0
- package/dist/index.mjs.map +1 -1
- package/dist/modules/auth/actions/social-google-login.action.mjs +14 -0
- package/dist/modules/auth/actions/social-google-login.action.mjs.map +1 -0
- package/dist/modules/auth/actions/social-google-onboarding.action.mjs +14 -0
- package/dist/modules/auth/actions/social-google-onboarding.action.mjs.map +1 -0
- package/dist/modules/auth/actions/unlink-google.action.mjs +10 -0
- package/dist/modules/auth/actions/unlink-google.action.mjs.map +1 -0
- package/dist/modules/auth/hooks/social-google-login.hook.mjs +13 -0
- package/dist/modules/auth/hooks/social-google-login.hook.mjs.map +1 -0
- package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs +13 -0
- package/dist/modules/auth/hooks/social-google-onboarding.hook.mjs.map +1 -0
- package/dist/modules/auth/hooks/unlink-google.hook.mjs +13 -0
- package/dist/modules/auth/hooks/unlink-google.hook.mjs.map +1 -0
- package/dist/modules/auth/services/auth.service.mjs +165 -0
- package/dist/modules/auth/services/auth.service.mjs.map +1 -1
- package/dist/modules/users/schema.mjs.map +1 -1
- package/dist/providers/auth.provider.mjs +63 -3
- package/dist/providers/auth.provider.mjs.map +1 -1
- package/dist/server.mjs +6 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/account/sections/SecuritySection.tsx +50 -3
- package/src/components/navigation/SubscriptionBanner.tsx +31 -14
- package/src/index.ts +3 -0
- package/src/modules/auth/actions/social-google-login.action.ts +12 -0
- package/src/modules/auth/actions/social-google-onboarding.action.ts +13 -0
- package/src/modules/auth/actions/unlink-google.action.ts +8 -0
- package/src/modules/auth/hooks/social-google-login.hook.tsx +13 -0
- package/src/modules/auth/hooks/social-google-onboarding.hook.tsx +13 -0
- package/src/modules/auth/hooks/unlink-google.hook.tsx +13 -0
- package/src/modules/auth/schema.ts +74 -0
- package/src/modules/auth/services/auth.service.ts +207 -0
- package/src/modules/users/schema.ts +2 -0
- package/src/providers/auth.provider.tsx +86 -1
- package/src/server.ts +3 -0
|
@@ -1 +1 @@
|
|
|
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};\r\n\r\nclass AuthService {\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(\r\n credentials.id_wl,\r\n );\r\n requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };\r\n }\r\n\r\n const response = await api.apps.post<LoginApiResponse>(\r\n \"/auth/login\",\r\n {\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 },\r\n requestConfig,\r\n );\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, twoFactorMode: response.two_factor_required };\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(\r\n requestConfig ? { authToken: requestConfig.authToken } : undefined,\r\n ),\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 options?: { window?: number },\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 endpoint = options?.window !== undefined ? `/auth/code?window=${options.window}` : '/auth/code';\r\n const response = await api.apps.post<TwoFactorApiResponse>(\r\n endpoint,\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(\r\n data: RegisterRequest,\r\n clientInfo: ClientInfo,\r\n ): Promise<RegisterResponse> {\r\n const today = new Date();\r\n const trialEndDate = new Date(today);\r\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\r\n trialEndDate.setDate(today.getDate() + trialDays);\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 id_affiliate: data.affiliateId || 0,\r\n origin: data.origin,\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 idPlan === -1\r\n ? {\r\n type: \"free\",\r\n id_coupon: data.couponId || 0,\r\n id_plan: 5, // Plano Free (ID fixo)\r\n id_product: 1,\r\n }\r\n : {\r\n type: \"trial\",\r\n id_coupon: data.couponId || 0,\r\n id_plan: idPlan,\r\n // Fluxo não-Stripe lê `date_due`; fluxo Stripe lê `trial_days`.\r\n // Mandamos os dois pra cobrir ambos os caminhos da API.\r\n date_due: trialEndDate.toISOString().split(\"T\")[0],\r\n trial_days: trialDays,\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 | null): Promise<number> {\r\n if (idPlan == null || idPlan === \"\") return -1;\r\n if (typeof idPlan === \"number\" || Number(idPlan)) return Number(idPlan);\r\n\r\n if (typeof idPlan === \"string\") {\r\n const response = await api.apps.get<SearchPlansApiResponse>(\r\n `/plans?search=${encodeURIComponent(idPlan)}`,\r\n );\r\n\r\n if (response.status === 1 && response.data?.length) {\r\n return response.data[0].id;\r\n }\r\n\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 return -1;\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\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\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 SocialGoogleApiResponse,\r\n SocialGoogleResponse,\r\n SocialOnboardingApiResponse,\r\n SocialOnboardingRequest,\r\n SocialOnboardingResponse,\r\n TwoFactorApiResponse,\r\n TwoFactorRequest,\r\n TwoFactorResponse,\r\n UnlinkGoogleApiResponse,\r\n UnlinkGoogleResponse,\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};\r\n\r\nclass AuthService {\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(\r\n credentials.id_wl,\r\n );\r\n requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };\r\n }\r\n\r\n const response = await api.apps.post<LoginApiResponse>(\r\n \"/auth/login\",\r\n {\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 },\r\n requestConfig,\r\n );\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, twoFactorMode: response.two_factor_required };\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(\r\n requestConfig ? { authToken: requestConfig.authToken } : undefined,\r\n ),\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 options?: { window?: number },\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 endpoint = options?.window !== undefined ? `/auth/code?window=${options.window}` : '/auth/code';\r\n const response = await api.apps.post<TwoFactorApiResponse>(\r\n endpoint,\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\r\n async socialLoginGoogle(\r\n code: string,\r\n clientInfo: ClientInfo,\r\n ): Promise<SocialGoogleResponse> {\r\n const response = await api.apps.post<SocialGoogleApiResponse>(\r\n \"/auth/social/google\",\r\n {\r\n code,\r\n location: clientInfo.location,\r\n ip: clientInfo.ip,\r\n timezone: clientInfo.timezone,\r\n agent: clientInfo.agent,\r\n verification: true,\r\n },\r\n );\r\n\r\n if (response.status === 0) {\r\n if (response.code === \"link_requires_password\") {\r\n return {\r\n result: \"link_requires_password\",\r\n message:\r\n response.message ||\r\n \"Uma conta com esse e-mail já existe. Faça login com e-mail e senha para vincular sua conta Google.\",\r\n };\r\n }\r\n throw new ApiError(\r\n response.message || \"Falha no login com Google\",\r\n response.code || \"GOOGLE_LOGIN_FAILED\",\r\n 401,\r\n );\r\n }\r\n\r\n if (response.needs_onboarding) {\r\n if (!response.onboarding_token || !response.partial?.email) {\r\n throw new ApiError(\r\n \"Resposta de onboarding inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500,\r\n );\r\n }\r\n return {\r\n result: \"needs_onboarding\",\r\n onboardingToken: response.onboarding_token,\r\n partial: response.partial,\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 {\r\n result: \"two_factor_required\",\r\n cookie: response.cookie,\r\n twoFactorMode: response.two_factor_required,\r\n };\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(),\r\n accountService.findCurrentAccount(),\r\n ]);\r\n\r\n return {\r\n result: \"success\",\r\n user,\r\n account,\r\n accessToken: response.cookie,\r\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\r\n };\r\n }\r\n\r\n async completeGoogleOnboarding(\r\n data: SocialOnboardingRequest,\r\n clientInfo: ClientInfo,\r\n ): Promise<SocialOnboardingResponse> {\r\n const today = new Date();\r\n const trialEndDate = new Date(today);\r\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\r\n trialEndDate.setDate(today.getDate() + trialDays);\r\n\r\n const idPlan = await this.resolvePlanId(data.idPlan);\r\n\r\n const payload = {\r\n onboarding_token: data.onboardingToken,\r\n name: data.user.name,\r\n bussiness_type: 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 id_affiliate: data.affiliateId || 0,\r\n origin: data.origin,\r\n user: {\r\n id_api: \"\",\r\n name: data.user.name || \"\",\r\n last_name: data.user.last_name || \"\",\r\n rg: data.user.rg || \"\",\r\n cpf: data.user.cpf || \"\",\r\n gender: data.user.gender ?? 1,\r\n ddi: data.user.ddi || \"55\",\r\n phone: data.user.phone || \"\",\r\n profile: \"owner\",\r\n language: \"pt-br\",\r\n },\r\n subscription:\r\n idPlan === -1\r\n ? {\r\n type: \"free\",\r\n id_coupon: data.couponId || 0,\r\n id_plan: 5,\r\n id_product: 1,\r\n }\r\n : {\r\n type: \"trial\",\r\n id_coupon: data.couponId || 0,\r\n id_plan: idPlan,\r\n date_due: trialEndDate.toISOString().split(\"T\")[0],\r\n trial_days: trialDays,\r\n id_product: 1,\r\n },\r\n };\r\n\r\n const response = await api.apps.post<SocialOnboardingApiResponse>(\r\n \"/auth/social/onboarding\",\r\n payload,\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao finalizar cadastro com Google\",\r\n \"ONBOARDING_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n if (!response.data?.length || !response.cookie) {\r\n throw new ApiError(\r\n \"Resposta de cadastro inválida\",\r\n \"INVALID_RESPONSE\",\r\n 500,\r\n );\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(),\r\n accountService.findCurrentAccount(),\r\n ]);\r\n\r\n return {\r\n user,\r\n account,\r\n accessToken: response.cookie,\r\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\r\n };\r\n }\r\n\r\n async unlinkGoogle(): Promise<UnlinkGoogleResponse> {\r\n const { id_account, id_user } = await import(\r\n \"../utils/get-user-context\"\r\n ).then((m) => m.getUserContext());\r\n\r\n const response = await api.apps.delete<UnlinkGoogleApiResponse>(\r\n `/accounts/${id_account}/users/${id_user}/social/google`,\r\n );\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || \"Erro ao desvincular conta Google\",\r\n \"UNLINK_FAILED\",\r\n 400,\r\n );\r\n }\r\n\r\n return {\r\n success: true,\r\n message: response.message,\r\n };\r\n }\r\n\r\n async register(\r\n data: RegisterRequest,\r\n clientInfo: ClientInfo,\r\n ): Promise<RegisterResponse> {\r\n const today = new Date();\r\n const trialEndDate = new Date(today);\r\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\r\n trialEndDate.setDate(today.getDate() + trialDays);\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 id_affiliate: data.affiliateId || 0,\r\n origin: data.origin,\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 idPlan === -1\r\n ? {\r\n type: \"free\",\r\n id_coupon: data.couponId || 0,\r\n id_plan: 5, // Plano Free (ID fixo)\r\n id_product: 1,\r\n }\r\n : {\r\n type: \"trial\",\r\n id_coupon: data.couponId || 0,\r\n id_plan: idPlan,\r\n // Fluxo não-Stripe lê `date_due`; fluxo Stripe lê `trial_days`.\r\n // Mandamos os dois pra cobrir ambos os caminhos da API.\r\n date_due: trialEndDate.toISOString().split(\"T\")[0],\r\n trial_days: trialDays,\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 | null): Promise<number> {\r\n if (idPlan == null || idPlan === \"\") return -1;\r\n if (typeof idPlan === \"number\" || Number(idPlan)) return Number(idPlan);\r\n\r\n if (typeof idPlan === \"string\") {\r\n const response = await api.apps.get<SearchPlansApiResponse>(\r\n `/plans?search=${encodeURIComponent(idPlan)}`,\r\n );\r\n\r\n if (response.status === 1 && response.data?.length) {\r\n return response.data[0].id;\r\n }\r\n\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 return -1;\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\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\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 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/modules/users/schema.ts"],"sourcesContent":["export enum UserProfile {\r\n viewer = 'viewer',\r\n collaborator = 'collaborator',\r\n admin = 'admin',\r\n owner = 'owner',\r\n}\r\n\r\nexport interface User {\r\n // Identificação\r\n id: number;\r\n id_wl: number;\r\n id_account: number;\r\n id_api: number;\r\n\r\n // Dados pessoais\r\n name: string;\r\n last_name: string;\r\n email: string;\r\n ddi: string;\r\n phone: string;\r\n rg: string | null;\r\n cpf: string | null;\r\n gender: number;\r\n\r\n // Autenticação e segurança\r\n two_factor_authentication: boolean;\r\n\r\n // Perfil e permissões\r\n profile: UserProfile;\r\n\r\n // Preferências\r\n language: string;\r\n receive_sms: boolean;\r\n receive_email: boolean;\r\n photo: string | null;\r\n\r\n // Metadados\r\n deleted: number;\r\n datetime_alt: string;\r\n datetime_del: string | null;\r\n datetime_add: string;\r\n\r\n total_projects: number;\r\n projects: { id: number; title: string }[];\r\n\r\n initials?: string;\r\n emailVerified?: boolean;\r\n createdAt?: string;\r\n updatedAt?: string;\r\n}\r\n\r\nexport interface GetUserDataResponse {\r\n status: 0 | 1;\r\n total: number;\r\n data: User[];\r\n}\r\n\r\nexport interface JWTPayload {\r\n session: {\r\n location: {\r\n continent: string;\r\n country: string;\r\n region: string;\r\n city: string;\r\n latitude: string;\r\n longitude: string;\r\n };\r\n ip: string;\r\n timezone: string;\r\n agent: string;\r\n code: string | null;\r\n };\r\n id_wl: string;\r\n id_account: number;\r\n id_user: number;\r\n iss: string;\r\n aud: string;\r\n iat: number;\r\n}\r\n"],"mappings":"AAAO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,kBAAe;AACf,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,WAAQ;AAJE,SAAAA;AAAA,GAAA;","names":["UserProfile"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/users/schema.ts"],"sourcesContent":["export enum UserProfile {\r\n viewer = 'viewer',\r\n collaborator = 'collaborator',\r\n admin = 'admin',\r\n owner = 'owner',\r\n}\r\n\r\nexport interface User {\r\n // Identificação\r\n id: number;\r\n id_wl: number;\r\n id_account: number;\r\n id_api: number;\r\n\r\n // Dados pessoais\r\n name: string;\r\n last_name: string;\r\n email: string;\r\n ddi: string;\r\n phone: string;\r\n rg: string | null;\r\n cpf: string | null;\r\n gender: number;\r\n\r\n // Autenticação e segurança\r\n two_factor_authentication: boolean;\r\n google_sub?: string | null;\r\n google_linked_at?: string | null;\r\n\r\n // Perfil e permissões\r\n profile: UserProfile;\r\n\r\n // Preferências\r\n language: string;\r\n receive_sms: boolean;\r\n receive_email: boolean;\r\n photo: string | null;\r\n\r\n // Metadados\r\n deleted: number;\r\n datetime_alt: string;\r\n datetime_del: string | null;\r\n datetime_add: string;\r\n\r\n total_projects: number;\r\n projects: { id: number; title: string }[];\r\n\r\n initials?: string;\r\n emailVerified?: boolean;\r\n createdAt?: string;\r\n updatedAt?: string;\r\n}\r\n\r\nexport interface GetUserDataResponse {\r\n status: 0 | 1;\r\n total: number;\r\n data: User[];\r\n}\r\n\r\nexport interface JWTPayload {\r\n session: {\r\n location: {\r\n continent: string;\r\n country: string;\r\n region: string;\r\n city: string;\r\n latitude: string;\r\n longitude: string;\r\n };\r\n ip: string;\r\n timezone: string;\r\n agent: string;\r\n code: string | null;\r\n };\r\n id_wl: string;\r\n id_account: number;\r\n id_user: number;\r\n iss: string;\r\n aud: string;\r\n iat: number;\r\n}\r\n"],"mappings":"AAAO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,kBAAe;AACf,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,WAAQ;AAJE,SAAAA;AAAA,GAAA;","names":["UserProfile"]}
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
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
|
+
import { useSocialGoogleLogin } from "../modules/auth/hooks/social-google-login.hook";
|
|
19
|
+
import { useSocialGoogleOnboarding } from "../modules/auth/hooks/social-google-onboarding.hook";
|
|
18
20
|
import {
|
|
19
21
|
useCurrentAccount,
|
|
20
22
|
ACCOUNT_QUERY_KEY
|
|
@@ -35,8 +37,10 @@ function AuthProvider({ children }) {
|
|
|
35
37
|
const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();
|
|
36
38
|
const { mutateAsync: registerMutate, isPending: isRegistering } = useRegister();
|
|
37
39
|
const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();
|
|
40
|
+
const { mutateAsync: googleLoginMutate, isPending: isGoogleLogging } = useSocialGoogleLogin();
|
|
41
|
+
const { mutateAsync: googleOnboardingMutate, isPending: isGoogleOnboarding } = useSocialGoogleOnboarding();
|
|
38
42
|
const isAuthenticated = !!user;
|
|
39
|
-
const isLoading = isLogging || isRegistering || isLoggingOut || isQueryLoading || isAccountLoading || isSessionLoading;
|
|
43
|
+
const isLoading = isLogging || isRegistering || isLoggingOut || isGoogleLogging || isGoogleOnboarding || isQueryLoading || isAccountLoading || isSessionLoading;
|
|
40
44
|
const login = useCallback(
|
|
41
45
|
async (credentials) => {
|
|
42
46
|
try {
|
|
@@ -67,6 +71,50 @@ function AuthProvider({ children }) {
|
|
|
67
71
|
},
|
|
68
72
|
[queryClient, setUserData, accountKey]
|
|
69
73
|
);
|
|
74
|
+
const loginWithGoogle = useCallback(
|
|
75
|
+
async (code) => {
|
|
76
|
+
try {
|
|
77
|
+
const data = await googleLoginMutate(code);
|
|
78
|
+
if (data.result === "two_factor_required") {
|
|
79
|
+
return {
|
|
80
|
+
result: "two_factor_required",
|
|
81
|
+
cookie: data.cookie,
|
|
82
|
+
twoFactorMode: data.twoFactorMode
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (data.result === "needs_onboarding") {
|
|
86
|
+
return {
|
|
87
|
+
result: "needs_onboarding",
|
|
88
|
+
onboardingToken: data.onboardingToken,
|
|
89
|
+
partial: data.partial
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (data.result === "link_requires_password") {
|
|
93
|
+
return { result: "link_requires_password", message: data.message };
|
|
94
|
+
}
|
|
95
|
+
queryClient.clear();
|
|
96
|
+
setUserData(data.user);
|
|
97
|
+
queryClient.setQueryData(accountKey, data.account);
|
|
98
|
+
return { result: "success" };
|
|
99
|
+
} catch (error) {
|
|
100
|
+
const message = error instanceof Error ? error.message : "Ocorreu um erro ao fazer login com Google. Tente novamente.";
|
|
101
|
+
return { result: "error", message };
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
[googleLoginMutate, queryClient, setUserData, accountKey]
|
|
105
|
+
);
|
|
106
|
+
const completeGoogleOnboarding = useCallback(
|
|
107
|
+
async (data) => {
|
|
108
|
+
await googleOnboardingMutate(data, {
|
|
109
|
+
onSuccess: (data2) => {
|
|
110
|
+
queryClient.clear();
|
|
111
|
+
setUserData(data2.user);
|
|
112
|
+
queryClient.setQueryData(accountKey, data2.account);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
[googleOnboardingMutate, queryClient, setUserData, accountKey]
|
|
117
|
+
);
|
|
70
118
|
const resolveLogoutRedirect = useCallback(() => {
|
|
71
119
|
try {
|
|
72
120
|
const currentOrigin = window.location.origin;
|
|
@@ -95,9 +143,21 @@ function AuthProvider({ children }) {
|
|
|
95
143
|
isLoading,
|
|
96
144
|
login,
|
|
97
145
|
register,
|
|
98
|
-
logout
|
|
146
|
+
logout,
|
|
147
|
+
loginWithGoogle,
|
|
148
|
+
completeGoogleOnboarding
|
|
99
149
|
}),
|
|
100
|
-
[
|
|
150
|
+
[
|
|
151
|
+
user,
|
|
152
|
+
account,
|
|
153
|
+
isAuthenticated,
|
|
154
|
+
isLoading,
|
|
155
|
+
login,
|
|
156
|
+
register,
|
|
157
|
+
logout,
|
|
158
|
+
loginWithGoogle,
|
|
159
|
+
completeGoogleOnboarding
|
|
160
|
+
]
|
|
101
161
|
);
|
|
102
162
|
return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
|
|
103
163
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n useUserQuery,\n useSetUserData,\n useUserValidateSession,\n} from \"../modules/auth/hooks/useUserQuery\";\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\nimport {\n AuthState,\n LoginRequest,\n RegisterRequest,\n} from \"../modules/auth/schema\";\n\nexport type LoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"error\"; message: string };\nimport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"../modules/accounts/hooks/current-account.hook\";\nimport { useWhitelabelUrls } from \"./whitelabel.provider\";\nimport { useWlQueryKey } from \"../hooks/useAuthQueryKey\";\n\ninterface AuthContextProps extends AuthState {\n login: (credentials: LoginRequest) => Promise<LoginResult>;\n register: (data: RegisterRequest) => Promise<void>;\n logout: () => Promise<void>;\n}\n\nexport const AuthContext = createContext<AuthContextProps | undefined>(\n undefined,\n);\n\ninterface AuthProviderProps {\n children: ReactNode;\n}\n\nexport function AuthProvider({ children }: AuthProviderProps) {\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\n const { data: account, isLoading: isAccountLoading } = useCurrentAccount();\n const { isLoading: isSessionLoading } = useUserValidateSession();\n\n const queryClient = useQueryClient();\n const setUserData = useSetUserData();\n const { accountsUrl, pagesUrl } = useWhitelabelUrls();\n const accountKey = useWlQueryKey([...ACCOUNT_QUERY_KEY]);\n\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\n const { mutateAsync: registerMutate, isPending: isRegistering } =\n useRegister();\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\n\n const isAuthenticated = !!user;\n const isLoading =\n isLogging ||\n isRegistering ||\n isLoggingOut ||\n isQueryLoading ||\n isAccountLoading ||\n isSessionLoading;\n\n const login = useCallback(\n async (credentials: LoginRequest): Promise<LoginResult> => {\n try {\n const data = await loginMutate(credentials);\n\n if (data.result === \"two_factor_required\") {\n return { result: \"two_factor_required\", cookie: data.cookie, twoFactorMode: data.twoFactorMode };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [queryClient, setUserData, accountKey],\n );\n\n const register = useCallback(\n async (data: RegisterRequest): Promise<void> => {\n await registerMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [queryClient, setUserData, accountKey],\n );\n\n const resolveLogoutRedirect = useCallback(() => {\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?redirect=${encodeURIComponent(pagesUrl)}`;\n }\n } catch {\n // fallback below\n }\n\n return `${accountsUrl}/login?redirect=${encodeURIComponent(pagesUrl || \"/\")}`;\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\n const value: AuthContextProps = useMemo(\n () => ({\n user: user ?? null,\n account: account ?? null,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n }),\n [user, account, isAuthenticated, isLoading, login, register, logout],\n );\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextProps {\n const context = useContext(AuthContext);\n\n if (context === undefined) {\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\n }\n\n return context;\n}\n"],"mappings":"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","names":["data"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/auth.provider.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n ReactNode,\n useCallback,\n useContext,\n useMemo,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n useUserQuery,\n useSetUserData,\n useUserValidateSession,\n} from \"../modules/auth/hooks/useUserQuery\";\nimport { useLogin } from \"../modules/auth/hooks/login.hook\";\nimport { useRegister } from \"../modules/auth/hooks/register.hook\";\nimport { useLogout } from \"../modules/auth/hooks/logout.hook\";\nimport { useSocialGoogleLogin } from \"../modules/auth/hooks/social-google-login.hook\";\nimport { useSocialGoogleOnboarding } from \"../modules/auth/hooks/social-google-onboarding.hook\";\nimport {\n AuthState,\n LoginRequest,\n RegisterRequest,\n SocialGooglePartial,\n SocialOnboardingRequest,\n} from \"../modules/auth/schema\";\n\nexport type LoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"error\"; message: string };\n\nexport type GoogleLoginResult =\n | { result: \"success\" }\n | { result: \"two_factor_required\"; cookie: string; twoFactorMode: \"verify\" | \"setup\" }\n | { result: \"needs_onboarding\"; onboardingToken: string; partial: SocialGooglePartial }\n | { result: \"link_requires_password\"; message: string }\n | { result: \"error\"; message: string };\nimport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"../modules/accounts/hooks/current-account.hook\";\nimport { useWhitelabelUrls } from \"./whitelabel.provider\";\nimport { useWlQueryKey } from \"../hooks/useAuthQueryKey\";\n\ninterface AuthContextProps extends AuthState {\n login: (credentials: LoginRequest) => Promise<LoginResult>;\n register: (data: RegisterRequest) => Promise<void>;\n logout: () => Promise<void>;\n loginWithGoogle: (code: string) => Promise<GoogleLoginResult>;\n completeGoogleOnboarding: (data: SocialOnboardingRequest) => Promise<void>;\n}\n\nexport const AuthContext = createContext<AuthContextProps | undefined>(\n undefined,\n);\n\ninterface AuthProviderProps {\n children: ReactNode;\n}\n\nexport function AuthProvider({ children }: AuthProviderProps) {\n const { data: user, isLoading: isQueryLoading } = useUserQuery();\n const { data: account, isLoading: isAccountLoading } = useCurrentAccount();\n const { isLoading: isSessionLoading } = useUserValidateSession();\n\n const queryClient = useQueryClient();\n const setUserData = useSetUserData();\n const { accountsUrl, pagesUrl } = useWhitelabelUrls();\n const accountKey = useWlQueryKey([...ACCOUNT_QUERY_KEY]);\n\n const { mutateAsync: loginMutate, isPending: isLogging } = useLogin();\n const { mutateAsync: registerMutate, isPending: isRegistering } =\n useRegister();\n const { mutateAsync: logoutMutate, isPending: isLoggingOut } = useLogout();\n const { mutateAsync: googleLoginMutate, isPending: isGoogleLogging } =\n useSocialGoogleLogin();\n const { mutateAsync: googleOnboardingMutate, isPending: isGoogleOnboarding } =\n useSocialGoogleOnboarding();\n\n const isAuthenticated = !!user;\n const isLoading =\n isLogging ||\n isRegistering ||\n isLoggingOut ||\n isGoogleLogging ||\n isGoogleOnboarding ||\n isQueryLoading ||\n isAccountLoading ||\n isSessionLoading;\n\n const login = useCallback(\n async (credentials: LoginRequest): Promise<LoginResult> => {\n try {\n const data = await loginMutate(credentials);\n\n if (data.result === \"two_factor_required\") {\n return { result: \"two_factor_required\", cookie: data.cookie, twoFactorMode: data.twoFactorMode };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [queryClient, setUserData, accountKey],\n );\n\n const register = useCallback(\n async (data: RegisterRequest): Promise<void> => {\n await registerMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [queryClient, setUserData, accountKey],\n );\n\n const loginWithGoogle = useCallback(\n async (code: string): Promise<GoogleLoginResult> => {\n try {\n const data = await googleLoginMutate(code);\n\n if (data.result === \"two_factor_required\") {\n return {\n result: \"two_factor_required\",\n cookie: data.cookie,\n twoFactorMode: data.twoFactorMode,\n };\n }\n\n if (data.result === \"needs_onboarding\") {\n return {\n result: \"needs_onboarding\",\n onboardingToken: data.onboardingToken,\n partial: data.partial,\n };\n }\n\n if (data.result === \"link_requires_password\") {\n return { result: \"link_requires_password\", message: data.message };\n }\n\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n\n return { result: \"success\" };\n } catch (error) {\n const message =\n error instanceof Error\n ? error.message\n : \"Ocorreu um erro ao fazer login com Google. Tente novamente.\";\n return { result: \"error\", message };\n }\n },\n [googleLoginMutate, queryClient, setUserData, accountKey],\n );\n\n const completeGoogleOnboarding = useCallback(\n async (data: SocialOnboardingRequest): Promise<void> => {\n await googleOnboardingMutate(data, {\n onSuccess: (data) => {\n queryClient.clear();\n setUserData(data.user);\n queryClient.setQueryData(accountKey, data.account);\n },\n });\n },\n [googleOnboardingMutate, queryClient, setUserData, accountKey],\n );\n\n const resolveLogoutRedirect = useCallback(() => {\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?redirect=${encodeURIComponent(pagesUrl)}`;\n }\n } catch {\n // fallback below\n }\n\n return `${accountsUrl}/login?redirect=${encodeURIComponent(pagesUrl || \"/\")}`;\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\n const value: AuthContextProps = useMemo(\n () => ({\n user: user ?? null,\n account: account ?? null,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n loginWithGoogle,\n completeGoogleOnboarding,\n }),\n [\n user,\n account,\n isAuthenticated,\n isLoading,\n login,\n register,\n logout,\n loginWithGoogle,\n completeGoogleOnboarding,\n ],\n );\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextProps {\n const context = useContext(AuthContext);\n\n if (context === undefined) {\n throw new Error(\"useAuth deve ser usado dentro de um AuthProvider\");\n }\n\n return context;\n}\n"],"mappings":";AA2OS;AAzOT;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;AAC1B,SAAS,4BAA4B;AACrC,SAAS,iCAAiC;AAoB1C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAUvB,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;AACnC,QAAM,EAAE,aAAa,SAAS,IAAI,kBAAkB;AACpD,QAAM,aAAa,cAAc,CAAC,GAAG,iBAAiB,CAAC;AAEvD,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;AACzE,QAAM,EAAE,aAAa,mBAAmB,WAAW,gBAAgB,IACjE,qBAAqB;AACvB,QAAM,EAAE,aAAa,wBAAwB,WAAW,mBAAmB,IACzE,0BAA0B;AAE5B,QAAM,kBAAkB,CAAC,CAAC;AAC1B,QAAM,YACJ,aACA,iBACA,gBACA,mBACA,sBACA,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,QAAQ,eAAe,KAAK,cAAc;AAAA,QACjG;AAEA,oBAAY,MAAM;AAClB,oBAAY,KAAK,IAAI;AACrB,oBAAY,aAAa,YAAY,KAAK,OAAO;AAEjD,eAAO,EAAE,QAAQ,UAAU;AAAA,MAC7B,SAAS,OAAO;AACd,cAAM,UACJ,iBAAiB,QACb,MAAM,UACN;AACN,eAAO,EAAE,QAAQ,SAAS,QAAQ;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC,aAAa,aAAa,UAAU;AAAA,EACvC;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,YAAYA,MAAK,OAAO;AAAA,QACnD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,aAAa,aAAa,UAAU;AAAA,EACvC;AAEA,QAAM,kBAAkB;AAAA,IACtB,OAAO,SAA6C;AAClD,UAAI;AACF,cAAM,OAAO,MAAM,kBAAkB,IAAI;AAEzC,YAAI,KAAK,WAAW,uBAAuB;AACzC,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,QAAQ,KAAK;AAAA,YACb,eAAe,KAAK;AAAA,UACtB;AAAA,QACF;AAEA,YAAI,KAAK,WAAW,oBAAoB;AACtC,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,iBAAiB,KAAK;AAAA,YACtB,SAAS,KAAK;AAAA,UAChB;AAAA,QACF;AAEA,YAAI,KAAK,WAAW,0BAA0B;AAC5C,iBAAO,EAAE,QAAQ,0BAA0B,SAAS,KAAK,QAAQ;AAAA,QACnE;AAEA,oBAAY,MAAM;AAClB,oBAAY,KAAK,IAAI;AACrB,oBAAY,aAAa,YAAY,KAAK,OAAO;AAEjD,eAAO,EAAE,QAAQ,UAAU;AAAA,MAC7B,SAAS,OAAO;AACd,cAAM,UACJ,iBAAiB,QACb,MAAM,UACN;AACN,eAAO,EAAE,QAAQ,SAAS,QAAQ;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC,mBAAmB,aAAa,aAAa,UAAU;AAAA,EAC1D;AAEA,QAAM,2BAA2B;AAAA,IAC/B,OAAO,SAAiD;AACtD,YAAM,uBAAuB,MAAM;AAAA,QACjC,WAAW,CAACA,UAAS;AACnB,sBAAY,MAAM;AAClB,sBAAYA,MAAK,IAAI;AACrB,sBAAY,aAAa,YAAYA,MAAK,OAAO;AAAA,QACnD;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,wBAAwB,aAAa,aAAa,UAAU;AAAA,EAC/D;AAEA,QAAM,wBAAwB,YAAY,MAAM;AAC9C,QAAI;AACF,YAAM,gBAAgB,OAAO,SAAS;AACtC,YAAM,cAAc,WAAW,IAAI,IAAI,QAAQ,EAAE,SAAS;AAE1D,UAAI,eAAe,kBAAkB,aAAa;AAChD,eAAO,GAAG,WAAW,mBAAmB,mBAAmB,QAAQ,CAAC;AAAA,MACtE;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,WAAO,GAAG,WAAW,mBAAmB,mBAAmB,YAAY,GAAG,CAAC;AAAA,EAC7E,GAAG,CAAC,aAAa,QAAQ,CAAC;AAE1B,QAAM,SAAS,YAAY,YAA2B;AACpD,QAAI;AACF,YAAM,aAAa,MAAS;AAAA,IAC9B,QAAQ;AAAA,IAER,UAAE;AACA,kBAAY,MAAM;AAClB,aAAO,SAAS,OAAO,sBAAsB,CAAC;AAAA,IAChD;AAAA,EACF,GAAG,CAAC,aAAa,cAAc,qBAAqB,CAAC;AAErD,QAAM,QAA0B;AAAA,IAC9B,OAAO;AAAA,MACL,MAAM,QAAQ;AAAA,MACd,SAAS,WAAW;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;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"]}
|
package/dist/server.mjs
CHANGED
|
@@ -14,6 +14,9 @@ import { chargesService } from "./modules/charges/services/charges.service";
|
|
|
14
14
|
import { iaCreditsService } from "./modules/ia-credits/services/ia-credits.service";
|
|
15
15
|
import { findWhitelabel } from "./modules/whitelabel/actions/find-whitelabel.action";
|
|
16
16
|
import { validateSessionAction } from "./modules/auth/actions/validate-session.action";
|
|
17
|
+
import { socialGoogleLoginAction } from "./modules/auth/actions/social-google-login.action";
|
|
18
|
+
import { socialGoogleOnboardingAction } from "./modules/auth/actions/social-google-onboarding.action";
|
|
19
|
+
import { unlinkGoogleAction } from "./modules/auth/actions/unlink-google.action";
|
|
17
20
|
import { findUserById } from "./modules/users/action/find-user-by-id.action";
|
|
18
21
|
import { findCurrentAccount } from "./modules/accounts/actions/find-current-account.action";
|
|
19
22
|
import { getAccountTokenAction } from "./modules/accounts/actions/get-account-token.action";
|
|
@@ -137,8 +140,11 @@ export {
|
|
|
137
140
|
revalidateWhitelabelAction,
|
|
138
141
|
safeMutationAction,
|
|
139
142
|
safeServerAction,
|
|
143
|
+
socialGoogleLoginAction,
|
|
144
|
+
socialGoogleOnboardingAction,
|
|
140
145
|
subscriptionsService,
|
|
141
146
|
twoFactorService,
|
|
147
|
+
unlinkGoogleAction,
|
|
142
148
|
updateAccountAction,
|
|
143
149
|
updateAccountUserByIdAction,
|
|
144
150
|
updateProjectAction,
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';\r\nexport { listPlansAction } from './modules/plans/actions/list-plans.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { listCardsAction } from './modules/cards/actions/list-cards.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { listChargesAction } from './modules/charges/actions/list-charges.action';\r\nexport { findChargeByIdAction } from './modules/charges/actions/find-charge-by-id.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { listIaCreditsAction } from './modules/ia-credits/actions/list-ia-credits.action';\r\nexport { countPagesAction } from './modules/pages/actions/count-pages.action';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { listAvailableUsersAction } from './modules/projects/actions/list-available-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AAGjC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import 'server-only';\r\n\r\n// API Client\r\nexport { ApiClient, api, apiClient } from './infra/api/client';\r\n\r\n// Services\r\nexport { authService } from './modules/auth/services/auth.service';\r\nexport { whitelabelService } from './modules/whitelabel/services/whitelabel.service';\r\nexport { revalidateWhitelabelAction } from './modules/whitelabel/actions/revalidate-whitelabel.action';\r\nexport { assertManagementPermission } from './modules/auth/utils/assert-management-permission';\r\nexport { assertManagementSubscription } from './modules/auth/utils/assert-management-subscription';\r\nexport { assertSubscriptionAddon } from './modules/auth/utils/assert-subscription-addon';\r\nexport { assertPaidSubscription } from './modules/auth/utils/assert-paid-subscription';\r\nexport { subscriptionsService } from './modules/subscriptions/services/subscriptions.service';\r\nexport { plansService } from './modules/plans/services/plans.service';\r\nexport { cardsService } from './modules/cards/services/cards.service';\r\nexport { chargesService } from './modules/charges/services/charges.service';\r\nexport { iaCreditsService } from './modules/ia-credits/services/ia-credits.service';\r\n\r\n// Actions\r\nexport { findWhitelabel } from './modules/whitelabel/actions/find-whitelabel.action';\r\nexport { validateSessionAction } from './modules/auth/actions/validate-session.action';\r\nexport { socialGoogleLoginAction } from './modules/auth/actions/social-google-login.action';\r\nexport { socialGoogleOnboardingAction } from './modules/auth/actions/social-google-onboarding.action';\r\nexport { unlinkGoogleAction } from './modules/auth/actions/unlink-google.action';\r\nexport { findUserById } from './modules/users/action/find-user-by-id.action';\r\nexport { findCurrentAccount } from './modules/accounts/actions/find-current-account.action';\r\nexport { getAccountTokenAction } from './modules/accounts/actions/get-account-token.action';\r\nexport { listSubscriptionsAction } from './modules/subscriptions/actions/list-subscriptions.action';\r\nexport { findPlanByIdAction } from './modules/plans/actions/find-plan-by-id.action';\r\nexport { listPlansAction } from './modules/plans/actions/list-plans.action';\r\nexport { calculateSubscriptionAction } from './modules/subscriptions/actions/calculate-subscription.action';\r\nexport { updateSubscriptionPlanAction } from './modules/subscriptions/actions/update-subscription-plan.action';\r\nexport { updateSubscriptionPaymentAction } from './modules/subscriptions/actions/update-subscription-payment.action';\r\nexport { listCardsAction } from './modules/cards/actions/list-cards.action';\r\nexport { createCardAction } from './modules/cards/actions/create-card.action';\r\nexport { createSetupIntentAction } from './modules/cards/actions/create-setup-intent.action';\r\nexport { listChargesAction } from './modules/charges/actions/list-charges.action';\r\nexport { findChargeByIdAction } from './modules/charges/actions/find-charge-by-id.action';\r\nexport { chargeActionAction } from './modules/charges/actions/charge-action.action';\r\nexport { resolvePlanExtrasPrices } from './modules/subscriptions/utils/resolve-plan-extras-prices';\r\nexport { hasSubscriptionExpired } from './modules/subscriptions/utils/has-subscription-expired';\r\nexport { listIaCreditsAction } from './modules/ia-credits/actions/list-ia-credits.action';\r\nexport { countPagesAction } from './modules/pages/actions/count-pages.action';\r\n\r\n// Project Services & Actions (server-only)\r\nexport { projectsService } from './modules/projects/services/projects.service';\r\nexport { listProjectsAction } from './modules/projects/actions/list-projects.action';\r\nexport { findProjectAction } from './modules/projects/actions/find-project.action';\r\nexport { createProjectAction } from './modules/projects/actions/create-project.action';\r\nexport { updateProjectAction } from './modules/projects/actions/update-project.action';\r\nexport { deleteProjectAction } from './modules/projects/actions/delete-project.action';\r\n\r\n// Project Users Services & Actions (server-only)\r\nexport { projectUsersService } from './modules/projects/services/project-users.service';\r\nexport { listProjectUsersAction } from './modules/projects/actions/list-project-users.action';\r\nexport { listAvailableUsersAction } from './modules/projects/actions/list-available-users.action';\r\nexport { addProjectUserAction } from './modules/projects/actions/add-project-user.action';\r\nexport { removeProjectUserAction } from './modules/projects/actions/remove-project-user.action';\r\n\r\n// Account Services & Actions (server-only)\r\nexport { accountService } from './modules/accounts/services/account.service';\r\nexport { twoFactorService } from './modules/accounts/services/two-factor.service';\r\nexport {\r\n listAccountUsersAction,\r\n updateUserAction,\r\n updateAccountAction,\r\n updateAccountUserByIdAction,\r\n deleteAccountUserAction,\r\n deleteAccountAction,\r\n createAccountUserAction,\r\n changePasswordAction,\r\n requestEmailChangeAction,\r\n confirmEmailChangeAction,\r\n requestPhoneChangeAction,\r\n confirmPhoneChangeAction,\r\n generateTwoFactorAction,\r\n confirmTwoFactorAction,\r\n disableTwoFactorAction,\r\n} from './modules/accounts/actions/account-management.action';\r\n\r\n// Server Utils\r\nexport { getClientInfoFromRequest } from './infra/utils/client-info';\r\nexport { getUserContext } from './modules/auth/utils/get-user-context';\r\nexport { requireValidSession } from './modules/auth/utils/require-valid-session';\r\nexport { requireTokenNotExpired } from './modules/auth/utils/require-token-not-expired';\r\nexport { buildWlOverride, buildWlOverrideFromJwt } from './modules/auth/utils/build-wl-override';\r\nexport { safeServerAction } from './utils/safeServerAction';\r\nexport { safeMutationAction } from './utils/safeMutationAction';\r\n\r\n// Image Processing (server-side)\r\nexport { processImageAction } from './modules/images/actions/process-image.action';\r\nexport { processImage } from './modules/images/services/image-processing.service';\r\nexport type {\r\n ProcessImageInput,\r\n ProcessImageOutput,\r\n ProcessImageActionInput,\r\n ProcessImageActionOutput,\r\n} from './modules/images/types/image.type';\r\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,WAAW,KAAK,iBAAiB;AAG1C,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kCAAkC;AAC3C,SAAS,kCAAkC;AAC3C,SAAS,oCAAoC;AAC7C,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AAGjC,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,oCAAoC;AAC7C,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,6BAA6B;AACtC,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,mCAAmC;AAC5C,SAAS,oCAAoC;AAC7C,SAAS,uCAAuC;AAChD,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AACjC,SAAS,+BAA+B;AACxC,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AAGjC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAGpC,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,+BAA+B;AAGxC,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,gCAAgC;AACzC,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,8BAA8B;AACvC,SAAS,iBAAiB,8BAA8B;AACxD,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AAGnC,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { IconAlertTriangle } from '@tabler/icons-react';
|
|
4
|
-
import {
|
|
3
|
+
import { IconAlertTriangle, IconBrandGoogleFilled } from '@tabler/icons-react';
|
|
4
|
+
import { toast } from 'sonner';
|
|
5
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
5
6
|
import { useAuth } from '../../../providers/auth.provider';
|
|
6
7
|
import { AccountSectionType } from '../../../enums/AccountSectionType';
|
|
8
|
+
import { useUnlinkGoogle } from '../../../modules/auth/hooks/unlink-google.hook';
|
|
9
|
+
import { USER_QUERY_KEY } from '../../../modules/auth/hooks/useUserQuery';
|
|
10
|
+
import { Toast } from '../../ui/feedback/Toast';
|
|
7
11
|
|
|
8
12
|
interface SecuritySectionProps {
|
|
9
13
|
setActiveSection: (section: AccountSectionType) => void;
|
|
@@ -12,13 +16,56 @@ interface SecuritySectionProps {
|
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
export function SecuritySection({
|
|
15
|
-
onClose,
|
|
16
19
|
onDeleteAccount,
|
|
17
20
|
}: SecuritySectionProps) {
|
|
21
|
+
const { user } = useAuth();
|
|
22
|
+
const queryClient = useQueryClient();
|
|
23
|
+
const { mutateAsync: unlinkGoogle, isPending: isUnlinking } = useUnlinkGoogle();
|
|
24
|
+
const hasGoogleLinked = !!user?.google_sub;
|
|
25
|
+
|
|
26
|
+
const handleUnlinkGoogle = async () => {
|
|
27
|
+
try {
|
|
28
|
+
const result = await unlinkGoogle();
|
|
29
|
+
toast.custom((t) => (
|
|
30
|
+
<Toast variant="success" message={result.message} toastId={t} />
|
|
31
|
+
));
|
|
32
|
+
queryClient.invalidateQueries({ queryKey: USER_QUERY_KEY });
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const message =
|
|
35
|
+
error instanceof Error ? error.message : 'Erro ao desvincular conta Google.';
|
|
36
|
+
toast.custom((t) => <Toast variant="error" message={message} toastId={t} />);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
18
40
|
return (
|
|
19
41
|
<div className="h-full overflow-y-auto overscroll-contain px-4 pb-20 lg:p-5 lg:pt-5 flex flex-col gap-5 lg:gap-6 lg:pb-31 lg:overscroll-auto">
|
|
20
42
|
<span className="paragraph-medium-semibold text-gray-950 hidden lg:block">Segurança</span>
|
|
21
43
|
|
|
44
|
+
{hasGoogleLinked && (
|
|
45
|
+
<div className="flex flex-col items-center lg:items-start gap-4">
|
|
46
|
+
<div className="size-10 rounded-lg bg-blue-50 flex items-center justify-center">
|
|
47
|
+
<IconBrandGoogleFilled size={20} className="text-blue-500" />
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div className="flex flex-col gap-2">
|
|
51
|
+
<span className="paragraph-medium-semibold text-gray-950">Conta Google vinculada</span>
|
|
52
|
+
<span className="paragraph-small-regular text-gray-600">
|
|
53
|
+
Sua conta está vinculada ao Google. Se desvincular, use "Esqueci minha senha" para
|
|
54
|
+
redefinir uma senha de acesso por e-mail.
|
|
55
|
+
</span>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
disabled={isUnlinking}
|
|
61
|
+
className="paragraph-small-semibold text-zinc-700 bg-zinc-100 rounded-lg px-3 py-2 cursor-pointer hover:bg-zinc-200 transition-colors w-fit disabled:opacity-50 disabled:cursor-not-allowed"
|
|
62
|
+
onClick={handleUnlinkGoogle}
|
|
63
|
+
>
|
|
64
|
+
{isUnlinking ? 'Desvinculando...' : 'Desvincular Google'}
|
|
65
|
+
</button>
|
|
66
|
+
</div>
|
|
67
|
+
)}
|
|
68
|
+
|
|
22
69
|
<div className="flex flex-col items-center lg:items-start gap-4">
|
|
23
70
|
<div className="size-10 rounded-lg bg-red-50 flex items-center justify-center">
|
|
24
71
|
<IconAlertTriangle size={20} className="text-red-500" />
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import { useActiveSubscription } from
|
|
4
|
-
import { useCharges } from
|
|
5
|
-
import { SUBSCRIPTION_GRACE_PERIOD_DAYS } from
|
|
6
|
-
import { toCalendarDate, daysBetween } from
|
|
7
|
-
import { OverdueInvoiceBanner } from
|
|
8
|
-
import { UpcomingInvoiceBanner } from
|
|
9
|
-
import { CancelledSubscriptionBanner } from
|
|
3
|
+
import { useActiveSubscription } from "../../modules/subscriptions/hooks/find-active-subscription.hook";
|
|
4
|
+
import { useCharges } from "../../modules/charges/hooks/charges.hook";
|
|
5
|
+
import { SUBSCRIPTION_GRACE_PERIOD_DAYS } from "../../modules/subscriptions/constants/subscription.constants";
|
|
6
|
+
import { toCalendarDate, daysBetween } from "../../infra/utils/date";
|
|
7
|
+
import { OverdueInvoiceBanner } from "./OverdueInvoiceBanner";
|
|
8
|
+
import { UpcomingInvoiceBanner } from "./UpcomingInvoiceBanner";
|
|
9
|
+
import { CancelledSubscriptionBanner } from "./CancelledSubscriptionBanner";
|
|
10
10
|
|
|
11
11
|
const UPCOMING_WINDOW_DAYS = 7;
|
|
12
12
|
const PAYMENT_METHOD_BOLETO = 2;
|
|
@@ -16,13 +16,21 @@ interface SubscriptionBannerProps {
|
|
|
16
16
|
onDetails?: () => void;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export function SubscriptionBanner({
|
|
19
|
+
export function SubscriptionBanner({
|
|
20
|
+
onReactivate,
|
|
21
|
+
onDetails,
|
|
22
|
+
}: SubscriptionBannerProps) {
|
|
20
23
|
const { data: { data: [subscription] = [] } = {} } = useActiveSubscription();
|
|
21
|
-
const { data: pendingChargesData, isLoading: isLoadingCharges } = useCharges({
|
|
24
|
+
const { data: pendingChargesData, isLoading: isLoadingCharges } = useCharges({
|
|
25
|
+
page: 1,
|
|
26
|
+
limit: 1,
|
|
27
|
+
status: [0],
|
|
28
|
+
});
|
|
22
29
|
|
|
23
30
|
if (isLoadingCharges) return null;
|
|
24
31
|
if (!subscription?.date_due) return null;
|
|
25
|
-
if (subscription.type ===
|
|
32
|
+
if (subscription.type === "free" || subscription.type === "trial")
|
|
33
|
+
return null;
|
|
26
34
|
|
|
27
35
|
const dueDate = toCalendarDate(subscription.date_due);
|
|
28
36
|
const today = toCalendarDate(new Date());
|
|
@@ -36,19 +44,28 @@ export function SubscriptionBanner({ onReactivate, onDetails }: SubscriptionBann
|
|
|
36
44
|
// Cancelamento só é efetivo quando date_cancellation existe E já passou do dia de hoje
|
|
37
45
|
// (comparação por calendar-day em horário local, via toCalendarDate).
|
|
38
46
|
const cancellationDate = toCalendarDate(subscription.date_cancellation);
|
|
39
|
-
const isCancelled =
|
|
47
|
+
const isCancelled =
|
|
48
|
+
!!cancellationDate &&
|
|
49
|
+
today.getTime() >= cancellationDate.getTime() &&
|
|
50
|
+
(!subscription.date_due ||
|
|
51
|
+
today.getTime() >= toCalendarDate(subscription.date_due)!.getTime());
|
|
40
52
|
|
|
41
53
|
if (isCancelled) {
|
|
42
54
|
return <CancelledSubscriptionBanner onReactivate={onReactivate} />;
|
|
43
55
|
}
|
|
44
56
|
|
|
45
|
-
if (subscription.type ===
|
|
57
|
+
if (subscription.type === "whitelabel") return null;
|
|
46
58
|
|
|
47
59
|
if (daysSinceDue > 0 && daysSinceDue <= SUBSCRIPTION_GRACE_PERIOD_DAYS) {
|
|
48
60
|
return <OverdueInvoiceBanner onDetails={onDetails} />;
|
|
49
61
|
}
|
|
50
62
|
|
|
51
|
-
if (
|
|
63
|
+
if (
|
|
64
|
+
isBoleto &&
|
|
65
|
+
hasPendingCharge &&
|
|
66
|
+
daysToDue >= 0 &&
|
|
67
|
+
daysToDue <= UPCOMING_WINDOW_DAYS
|
|
68
|
+
) {
|
|
52
69
|
return <UpcomingInvoiceBanner dueDate={dueDate} onDetails={onDetails} />;
|
|
53
70
|
}
|
|
54
71
|
|
package/src/index.ts
CHANGED
|
@@ -62,6 +62,9 @@ export {
|
|
|
62
62
|
} from "./modules/auth/hooks/useUserQuery";
|
|
63
63
|
export { useManagementPermissions } from "./modules/auth/hooks/useManagementPermissions";
|
|
64
64
|
export type { ManagementPermission } from "./modules/auth/types/management-permission.type";
|
|
65
|
+
export { useSocialGoogleLogin } from "./modules/auth/hooks/social-google-login.hook";
|
|
66
|
+
export { useSocialGoogleOnboarding } from "./modules/auth/hooks/social-google-onboarding.hook";
|
|
67
|
+
export { useUnlinkGoogle } from "./modules/auth/hooks/unlink-google.hook";
|
|
65
68
|
export { useSubscriptions } from "./modules/subscriptions/hooks/list-subscriptions.hook";
|
|
66
69
|
export {
|
|
67
70
|
SUBSCRIPTIONS_QUERY_KEY,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { safeServerAction } from "../../../utils/safeServerAction";
|
|
4
|
+
import { authService } from "../services/auth.service";
|
|
5
|
+
import { getClientInfoFromRequest } from "../../../infra/utils/client-info";
|
|
6
|
+
|
|
7
|
+
export async function socialGoogleLoginAction(code: string) {
|
|
8
|
+
return safeServerAction(async () => {
|
|
9
|
+
const clientInfo = await getClientInfoFromRequest();
|
|
10
|
+
return authService.socialLoginGoogle(code, clientInfo);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { safeServerAction } from "../../../utils/safeServerAction";
|
|
4
|
+
import { authService } from "../services/auth.service";
|
|
5
|
+
import { SocialOnboardingRequest } from "../schema";
|
|
6
|
+
import { getClientInfoFromRequest } from "../../../infra/utils/client-info";
|
|
7
|
+
|
|
8
|
+
export async function socialGoogleOnboardingAction(data: SocialOnboardingRequest) {
|
|
9
|
+
return safeServerAction(async () => {
|
|
10
|
+
const clientInfo = await getClientInfoFromRequest();
|
|
11
|
+
return authService.completeGoogleOnboarding(data, clientInfo);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMutation } from "@tanstack/react-query";
|
|
4
|
+
import { socialGoogleLoginAction } from "../actions/social-google-login.action";
|
|
5
|
+
import { SocialGoogleResponse } from "../schema";
|
|
6
|
+
import { withAction } from "../../../utils/withAction";
|
|
7
|
+
|
|
8
|
+
export function useSocialGoogleLogin() {
|
|
9
|
+
return useMutation({
|
|
10
|
+
mutationFn: (code: string) =>
|
|
11
|
+
withAction(socialGoogleLoginAction)(code) as Promise<SocialGoogleResponse>,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMutation } from "@tanstack/react-query";
|
|
4
|
+
import { socialGoogleOnboardingAction } from "../actions/social-google-onboarding.action";
|
|
5
|
+
import { SocialOnboardingRequest, SocialOnboardingResponse } from "../schema";
|
|
6
|
+
import { withAction } from "../../../utils/withAction";
|
|
7
|
+
|
|
8
|
+
export function useSocialGoogleOnboarding() {
|
|
9
|
+
return useMutation({
|
|
10
|
+
mutationFn: (data: SocialOnboardingRequest) =>
|
|
11
|
+
withAction(socialGoogleOnboardingAction)(data) as Promise<SocialOnboardingResponse>,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useMutation } from "@tanstack/react-query";
|
|
4
|
+
import { unlinkGoogleAction } from "../actions/unlink-google.action";
|
|
5
|
+
import { UnlinkGoogleResponse } from "../schema";
|
|
6
|
+
import { withAction } from "../../../utils/withAction";
|
|
7
|
+
|
|
8
|
+
export function useUnlinkGoogle() {
|
|
9
|
+
return useMutation({
|
|
10
|
+
mutationFn: () =>
|
|
11
|
+
withAction(unlinkGoogleAction)() as Promise<UnlinkGoogleResponse>,
|
|
12
|
+
});
|
|
13
|
+
}
|