@better-auth-ui/react 1.6.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 (250) hide show
  1. package/dist/components/auth/auth-provider.d.ts +32 -0
  2. package/dist/components/auth/auth-provider.js +44 -0
  3. package/dist/components/email/email-changed.d.ts +97 -0
  4. package/dist/components/email/email-changed.js +70 -0
  5. package/dist/components/email/email-localization.d.ts +61 -0
  6. package/dist/components/email/email-localization.js +24 -0
  7. package/dist/components/email/email-styles.d.ts +89 -0
  8. package/dist/components/email/email-styles.js +129 -0
  9. package/dist/components/email/email-verification.d.ts +97 -0
  10. package/dist/components/email/email-verification.js +75 -0
  11. package/dist/components/email/index.d.ts +9 -0
  12. package/dist/components/email/index.js +9 -0
  13. package/dist/components/email/magic-link.d.ts +93 -0
  14. package/dist/components/email/magic-link.js +72 -0
  15. package/dist/components/email/new-device.d.ts +123 -0
  16. package/dist/components/email/new-device.js +90 -0
  17. package/dist/components/email/otp-email.d.ts +88 -0
  18. package/dist/components/email/otp-email.js +65 -0
  19. package/dist/components/email/password-changed.d.ts +96 -0
  20. package/dist/components/email/password-changed.js +76 -0
  21. package/dist/components/email/reset-password.d.ts +90 -0
  22. package/dist/components/email/reset-password.js +68 -0
  23. package/dist/components/icons/apple.d.ts +8 -0
  24. package/dist/components/icons/apple.js +10 -0
  25. package/dist/components/icons/atlassian.d.ts +10 -0
  26. package/dist/components/icons/atlassian.js +14 -0
  27. package/dist/components/icons/cognito.d.ts +8 -0
  28. package/dist/components/icons/cognito.js +10 -0
  29. package/dist/components/icons/discord.d.ts +8 -0
  30. package/dist/components/icons/discord.js +10 -0
  31. package/dist/components/icons/dropbox.d.ts +8 -0
  32. package/dist/components/icons/dropbox.js +10 -0
  33. package/dist/components/icons/facebook.d.ts +10 -0
  34. package/dist/components/icons/facebook.js +12 -0
  35. package/dist/components/icons/figma.d.ts +11 -0
  36. package/dist/components/icons/figma.js +13 -0
  37. package/dist/components/icons/github.d.ts +10 -0
  38. package/dist/components/icons/github.js +12 -0
  39. package/dist/components/icons/gitlab.d.ts +8 -0
  40. package/dist/components/icons/gitlab.js +10 -0
  41. package/dist/components/icons/google.d.ts +8 -0
  42. package/dist/components/icons/google.js +10 -0
  43. package/dist/components/icons/huggingface.d.ts +8 -0
  44. package/dist/components/icons/huggingface.js +10 -0
  45. package/dist/components/icons/index.d.ts +35 -0
  46. package/dist/components/icons/index.js +35 -0
  47. package/dist/components/icons/kakao.d.ts +10 -0
  48. package/dist/components/icons/kakao.js +12 -0
  49. package/dist/components/icons/kick.d.ts +10 -0
  50. package/dist/components/icons/kick.js +12 -0
  51. package/dist/components/icons/line.d.ts +8 -0
  52. package/dist/components/icons/line.js +10 -0
  53. package/dist/components/icons/linear.d.ts +8 -0
  54. package/dist/components/icons/linear.js +10 -0
  55. package/dist/components/icons/linkedin.d.ts +8 -0
  56. package/dist/components/icons/linkedin.js +10 -0
  57. package/dist/components/icons/microsoft.d.ts +8 -0
  58. package/dist/components/icons/microsoft.js +10 -0
  59. package/dist/components/icons/naver.d.ts +8 -0
  60. package/dist/components/icons/naver.js +10 -0
  61. package/dist/components/icons/notion.d.ts +8 -0
  62. package/dist/components/icons/notion.js +10 -0
  63. package/dist/components/icons/paybin.d.ts +7 -0
  64. package/dist/components/icons/paybin.js +9 -0
  65. package/dist/components/icons/paypal.d.ts +8 -0
  66. package/dist/components/icons/paypal.js +10 -0
  67. package/dist/components/icons/polar.d.ts +8 -0
  68. package/dist/components/icons/polar.js +10 -0
  69. package/dist/components/icons/railway.d.ts +8 -0
  70. package/dist/components/icons/railway.js +10 -0
  71. package/dist/components/icons/reddit.d.ts +8 -0
  72. package/dist/components/icons/reddit.js +10 -0
  73. package/dist/components/icons/roblox.d.ts +11 -0
  74. package/dist/components/icons/roblox.js +13 -0
  75. package/dist/components/icons/salesforce.d.ts +8 -0
  76. package/dist/components/icons/salesforce.js +10 -0
  77. package/dist/components/icons/slack.d.ts +8 -0
  78. package/dist/components/icons/slack.js +10 -0
  79. package/dist/components/icons/spotify.d.ts +8 -0
  80. package/dist/components/icons/spotify.js +10 -0
  81. package/dist/components/icons/tiktok.d.ts +9 -0
  82. package/dist/components/icons/tiktok.js +11 -0
  83. package/dist/components/icons/twitch.d.ts +8 -0
  84. package/dist/components/icons/twitch.js +13 -0
  85. package/dist/components/icons/vercel.d.ts +8 -0
  86. package/dist/components/icons/vercel.js +10 -0
  87. package/dist/components/icons/vk.d.ts +8 -0
  88. package/dist/components/icons/vk.js +10 -0
  89. package/dist/components/icons/wechat.d.ts +8 -0
  90. package/dist/components/icons/wechat.js +10 -0
  91. package/dist/components/icons/x.d.ts +8 -0
  92. package/dist/components/icons/x.js +10 -0
  93. package/dist/components/icons/zoom.d.ts +8 -0
  94. package/dist/components/icons/zoom.js +12 -0
  95. package/dist/components/settings/account/theme-preview.d.ts +3 -0
  96. package/dist/components/settings/account/theme-preview.js +10 -0
  97. package/dist/core.d.ts +1 -0
  98. package/dist/core.js +1 -0
  99. package/dist/hooks/auth/use-auth-mutation.d.ts +18 -0
  100. package/dist/hooks/auth/use-auth-mutation.js +10 -0
  101. package/dist/hooks/auth/use-auth-query.d.ts +24 -0
  102. package/dist/hooks/auth/use-auth-query.js +10 -0
  103. package/dist/hooks/auth/use-authenticate.d.ts +9 -0
  104. package/dist/hooks/auth/use-authenticate.js +28 -0
  105. package/dist/hooks/auth/use-forgot-password.d.ts +20 -0
  106. package/dist/hooks/auth/use-forgot-password.js +14 -0
  107. package/dist/hooks/auth/use-request-password-reset.d.ts +26 -0
  108. package/dist/hooks/auth/use-request-password-reset.js +14 -0
  109. package/dist/hooks/auth/use-reset-password.d.ts +40 -0
  110. package/dist/hooks/auth/use-reset-password.js +13 -0
  111. package/dist/hooks/auth/use-send-verification-email.d.ts +24 -0
  112. package/dist/hooks/auth/use-send-verification-email.js +13 -0
  113. package/dist/hooks/auth/use-session.d.ts +9 -0
  114. package/dist/hooks/auth/use-session.js +18 -0
  115. package/dist/hooks/auth/use-sign-in-email.d.ts +53 -0
  116. package/dist/hooks/auth/use-sign-in-email.js +24 -0
  117. package/dist/hooks/auth/use-sign-in-magic-link.d.ts +32 -0
  118. package/dist/hooks/auth/use-sign-in-magic-link.js +13 -0
  119. package/dist/hooks/auth/use-sign-in-social.d.ts +93 -0
  120. package/dist/hooks/auth/use-sign-in-social.js +13 -0
  121. package/dist/hooks/auth/use-sign-out.d.ts +19 -0
  122. package/dist/hooks/auth/use-sign-out.js +24 -0
  123. package/dist/hooks/auth/use-sign-up-email.d.ts +526 -0
  124. package/dist/hooks/auth/use-sign-up-email.js +24 -0
  125. package/dist/hooks/auth/use-user.d.ts +513 -0
  126. package/dist/hooks/auth/use-user.js +14 -0
  127. package/dist/hooks/settings/use-account-info.d.ts +17 -0
  128. package/dist/hooks/settings/use-account-info.js +25 -0
  129. package/dist/hooks/settings/use-change-email.d.ts +24 -0
  130. package/dist/hooks/settings/use-change-email.js +23 -0
  131. package/dist/hooks/settings/use-change-password.d.ts +54 -0
  132. package/dist/hooks/settings/use-change-password.js +11 -0
  133. package/dist/hooks/settings/use-delete-user.d.ts +42 -0
  134. package/dist/hooks/settings/use-delete-user.js +11 -0
  135. package/dist/hooks/settings/use-link-social.d.ts +46 -0
  136. package/dist/hooks/settings/use-link-social.js +10 -0
  137. package/dist/hooks/settings/use-list-accounts.d.ts +20 -0
  138. package/dist/hooks/settings/use-list-accounts.js +23 -0
  139. package/dist/hooks/settings/use-list-device-sessions.d.ts +11 -0
  140. package/dist/hooks/settings/use-list-device-sessions.js +22 -0
  141. package/dist/hooks/settings/use-list-sessions.d.ts +20 -0
  142. package/dist/hooks/settings/use-list-sessions.js +22 -0
  143. package/dist/hooks/settings/use-revoke-multi-session.d.ts +19 -0
  144. package/dist/hooks/settings/use-revoke-multi-session.js +20 -0
  145. package/dist/hooks/settings/use-revoke-session.d.ts +19 -0
  146. package/dist/hooks/settings/use-revoke-session.js +21 -0
  147. package/dist/hooks/settings/use-set-active-session.d.ts +37 -0
  148. package/dist/hooks/settings/use-set-active-session.js +28 -0
  149. package/dist/hooks/settings/use-unlink-account.d.ts +21 -0
  150. package/dist/hooks/settings/use-unlink-account.js +21 -0
  151. package/dist/hooks/settings/use-update-user.d.ts +11 -0
  152. package/dist/hooks/settings/use-update-user.js +29 -0
  153. package/dist/hooks/use-hydrated.d.ts +6 -0
  154. package/dist/hooks/use-hydrated.js +18 -0
  155. package/dist/index.d.ts +32 -0
  156. package/dist/index.js +33 -0
  157. package/dist/lib/auth-client.d.ts +1979 -0
  158. package/dist/lib/auth-client.js +5 -0
  159. package/dist/lib/auth-config.d.ts +43 -0
  160. package/dist/lib/auth-config.js +1 -0
  161. package/dist/lib/auth-context.d.ts +2 -0
  162. package/dist/lib/auth-context.js +3 -0
  163. package/dist/lib/auth-hook-options.d.ts +8 -0
  164. package/dist/lib/auth-hook-options.js +1 -0
  165. package/dist/lib/provider-icons.d.ts +13 -0
  166. package/dist/lib/provider-icons.js +48 -0
  167. package/dist/lib/utils.d.ts +2 -0
  168. package/dist/lib/utils.js +5 -0
  169. package/package.json +64 -0
  170. package/src/components/auth/auth-provider.tsx +82 -0
  171. package/src/components/email/email-changed.tsx +381 -0
  172. package/src/components/email/email-localization.tsx +33 -0
  173. package/src/components/email/email-styles.tsx +175 -0
  174. package/src/components/email/email-verification.tsx +350 -0
  175. package/src/components/email/index.ts +9 -0
  176. package/src/components/email/magic-link.tsx +349 -0
  177. package/src/components/email/new-device.tsx +452 -0
  178. package/src/components/email/otp-email.tsx +321 -0
  179. package/src/components/email/password-changed.tsx +380 -0
  180. package/src/components/email/reset-password.tsx +343 -0
  181. package/src/components/icons/apple.tsx +24 -0
  182. package/src/components/icons/atlassian.tsx +43 -0
  183. package/src/components/icons/cognito.tsx +25 -0
  184. package/src/components/icons/discord.tsx +24 -0
  185. package/src/components/icons/dropbox.tsx +24 -0
  186. package/src/components/icons/facebook.tsx +30 -0
  187. package/src/components/icons/figma.tsx +43 -0
  188. package/src/components/icons/github.tsx +26 -0
  189. package/src/components/icons/gitlab.tsx +36 -0
  190. package/src/components/icons/google.tsx +42 -0
  191. package/src/components/icons/huggingface.tsx +44 -0
  192. package/src/components/icons/index.ts +35 -0
  193. package/src/components/icons/kakao.tsx +26 -0
  194. package/src/components/icons/kick.tsx +30 -0
  195. package/src/components/icons/line.tsx +24 -0
  196. package/src/components/icons/linear.tsx +24 -0
  197. package/src/components/icons/linkedin.tsx +28 -0
  198. package/src/components/icons/microsoft.tsx +24 -0
  199. package/src/components/icons/naver.tsx +24 -0
  200. package/src/components/icons/notion.tsx +25 -0
  201. package/src/components/icons/paybin.tsx +37 -0
  202. package/src/components/icons/paypal.tsx +36 -0
  203. package/src/components/icons/polar.tsx +31 -0
  204. package/src/components/icons/railway.tsx +24 -0
  205. package/src/components/icons/reddit.tsx +25 -0
  206. package/src/components/icons/roblox.tsx +28 -0
  207. package/src/components/icons/salesforce.tsx +24 -0
  208. package/src/components/icons/slack.tsx +36 -0
  209. package/src/components/icons/spotify.tsx +24 -0
  210. package/src/components/icons/tiktok.tsx +32 -0
  211. package/src/components/icons/twitch.tsx +50 -0
  212. package/src/components/icons/vercel.tsx +21 -0
  213. package/src/components/icons/vk.tsx +24 -0
  214. package/src/components/icons/wechat.tsx +24 -0
  215. package/src/components/icons/x.tsx +24 -0
  216. package/src/components/icons/zoom.tsx +48 -0
  217. package/src/components/settings/account/theme-preview.tsx +271 -0
  218. package/src/core.ts +1 -0
  219. package/src/hooks/auth/use-auth-mutation.ts +56 -0
  220. package/src/hooks/auth/use-auth-query.ts +50 -0
  221. package/src/hooks/auth/use-authenticate.ts +35 -0
  222. package/src/hooks/auth/use-request-password-reset.ts +24 -0
  223. package/src/hooks/auth/use-reset-password.ts +23 -0
  224. package/src/hooks/auth/use-send-verification-email.ts +23 -0
  225. package/src/hooks/auth/use-session.ts +26 -0
  226. package/src/hooks/auth/use-sign-in-email.ts +35 -0
  227. package/src/hooks/auth/use-sign-in-magic-link.ts +23 -0
  228. package/src/hooks/auth/use-sign-in-social.ts +23 -0
  229. package/src/hooks/auth/use-sign-out.ts +34 -0
  230. package/src/hooks/auth/use-sign-up-email.ts +35 -0
  231. package/src/hooks/auth/use-user.ts +21 -0
  232. package/src/hooks/settings/use-account-info.ts +30 -0
  233. package/src/hooks/settings/use-change-email.ts +33 -0
  234. package/src/hooks/settings/use-change-password.ts +21 -0
  235. package/src/hooks/settings/use-delete-user.ts +21 -0
  236. package/src/hooks/settings/use-link-social.ts +19 -0
  237. package/src/hooks/settings/use-list-accounts.ts +27 -0
  238. package/src/hooks/settings/use-list-device-sessions.ts +32 -0
  239. package/src/hooks/settings/use-list-sessions.ts +26 -0
  240. package/src/hooks/settings/use-revoke-multi-session.ts +30 -0
  241. package/src/hooks/settings/use-revoke-session.ts +31 -0
  242. package/src/hooks/settings/use-set-active-session.ts +46 -0
  243. package/src/hooks/settings/use-unlink-account.ts +31 -0
  244. package/src/hooks/settings/use-update-user.ts +44 -0
  245. package/src/index.ts +34 -0
  246. package/src/lib/auth-client.ts +37 -0
  247. package/src/lib/auth-config.ts +48 -0
  248. package/src/lib/auth-context.ts +6 -0
  249. package/src/lib/provider-icons.ts +90 -0
  250. package/src/lib/utils.ts +6 -0
@@ -0,0 +1,32 @@
1
+ import { type AnyAuthClient, type AnyAuthConfig, type AuthConfig } from "@better-auth-ui/react";
2
+ import { QueryClient } from "@tanstack/react-query";
3
+ import { type PropsWithChildren } from "react";
4
+ export type AuthProviderProps = PropsWithChildren<AnyAuthConfig> & {
5
+ authClient: AnyAuthClient;
6
+ navigate: (options: {
7
+ to: string;
8
+ replace?: boolean;
9
+ }) => void;
10
+ /**
11
+ * TanStack QueryClient to use for your application's queries
12
+ */
13
+ queryClient?: QueryClient;
14
+ };
15
+ /**
16
+ * Provides merged authentication configuration and a resolved React Query client to descendant components.
17
+ *
18
+ * The component merges the provided auth config with the library defaults, updates `redirectTo` from the
19
+ * current URL when the app is hydrated, wires a QueryClient (prop, context, or fallback) and installs an
20
+ * error handler that surfaces query errors via the configured toast. It then supplies the merged config
21
+ * via AuthContext and wraps children with QueryClientProvider.
22
+ *
23
+ * @returns The children wrapped with AuthContext.Provider and QueryClientProvider configured for auth.
24
+ */
25
+ export declare function AuthProvider({ children, queryClient, ...config }: AuthProviderProps): import("react/jsx-runtime").JSX.Element;
26
+ /**
27
+ * Accesses the current authentication configuration from AuthContext.
28
+ *
29
+ * @returns The merged authentication configuration provided by AuthProvider.
30
+ * @throws If no AuthProvider is present in the component tree.
31
+ */
32
+ export declare function useAuth(): AuthConfig;
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { deepmerge, defaultAuthConfig } from "@better-auth-ui/core";
4
+ import { AuthContext } from "@better-auth-ui/react";
5
+ import { QueryClient, QueryClientContext, QueryClientProvider } from "@tanstack/react-query";
6
+ import { useContext } from "react";
7
+ const fallbackQueryClient = new QueryClient();
8
+ const baseAuthConfig = {
9
+ ...defaultAuthConfig,
10
+ Link: (props) => _jsx("a", { ...props })
11
+ };
12
+ /**
13
+ * Provides merged authentication configuration and a resolved React Query client to descendant components.
14
+ *
15
+ * The component merges the provided auth config with the library defaults, updates `redirectTo` from the
16
+ * current URL when the app is hydrated, wires a QueryClient (prop, context, or fallback) and installs an
17
+ * error handler that surfaces query errors via the configured toast. It then supplies the merged config
18
+ * via AuthContext and wraps children with QueryClientProvider.
19
+ *
20
+ * @returns The children wrapped with AuthContext.Provider and QueryClientProvider configured for auth.
21
+ */
22
+ export function AuthProvider({ children, queryClient, ...config }) {
23
+ const contextQueryClient = useContext(QueryClientContext);
24
+ const resolvedQueryClient = queryClient || contextQueryClient || fallbackQueryClient;
25
+ const mergedConfig = deepmerge(baseAuthConfig, config);
26
+ mergedConfig.redirectTo =
27
+ (typeof window !== "undefined" &&
28
+ new URLSearchParams(window.location.search).get("redirectTo")?.trim()) ||
29
+ mergedConfig.redirectTo;
30
+ return (_jsx(AuthContext.Provider, { value: mergedConfig, children: _jsx(QueryClientProvider, { client: resolvedQueryClient, children: children }) }));
31
+ }
32
+ /**
33
+ * Accesses the current authentication configuration from AuthContext.
34
+ *
35
+ * @returns The merged authentication configuration provided by AuthProvider.
36
+ * @throws If no AuthProvider is present in the component tree.
37
+ */
38
+ export function useAuth() {
39
+ const context = useContext(AuthContext);
40
+ if (!context) {
41
+ throw new Error("[Better Auth UI] AuthProvider is required");
42
+ }
43
+ return context;
44
+ }
@@ -0,0 +1,97 @@
1
+ import type { ReactNode } from "react";
2
+ import { type EmailClassNames, type EmailColors } from "./email-styles";
3
+ declare const emailChangedEmailLocalization: {
4
+ YOUR_EMAIL_ADDRESS_HAS_BEEN_CHANGED: string;
5
+ LOGO: string;
6
+ EMAIL_ADDRESS_CHANGED: string;
7
+ EMAIL_ADDRESS_FOR_YOUR_ACCOUNT_CHANGED: string;
8
+ PREVIOUS_EMAIL: string;
9
+ NEW_EMAIL: string;
10
+ IF_YOU_MADE_THIS_CHANGE: string;
11
+ I_DIDNT_MAKE_THIS_CHANGE: string;
12
+ EMAIL_SENT_BY: string;
13
+ IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE: string;
14
+ POWERED_BY_BETTER_AUTH: string;
15
+ };
16
+ /**
17
+ * Localization strings for the EmailChangedEmail component.
18
+ *
19
+ * Contains all text content used in the email changed notification email template.
20
+ */
21
+ export type EmailChangedEmailLocalization = typeof emailChangedEmailLocalization;
22
+ /**
23
+ * Props for the EmailChangedEmail component.
24
+ */
25
+ export interface EmailChangedEmailProps {
26
+ /** The previous email address that was changed */
27
+ oldEmail?: string;
28
+ /** The new email address */
29
+ newEmail?: string;
30
+ /** URL to revert the email change if unauthorized */
31
+ revertURL?: string;
32
+ /** Name of the application sending the email */
33
+ appName?: string;
34
+ /** Support email address for security concerns */
35
+ supportEmail?: string;
36
+ /** Logo URL(s) - a single string or light/dark variants. If omitted, no logo is shown. */
37
+ logoURL?: string | {
38
+ light: string;
39
+ dark: string;
40
+ };
41
+ /** Custom CSS class names for styling specific parts of the email */
42
+ classNames?: EmailClassNames;
43
+ /** Custom color scheme for light and dark modes */
44
+ colors?: EmailColors;
45
+ /** Whether to show the "Powered by better-auth" footer */
46
+ poweredBy?: boolean;
47
+ /** Whether to enable dark mode support */
48
+ darkMode?: boolean;
49
+ /** Additional React nodes to inject into the email head */
50
+ head?: ReactNode;
51
+ /**
52
+ * Localization overrides for customizing email text
53
+ * @remarks `EmailChangedEmailLocalization`
54
+ */
55
+ localization?: Partial<EmailChangedEmailLocalization>;
56
+ }
57
+ /**
58
+ * Email template component that notifies users when their email address has been changed.
59
+ *
60
+ * This email includes:
61
+ * - Display of both old and new email addresses
62
+ * - Revert action button if unauthorized change occurred
63
+ * - Security information and support contact details
64
+ * - Customizable branding and styling
65
+ * - Support for light/dark mode themes
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * <EmailChangedEmail
70
+ * oldEmail="old@example.com"
71
+ * newEmail="new@example.com"
72
+ * revertURL="https://example.com/revert?token=abc123"
73
+ * appName="My App"
74
+ * supportEmail="support@example.com"
75
+ * logoURL="https://example.com/logo.png"
76
+ * darkMode={true}
77
+ * />
78
+ * ```
79
+ */
80
+ export declare const EmailChangedEmail: {
81
+ ({ oldEmail, newEmail, revertURL, appName, supportEmail, logoURL, colors, classNames, darkMode, poweredBy, head, ...props }: EmailChangedEmailProps): import("react/jsx-runtime").JSX.Element;
82
+ localization: {
83
+ YOUR_EMAIL_ADDRESS_HAS_BEEN_CHANGED: string;
84
+ LOGO: string;
85
+ EMAIL_ADDRESS_CHANGED: string;
86
+ EMAIL_ADDRESS_FOR_YOUR_ACCOUNT_CHANGED: string;
87
+ PREVIOUS_EMAIL: string;
88
+ NEW_EMAIL: string;
89
+ IF_YOU_MADE_THIS_CHANGE: string;
90
+ I_DIDNT_MAKE_THIS_CHANGE: string;
91
+ EMAIL_SENT_BY: string;
92
+ IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE: string;
93
+ POWERED_BY_BETTER_AUTH: string;
94
+ };
95
+ PreviewProps: EmailChangedEmailProps;
96
+ };
97
+ export default EmailChangedEmail;
@@ -0,0 +1,70 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Body, Button, Container, Head, Heading, Hr, Html, Img, Link, Preview, pixelBasedPreset, Section, Tailwind, Text } from "@react-email/components";
3
+ import { cn } from "../../lib/utils";
4
+ import { EmailStyles } from "./email-styles";
5
+ const emailChangedEmailLocalization = {
6
+ YOUR_EMAIL_ADDRESS_HAS_BEEN_CHANGED: "Your email address has been changed",
7
+ LOGO: "Logo",
8
+ EMAIL_ADDRESS_CHANGED: "Email address changed",
9
+ EMAIL_ADDRESS_FOR_YOUR_ACCOUNT_CHANGED: "The email address for your {appName} account has been changed.",
10
+ PREVIOUS_EMAIL: "Previous email:",
11
+ NEW_EMAIL: "New email:",
12
+ IF_YOU_MADE_THIS_CHANGE: "If you made this change, you can safely ignore this email.",
13
+ I_DIDNT_MAKE_THIS_CHANGE: "I didn't make this change",
14
+ EMAIL_SENT_BY: "Email sent by {appName}.",
15
+ IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE: "If you didn't authorize this change, please contact support immediately {supportEmail} to secure your account.",
16
+ POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}"
17
+ };
18
+ /**
19
+ * Email template component that notifies users when their email address has been changed.
20
+ *
21
+ * This email includes:
22
+ * - Display of both old and new email addresses
23
+ * - Revert action button if unauthorized change occurred
24
+ * - Security information and support contact details
25
+ * - Customizable branding and styling
26
+ * - Support for light/dark mode themes
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * <EmailChangedEmail
31
+ * oldEmail="old@example.com"
32
+ * newEmail="new@example.com"
33
+ * revertURL="https://example.com/revert?token=abc123"
34
+ * appName="My App"
35
+ * supportEmail="support@example.com"
36
+ * logoURL="https://example.com/logo.png"
37
+ * darkMode={true}
38
+ * />
39
+ * ```
40
+ */
41
+ export const EmailChangedEmail = ({ oldEmail, newEmail, revertURL, appName, supportEmail, logoURL, colors, classNames, darkMode = true, poweredBy, head, ...props }) => {
42
+ const localization = {
43
+ ...EmailChangedEmail.localization,
44
+ ...props.localization
45
+ };
46
+ const previewText = localization.YOUR_EMAIL_ADDRESS_HAS_BEEN_CHANGED;
47
+ return (_jsxs(Html, { children: [_jsxs(Head, { children: [_jsx("meta", { content: "light dark", name: "color-scheme" }), _jsx("meta", { content: "light dark", name: "supported-color-schemes" }), _jsx(EmailStyles, { colors: colors, darkMode: darkMode }), head] }), _jsx(Preview, { children: previewText }), _jsx(Tailwind, { config: { presets: [pixelBasedPreset] }, children: _jsx(Body, { className: cn("bg-background font-sans", classNames?.body), children: _jsx(Container, { className: cn("mx-auto my-auto max-w-xl px-2 py-10", classNames?.container), children: _jsxs(Section, { className: cn("bg-card text-card-foreground rounded-none border border-border p-8", classNames?.card), children: [logoURL &&
48
+ (typeof logoURL === "string" ? (_jsx(Img, { src: logoURL, width: 48, height: 48, alt: appName || localization.LOGO, className: cn("mx-auto mb-8", classNames?.logo) })) : (_jsxs(_Fragment, { children: [_jsx(Img, { src: logoURL.light, width: 48, height: 48, alt: appName || localization.LOGO, className: cn("mx-auto mb-8 logo-light", classNames?.logo) }), _jsx(Img, { src: logoURL.dark, width: 48, height: 48, alt: appName || localization.LOGO, className: cn("hidden mx-auto mb-8 logo-dark", classNames?.logo) })] }))), _jsx(Heading, { className: cn("m-0 mb-5 text-2xl font-semibold", classNames?.title), children: localization.EMAIL_ADDRESS_CHANGED }), _jsx(Text, { className: cn("text-sm font-normal", classNames?.content), children: localization.EMAIL_ADDRESS_FOR_YOUR_ACCOUNT_CHANGED.replace("{appName}", appName || "")
49
+ .replace(/\s{2,}/g, " ")
50
+ .replace(" .", ".") }), (oldEmail || newEmail) && (_jsxs(Section, { className: cn("my-6 border border-border bg-muted p-4", classNames?.codeBlock), children: [oldEmail && (_jsxs(_Fragment, { children: [_jsx(Text, { className: cn("m-0 mb-2 text-xs text-muted-foreground", classNames?.description), children: localization.PREVIOUS_EMAIL }), _jsx(Text, { className: cn("m-0 mb-4 text-sm font-semibold", classNames?.content), children: oldEmail })] })), newEmail && (_jsxs(_Fragment, { children: [_jsx(Text, { className: cn("m-0 mb-2 text-xs text-muted-foreground", classNames?.description), children: localization.NEW_EMAIL }), _jsx(Text, { className: cn("m-0 text-sm font-semibold text-primary", classNames?.content), children: newEmail })] }))] })), _jsx(Text, { className: cn("text-sm font-normal", classNames?.content), children: localization.IF_YOU_MADE_THIS_CHANGE }), revertURL && (_jsx(Section, { className: "my-6", children: _jsx(Button, { href: revertURL, className: cn("inline-block whitespace-nowrap rounded-none text-sm font-medium py-2.5 px-6 bg-primary text-primary-foreground no-underline", classNames?.button), children: localization.I_DIDNT_MAKE_THIS_CHANGE }) })), _jsx(Hr, { className: cn("my-6 w-full border border-solid border-border", classNames?.separator) }), appName && (_jsx(Text, { className: cn("mb-3 text-xs text-muted-foreground", classNames?.description), children: localization.EMAIL_SENT_BY.replace("{appName}", appName) })), _jsx(Text, { className: cn("mt-3 text-xs text-muted-foreground", classNames?.description), children: (() => {
51
+ const [beforeSupportEmail, afterSupportEmail] = localization.IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE.split("{supportEmail}");
52
+ return supportEmail ? (_jsxs(_Fragment, { children: [beforeSupportEmail, _jsx(Link, { href: `mailto:${supportEmail}`, className: cn("text-primary underline", classNames?.link), children: supportEmail }), afterSupportEmail] })) : (localization.IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE.replace("{supportEmail}", "")
53
+ .replace(/\s{2,}/g, " ")
54
+ .replace(" .", "."));
55
+ })() }), poweredBy && (_jsx(Text, { className: cn("mt-4 mb-0 text-center text-[11px] text-muted-foreground", classNames?.poweredBy), children: (() => {
56
+ const [beforeBetterAuth, afterBetterAuth] = localization.POWERED_BY_BETTER_AUTH.split("{betterAuth}");
57
+ return (_jsxs(_Fragment, { children: [beforeBetterAuth, _jsx(Link, { href: "https://better-auth.com", className: cn("text-primary underline", classNames?.link), children: "better-auth" }), afterBetterAuth] }));
58
+ })() }))] }) }) }) })] }));
59
+ };
60
+ EmailChangedEmail.localization = emailChangedEmailLocalization;
61
+ EmailChangedEmail.PreviewProps = {
62
+ oldEmail: "old@example.com",
63
+ newEmail: "new@example.com",
64
+ supportEmail: "support@example.com",
65
+ revertURL: "https://better-auth-ui.com/auth/revert-email?token=example-token",
66
+ appName: "Better Auth",
67
+ poweredBy: true,
68
+ darkMode: true
69
+ };
70
+ export default EmailChangedEmail;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Aggregated localization strings for all email components.
3
+ *
4
+ * Combines localization strings from all email templates (EmailChangedEmail,
5
+ * EmailVerificationEmail, MagicLinkEmail, NewDeviceEmail, OtpEmail,
6
+ * PasswordChangedEmail, ResetPasswordEmail) into a single object for convenient
7
+ * bulk customization.
8
+ */
9
+ export declare const emailLocalization: {
10
+ RESET_YOUR_PASSWORD: string;
11
+ LOGO: string;
12
+ WE_RECEIVED_REQUEST_TO_RESET_PASSWORD: string;
13
+ RESET_PASSWORD: string;
14
+ OR_COPY_AND_PASTE_URL: string;
15
+ THIS_LINK_EXPIRES_IN_MINUTES: string;
16
+ EMAIL_SENT_BY: string;
17
+ IF_YOU_DIDNT_REQUEST_PASSWORD_RESET: string;
18
+ POWERED_BY_BETTER_AUTH: string;
19
+ YOUR_PASSWORD_HAS_BEEN_CHANGED: string;
20
+ PASSWORD_CHANGED_SUCCESSFULLY: string;
21
+ PASSWORD_FOR_YOUR_ACCOUNT_CHANGED: string;
22
+ CHANGED_AT: string;
23
+ IF_YOU_MADE_THIS_CHANGE: string;
24
+ I_DIDNT_MAKE_THIS_CHANGE: string;
25
+ IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE: string;
26
+ YOUR_VERIFICATION_CODE_IS_CODE: string;
27
+ VERIFY_YOUR_EMAIL: string;
28
+ WE_NEED_TO_VERIFY_YOUR_EMAIL_ADDRESS: string;
29
+ THIS_CODE_EXPIRES_IN_MINUTES: string;
30
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL: string;
31
+ NEW_SIGN_IN_DETECTED: string;
32
+ NEW_SIGN_IN_TO_YOUR_ACCOUNT: string;
33
+ DEVICE_DETAILS: string;
34
+ BROWSER: string;
35
+ OPERATING_SYSTEM: string;
36
+ LOCATION: string;
37
+ IP_ADDRESS: string;
38
+ TIME: string;
39
+ IF_THIS_WAS_YOU: string;
40
+ SECURE_MY_ACCOUNT: string;
41
+ IF_YOU_DIDNT_SIGN_IN: string;
42
+ SIGN_IN_TO_APP_NAME: string;
43
+ SIGN_IN_TO_YOUR_ACCOUNT: string;
44
+ YOUR_ACCOUNT: string;
45
+ CLICK_BUTTON_TO_SIGN_IN: string;
46
+ VERIFY_YOUR_EMAIL_ADDRESS: string;
47
+ CLICK_BUTTON_TO_VERIFY_EMAIL: string;
48
+ VERIFY_EMAIL_ADDRESS: string;
49
+ YOUR_EMAIL_ADDRESS_HAS_BEEN_CHANGED: string;
50
+ EMAIL_ADDRESS_CHANGED: string;
51
+ EMAIL_ADDRESS_FOR_YOUR_ACCOUNT_CHANGED: string;
52
+ PREVIOUS_EMAIL: string;
53
+ NEW_EMAIL: string;
54
+ };
55
+ /**
56
+ * Type representing all available email localization strings.
57
+ *
58
+ * Derived from the emailLocalization constant, this type can be used for
59
+ * type-safe localization overrides across all email templates.
60
+ */
61
+ export type EmailLocalization = typeof emailLocalization;
@@ -0,0 +1,24 @@
1
+ import EmailChangedEmail from "./email-changed";
2
+ import EmailVerificationEmail from "./email-verification";
3
+ import MagicLinkEmail from "./magic-link";
4
+ import NewDeviceEmail from "./new-device";
5
+ import OtpEmail from "./otp-email";
6
+ import PasswordChangedEmail from "./password-changed";
7
+ import ResetPasswordEmail from "./reset-password";
8
+ /**
9
+ * Aggregated localization strings for all email components.
10
+ *
11
+ * Combines localization strings from all email templates (EmailChangedEmail,
12
+ * EmailVerificationEmail, MagicLinkEmail, NewDeviceEmail, OtpEmail,
13
+ * PasswordChangedEmail, ResetPasswordEmail) into a single object for convenient
14
+ * bulk customization.
15
+ */
16
+ export const emailLocalization = {
17
+ ...EmailChangedEmail.localization,
18
+ ...EmailVerificationEmail.localization,
19
+ ...MagicLinkEmail.localization,
20
+ ...NewDeviceEmail.localization,
21
+ ...OtpEmail.localization,
22
+ ...PasswordChangedEmail.localization,
23
+ ...ResetPasswordEmail.localization
24
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Default color scheme for email templates in light and dark modes.
3
+ *
4
+ * Provides a consistent color palette that can be customized via the EmailColors type.
5
+ */
6
+ export declare const defaultColors: {
7
+ light: {
8
+ background: string;
9
+ border: string;
10
+ card: string;
11
+ cardForeground: string;
12
+ foreground: string;
13
+ muted: string;
14
+ mutedForeground: string;
15
+ primary: string;
16
+ primaryForeground: string;
17
+ };
18
+ dark: {
19
+ background: string;
20
+ border: string;
21
+ card: string;
22
+ cardForeground: string;
23
+ foreground: string;
24
+ muted: string;
25
+ mutedForeground: string;
26
+ primary: string;
27
+ primaryForeground: string;
28
+ };
29
+ };
30
+ /**
31
+ * Custom CSS class names for styling different parts of email templates.
32
+ *
33
+ * Allows fine-grained control over the appearance of email components.
34
+ */
35
+ export type EmailClassNames = {
36
+ body?: string;
37
+ container?: string;
38
+ card?: string;
39
+ logo?: string;
40
+ title?: string;
41
+ content?: string;
42
+ button?: string;
43
+ description?: string;
44
+ separator?: string;
45
+ link?: string;
46
+ poweredBy?: string;
47
+ codeBlock?: string;
48
+ };
49
+ /**
50
+ * Custom color scheme configuration for email templates.
51
+ *
52
+ * Supports separate color definitions for light and dark modes.
53
+ * Any color not specified will fall back to the defaultColors values.
54
+ */
55
+ export type EmailColors = {
56
+ light?: Partial<typeof defaultColors.light>;
57
+ dark?: Partial<typeof defaultColors.dark>;
58
+ };
59
+ /**
60
+ * Props for the EmailStyles component.
61
+ */
62
+ interface EmailStylesProps {
63
+ /** Custom color scheme for light and dark modes */
64
+ colors?: EmailColors;
65
+ /** Whether to enable dark mode support */
66
+ darkMode?: boolean;
67
+ }
68
+ /**
69
+ * Component that injects CSS styles for email templates with support for light and dark modes.
70
+ *
71
+ * Generates inline styles that adapt to the user's color scheme preference and applies
72
+ * custom colors if provided. Handles logo visibility switching between light and dark modes.
73
+ *
74
+ * @param props - Style configuration options
75
+ * @returns A style element containing CSS for email template theming
76
+ *
77
+ * @example
78
+ * ```tsx
79
+ * <EmailStyles
80
+ * colors={{
81
+ * light: { primary: "#000000" },
82
+ * dark: { primary: "#FFFFFF" }
83
+ * }}
84
+ * darkMode={true}
85
+ * />
86
+ * ```
87
+ */
88
+ export declare const EmailStyles: ({ colors, darkMode }: EmailStylesProps) => import("react/jsx-runtime").JSX.Element;
89
+ export default EmailStyles;
@@ -0,0 +1,129 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Default color scheme for email templates in light and dark modes.
4
+ *
5
+ * Provides a consistent color palette that can be customized via the EmailColors type.
6
+ */
7
+ export const defaultColors = {
8
+ light: {
9
+ background: "#F5F5F5",
10
+ border: "#E5E5E5",
11
+ card: "#FFFFFF",
12
+ cardForeground: "#0A0A0A",
13
+ foreground: "#262626",
14
+ muted: "#F5F5F5",
15
+ mutedForeground: "#737373",
16
+ primary: "#171717",
17
+ primaryForeground: "#FAFAFA"
18
+ },
19
+ dark: {
20
+ background: "#0A0A0A",
21
+ border: "#2E2E2E",
22
+ card: "#171717",
23
+ cardForeground: "#FAFAFA",
24
+ foreground: "#D4D4D4",
25
+ muted: "#212121",
26
+ mutedForeground: "#A1A1A1",
27
+ primary: "#E5E5E5",
28
+ primaryForeground: "#171717"
29
+ }
30
+ };
31
+ /**
32
+ * Component that injects CSS styles for email templates with support for light and dark modes.
33
+ *
34
+ * Generates inline styles that adapt to the user's color scheme preference and applies
35
+ * custom colors if provided. Handles logo visibility switching between light and dark modes.
36
+ *
37
+ * @param props - Style configuration options
38
+ * @returns A style element containing CSS for email template theming
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * <EmailStyles
43
+ * colors={{
44
+ * light: { primary: "#000000" },
45
+ * dark: { primary: "#FFFFFF" }
46
+ * }}
47
+ * darkMode={true}
48
+ * />
49
+ * ```
50
+ */
51
+ export const EmailStyles = ({ colors, darkMode = true }) => {
52
+ return (_jsx("style", { type: "text/css", children: `
53
+ .bg-background {
54
+ background-color: ${colors?.light?.background || defaultColors.light.background} !important;
55
+ }
56
+ .bg-card {
57
+ background-color: ${colors?.light?.card || defaultColors.light.card} !important;
58
+ }
59
+ .bg-primary {
60
+ background-color: ${colors?.light?.primary || defaultColors.light.primary} !important;
61
+ }
62
+ .bg-muted {
63
+ background-color: ${colors?.light?.muted || defaultColors.light.muted} !important;
64
+ }
65
+ .border-border {
66
+ border-color: ${colors?.light?.border || defaultColors.light.border} !important;
67
+ }
68
+ .text-card-foreground {
69
+ color: ${colors?.light?.cardForeground || defaultColors.light.cardForeground} !important;
70
+ }
71
+ .text-muted-foreground {
72
+ color: ${colors?.light?.mutedForeground || defaultColors.light.mutedForeground} !important;
73
+ }
74
+ .text-primary {
75
+ color: ${colors?.light?.primary || defaultColors.light.primary} !important;
76
+ }
77
+ .text-primary-foreground {
78
+ color: ${colors?.light?.primaryForeground || defaultColors.light.primaryForeground} !important;
79
+ }
80
+ .logo-dark {
81
+ display: none !important;
82
+ }
83
+ .logo-light {
84
+ display: block !important;
85
+ }
86
+
87
+ ${darkMode
88
+ ? `@media (prefers-color-scheme: dark) {
89
+ .bg-background {
90
+ background-color: ${colors?.dark?.background || defaultColors.dark.background} !important;
91
+ }
92
+ .bg-card {
93
+ background-color: ${colors?.dark?.card || defaultColors.dark.card} !important;
94
+ }
95
+ .bg-primary {
96
+ background-color: ${colors?.dark?.primary || defaultColors.dark.primary} !important;
97
+ }
98
+ .bg-muted {
99
+ background-color: ${colors?.dark?.muted || defaultColors.dark.muted} !important;
100
+ }
101
+ .border-border {
102
+ border-color: ${colors?.dark?.border || defaultColors.dark.border} !important;
103
+ }
104
+ .text-card-foreground {
105
+ color: ${colors?.dark?.cardForeground || defaultColors.dark.cardForeground} !important;
106
+ }
107
+ .text-muted-foreground {
108
+ color: ${colors?.dark?.mutedForeground || defaultColors.dark.mutedForeground} !important;
109
+ }
110
+ .text-primary {
111
+ color: ${colors?.dark?.primary || defaultColors.dark.primary} !important;
112
+ }
113
+ .text-primary-foreground {
114
+ color: ${colors?.dark?.primaryForeground || defaultColors.dark.primaryForeground} !important;
115
+ }
116
+ .logo-dark {
117
+ display: block !important;
118
+ }
119
+ .logo-light {
120
+ display: none !important;
121
+ }
122
+ * {
123
+ box-shadow: none !important;
124
+ }
125
+ }`
126
+ : ""}
127
+ ` }));
128
+ };
129
+ export default EmailStyles;
@@ -0,0 +1,97 @@
1
+ import type { ReactNode } from "react";
2
+ import { type EmailClassNames, type EmailColors } from "./email-styles";
3
+ declare const emailVerificationEmailLocalization: {
4
+ VERIFY_YOUR_EMAIL_ADDRESS: string;
5
+ LOGO: string;
6
+ CLICK_BUTTON_TO_VERIFY_EMAIL: string;
7
+ VERIFY_EMAIL_ADDRESS: string;
8
+ OR_COPY_AND_PASTE_URL: string;
9
+ THIS_LINK_EXPIRES_IN_MINUTES: string;
10
+ EMAIL_SENT_BY: string;
11
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL: string;
12
+ POWERED_BY_BETTER_AUTH: string;
13
+ };
14
+ /**
15
+ * Localization strings for the EmailVerificationEmail component.
16
+ *
17
+ * Contains all text content used in the email verification email template.
18
+ */
19
+ export type EmailVerificationEmailLocalization = typeof emailVerificationEmailLocalization;
20
+ /**
21
+ * Props for the EmailVerificationEmail component.
22
+ */
23
+ export interface EmailVerificationEmailProps {
24
+ /** Verification URL that users must click to verify their email */
25
+ url: string;
26
+ /** Email address being verified */
27
+ email?: string;
28
+ /** Name of the application sending the email */
29
+ appName?: string;
30
+ /** Number of minutes until the verification link expires */
31
+ expirationMinutes?: number;
32
+ /** Logo URL(s) - a single string or light/dark variants. If omitted, no logo is shown. */
33
+ logoURL?: string | {
34
+ light: string;
35
+ dark: string;
36
+ };
37
+ /** Custom CSS class names for styling specific parts of the email */
38
+ classNames?: EmailClassNames;
39
+ /** Custom color scheme for light and dark modes */
40
+ colors?: EmailColors;
41
+ /** Whether to show the "Powered by better-auth" footer */
42
+ poweredBy?: boolean;
43
+ /** Whether to enable dark mode support */
44
+ darkMode?: boolean;
45
+ /** Additional React nodes to inject into the email head */
46
+ head?: ReactNode;
47
+ /**
48
+ * Localization overrides for customizing email text
49
+ * @remarks `EmailVerificationEmailLocalization`
50
+ */
51
+ localization?: Partial<EmailVerificationEmailLocalization>;
52
+ }
53
+ /**
54
+ * Email template component that sends email verification links to users.
55
+ *
56
+ * This email includes:
57
+ * - Verification button and fallback URL
58
+ * - Expiration time information
59
+ * - Security notice for unauthorized requests
60
+ * - Customizable branding and styling
61
+ * - Support for light/dark mode themes
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * <EmailVerificationEmail
66
+ * url="https://example.com/verify?token=abc123"
67
+ * email="user@example.com"
68
+ * appName="My App"
69
+ * expirationMinutes={60}
70
+ * logoURL="https://example.com/logo.png"
71
+ * darkMode={true}
72
+ * />
73
+ * ```
74
+ */
75
+ export declare const EmailVerificationEmail: {
76
+ ({ url, email, appName, expirationMinutes, logoURL, colors, classNames, darkMode, poweredBy, head, ...props }: EmailVerificationEmailProps): import("react/jsx-runtime").JSX.Element;
77
+ /**
78
+ * Default localization strings for the email verification template.
79
+ * Can be overridden via the `localization` prop.
80
+ */
81
+ localization: {
82
+ VERIFY_YOUR_EMAIL_ADDRESS: string;
83
+ LOGO: string;
84
+ CLICK_BUTTON_TO_VERIFY_EMAIL: string;
85
+ VERIFY_EMAIL_ADDRESS: string;
86
+ OR_COPY_AND_PASTE_URL: string;
87
+ THIS_LINK_EXPIRES_IN_MINUTES: string;
88
+ EMAIL_SENT_BY: string;
89
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL: string;
90
+ POWERED_BY_BETTER_AUTH: string;
91
+ };
92
+ /**
93
+ * Example props for previewing the email template in development.
94
+ */
95
+ PreviewProps: EmailVerificationEmailProps;
96
+ };
97
+ export default EmailVerificationEmail;