@tinyrack/tinyauth-server 0.6.1 → 0.8.0

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.
Files changed (104) hide show
  1. package/dist/services/account-selection.service.d.ts.map +1 -1
  2. package/dist/services/account-selection.service.js +5 -2
  3. package/dist/services/account-selection.service.js.map +1 -1
  4. package/dist/services/oauth-authorize.service.d.ts.map +1 -1
  5. package/dist/services/oauth-authorize.service.js +3 -1
  6. package/dist/services/oauth-authorize.service.js.map +1 -1
  7. package/package.json +1 -1
  8. package/public/assets/2fa-DZSOQLyd.js +2 -0
  9. package/public/assets/{2fa-Cteolf9l.js.map → 2fa-DZSOQLyd.js.map} +1 -1
  10. package/public/assets/2fa-DvD9N_wj.js +2 -0
  11. package/public/assets/{2fa-BMEIiDXv.js.map → 2fa-DvD9N_wj.js.map} +1 -1
  12. package/public/assets/{2fa-BhCgCfEc.js → 2fa-P8YqnDXC.js} +2 -2
  13. package/public/assets/{2fa-BhCgCfEc.js.map → 2fa-P8YqnDXC.js.map} +1 -1
  14. package/public/assets/{2fa-E0x3Samn.js → 2fa-fLX-LED8.js} +2 -2
  15. package/public/assets/{2fa-E0x3Samn.js.map → 2fa-fLX-LED8.js.map} +1 -1
  16. package/public/assets/{admin-CXJ0z2QN.js → admin-BLPp8bT8.js} +2 -2
  17. package/public/assets/{admin-CXJ0z2QN.js.map → admin-BLPp8bT8.js.map} +1 -1
  18. package/public/assets/{consent-C-h_pWHQ.js → consent-CjXe4bU5.js} +2 -2
  19. package/public/assets/{consent-C-h_pWHQ.js.map → consent-CjXe4bU5.js.map} +1 -1
  20. package/public/assets/consent-Cq6tCfwA.js +2 -0
  21. package/public/assets/{consent-B17hGrta.js.map → consent-Cq6tCfwA.js.map} +1 -1
  22. package/public/assets/{email-DjE7mqnX.js → email-CpOX6Ig_.js} +2 -2
  23. package/public/assets/email-CpOX6Ig_.js.map +1 -0
  24. package/public/assets/email-DvD9N_wj.js +2 -0
  25. package/public/assets/email-DvD9N_wj.js.map +1 -0
  26. package/public/assets/{error-BKXsXhdR.js → error-DMzYyopT.js} +2 -2
  27. package/public/assets/{error-BKXsXhdR.js.map → error-DMzYyopT.js.map} +1 -1
  28. package/public/assets/forgot-DvD9N_wj.js +2 -0
  29. package/public/assets/{forgot-BMEIiDXv.js.map → forgot-DvD9N_wj.js.map} +1 -1
  30. package/public/assets/{forgot-C9zSfaX9.js → forgot-RbSzzjWF.js} +2 -2
  31. package/public/assets/{forgot-C9zSfaX9.js.map → forgot-RbSzzjWF.js.map} +1 -1
  32. package/public/assets/{index-BmfaaNx6.js → index-CgkA6nnx.js} +3 -3
  33. package/public/assets/index-CgkA6nnx.js.map +1 -0
  34. package/public/assets/{login-DG1Yfmb8.js → login-BQI7QY9W.js} +2 -2
  35. package/public/assets/login-BQI7QY9W.js.map +1 -0
  36. package/public/assets/login-DvD9N_wj.js +2 -0
  37. package/public/assets/login-DvD9N_wj.js.map +1 -0
  38. package/public/assets/{passkey-BDrX3jVg.js → passkey-C0BKdldQ.js} +2 -2
  39. package/public/assets/passkey-C0BKdldQ.js.map +1 -0
  40. package/public/assets/{passkey-C-h8Fvqn.js → passkey-D9qQ8xoR.js} +2 -2
  41. package/public/assets/passkey-D9qQ8xoR.js.map +1 -0
  42. package/public/assets/password-CqjbZggE.js +2 -0
  43. package/public/assets/password-CqjbZggE.js.map +1 -0
  44. package/public/assets/password-DvD9N_wj.js +2 -0
  45. package/public/assets/password-DvD9N_wj.js.map +1 -0
  46. package/public/assets/{profile-8buOY6GT.js → profile-B5qQlPwW.js} +2 -2
  47. package/public/assets/{profile-8buOY6GT.js.map → profile-B5qQlPwW.js.map} +1 -1
  48. package/public/assets/profile-fwH7_EJ0.js +2 -0
  49. package/public/assets/{profile-DcpL_XUt.js.map → profile-fwH7_EJ0.js.map} +1 -1
  50. package/public/assets/{recovery-Csf6dtvj.js → recovery-DqEhUHzv.js} +2 -2
  51. package/public/assets/{recovery-Csf6dtvj.js.map → recovery-DqEhUHzv.js.map} +1 -1
  52. package/public/assets/{register-X6dycne4.js → register-CntgI-rd.js} +2 -2
  53. package/public/assets/register-CntgI-rd.js.map +1 -0
  54. package/public/assets/register-DvD9N_wj.js +2 -0
  55. package/public/assets/register-DvD9N_wj.js.map +1 -0
  56. package/public/assets/{reset-1nsqPlxL.js → reset-BK1XYJiv.js} +2 -2
  57. package/public/assets/{reset-1nsqPlxL.js.map → reset-BK1XYJiv.js.map} +1 -1
  58. package/public/assets/reset-DvD9N_wj.js +2 -0
  59. package/public/assets/{reset-BMEIiDXv.js.map → reset-DvD9N_wj.js.map} +1 -1
  60. package/public/assets/{select-CDdb3jyc.js → select-DeUoTgDw.js} +2 -2
  61. package/public/assets/{select-CDdb3jyc.js.map → select-DeUoTgDw.js.map} +1 -1
  62. package/public/assets/select-DvD9N_wj.js +2 -0
  63. package/public/assets/{select-BMEIiDXv.js.map → select-DvD9N_wj.js.map} +1 -1
  64. package/public/assets/{terms-CUhvMN9k.js → terms-CPEuXMaO.js} +2 -2
  65. package/public/assets/{terms-CUhvMN9k.js.map → terms-CPEuXMaO.js.map} +1 -1
  66. package/public/assets/terms-fwH7_EJ0.js +2 -0
  67. package/public/assets/{terms-DcpL_XUt.js.map → terms-fwH7_EJ0.js.map} +1 -1
  68. package/public/assets/{totp-DB9WqW4V.js → totp-B1ebEiOW.js} +2 -2
  69. package/public/assets/totp-B1ebEiOW.js.map +1 -0
  70. package/public/assets/{totp-UDT2P91H.js → totp-DWWZe-tJ.js} +2 -2
  71. package/public/assets/totp-DWWZe-tJ.js.map +1 -0
  72. package/public/assets/{use-totp-setup-9fktn_he.js → use-totp-setup-Z96pOMXt.js} +2 -2
  73. package/public/assets/{use-totp-setup-9fktn_he.js.map → use-totp-setup-Z96pOMXt.js.map} +1 -1
  74. package/public/assets/{useMutation-Iu4AJCB4.js → useMutation-Biy2-pH_.js} +2 -2
  75. package/public/assets/{useMutation-Iu4AJCB4.js.map → useMutation-Biy2-pH_.js.map} +1 -1
  76. package/public/assets/{users-Bi7gjreq.js → users-YtDGJlDl.js} +2 -2
  77. package/public/assets/{users-Bi7gjreq.js.map → users-YtDGJlDl.js.map} +1 -1
  78. package/public/index.html +1 -1
  79. package/public/assets/2fa-BMEIiDXv.js +0 -2
  80. package/public/assets/2fa-Cteolf9l.js +0 -2
  81. package/public/assets/consent-B17hGrta.js +0 -2
  82. package/public/assets/email-BMEIiDXv.js +0 -2
  83. package/public/assets/email-BMEIiDXv.js.map +0 -1
  84. package/public/assets/email-DjE7mqnX.js.map +0 -1
  85. package/public/assets/forgot-BMEIiDXv.js +0 -2
  86. package/public/assets/index-BmfaaNx6.js.map +0 -1
  87. package/public/assets/login-BMEIiDXv.js +0 -2
  88. package/public/assets/login-BMEIiDXv.js.map +0 -1
  89. package/public/assets/login-DG1Yfmb8.js.map +0 -1
  90. package/public/assets/passkey-BDrX3jVg.js.map +0 -1
  91. package/public/assets/passkey-C-h8Fvqn.js.map +0 -1
  92. package/public/assets/password-86C-hCze.js +0 -2
  93. package/public/assets/password-86C-hCze.js.map +0 -1
  94. package/public/assets/password-BMEIiDXv.js +0 -2
  95. package/public/assets/password-BMEIiDXv.js.map +0 -1
  96. package/public/assets/profile-DcpL_XUt.js +0 -2
  97. package/public/assets/register-BMEIiDXv.js +0 -2
  98. package/public/assets/register-BMEIiDXv.js.map +0 -1
  99. package/public/assets/register-X6dycne4.js.map +0 -1
  100. package/public/assets/reset-BMEIiDXv.js +0 -2
  101. package/public/assets/select-BMEIiDXv.js +0 -2
  102. package/public/assets/terms-DcpL_XUt.js +0 -2
  103. package/public/assets/totp-DB9WqW4V.js.map +0 -1
  104. package/public/assets/totp-UDT2P91H.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-BMEIiDXv.js","names":["RouteErrorFallback","VerifyEmailFormValues","token","SplitErrorComponent","errorComponent"],"sources":["../../../frontend/src/routes/verify/email/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n EnvelopeSimpleIcon,\n KeyIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { Divider } from '#frontend/components/ui/divider.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n type SecondFactorMethod,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport {\n resendVerificationMutationOptions,\n verifyEmailMutationOptions,\n} from '#frontend/queries/verify-email.ts';\n\nconst SearchSchema = z.object({\n ...OAuthSearchSchema.shape,\n token: z.string().default(''),\n email: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/verify/email/')({\n component: VerifyEmail,\n errorComponent: RouteErrorFallback,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype VerifyEmailFormValues = {\n token: string;\n};\n\nfunction VerifyEmail() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const { token: queryToken, email } = search;\n const [verified, setVerified] = useState(false);\n const [resendSuccess, setResendSuccess] = useState(false);\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const verifyEmailSchema = useMemo(\n () =>\n z.object({\n token: z.string().min(1, t('validation.token.required')),\n }),\n [t],\n );\n\n const verifyEmailMutation = useMutation({\n ...verifyEmailMutationOptions,\n onSuccess: async (data) => {\n const user = data.user;\n\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: user,\n });\n await tick();\n\n if (user.second_factor_required) {\n const available_2fa_methods: SecondFactorMethod[] = [];\n if (appConfig.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (appConfig.auth.passkey.enabled) {\n available_2fa_methods.push('passkey');\n }\n\n if (available_2fa_methods.length === 1) {\n const method = available_2fa_methods[0];\n if (method === 'totp') {\n return navigate({\n to: '/setup/totp',\n search: extractOAuthParams(search),\n });\n } else {\n return navigate({\n to: '/setup/passkey',\n search: extractOAuthParams(search),\n });\n }\n } else {\n return navigate({\n to: '/setup/2fa',\n search: extractOAuthParams(search),\n });\n }\n }\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthorizeUrl(search);\n } else {\n setVerified(true);\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const resendVerificationMutation = useMutation({\n ...resendVerificationMutationOptions,\n onSuccess: () => {\n setResendSuccess(true);\n setTimeout(() => setResendSuccess(false), 5000);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<VerifyEmailFormValues>({\n defaultValues: {\n token: queryToken || '',\n },\n resolver: standardSchemaResolver(verifyEmailSchema),\n });\n\n const onSubmit = async (values: VerifyEmailFormValues) => {\n try {\n await verifyEmailMutation.mutateAsync(values);\n } catch (_error) {\n setError('token', {\n type: 'manual',\n message: t('verifyEmail.error.invalidToken'),\n });\n }\n };\n\n const handleResend = async () => {\n if (!email) {\n return;\n }\n try {\n await resendVerificationMutation.mutateAsync({ email });\n } catch (_error) {}\n };\n\n if (verified) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('verifyEmail.success.description')}\n title={t('verifyEmail.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"email-verify-go-profile\"\n onClick={() => navigate({ to: '/profile' })}\n type=\"button\"\n >\n {t('verifyEmail.success.goToProfile')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyEmail.subtitle')}\n title={t('verifyEmail.title')}\n />\n\n {email && (\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n <div className=\"text-left\">\n <p className=\"font-semibold\">{t('register.success.subtitle')}</p>\n <p className=\"text-xs\">\n {t('register.success.description', { email })}\n </p>\n </div>\n </Alert>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('verifyEmail.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyEmailMutation.isPending}\n pendingText={t('verifyEmail.submitting')}\n >\n {t('verifyEmail.submit')}\n </SubmitButton>\n </form>\n\n {email && (\n <>\n <Divider />\n\n {resendSuccess && (\n <Alert className=\"mb-2\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.resendSuccess')}\n </Alert>\n )}\n\n <button\n className=\"btn btn-ghost btn-sm w-full\"\n data-testid=\"email-verify-resend\"\n disabled={resendVerificationMutation.isPending || resendSuccess}\n onClick={handleResend}\n type=\"button\"\n >\n {resendVerificationMutation.isPending ? (\n <>\n <span className=\"loading loading-spinner loading-xs\" />\n {t('verifyEmail.resending')}\n </>\n ) : (\n t('verifyEmail.resend')\n )}\n </button>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"wCAgEE,IAAAG,EA3COH"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"email-DjE7mqnX.js","names":["standardSchemaResolver","CheckCircleIcon","EnvelopeSimpleIcon","KeyIcon","useMutation","useQueryClient","useSuspenseQuery","useNavigate","useMemo","useState","useForm","useTranslation","z","IconInput","PageHeader","SubmitButton","Alert","Divider","PageLayout","buildAuthorizeUrl","extractOAuthParams","isOAuthFlow","tick","appConfigQueryOptions","getSessionQueryOptions","resendVerificationMutationOptions","verifyEmailMutationOptions","Route","VerifyEmailFormValues","token","VerifyEmail","t","navigate","queryClient","search","useSearch","queryToken","email","verified","setVerified","resendSuccess","setResendSuccess","data","appConfig","verifyEmailSchema","object","string","min","verifyEmailMutation","onSuccess","user","setQueryData","queryKey","second_factor_required","available_2fa_methods","SecondFactorMethod","auth","password","totp","enabled","push","passkey","length","method","to","window","location","href","onSettled","invalidateQueries","resendVerificationMutation","setTimeout","register","setError","handleSubmit","formState","errors","defaultValues","resolver","onSubmit","values","mutateAsync","_error","type","message","handleResend","isPending","component"],"sources":["../../../frontend/src/components/ui/divider.tsx","../../../frontend/src/queries/verify-email.ts","../../../frontend/src/routes/verify/email/index.tsx?tsr-split=component"],"sourcesContent":["type DividerProps = {\n text?: string;\n className?: string;\n};\n\nexport function Divider({ text, className = '' }: DividerProps) {\n return (\n <div className={`my-4 flex items-center ${className}`}>\n <div className=\"h-px flex-1 bg-base-200\" />\n {text && (\n <span className=\"px-3 text-base-content/60 text-sm\">{text}</span>\n )}\n <div className=\"h-px flex-1 bg-base-200\" />\n </div>\n );\n}\n","import { mutationOptions } from '@tanstack/react-query';\nimport type { InferRequestType, InferResponseType } from 'hono/client';\nimport { client, jsonOk } from '#frontend/libs/api.ts';\n\nexport type VerifyEmailParams = InferRequestType<\n (typeof client.api.auth.email.verify)['$post']\n>['json'];\n\nexport type VerifyEmailResponse = InferResponseType<\n (typeof client.api.auth.email.verify)['$post'],\n 200\n>;\n\nexport const verifyEmailMutationOptions = mutationOptions({\n mutationFn: async (values: VerifyEmailParams) => {\n const res = await client.api.auth.email.verify.$post({\n json: values,\n });\n return jsonOk(res);\n },\n});\n\nexport type ResendVerificationParams = InferRequestType<\n (typeof client.api.auth.email.resend)['$post']\n>['json'];\n\nexport type ResendVerificationResponse = InferResponseType<\n (typeof client.api.auth.email.resend)['$post'],\n 200\n>;\n\nexport const resendVerificationMutationOptions = mutationOptions({\n mutationFn: async (values: ResendVerificationParams) => {\n const res = await client.api.auth.email.resend.$post({\n json: values,\n header: {},\n });\n return jsonOk(res);\n },\n});\n","import { standardSchemaResolver } from '@hookform/resolvers/standard-schema';\nimport {\n CheckCircleIcon,\n EnvelopeSimpleIcon,\n KeyIcon,\n} from '@phosphor-icons/react';\nimport {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from '@tanstack/react-query';\nimport { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';\nimport { useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { IconInput } from '#frontend/components/auth/icon-input.tsx';\nimport { PageHeader } from '#frontend/components/auth/page-header.tsx';\nimport { SubmitButton } from '#frontend/components/auth/submit-button.tsx';\nimport { Alert } from '#frontend/components/ui/alert.tsx';\nimport { Divider } from '#frontend/components/ui/divider.tsx';\nimport { RouteErrorFallback } from '#frontend/components/ui/route-error-fallback.tsx';\nimport { PageLayout } from '#frontend/features/layout/page-layout.tsx';\nimport {\n buildAuthorizeUrl,\n extractOAuthParams,\n isOAuthFlow,\n OAuthSearchSchema,\n type SecondFactorMethod,\n} from '#frontend/libs/oauth-search.ts';\nimport { tick } from '#frontend/libs/promise.ts';\nimport { appConfigQueryOptions } from '#frontend/queries/config.ts';\nimport { getSessionQueryOptions } from '#frontend/queries/session.ts';\nimport {\n resendVerificationMutationOptions,\n verifyEmailMutationOptions,\n} from '#frontend/queries/verify-email.ts';\n\nconst SearchSchema = z.object({\n ...OAuthSearchSchema.shape,\n token: z.string().default(''),\n email: z.string().default(''),\n});\n\nexport const Route = createFileRoute('/verify/email/')({\n component: VerifyEmail,\n errorComponent: RouteErrorFallback,\n validateSearch: SearchSchema,\n beforeLoad: async ({ context }) => {\n const config = await context.queryClient.ensureQueryData(\n appConfigQueryOptions,\n );\n const isPasswordAuthEnabled = config.auth.password.enabled;\n if (!isPasswordAuthEnabled) {\n throw redirect({ to: '/login' });\n }\n },\n loader: async ({ context }) => {\n await context.queryClient.ensureQueryData(appConfigQueryOptions);\n },\n});\n\ntype VerifyEmailFormValues = {\n token: string;\n};\n\nfunction VerifyEmail() {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const search = Route.useSearch();\n const { token: queryToken, email } = search;\n const [verified, setVerified] = useState(false);\n const [resendSuccess, setResendSuccess] = useState(false);\n const { data: appConfig } = useSuspenseQuery(appConfigQueryOptions);\n\n const verifyEmailSchema = useMemo(\n () =>\n z.object({\n token: z.string().min(1, t('validation.token.required')),\n }),\n [t],\n );\n\n const verifyEmailMutation = useMutation({\n ...verifyEmailMutationOptions,\n onSuccess: async (data) => {\n const user = data.user;\n\n queryClient.setQueryData(getSessionQueryOptions.queryKey, {\n user: user,\n });\n await tick();\n\n if (user.second_factor_required) {\n const available_2fa_methods: SecondFactorMethod[] = [];\n if (appConfig.auth.password.totp.enabled) {\n available_2fa_methods.push('totp');\n }\n if (appConfig.auth.passkey.enabled) {\n available_2fa_methods.push('passkey');\n }\n\n if (available_2fa_methods.length === 1) {\n const method = available_2fa_methods[0];\n if (method === 'totp') {\n return navigate({\n to: '/setup/totp',\n search: extractOAuthParams(search),\n });\n } else {\n return navigate({\n to: '/setup/passkey',\n search: extractOAuthParams(search),\n });\n }\n } else {\n return navigate({\n to: '/setup/2fa',\n search: extractOAuthParams(search),\n });\n }\n }\n\n if (isOAuthFlow(search)) {\n window.location.href = buildAuthorizeUrl(search);\n } else {\n setVerified(true);\n }\n },\n onSettled: () => {\n queryClient.invalidateQueries({\n queryKey: getSessionQueryOptions.queryKey,\n });\n },\n });\n\n const resendVerificationMutation = useMutation({\n ...resendVerificationMutationOptions,\n onSuccess: () => {\n setResendSuccess(true);\n setTimeout(() => setResendSuccess(false), 5000);\n },\n });\n\n const {\n register,\n setError,\n handleSubmit,\n formState: { errors },\n } = useForm<VerifyEmailFormValues>({\n defaultValues: {\n token: queryToken || '',\n },\n resolver: standardSchemaResolver(verifyEmailSchema),\n });\n\n const onSubmit = async (values: VerifyEmailFormValues) => {\n try {\n await verifyEmailMutation.mutateAsync(values);\n } catch (_error) {\n setError('token', {\n type: 'manual',\n message: t('verifyEmail.error.invalidToken'),\n });\n }\n };\n\n const handleResend = async () => {\n if (!email) {\n return;\n }\n try {\n await resendVerificationMutation.mutateAsync({ email });\n } catch (_error) {}\n };\n\n if (verified) {\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <Alert className=\"mb-4\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.success.title')}\n </Alert>\n\n <PageHeader\n subtitle={t('verifyEmail.success.description')}\n title={t('verifyEmail.success.subtitle')}\n />\n\n <button\n className=\"btn btn-block h-10 font-semibold text-[14px]\"\n data-testid=\"email-verify-go-profile\"\n onClick={() => navigate({ to: '/profile' })}\n type=\"button\"\n >\n {t('verifyEmail.success.goToProfile')}\n </button>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout cardPadding maxWidth=\"100\">\n <PageHeader\n subtitle={t('verifyEmail.subtitle')}\n title={t('verifyEmail.title')}\n />\n\n {email && (\n <Alert className=\"mb-4\" icon={EnvelopeSimpleIcon} type=\"info\">\n <div className=\"text-left\">\n <p className=\"font-semibold\">{t('register.success.subtitle')}</p>\n <p className=\"text-xs\">\n {t('register.success.description', { email })}\n </p>\n </div>\n </Alert>\n )}\n\n <form className=\"flex flex-col gap-4\" onSubmit={handleSubmit(onSubmit)}>\n <IconInput\n error={errors.token}\n icon={KeyIcon}\n placeholder={t('verifyEmail.token.placeholder')}\n {...register('token')}\n type=\"text\"\n />\n\n <SubmitButton\n className=\"mt-2\"\n isPending={verifyEmailMutation.isPending}\n pendingText={t('verifyEmail.submitting')}\n >\n {t('verifyEmail.submit')}\n </SubmitButton>\n </form>\n\n {email && (\n <>\n <Divider />\n\n {resendSuccess && (\n <Alert className=\"mb-2\" icon={CheckCircleIcon} type=\"success\">\n {t('verifyEmail.resendSuccess')}\n </Alert>\n )}\n\n <button\n className=\"btn btn-ghost btn-sm w-full\"\n data-testid=\"email-verify-resend\"\n disabled={resendVerificationMutation.isPending || resendSuccess}\n onClick={handleResend}\n type=\"button\"\n >\n {resendVerificationMutation.isPending ? (\n <>\n <span className=\"loading loading-spinner loading-xs\" />\n {t('verifyEmail.resending')}\n </>\n ) : (\n t('verifyEmail.resend')\n )}\n </button>\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{N as e}from"./index-BmfaaNx6.js";var t=e;export{t as errorComponent};
2
- //# sourceMappingURL=forgot-BMEIiDXv.js.map