@greatapps/common 1.1.704 → 1.1.706
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/modals/HexaPromoModal.mjs +2 -2
- package/dist/components/modals/HexaPromoModal.mjs.map +1 -1
- package/dist/modules/auth/services/auth.service.mjs +1 -1
- package/dist/modules/auth/services/auth.service.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/modals/HexaPromoModal.tsx +2 -2
- package/src/modules/auth/schema.ts +1 -0
- package/src/modules/auth/services/auth.service.ts +1 -1
|
@@ -80,7 +80,7 @@ function HexaPromoModal() {
|
|
|
80
80
|
className: "pointer-events-none absolute -top-10 right-0 w-[280px] rotate-[16deg] select-none"
|
|
81
81
|
}
|
|
82
82
|
),
|
|
83
|
-
/* @__PURE__ */ jsxs(DialogClose, { className: "absolute right-3 top-3 z-10 flex size-[34px] items-center justify-center rounded-lg bg-white p-2 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-950 focus:outline-none", children: [
|
|
83
|
+
/* @__PURE__ */ jsxs(DialogClose, { className: "absolute right-3 top-3 z-10 flex size-[34px] cursor-pointer items-center justify-center rounded-lg bg-white p-2 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-950 focus:outline-none", children: [
|
|
84
84
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: COPY.close }),
|
|
85
85
|
/* @__PURE__ */ jsx(IconX, { className: "size-[18px]" })
|
|
86
86
|
] }),
|
|
@@ -145,7 +145,7 @@ function ComboCard({ combo, onChoose }) {
|
|
|
145
145
|
type: "button",
|
|
146
146
|
"aria-label": COPY.couponLabel,
|
|
147
147
|
onClick: () => copy(combo.coupon),
|
|
148
|
-
className: "flex size-8 shrink-0 items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-cyan-100 hover:text-zinc-950",
|
|
148
|
+
className: "flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-cyan-100 hover:text-zinc-950",
|
|
149
149
|
children: isCopied ? /* @__PURE__ */ jsx(IconCheck, { className: "size-[18px]" }) : /* @__PURE__ */ jsx(IconCopy, { className: "size-[18px]" })
|
|
150
150
|
}
|
|
151
151
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/modals/HexaPromoModal.tsx"],"sourcesContent":["'use client';\n\nimport { toast } from 'sonner';\nimport {\n IconCheck,\n IconCopy,\n IconInfoCircle,\n IconStar,\n IconTicket,\n IconX,\n} from '@tabler/icons-react';\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from '../ui/overlay/Dialog';\nimport { Toast } from '../ui/feedback/Toast';\nimport { Button } from '../ui/buttons/Button';\nimport useCopyToClipboard from '../../hooks/copy-to-clipboard.hook';\nimport { useModalManager } from '../../store/useModalManager';\nimport { useWhitelabelUrls } from '../../providers/whitelabel.provider';\nimport { cn } from '../../infra/utils/clsx';\n\ntype ComboPeriod = 'monthly' | 'semiannual' | 'annual';\n\ninterface HexaCombo {\n coupon: string;\n name: string;\n features: string[];\n highlighted: boolean;\n period: ComboPeriod;\n}\n\n// Campanha \"Rumo ao Hexa\" — exclusiva da whitelabel 1 (público pt-br). O texto é fixo de\n// propósito: a modal precisa renderizar também no gapps, que não tem provider de next-intl.\nconst COPY = {\n title: 'Rumo ao Hexa!',\n subtitlePrefix: 'Ofertas exclusivas até ',\n subtitleDate: '24/06',\n mostChosen: 'Mais escolhido',\n couponLabel: 'Cupom',\n choosePlan: 'Escolher plano',\n couponCopied: 'Cupom copiado!',\n close: 'Fechar',\n footerPrefix: 'Válido para a ',\n footerBold: 'primeira contratação',\n footerSuffix: ' dos planos Essencial, Negócio ou Agência',\n};\n\nconst COMBOS: HexaCombo[] = [\n {\n coupon: 'MENSAL10',\n name: 'Combo convocação',\n highlighted: false,\n period: 'monthly',\n features: ['10% OFF no plano mensal', 'Webinars exclusivos'],\n },\n {\n coupon: 'SEMESTRAL10',\n name: 'Combo Hexa',\n highlighted: true,\n period: 'semiannual',\n features: ['10% OFF no plano semestral', '3 templates exclusivos', 'Webinars exclusivos'],\n },\n {\n coupon: 'ANUAL10',\n name: 'Combo escalação',\n highlighted: false,\n period: 'annual',\n features: ['10% OFF no plano anual', '3 templates exclusivos'],\n },\n];\n\n// Cores promocionais (verde/amarelo do Brasil) — específicas desta campanha, fora do design\n// system, por isso ficam hardcoded apenas aqui.\nconst GRADIENT = 'linear-gradient(180deg, #08c44f 0%, #7bd237 46.6%, #ffe31b 100%)';\n\nexport default function HexaPromoModal() {\n const { activeModal, closeModal } = useModalManager();\n const { accountsUrl } = useWhitelabelUrls();\n const isOpen = activeModal === 'hexaPromoModal';\n\n const goToPlans = (coupon: string, period: ComboPeriod) => {\n closeModal();\n const url = `${accountsUrl}/subscriptions?tab=plans&coupon=${encodeURIComponent(coupon)}&period=${encodeURIComponent(period)}`;\n window.location.assign(url);\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={() => closeModal()}>\n <DialogContent\n showCloseButton={false}\n onOpenAutoFocus={(e) => e.preventDefault()}\n className=\"border-0 bg-transparent p-0 shadow-none w-[calc(100%-32px)] sm:max-w-[940px] md:w-[924px] lg:w-[924px] max-h-[calc(100dvh-32px)] overflow-y-auto\"\n >\n <DialogTitle className=\"sr-only\">{COPY.title}</DialogTitle>\n\n <div className=\"rounded-[12px] p-1\" style={{ background: GRADIENT }}>\n <div className=\"relative overflow-hidden rounded-[10px] bg-white p-8 shadow-[0px_2px_10px_0px_rgba(26,26,26,0.05)]\">\n {/* Arte decorativa (festão/bandeira) no canto superior direito */}\n <img\n src=\"/promo/hexa-confetti.png\"\n alt=\"\"\n aria-hidden\n className=\"pointer-events-none absolute -top-10 right-0 w-[280px] rotate-[16deg] select-none\"\n />\n\n <DialogClose className=\"absolute right-3 top-3 z-10 flex size-[34px] items-center justify-center rounded-lg bg-white p-2 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-950 focus:outline-none\">\n <span className=\"sr-only\">{COPY.close}</span>\n <IconX className=\"size-[18px]\" />\n </DialogClose>\n\n {/* Header: logo + bandeira */}\n <div className=\"relative z-[1] flex w-fit items-center gap-[9px] rounded-lg bg-zinc-100 px-[9px] py-2\">\n <img src=\"/promo/hexa-logo.svg\" alt=\"\" aria-hidden className=\"size-6 select-none\" />\n <img src=\"/promo/hexa-flag.png\" alt=\"\" aria-hidden className=\"size-6 rounded select-none\" />\n </div>\n\n {/* Título */}\n <div className=\"relative z-[1] mt-4 flex flex-col gap-1\">\n <h2 className=\"font-['Outfit'] text-[32px] font-semibold leading-8 text-zinc-950\">\n {COPY.title}\n </h2>\n <p className=\"paragraph-medium-medium text-zinc-950\">\n {COPY.subtitlePrefix}\n <span className=\"font-bold\">{COPY.subtitleDate}</span>\n </p>\n </div>\n\n {/* Cards */}\n <div className=\"relative z-[1] mt-10 flex flex-col items-stretch gap-3 md:flex-row\">\n {COMBOS.map((combo) => (\n <ComboCard key={combo.coupon} combo={combo} onChoose={() => goToPlans(combo.coupon, combo.period)} />\n ))}\n </div>\n\n {/* Rodapé informativo */}\n <div className=\"relative z-[1] mt-3 flex items-center justify-center gap-2.5 rounded-[10px] bg-zinc-100 p-3 text-center\">\n <IconInfoCircle className=\"size-4 shrink-0 text-zinc-950\" />\n <p className=\"paragraph-small-medium text-zinc-950\">\n {COPY.footerPrefix}\n <span className=\"font-semibold\">{COPY.footerBold}</span>\n {COPY.footerSuffix}\n </p>\n </div>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\ninterface ComboCardProps {\n combo: HexaCombo;\n onChoose: () => void;\n}\n\nfunction ComboCard({ combo, onChoose }: ComboCardProps) {\n const { isCopied, copy } = useCopyToClipboard({\n onSuccess: () => {\n toast.custom((t) => <Toast variant=\"success\" message={COPY.couponCopied} toastId={t} />);\n },\n });\n\n return (\n <div\n className={cn(\n 'relative flex flex-1 flex-col rounded-[10px] border bg-white pb-3 md:w-[276px]',\n combo.highlighted ? 'border-cyan-500' : 'border-zinc-200',\n )}\n >\n {combo.highlighted && (\n <div className=\"absolute left-1/2 top-0 z-[1] flex h-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center gap-[5px] rounded-md border-4 border-white bg-cyan-100 px-2\">\n <IconStar className=\"size-3 text-cyan-600\" />\n <span className=\"paragraph-xsmall-semibold whitespace-nowrap text-cyan-600\">\n {COPY.mostChosen}\n </span>\n <IconStar className=\"size-3 text-cyan-600\" />\n </div>\n )}\n\n <h3 className=\"border-b border-zinc-200 px-4 py-4 text-center font-['Outfit'] text-base font-semibold text-zinc-950\">\n {combo.name}\n </h3>\n\n <ul className=\"flex flex-1 flex-col gap-5 px-5 pt-5\">\n {combo.features.map((feature) => (\n <li key={feature} className=\"flex items-center gap-2.5\">\n <IconCheck className=\"size-5 shrink-0 text-cyan-500\" />\n <span className=\"paragraph-small-medium text-zinc-950\">{feature}</span>\n </li>\n ))}\n </ul>\n\n <div className=\"mx-3 mt-5 flex items-center gap-3 rounded-lg bg-cyan-50 py-2 pl-3.5 pr-2.5\">\n <IconTicket className=\"size-5 shrink-0 text-cyan-600\" />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"paragraph-xsmall-medium text-zinc-400\">{COPY.couponLabel}</span>\n <span className=\"paragraph-small-semibold text-zinc-950\">{combo.coupon}</span>\n </div>\n <button\n type=\"button\"\n aria-label={COPY.couponLabel}\n onClick={() => copy(combo.coupon)}\n className=\"flex size-8 shrink-0 items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-cyan-100 hover:text-zinc-950\"\n >\n {isCopied ? <IconCheck className=\"size-[18px]\" /> : <IconCopy className=\"size-[18px]\" />}\n </button>\n </div>\n\n <div className=\"mx-3 mt-3\">\n <Button\n variant={combo.highlighted ? 'default' : 'secondary'}\n className={cn('h-11! w-full', combo.highlighted && 'bg-cyan-500 text-white hover:bg-cyan-600')}\n onClick={onChoose}\n >\n {COPY.choosePlan}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/modals/HexaPromoModal.tsx"],"sourcesContent":["'use client';\n\nimport { toast } from 'sonner';\nimport {\n IconCheck,\n IconCopy,\n IconInfoCircle,\n IconStar,\n IconTicket,\n IconX,\n} from '@tabler/icons-react';\nimport { Dialog, DialogClose, DialogContent, DialogTitle } from '../ui/overlay/Dialog';\nimport { Toast } from '../ui/feedback/Toast';\nimport { Button } from '../ui/buttons/Button';\nimport useCopyToClipboard from '../../hooks/copy-to-clipboard.hook';\nimport { useModalManager } from '../../store/useModalManager';\nimport { useWhitelabelUrls } from '../../providers/whitelabel.provider';\nimport { cn } from '../../infra/utils/clsx';\n\ntype ComboPeriod = 'monthly' | 'semiannual' | 'annual';\n\ninterface HexaCombo {\n coupon: string;\n name: string;\n features: string[];\n highlighted: boolean;\n period: ComboPeriod;\n}\n\n// Campanha \"Rumo ao Hexa\" — exclusiva da whitelabel 1 (público pt-br). O texto é fixo de\n// propósito: a modal precisa renderizar também no gapps, que não tem provider de next-intl.\nconst COPY = {\n title: 'Rumo ao Hexa!',\n subtitlePrefix: 'Ofertas exclusivas até ',\n subtitleDate: '24/06',\n mostChosen: 'Mais escolhido',\n couponLabel: 'Cupom',\n choosePlan: 'Escolher plano',\n couponCopied: 'Cupom copiado!',\n close: 'Fechar',\n footerPrefix: 'Válido para a ',\n footerBold: 'primeira contratação',\n footerSuffix: ' dos planos Essencial, Negócio ou Agência',\n};\n\nconst COMBOS: HexaCombo[] = [\n {\n coupon: 'MENSAL10',\n name: 'Combo convocação',\n highlighted: false,\n period: 'monthly',\n features: ['10% OFF no plano mensal', 'Webinars exclusivos'],\n },\n {\n coupon: 'SEMESTRAL10',\n name: 'Combo Hexa',\n highlighted: true,\n period: 'semiannual',\n features: ['10% OFF no plano semestral', '3 templates exclusivos', 'Webinars exclusivos'],\n },\n {\n coupon: 'ANUAL10',\n name: 'Combo escalação',\n highlighted: false,\n period: 'annual',\n features: ['10% OFF no plano anual', '3 templates exclusivos'],\n },\n];\n\n// Cores promocionais (verde/amarelo do Brasil) — específicas desta campanha, fora do design\n// system, por isso ficam hardcoded apenas aqui.\nconst GRADIENT = 'linear-gradient(180deg, #08c44f 0%, #7bd237 46.6%, #ffe31b 100%)';\n\nexport default function HexaPromoModal() {\n const { activeModal, closeModal } = useModalManager();\n const { accountsUrl } = useWhitelabelUrls();\n const isOpen = activeModal === 'hexaPromoModal';\n\n const goToPlans = (coupon: string, period: ComboPeriod) => {\n closeModal();\n const url = `${accountsUrl}/subscriptions?tab=plans&coupon=${encodeURIComponent(coupon)}&period=${encodeURIComponent(period)}`;\n window.location.assign(url);\n };\n\n return (\n <Dialog open={isOpen} onOpenChange={() => closeModal()}>\n <DialogContent\n showCloseButton={false}\n onOpenAutoFocus={(e) => e.preventDefault()}\n className=\"border-0 bg-transparent p-0 shadow-none w-[calc(100%-32px)] sm:max-w-[940px] md:w-[924px] lg:w-[924px] max-h-[calc(100dvh-32px)] overflow-y-auto\"\n >\n <DialogTitle className=\"sr-only\">{COPY.title}</DialogTitle>\n\n <div className=\"rounded-[12px] p-1\" style={{ background: GRADIENT }}>\n <div className=\"relative overflow-hidden rounded-[10px] bg-white p-8 shadow-[0px_2px_10px_0px_rgba(26,26,26,0.05)]\">\n {/* Arte decorativa (festão/bandeira) no canto superior direito */}\n <img\n src=\"/promo/hexa-confetti.png\"\n alt=\"\"\n aria-hidden\n className=\"pointer-events-none absolute -top-10 right-0 w-[280px] rotate-[16deg] select-none\"\n />\n\n <DialogClose className=\"absolute right-3 top-3 z-10 flex size-[34px] cursor-pointer items-center justify-center rounded-lg bg-white p-2 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-950 focus:outline-none\">\n <span className=\"sr-only\">{COPY.close}</span>\n <IconX className=\"size-[18px]\" />\n </DialogClose>\n\n {/* Header: logo + bandeira */}\n <div className=\"relative z-[1] flex w-fit items-center gap-[9px] rounded-lg bg-zinc-100 px-[9px] py-2\">\n <img src=\"/promo/hexa-logo.svg\" alt=\"\" aria-hidden className=\"size-6 select-none\" />\n <img src=\"/promo/hexa-flag.png\" alt=\"\" aria-hidden className=\"size-6 rounded select-none\" />\n </div>\n\n {/* Título */}\n <div className=\"relative z-[1] mt-4 flex flex-col gap-1\">\n <h2 className=\"font-['Outfit'] text-[32px] font-semibold leading-8 text-zinc-950\">\n {COPY.title}\n </h2>\n <p className=\"paragraph-medium-medium text-zinc-950\">\n {COPY.subtitlePrefix}\n <span className=\"font-bold\">{COPY.subtitleDate}</span>\n </p>\n </div>\n\n {/* Cards */}\n <div className=\"relative z-[1] mt-10 flex flex-col items-stretch gap-3 md:flex-row\">\n {COMBOS.map((combo) => (\n <ComboCard key={combo.coupon} combo={combo} onChoose={() => goToPlans(combo.coupon, combo.period)} />\n ))}\n </div>\n\n {/* Rodapé informativo */}\n <div className=\"relative z-[1] mt-3 flex items-center justify-center gap-2.5 rounded-[10px] bg-zinc-100 p-3 text-center\">\n <IconInfoCircle className=\"size-4 shrink-0 text-zinc-950\" />\n <p className=\"paragraph-small-medium text-zinc-950\">\n {COPY.footerPrefix}\n <span className=\"font-semibold\">{COPY.footerBold}</span>\n {COPY.footerSuffix}\n </p>\n </div>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n\ninterface ComboCardProps {\n combo: HexaCombo;\n onChoose: () => void;\n}\n\nfunction ComboCard({ combo, onChoose }: ComboCardProps) {\n const { isCopied, copy } = useCopyToClipboard({\n onSuccess: () => {\n toast.custom((t) => <Toast variant=\"success\" message={COPY.couponCopied} toastId={t} />);\n },\n });\n\n return (\n <div\n className={cn(\n 'relative flex flex-1 flex-col rounded-[10px] border bg-white pb-3 md:w-[276px]',\n combo.highlighted ? 'border-cyan-500' : 'border-zinc-200',\n )}\n >\n {combo.highlighted && (\n <div className=\"absolute left-1/2 top-0 z-[1] flex h-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center gap-[5px] rounded-md border-4 border-white bg-cyan-100 px-2\">\n <IconStar className=\"size-3 text-cyan-600\" />\n <span className=\"paragraph-xsmall-semibold whitespace-nowrap text-cyan-600\">\n {COPY.mostChosen}\n </span>\n <IconStar className=\"size-3 text-cyan-600\" />\n </div>\n )}\n\n <h3 className=\"border-b border-zinc-200 px-4 py-4 text-center font-['Outfit'] text-base font-semibold text-zinc-950\">\n {combo.name}\n </h3>\n\n <ul className=\"flex flex-1 flex-col gap-5 px-5 pt-5\">\n {combo.features.map((feature) => (\n <li key={feature} className=\"flex items-center gap-2.5\">\n <IconCheck className=\"size-5 shrink-0 text-cyan-500\" />\n <span className=\"paragraph-small-medium text-zinc-950\">{feature}</span>\n </li>\n ))}\n </ul>\n\n <div className=\"mx-3 mt-5 flex items-center gap-3 rounded-lg bg-cyan-50 py-2 pl-3.5 pr-2.5\">\n <IconTicket className=\"size-5 shrink-0 text-cyan-600\" />\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"paragraph-xsmall-medium text-zinc-400\">{COPY.couponLabel}</span>\n <span className=\"paragraph-small-semibold text-zinc-950\">{combo.coupon}</span>\n </div>\n <button\n type=\"button\"\n aria-label={COPY.couponLabel}\n onClick={() => copy(combo.coupon)}\n className=\"flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-cyan-100 hover:text-zinc-950\"\n >\n {isCopied ? <IconCheck className=\"size-[18px]\" /> : <IconCopy className=\"size-[18px]\" />}\n </button>\n </div>\n\n <div className=\"mx-3 mt-3\">\n <Button\n variant={combo.highlighted ? 'default' : 'secondary'}\n className={cn('h-11! w-full', combo.highlighted && 'bg-cyan-500 text-white hover:bg-cyan-600')}\n onClick={onChoose}\n >\n {COPY.choosePlan}\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -183,7 +183,7 @@ class AuthService {
|
|
|
183
183
|
const payload = {
|
|
184
184
|
onboarding_token: data.onboardingToken,
|
|
185
185
|
name: data.user.name,
|
|
186
|
-
bussiness_type: 0,
|
|
186
|
+
bussiness_type: data.businessType ?? 0,
|
|
187
187
|
language: "pt-br",
|
|
188
188
|
timezone: "America/Sao_Paulo",
|
|
189
189
|
currency: "BRL",
|
|
@@ -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 SocialGoogleApiResponse,\r\n SocialGoogleResponse,\r\n SocialOnboardingApiResponse,\r\n SocialOnboardingRequest,\r\n SocialOnboardingResponse,\r\n IsolatedLoginResponse,\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 async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo,\r\n options: { setCookie: false },\r\n ): Promise<IsolatedLoginResponse>;\r\n async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo,\r\n options?: { setCookie?: boolean },\r\n ): Promise<LoginResponse | IsolatedLoginResponse>;\r\n async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo,\r\n options?: { setCookie?: boolean },\r\n ): Promise<LoginResponse | IsolatedLoginResponse> {\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 // Modo isolado: caller só quer o token, sem afetar a sessão do navegador\r\n // nem pagar pelas chamadas de user/account (ex.: fluxo de SSO).\r\n if (options?.setCookie === false) {\r\n return { result: \"success\", accessToken: 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(\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; setCookie?: boolean },\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 // Modo isolado: devolve o token sem gravar o cookie — o caller redireciona\r\n // pra outro lugar (ex.: SSO callback) e não quer mexer na sessão atual.\r\n if (options?.setCookie === false) {\r\n return { status: 1, accessToken: response.data.cookie };\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
|
+
{"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 IsolatedLoginResponse,\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 async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo,\r\n options: { setCookie: false },\r\n ): Promise<IsolatedLoginResponse>;\r\n async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo,\r\n options?: { setCookie?: boolean },\r\n ): Promise<LoginResponse | IsolatedLoginResponse>;\r\n async login(\r\n credentials: LoginRequest,\r\n clientInfo: ClientInfo,\r\n options?: { setCookie?: boolean },\r\n ): Promise<LoginResponse | IsolatedLoginResponse> {\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 // Modo isolado: caller só quer o token, sem afetar a sessão do navegador\r\n // nem pagar pelas chamadas de user/account (ex.: fluxo de SSO).\r\n if (options?.setCookie === false) {\r\n return { result: \"success\", accessToken: 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(\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; setCookie?: boolean },\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 // Modo isolado: devolve o token sem gravar o cookie — o caller redireciona\r\n // pra outro lugar (ex.: SSO callback) e não quer mexer na sessão atual.\r\n if (options?.setCookie === false) {\r\n return { status: 1, accessToken: response.data.cookie };\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: 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.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":[]}
|
package/package.json
CHANGED
|
@@ -101,7 +101,7 @@ export default function HexaPromoModal() {
|
|
|
101
101
|
className="pointer-events-none absolute -top-10 right-0 w-[280px] rotate-[16deg] select-none"
|
|
102
102
|
/>
|
|
103
103
|
|
|
104
|
-
<DialogClose className="absolute right-3 top-3 z-10 flex size-[34px] items-center justify-center rounded-lg bg-white p-2 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-950 focus:outline-none">
|
|
104
|
+
<DialogClose className="absolute right-3 top-3 z-10 flex size-[34px] cursor-pointer items-center justify-center rounded-lg bg-white p-2 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-950 focus:outline-none">
|
|
105
105
|
<span className="sr-only">{COPY.close}</span>
|
|
106
106
|
<IconX className="size-[18px]" />
|
|
107
107
|
</DialogClose>
|
|
@@ -198,7 +198,7 @@ function ComboCard({ combo, onChoose }: ComboCardProps) {
|
|
|
198
198
|
type="button"
|
|
199
199
|
aria-label={COPY.couponLabel}
|
|
200
200
|
onClick={() => copy(combo.coupon)}
|
|
201
|
-
className="flex size-8 shrink-0 items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-cyan-100 hover:text-zinc-950"
|
|
201
|
+
className="flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-md text-zinc-500 transition-colors hover:bg-cyan-100 hover:text-zinc-950"
|
|
202
202
|
>
|
|
203
203
|
{isCopied ? <IconCheck className="size-[18px]" /> : <IconCopy className="size-[18px]" />}
|
|
204
204
|
</button>
|
|
@@ -333,6 +333,7 @@ export interface SocialOnboardingUserPayload {
|
|
|
333
333
|
export interface SocialOnboardingRequest {
|
|
334
334
|
onboardingToken: string;
|
|
335
335
|
user: SocialOnboardingUserPayload;
|
|
336
|
+
businessType?: number;
|
|
336
337
|
acceptTerms: boolean;
|
|
337
338
|
affiliateId?: number | string;
|
|
338
339
|
couponId?: number | string;
|
|
@@ -284,7 +284,7 @@ class AuthService {
|
|
|
284
284
|
const payload = {
|
|
285
285
|
onboarding_token: data.onboardingToken,
|
|
286
286
|
name: data.user.name,
|
|
287
|
-
bussiness_type: 0,
|
|
287
|
+
bussiness_type: data.businessType ?? 0,
|
|
288
288
|
language: "pt-br",
|
|
289
289
|
timezone: "America/Sao_Paulo",
|
|
290
290
|
currency: "BRL",
|