@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.
- package/dist/components/auth/auth-provider.d.ts +32 -0
- package/dist/components/auth/auth-provider.js +44 -0
- package/dist/components/email/email-changed.d.ts +97 -0
- package/dist/components/email/email-changed.js +70 -0
- package/dist/components/email/email-localization.d.ts +61 -0
- package/dist/components/email/email-localization.js +24 -0
- package/dist/components/email/email-styles.d.ts +89 -0
- package/dist/components/email/email-styles.js +129 -0
- package/dist/components/email/email-verification.d.ts +97 -0
- package/dist/components/email/email-verification.js +75 -0
- package/dist/components/email/index.d.ts +9 -0
- package/dist/components/email/index.js +9 -0
- package/dist/components/email/magic-link.d.ts +93 -0
- package/dist/components/email/magic-link.js +72 -0
- package/dist/components/email/new-device.d.ts +123 -0
- package/dist/components/email/new-device.js +90 -0
- package/dist/components/email/otp-email.d.ts +88 -0
- package/dist/components/email/otp-email.js +65 -0
- package/dist/components/email/password-changed.d.ts +96 -0
- package/dist/components/email/password-changed.js +76 -0
- package/dist/components/email/reset-password.d.ts +90 -0
- package/dist/components/email/reset-password.js +68 -0
- package/dist/components/icons/apple.d.ts +8 -0
- package/dist/components/icons/apple.js +10 -0
- package/dist/components/icons/atlassian.d.ts +10 -0
- package/dist/components/icons/atlassian.js +14 -0
- package/dist/components/icons/cognito.d.ts +8 -0
- package/dist/components/icons/cognito.js +10 -0
- package/dist/components/icons/discord.d.ts +8 -0
- package/dist/components/icons/discord.js +10 -0
- package/dist/components/icons/dropbox.d.ts +8 -0
- package/dist/components/icons/dropbox.js +10 -0
- package/dist/components/icons/facebook.d.ts +10 -0
- package/dist/components/icons/facebook.js +12 -0
- package/dist/components/icons/figma.d.ts +11 -0
- package/dist/components/icons/figma.js +13 -0
- package/dist/components/icons/github.d.ts +10 -0
- package/dist/components/icons/github.js +12 -0
- package/dist/components/icons/gitlab.d.ts +8 -0
- package/dist/components/icons/gitlab.js +10 -0
- package/dist/components/icons/google.d.ts +8 -0
- package/dist/components/icons/google.js +10 -0
- package/dist/components/icons/huggingface.d.ts +8 -0
- package/dist/components/icons/huggingface.js +10 -0
- package/dist/components/icons/index.d.ts +35 -0
- package/dist/components/icons/index.js +35 -0
- package/dist/components/icons/kakao.d.ts +10 -0
- package/dist/components/icons/kakao.js +12 -0
- package/dist/components/icons/kick.d.ts +10 -0
- package/dist/components/icons/kick.js +12 -0
- package/dist/components/icons/line.d.ts +8 -0
- package/dist/components/icons/line.js +10 -0
- package/dist/components/icons/linear.d.ts +8 -0
- package/dist/components/icons/linear.js +10 -0
- package/dist/components/icons/linkedin.d.ts +8 -0
- package/dist/components/icons/linkedin.js +10 -0
- package/dist/components/icons/microsoft.d.ts +8 -0
- package/dist/components/icons/microsoft.js +10 -0
- package/dist/components/icons/naver.d.ts +8 -0
- package/dist/components/icons/naver.js +10 -0
- package/dist/components/icons/notion.d.ts +8 -0
- package/dist/components/icons/notion.js +10 -0
- package/dist/components/icons/paybin.d.ts +7 -0
- package/dist/components/icons/paybin.js +9 -0
- package/dist/components/icons/paypal.d.ts +8 -0
- package/dist/components/icons/paypal.js +10 -0
- package/dist/components/icons/polar.d.ts +8 -0
- package/dist/components/icons/polar.js +10 -0
- package/dist/components/icons/railway.d.ts +8 -0
- package/dist/components/icons/railway.js +10 -0
- package/dist/components/icons/reddit.d.ts +8 -0
- package/dist/components/icons/reddit.js +10 -0
- package/dist/components/icons/roblox.d.ts +11 -0
- package/dist/components/icons/roblox.js +13 -0
- package/dist/components/icons/salesforce.d.ts +8 -0
- package/dist/components/icons/salesforce.js +10 -0
- package/dist/components/icons/slack.d.ts +8 -0
- package/dist/components/icons/slack.js +10 -0
- package/dist/components/icons/spotify.d.ts +8 -0
- package/dist/components/icons/spotify.js +10 -0
- package/dist/components/icons/tiktok.d.ts +9 -0
- package/dist/components/icons/tiktok.js +11 -0
- package/dist/components/icons/twitch.d.ts +8 -0
- package/dist/components/icons/twitch.js +13 -0
- package/dist/components/icons/vercel.d.ts +8 -0
- package/dist/components/icons/vercel.js +10 -0
- package/dist/components/icons/vk.d.ts +8 -0
- package/dist/components/icons/vk.js +10 -0
- package/dist/components/icons/wechat.d.ts +8 -0
- package/dist/components/icons/wechat.js +10 -0
- package/dist/components/icons/x.d.ts +8 -0
- package/dist/components/icons/x.js +10 -0
- package/dist/components/icons/zoom.d.ts +8 -0
- package/dist/components/icons/zoom.js +12 -0
- package/dist/components/settings/account/theme-preview.d.ts +3 -0
- package/dist/components/settings/account/theme-preview.js +10 -0
- package/dist/core.d.ts +1 -0
- package/dist/core.js +1 -0
- package/dist/hooks/auth/use-auth-mutation.d.ts +18 -0
- package/dist/hooks/auth/use-auth-mutation.js +10 -0
- package/dist/hooks/auth/use-auth-query.d.ts +24 -0
- package/dist/hooks/auth/use-auth-query.js +10 -0
- package/dist/hooks/auth/use-authenticate.d.ts +9 -0
- package/dist/hooks/auth/use-authenticate.js +28 -0
- package/dist/hooks/auth/use-forgot-password.d.ts +20 -0
- package/dist/hooks/auth/use-forgot-password.js +14 -0
- package/dist/hooks/auth/use-request-password-reset.d.ts +26 -0
- package/dist/hooks/auth/use-request-password-reset.js +14 -0
- package/dist/hooks/auth/use-reset-password.d.ts +40 -0
- package/dist/hooks/auth/use-reset-password.js +13 -0
- package/dist/hooks/auth/use-send-verification-email.d.ts +24 -0
- package/dist/hooks/auth/use-send-verification-email.js +13 -0
- package/dist/hooks/auth/use-session.d.ts +9 -0
- package/dist/hooks/auth/use-session.js +18 -0
- package/dist/hooks/auth/use-sign-in-email.d.ts +53 -0
- package/dist/hooks/auth/use-sign-in-email.js +24 -0
- package/dist/hooks/auth/use-sign-in-magic-link.d.ts +32 -0
- package/dist/hooks/auth/use-sign-in-magic-link.js +13 -0
- package/dist/hooks/auth/use-sign-in-social.d.ts +93 -0
- package/dist/hooks/auth/use-sign-in-social.js +13 -0
- package/dist/hooks/auth/use-sign-out.d.ts +19 -0
- package/dist/hooks/auth/use-sign-out.js +24 -0
- package/dist/hooks/auth/use-sign-up-email.d.ts +526 -0
- package/dist/hooks/auth/use-sign-up-email.js +24 -0
- package/dist/hooks/auth/use-user.d.ts +513 -0
- package/dist/hooks/auth/use-user.js +14 -0
- package/dist/hooks/settings/use-account-info.d.ts +17 -0
- package/dist/hooks/settings/use-account-info.js +25 -0
- package/dist/hooks/settings/use-change-email.d.ts +24 -0
- package/dist/hooks/settings/use-change-email.js +23 -0
- package/dist/hooks/settings/use-change-password.d.ts +54 -0
- package/dist/hooks/settings/use-change-password.js +11 -0
- package/dist/hooks/settings/use-delete-user.d.ts +42 -0
- package/dist/hooks/settings/use-delete-user.js +11 -0
- package/dist/hooks/settings/use-link-social.d.ts +46 -0
- package/dist/hooks/settings/use-link-social.js +10 -0
- package/dist/hooks/settings/use-list-accounts.d.ts +20 -0
- package/dist/hooks/settings/use-list-accounts.js +23 -0
- package/dist/hooks/settings/use-list-device-sessions.d.ts +11 -0
- package/dist/hooks/settings/use-list-device-sessions.js +22 -0
- package/dist/hooks/settings/use-list-sessions.d.ts +20 -0
- package/dist/hooks/settings/use-list-sessions.js +22 -0
- package/dist/hooks/settings/use-revoke-multi-session.d.ts +19 -0
- package/dist/hooks/settings/use-revoke-multi-session.js +20 -0
- package/dist/hooks/settings/use-revoke-session.d.ts +19 -0
- package/dist/hooks/settings/use-revoke-session.js +21 -0
- package/dist/hooks/settings/use-set-active-session.d.ts +37 -0
- package/dist/hooks/settings/use-set-active-session.js +28 -0
- package/dist/hooks/settings/use-unlink-account.d.ts +21 -0
- package/dist/hooks/settings/use-unlink-account.js +21 -0
- package/dist/hooks/settings/use-update-user.d.ts +11 -0
- package/dist/hooks/settings/use-update-user.js +29 -0
- package/dist/hooks/use-hydrated.d.ts +6 -0
- package/dist/hooks/use-hydrated.js +18 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +33 -0
- package/dist/lib/auth-client.d.ts +1979 -0
- package/dist/lib/auth-client.js +5 -0
- package/dist/lib/auth-config.d.ts +43 -0
- package/dist/lib/auth-config.js +1 -0
- package/dist/lib/auth-context.d.ts +2 -0
- package/dist/lib/auth-context.js +3 -0
- package/dist/lib/auth-hook-options.d.ts +8 -0
- package/dist/lib/auth-hook-options.js +1 -0
- package/dist/lib/provider-icons.d.ts +13 -0
- package/dist/lib/provider-icons.js +48 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/package.json +64 -0
- package/src/components/auth/auth-provider.tsx +82 -0
- package/src/components/email/email-changed.tsx +381 -0
- package/src/components/email/email-localization.tsx +33 -0
- package/src/components/email/email-styles.tsx +175 -0
- package/src/components/email/email-verification.tsx +350 -0
- package/src/components/email/index.ts +9 -0
- package/src/components/email/magic-link.tsx +349 -0
- package/src/components/email/new-device.tsx +452 -0
- package/src/components/email/otp-email.tsx +321 -0
- package/src/components/email/password-changed.tsx +380 -0
- package/src/components/email/reset-password.tsx +343 -0
- package/src/components/icons/apple.tsx +24 -0
- package/src/components/icons/atlassian.tsx +43 -0
- package/src/components/icons/cognito.tsx +25 -0
- package/src/components/icons/discord.tsx +24 -0
- package/src/components/icons/dropbox.tsx +24 -0
- package/src/components/icons/facebook.tsx +30 -0
- package/src/components/icons/figma.tsx +43 -0
- package/src/components/icons/github.tsx +26 -0
- package/src/components/icons/gitlab.tsx +36 -0
- package/src/components/icons/google.tsx +42 -0
- package/src/components/icons/huggingface.tsx +44 -0
- package/src/components/icons/index.ts +35 -0
- package/src/components/icons/kakao.tsx +26 -0
- package/src/components/icons/kick.tsx +30 -0
- package/src/components/icons/line.tsx +24 -0
- package/src/components/icons/linear.tsx +24 -0
- package/src/components/icons/linkedin.tsx +28 -0
- package/src/components/icons/microsoft.tsx +24 -0
- package/src/components/icons/naver.tsx +24 -0
- package/src/components/icons/notion.tsx +25 -0
- package/src/components/icons/paybin.tsx +37 -0
- package/src/components/icons/paypal.tsx +36 -0
- package/src/components/icons/polar.tsx +31 -0
- package/src/components/icons/railway.tsx +24 -0
- package/src/components/icons/reddit.tsx +25 -0
- package/src/components/icons/roblox.tsx +28 -0
- package/src/components/icons/salesforce.tsx +24 -0
- package/src/components/icons/slack.tsx +36 -0
- package/src/components/icons/spotify.tsx +24 -0
- package/src/components/icons/tiktok.tsx +32 -0
- package/src/components/icons/twitch.tsx +50 -0
- package/src/components/icons/vercel.tsx +21 -0
- package/src/components/icons/vk.tsx +24 -0
- package/src/components/icons/wechat.tsx +24 -0
- package/src/components/icons/x.tsx +24 -0
- package/src/components/icons/zoom.tsx +48 -0
- package/src/components/settings/account/theme-preview.tsx +271 -0
- package/src/core.ts +1 -0
- package/src/hooks/auth/use-auth-mutation.ts +56 -0
- package/src/hooks/auth/use-auth-query.ts +50 -0
- package/src/hooks/auth/use-authenticate.ts +35 -0
- package/src/hooks/auth/use-request-password-reset.ts +24 -0
- package/src/hooks/auth/use-reset-password.ts +23 -0
- package/src/hooks/auth/use-send-verification-email.ts +23 -0
- package/src/hooks/auth/use-session.ts +26 -0
- package/src/hooks/auth/use-sign-in-email.ts +35 -0
- package/src/hooks/auth/use-sign-in-magic-link.ts +23 -0
- package/src/hooks/auth/use-sign-in-social.ts +23 -0
- package/src/hooks/auth/use-sign-out.ts +34 -0
- package/src/hooks/auth/use-sign-up-email.ts +35 -0
- package/src/hooks/auth/use-user.ts +21 -0
- package/src/hooks/settings/use-account-info.ts +30 -0
- package/src/hooks/settings/use-change-email.ts +33 -0
- package/src/hooks/settings/use-change-password.ts +21 -0
- package/src/hooks/settings/use-delete-user.ts +21 -0
- package/src/hooks/settings/use-link-social.ts +19 -0
- package/src/hooks/settings/use-list-accounts.ts +27 -0
- package/src/hooks/settings/use-list-device-sessions.ts +32 -0
- package/src/hooks/settings/use-list-sessions.ts +26 -0
- package/src/hooks/settings/use-revoke-multi-session.ts +30 -0
- package/src/hooks/settings/use-revoke-session.ts +31 -0
- package/src/hooks/settings/use-set-active-session.ts +46 -0
- package/src/hooks/settings/use-unlink-account.ts +31 -0
- package/src/hooks/settings/use-update-user.ts +44 -0
- package/src/index.ts +34 -0
- package/src/lib/auth-client.ts +37 -0
- package/src/lib/auth-config.ts +48 -0
- package/src/lib/auth-context.ts +6 -0
- package/src/lib/provider-icons.ts +90 -0
- package/src/lib/utils.ts +6 -0
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
/**
|
|
10
|
+
* Aggregated localization strings for all email components.
|
|
11
|
+
*
|
|
12
|
+
* Combines localization strings from all email templates (EmailChangedEmail,
|
|
13
|
+
* EmailVerificationEmail, MagicLinkEmail, NewDeviceEmail, OtpEmail,
|
|
14
|
+
* PasswordChangedEmail, ResetPasswordEmail) into a single object for convenient
|
|
15
|
+
* bulk customization.
|
|
16
|
+
*/
|
|
17
|
+
export const emailLocalization = {
|
|
18
|
+
...EmailChangedEmail.localization,
|
|
19
|
+
...EmailVerificationEmail.localization,
|
|
20
|
+
...MagicLinkEmail.localization,
|
|
21
|
+
...NewDeviceEmail.localization,
|
|
22
|
+
...OtpEmail.localization,
|
|
23
|
+
...PasswordChangedEmail.localization,
|
|
24
|
+
...ResetPasswordEmail.localization
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Type representing all available email localization strings.
|
|
29
|
+
*
|
|
30
|
+
* Derived from the emailLocalization constant, this type can be used for
|
|
31
|
+
* type-safe localization overrides across all email templates.
|
|
32
|
+
*/
|
|
33
|
+
export type EmailLocalization = typeof emailLocalization
|
|
@@ -0,0 +1,175 @@
|
|
|
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 const defaultColors = {
|
|
7
|
+
light: {
|
|
8
|
+
background: "#F5F5F5",
|
|
9
|
+
border: "#E5E5E5",
|
|
10
|
+
card: "#FFFFFF",
|
|
11
|
+
cardForeground: "#0A0A0A",
|
|
12
|
+
foreground: "#262626",
|
|
13
|
+
muted: "#F5F5F5",
|
|
14
|
+
mutedForeground: "#737373",
|
|
15
|
+
primary: "#171717",
|
|
16
|
+
primaryForeground: "#FAFAFA"
|
|
17
|
+
},
|
|
18
|
+
dark: {
|
|
19
|
+
background: "#0A0A0A",
|
|
20
|
+
border: "#2E2E2E",
|
|
21
|
+
card: "#171717",
|
|
22
|
+
cardForeground: "#FAFAFA",
|
|
23
|
+
foreground: "#D4D4D4",
|
|
24
|
+
muted: "#212121",
|
|
25
|
+
mutedForeground: "#A1A1A1",
|
|
26
|
+
primary: "#E5E5E5",
|
|
27
|
+
primaryForeground: "#171717"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Custom CSS class names for styling different parts of email templates.
|
|
33
|
+
*
|
|
34
|
+
* Allows fine-grained control over the appearance of email components.
|
|
35
|
+
*/
|
|
36
|
+
export type EmailClassNames = {
|
|
37
|
+
body?: string
|
|
38
|
+
container?: string
|
|
39
|
+
card?: string
|
|
40
|
+
logo?: string
|
|
41
|
+
title?: string
|
|
42
|
+
content?: string
|
|
43
|
+
button?: string
|
|
44
|
+
description?: string
|
|
45
|
+
separator?: string
|
|
46
|
+
link?: string
|
|
47
|
+
poweredBy?: string
|
|
48
|
+
codeBlock?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Custom color scheme configuration for email templates.
|
|
53
|
+
*
|
|
54
|
+
* Supports separate color definitions for light and dark modes.
|
|
55
|
+
* Any color not specified will fall back to the defaultColors values.
|
|
56
|
+
*/
|
|
57
|
+
export type EmailColors = {
|
|
58
|
+
light?: Partial<typeof defaultColors.light>
|
|
59
|
+
dark?: Partial<typeof defaultColors.dark>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Props for the EmailStyles component.
|
|
64
|
+
*/
|
|
65
|
+
interface EmailStylesProps {
|
|
66
|
+
/** Custom color scheme for light and dark modes */
|
|
67
|
+
colors?: EmailColors
|
|
68
|
+
/** Whether to enable dark mode support */
|
|
69
|
+
darkMode?: boolean
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Component that injects CSS styles for email templates with support for light and dark modes.
|
|
74
|
+
*
|
|
75
|
+
* Generates inline styles that adapt to the user's color scheme preference and applies
|
|
76
|
+
* custom colors if provided. Handles logo visibility switching between light and dark modes.
|
|
77
|
+
*
|
|
78
|
+
* @param props - Style configuration options
|
|
79
|
+
* @returns A style element containing CSS for email template theming
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <EmailStyles
|
|
84
|
+
* colors={{
|
|
85
|
+
* light: { primary: "#000000" },
|
|
86
|
+
* dark: { primary: "#FFFFFF" }
|
|
87
|
+
* }}
|
|
88
|
+
* darkMode={true}
|
|
89
|
+
* />
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export const EmailStyles = ({ colors, darkMode = true }: EmailStylesProps) => {
|
|
93
|
+
return (
|
|
94
|
+
<style type="text/css">{`
|
|
95
|
+
.bg-background {
|
|
96
|
+
background-color: ${colors?.light?.background || defaultColors.light.background} !important;
|
|
97
|
+
}
|
|
98
|
+
.bg-card {
|
|
99
|
+
background-color: ${colors?.light?.card || defaultColors.light.card} !important;
|
|
100
|
+
}
|
|
101
|
+
.bg-primary {
|
|
102
|
+
background-color: ${colors?.light?.primary || defaultColors.light.primary} !important;
|
|
103
|
+
}
|
|
104
|
+
.bg-muted {
|
|
105
|
+
background-color: ${colors?.light?.muted || defaultColors.light.muted} !important;
|
|
106
|
+
}
|
|
107
|
+
.border-border {
|
|
108
|
+
border-color: ${colors?.light?.border || defaultColors.light.border} !important;
|
|
109
|
+
}
|
|
110
|
+
.text-card-foreground {
|
|
111
|
+
color: ${colors?.light?.cardForeground || defaultColors.light.cardForeground} !important;
|
|
112
|
+
}
|
|
113
|
+
.text-muted-foreground {
|
|
114
|
+
color: ${colors?.light?.mutedForeground || defaultColors.light.mutedForeground} !important;
|
|
115
|
+
}
|
|
116
|
+
.text-primary {
|
|
117
|
+
color: ${colors?.light?.primary || defaultColors.light.primary} !important;
|
|
118
|
+
}
|
|
119
|
+
.text-primary-foreground {
|
|
120
|
+
color: ${colors?.light?.primaryForeground || defaultColors.light.primaryForeground} !important;
|
|
121
|
+
}
|
|
122
|
+
.logo-dark {
|
|
123
|
+
display: none !important;
|
|
124
|
+
}
|
|
125
|
+
.logo-light {
|
|
126
|
+
display: block !important;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
${
|
|
130
|
+
darkMode
|
|
131
|
+
? `@media (prefers-color-scheme: dark) {
|
|
132
|
+
.bg-background {
|
|
133
|
+
background-color: ${colors?.dark?.background || defaultColors.dark.background} !important;
|
|
134
|
+
}
|
|
135
|
+
.bg-card {
|
|
136
|
+
background-color: ${colors?.dark?.card || defaultColors.dark.card} !important;
|
|
137
|
+
}
|
|
138
|
+
.bg-primary {
|
|
139
|
+
background-color: ${colors?.dark?.primary || defaultColors.dark.primary} !important;
|
|
140
|
+
}
|
|
141
|
+
.bg-muted {
|
|
142
|
+
background-color: ${colors?.dark?.muted || defaultColors.dark.muted} !important;
|
|
143
|
+
}
|
|
144
|
+
.border-border {
|
|
145
|
+
border-color: ${colors?.dark?.border || defaultColors.dark.border} !important;
|
|
146
|
+
}
|
|
147
|
+
.text-card-foreground {
|
|
148
|
+
color: ${colors?.dark?.cardForeground || defaultColors.dark.cardForeground} !important;
|
|
149
|
+
}
|
|
150
|
+
.text-muted-foreground {
|
|
151
|
+
color: ${colors?.dark?.mutedForeground || defaultColors.dark.mutedForeground} !important;
|
|
152
|
+
}
|
|
153
|
+
.text-primary {
|
|
154
|
+
color: ${colors?.dark?.primary || defaultColors.dark.primary} !important;
|
|
155
|
+
}
|
|
156
|
+
.text-primary-foreground {
|
|
157
|
+
color: ${colors?.dark?.primaryForeground || defaultColors.dark.primaryForeground} !important;
|
|
158
|
+
}
|
|
159
|
+
.logo-dark {
|
|
160
|
+
display: block !important;
|
|
161
|
+
}
|
|
162
|
+
.logo-light {
|
|
163
|
+
display: none !important;
|
|
164
|
+
}
|
|
165
|
+
* {
|
|
166
|
+
box-shadow: none !important;
|
|
167
|
+
}
|
|
168
|
+
}`
|
|
169
|
+
: ""
|
|
170
|
+
}
|
|
171
|
+
`}</style>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export default EmailStyles
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Body,
|
|
3
|
+
Button,
|
|
4
|
+
Container,
|
|
5
|
+
Head,
|
|
6
|
+
Heading,
|
|
7
|
+
Hr,
|
|
8
|
+
Html,
|
|
9
|
+
Img,
|
|
10
|
+
Link,
|
|
11
|
+
Preview,
|
|
12
|
+
pixelBasedPreset,
|
|
13
|
+
Section,
|
|
14
|
+
Tailwind,
|
|
15
|
+
Text
|
|
16
|
+
} from "@react-email/components"
|
|
17
|
+
import type { ReactNode } from "react"
|
|
18
|
+
|
|
19
|
+
import { cn } from "../../lib/utils"
|
|
20
|
+
import {
|
|
21
|
+
type EmailClassNames,
|
|
22
|
+
type EmailColors,
|
|
23
|
+
EmailStyles
|
|
24
|
+
} from "./email-styles"
|
|
25
|
+
|
|
26
|
+
const emailVerificationEmailLocalization = {
|
|
27
|
+
VERIFY_YOUR_EMAIL_ADDRESS: "Verify your email address",
|
|
28
|
+
LOGO: "Logo",
|
|
29
|
+
CLICK_BUTTON_TO_VERIFY_EMAIL:
|
|
30
|
+
"Click the button below to verify your email address {emailAddress} for your {appName} account.",
|
|
31
|
+
VERIFY_EMAIL_ADDRESS: "Verify email address",
|
|
32
|
+
OR_COPY_AND_PASTE_URL: "Or copy and paste this URL into your browser:",
|
|
33
|
+
THIS_LINK_EXPIRES_IN_MINUTES:
|
|
34
|
+
"This link expires in {expirationMinutes} minutes.",
|
|
35
|
+
EMAIL_SENT_BY: "Email sent by {appName}.",
|
|
36
|
+
IF_YOU_DIDNT_REQUEST_THIS_EMAIL:
|
|
37
|
+
"If you didn't request this email, you can safely ignore it. Someone else might have typed your email address by mistake.",
|
|
38
|
+
POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Localization strings for the EmailVerificationEmail component.
|
|
43
|
+
*
|
|
44
|
+
* Contains all text content used in the email verification email template.
|
|
45
|
+
*/
|
|
46
|
+
export type EmailVerificationEmailLocalization =
|
|
47
|
+
typeof emailVerificationEmailLocalization
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Props for the EmailVerificationEmail component.
|
|
51
|
+
*/
|
|
52
|
+
export interface EmailVerificationEmailProps {
|
|
53
|
+
/** Verification URL that users must click to verify their email */
|
|
54
|
+
url: string
|
|
55
|
+
/** Email address being verified */
|
|
56
|
+
email?: string
|
|
57
|
+
/** Name of the application sending the email */
|
|
58
|
+
appName?: string
|
|
59
|
+
/** Number of minutes until the verification link expires */
|
|
60
|
+
expirationMinutes?: number
|
|
61
|
+
/** Logo URL(s) - a single string or light/dark variants. If omitted, no logo is shown. */
|
|
62
|
+
logoURL?: string | { light: string; dark: string }
|
|
63
|
+
/** Custom CSS class names for styling specific parts of the email */
|
|
64
|
+
classNames?: EmailClassNames
|
|
65
|
+
/** Custom color scheme for light and dark modes */
|
|
66
|
+
colors?: EmailColors
|
|
67
|
+
/** Whether to show the "Powered by better-auth" footer */
|
|
68
|
+
poweredBy?: boolean
|
|
69
|
+
/** Whether to enable dark mode support */
|
|
70
|
+
darkMode?: boolean
|
|
71
|
+
/** Additional React nodes to inject into the email head */
|
|
72
|
+
head?: ReactNode
|
|
73
|
+
/**
|
|
74
|
+
* Localization overrides for customizing email text
|
|
75
|
+
* @remarks `EmailVerificationEmailLocalization`
|
|
76
|
+
*/
|
|
77
|
+
localization?: Partial<EmailVerificationEmailLocalization>
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Email template component that sends email verification links to users.
|
|
82
|
+
*
|
|
83
|
+
* This email includes:
|
|
84
|
+
* - Verification button and fallback URL
|
|
85
|
+
* - Expiration time information
|
|
86
|
+
* - Security notice for unauthorized requests
|
|
87
|
+
* - Customizable branding and styling
|
|
88
|
+
* - Support for light/dark mode themes
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* <EmailVerificationEmail
|
|
93
|
+
* url="https://example.com/verify?token=abc123"
|
|
94
|
+
* email="user@example.com"
|
|
95
|
+
* appName="My App"
|
|
96
|
+
* expirationMinutes={60}
|
|
97
|
+
* logoURL="https://example.com/logo.png"
|
|
98
|
+
* darkMode={true}
|
|
99
|
+
* />
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export const EmailVerificationEmail = ({
|
|
103
|
+
url,
|
|
104
|
+
email,
|
|
105
|
+
appName,
|
|
106
|
+
expirationMinutes = 60,
|
|
107
|
+
logoURL,
|
|
108
|
+
colors,
|
|
109
|
+
classNames,
|
|
110
|
+
darkMode = true,
|
|
111
|
+
poweredBy,
|
|
112
|
+
head,
|
|
113
|
+
...props
|
|
114
|
+
}: EmailVerificationEmailProps) => {
|
|
115
|
+
const localization = {
|
|
116
|
+
...EmailVerificationEmail.localization,
|
|
117
|
+
...props.localization
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const previewText = localization.VERIFY_YOUR_EMAIL_ADDRESS
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<Html>
|
|
124
|
+
<Head>
|
|
125
|
+
<meta content="light dark" name="color-scheme" />
|
|
126
|
+
<meta content="light dark" name="supported-color-schemes" />
|
|
127
|
+
|
|
128
|
+
<EmailStyles colors={colors} darkMode={darkMode} />
|
|
129
|
+
|
|
130
|
+
{head}
|
|
131
|
+
</Head>
|
|
132
|
+
|
|
133
|
+
<Preview>{previewText}</Preview>
|
|
134
|
+
|
|
135
|
+
<Tailwind config={{ presets: [pixelBasedPreset] }}>
|
|
136
|
+
<Body className={cn("bg-background font-sans", classNames?.body)}>
|
|
137
|
+
<Container
|
|
138
|
+
className={cn(
|
|
139
|
+
"mx-auto my-auto max-w-xl px-2 py-10",
|
|
140
|
+
classNames?.container
|
|
141
|
+
)}
|
|
142
|
+
>
|
|
143
|
+
<Section
|
|
144
|
+
className={cn(
|
|
145
|
+
"bg-card text-card-foreground rounded-none border border-border p-8",
|
|
146
|
+
classNames?.card
|
|
147
|
+
)}
|
|
148
|
+
>
|
|
149
|
+
{logoURL &&
|
|
150
|
+
(typeof logoURL === "string" ? (
|
|
151
|
+
<Img
|
|
152
|
+
src={logoURL}
|
|
153
|
+
width={48}
|
|
154
|
+
height={48}
|
|
155
|
+
alt={appName || localization.LOGO}
|
|
156
|
+
className={cn("mx-auto mb-8", classNames?.logo)}
|
|
157
|
+
/>
|
|
158
|
+
) : (
|
|
159
|
+
<>
|
|
160
|
+
<Img
|
|
161
|
+
src={logoURL.light}
|
|
162
|
+
width={48}
|
|
163
|
+
height={48}
|
|
164
|
+
alt={appName || localization.LOGO}
|
|
165
|
+
className={cn(
|
|
166
|
+
"mx-auto mb-8 logo-light",
|
|
167
|
+
classNames?.logo
|
|
168
|
+
)}
|
|
169
|
+
/>
|
|
170
|
+
<Img
|
|
171
|
+
src={logoURL.dark}
|
|
172
|
+
width={48}
|
|
173
|
+
height={48}
|
|
174
|
+
alt={appName || localization.LOGO}
|
|
175
|
+
className={cn(
|
|
176
|
+
"hidden mx-auto mb-8 logo-dark",
|
|
177
|
+
classNames?.logo
|
|
178
|
+
)}
|
|
179
|
+
/>
|
|
180
|
+
</>
|
|
181
|
+
))}
|
|
182
|
+
|
|
183
|
+
<Heading
|
|
184
|
+
className={cn(
|
|
185
|
+
"m-0 mb-5 text-2xl font-semibold",
|
|
186
|
+
classNames?.title
|
|
187
|
+
)}
|
|
188
|
+
>
|
|
189
|
+
{localization.VERIFY_EMAIL_ADDRESS}
|
|
190
|
+
</Heading>
|
|
191
|
+
|
|
192
|
+
<Text className={cn("text-sm font-normal", classNames?.content)}>
|
|
193
|
+
{(() => {
|
|
194
|
+
const textWithAppName =
|
|
195
|
+
localization.CLICK_BUTTON_TO_VERIFY_EMAIL.replace(
|
|
196
|
+
"{appName}",
|
|
197
|
+
appName || ""
|
|
198
|
+
)
|
|
199
|
+
.replace(/\s{2,}/g, " ")
|
|
200
|
+
.replace(" .", ".")
|
|
201
|
+
|
|
202
|
+
const [beforeEmailAddress, afterEmailAddress] =
|
|
203
|
+
textWithAppName.split("{emailAddress}")
|
|
204
|
+
|
|
205
|
+
return email ? (
|
|
206
|
+
<>
|
|
207
|
+
{beforeEmailAddress}
|
|
208
|
+
|
|
209
|
+
<Link
|
|
210
|
+
href={`mailto:${email}`}
|
|
211
|
+
className="text-primary font-medium"
|
|
212
|
+
>
|
|
213
|
+
{email}
|
|
214
|
+
</Link>
|
|
215
|
+
|
|
216
|
+
{afterEmailAddress}
|
|
217
|
+
</>
|
|
218
|
+
) : (
|
|
219
|
+
textWithAppName
|
|
220
|
+
.replace("{emailAddress}", "")
|
|
221
|
+
.replace(/\s{2,}/g, " ")
|
|
222
|
+
.replace(" .", ".")
|
|
223
|
+
)
|
|
224
|
+
})()}
|
|
225
|
+
</Text>
|
|
226
|
+
|
|
227
|
+
<Section className="my-6">
|
|
228
|
+
<Button
|
|
229
|
+
href={url}
|
|
230
|
+
className={cn(
|
|
231
|
+
"inline-block whitespace-nowrap rounded-none text-sm font-medium py-2.5 px-6 bg-primary text-primary-foreground no-underline",
|
|
232
|
+
classNames?.button
|
|
233
|
+
)}
|
|
234
|
+
>
|
|
235
|
+
{localization.VERIFY_EMAIL_ADDRESS}
|
|
236
|
+
</Button>
|
|
237
|
+
</Section>
|
|
238
|
+
|
|
239
|
+
<Text
|
|
240
|
+
className={cn(
|
|
241
|
+
"mb-3 text-xs text-muted-foreground",
|
|
242
|
+
classNames?.description
|
|
243
|
+
)}
|
|
244
|
+
>
|
|
245
|
+
{localization.OR_COPY_AND_PASTE_URL}
|
|
246
|
+
</Text>
|
|
247
|
+
|
|
248
|
+
<Link
|
|
249
|
+
className={cn(
|
|
250
|
+
"break-all text-xs text-primary",
|
|
251
|
+
classNames?.link
|
|
252
|
+
)}
|
|
253
|
+
href={url}
|
|
254
|
+
>
|
|
255
|
+
{url}
|
|
256
|
+
</Link>
|
|
257
|
+
|
|
258
|
+
<Hr
|
|
259
|
+
className={cn(
|
|
260
|
+
"my-6 w-full border border-solid border-border",
|
|
261
|
+
classNames?.separator
|
|
262
|
+
)}
|
|
263
|
+
/>
|
|
264
|
+
|
|
265
|
+
{expirationMinutes || appName ? (
|
|
266
|
+
<Text
|
|
267
|
+
className={cn(
|
|
268
|
+
"mb-3 text-xs text-muted-foreground",
|
|
269
|
+
classNames?.description
|
|
270
|
+
)}
|
|
271
|
+
>
|
|
272
|
+
{expirationMinutes
|
|
273
|
+
? localization.THIS_LINK_EXPIRES_IN_MINUTES.replace(
|
|
274
|
+
"{expirationMinutes}",
|
|
275
|
+
expirationMinutes.toString()
|
|
276
|
+
)
|
|
277
|
+
: null}
|
|
278
|
+
|
|
279
|
+
{appName && (
|
|
280
|
+
<>
|
|
281
|
+
{expirationMinutes ? " " : ""}
|
|
282
|
+
{localization.EMAIL_SENT_BY.replace("{appName}", appName)}
|
|
283
|
+
</>
|
|
284
|
+
)}
|
|
285
|
+
</Text>
|
|
286
|
+
) : null}
|
|
287
|
+
|
|
288
|
+
<Text
|
|
289
|
+
className={cn(
|
|
290
|
+
"mt-3 text-xs text-muted-foreground",
|
|
291
|
+
classNames?.description
|
|
292
|
+
)}
|
|
293
|
+
>
|
|
294
|
+
{localization.IF_YOU_DIDNT_REQUEST_THIS_EMAIL}
|
|
295
|
+
</Text>
|
|
296
|
+
|
|
297
|
+
{poweredBy && (
|
|
298
|
+
<Text
|
|
299
|
+
className={cn(
|
|
300
|
+
"mt-4 mb-0 text-center text-[11px] text-muted-foreground",
|
|
301
|
+
classNames?.poweredBy
|
|
302
|
+
)}
|
|
303
|
+
>
|
|
304
|
+
{(() => {
|
|
305
|
+
const [beforeBetterAuth, afterBetterAuth] =
|
|
306
|
+
localization.POWERED_BY_BETTER_AUTH.split("{betterAuth}")
|
|
307
|
+
|
|
308
|
+
return (
|
|
309
|
+
<>
|
|
310
|
+
{beforeBetterAuth}
|
|
311
|
+
<Link
|
|
312
|
+
href="https://better-auth.com"
|
|
313
|
+
className={cn(
|
|
314
|
+
"text-primary underline",
|
|
315
|
+
classNames?.link
|
|
316
|
+
)}
|
|
317
|
+
>
|
|
318
|
+
better-auth
|
|
319
|
+
</Link>
|
|
320
|
+
{afterBetterAuth}
|
|
321
|
+
</>
|
|
322
|
+
)
|
|
323
|
+
})()}
|
|
324
|
+
</Text>
|
|
325
|
+
)}
|
|
326
|
+
</Section>
|
|
327
|
+
</Container>
|
|
328
|
+
</Body>
|
|
329
|
+
</Tailwind>
|
|
330
|
+
</Html>
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Default localization strings for the email verification template.
|
|
336
|
+
* Can be overridden via the `localization` prop.
|
|
337
|
+
*/
|
|
338
|
+
EmailVerificationEmail.localization = emailVerificationEmailLocalization
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Example props for previewing the email template in development.
|
|
342
|
+
*/
|
|
343
|
+
EmailVerificationEmail.PreviewProps = {
|
|
344
|
+
url: "https://better-auth-ui.com/auth/verify-email?token=example-token",
|
|
345
|
+
appName: "Better Auth",
|
|
346
|
+
email: "m@example.com",
|
|
347
|
+
darkMode: true
|
|
348
|
+
} as EmailVerificationEmailProps
|
|
349
|
+
|
|
350
|
+
export default EmailVerificationEmail
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./email-changed"
|
|
2
|
+
export * from "./email-localization"
|
|
3
|
+
export * from "./email-styles"
|
|
4
|
+
export * from "./email-verification"
|
|
5
|
+
export * from "./magic-link"
|
|
6
|
+
export * from "./new-device"
|
|
7
|
+
export * from "./otp-email"
|
|
8
|
+
export * from "./password-changed"
|
|
9
|
+
export * from "./reset-password"
|