@better-auth-ui/solid 1.6.19

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 (270) hide show
  1. package/dist/components/auth/email/email-changed.d.ts +59 -0
  2. package/dist/components/auth/email/email-changed.js +264 -0
  3. package/dist/components/auth/email/email-styles.d.ts +48 -0
  4. package/dist/components/auth/email/email-styles.js +107 -0
  5. package/dist/components/auth/email/email-verification.d.ts +51 -0
  6. package/dist/components/auth/email/email-verification.js +212 -0
  7. package/dist/components/auth/email/index.d.ts +9 -0
  8. package/dist/components/auth/email/magic-link.d.ts +53 -0
  9. package/dist/components/auth/email/magic-link.js +213 -0
  10. package/dist/components/auth/email/new-device.d.ts +77 -0
  11. package/dist/components/auth/email/new-device.js +326 -0
  12. package/dist/components/auth/email/organization-invitation.d.ts +70 -0
  13. package/dist/components/auth/email/organization-invitation.js +260 -0
  14. package/dist/components/auth/email/otp-email.d.ts +49 -0
  15. package/dist/components/auth/email/otp-email.js +191 -0
  16. package/dist/components/auth/email/password-changed.d.ts +56 -0
  17. package/dist/components/auth/email/password-changed.js +236 -0
  18. package/dist/components/auth/email/reset-password.d.ts +51 -0
  19. package/dist/components/auth/email/reset-password.js +212 -0
  20. package/dist/email.d.ts +18 -0
  21. package/dist/email.js +10 -0
  22. package/dist/hooks/auth/use-authenticate.d.ts +3 -0
  23. package/dist/hooks/auth/use-authenticate.js +18 -0
  24. package/dist/hooks/auth/use-sign-out.d.ts +2 -0
  25. package/dist/hooks/auth/use-sign-out.js +17 -0
  26. package/dist/hooks/auth/use-user.d.ts +213 -0
  27. package/dist/hooks/auth/use-user.js +13 -0
  28. package/dist/hooks/use-auth-mutation.d.ts +6 -0
  29. package/dist/hooks/use-auth-mutation.js +11 -0
  30. package/dist/hooks/use-auth-query.d.ts +5 -0
  31. package/dist/hooks/use-auth-query.js +17 -0
  32. package/dist/index.d.ts +48 -0
  33. package/dist/index.js +68 -0
  34. package/dist/lib/auth-client.d.ts +26 -0
  35. package/dist/lib/auth-config.d.ts +12 -0
  36. package/dist/lib/auth-config.js +21 -0
  37. package/dist/lib/auth-plugin.d.ts +16 -0
  38. package/dist/lib/auth-provider.d.ts +12 -0
  39. package/dist/lib/auth-provider.js +36 -0
  40. package/dist/lib/auth-server.d.ts +16 -0
  41. package/dist/lib/auth-utils.d.ts +3 -0
  42. package/dist/lib/auth-utils.js +12 -0
  43. package/dist/lib/fetch-options-provider.d.ts +23 -0
  44. package/dist/lib/fetch-options-provider.js +29 -0
  45. package/dist/lib/mutation-invalidator.d.ts +11 -0
  46. package/dist/lib/mutation-invalidator.js +20 -0
  47. package/dist/lib/provider-icons.d.ts +8 -0
  48. package/dist/lib/provider-icons.js +5 -0
  49. package/dist/mutations/api-key/create-api-key-mutation.d.ts +71 -0
  50. package/dist/mutations/api-key/create-api-key-mutation.js +12 -0
  51. package/dist/mutations/api-key/delete-api-key-mutation.d.ts +23 -0
  52. package/dist/mutations/api-key/delete-api-key-mutation.js +12 -0
  53. package/dist/mutations/auth/request-password-reset-mutation.d.ts +11 -0
  54. package/dist/mutations/auth/request-password-reset-mutation.js +8 -0
  55. package/dist/mutations/auth/reset-password-mutation.d.ts +13 -0
  56. package/dist/mutations/auth/reset-password-mutation.js +8 -0
  57. package/dist/mutations/auth/send-verification-email-mutation.d.ts +11 -0
  58. package/dist/mutations/auth/send-verification-email-mutation.js +8 -0
  59. package/dist/mutations/auth/sign-in-email-mutation.d.ts +15 -0
  60. package/dist/mutations/auth/sign-in-email-mutation.js +8 -0
  61. package/dist/mutations/auth/sign-in-social-mutation.d.ts +53 -0
  62. package/dist/mutations/auth/sign-in-social-mutation.js +8 -0
  63. package/dist/mutations/auth/sign-out-mutation.d.ts +6 -0
  64. package/dist/mutations/auth/sign-out-mutation.js +8 -0
  65. package/dist/mutations/auth/sign-up-email-mutation.d.ts +17 -0
  66. package/dist/mutations/auth/sign-up-email-mutation.js +8 -0
  67. package/dist/mutations/auth-mutation-options.d.ts +10 -0
  68. package/dist/mutations/auth-mutation-options.js +19 -0
  69. package/dist/mutations/create-auth-mutation.d.ts +10 -0
  70. package/dist/mutations/create-auth-mutation.js +20 -0
  71. package/dist/mutations/magic-link/sign-in-magic-link-mutation.d.ts +19 -0
  72. package/dist/mutations/magic-link/sign-in-magic-link-mutation.js +8 -0
  73. package/dist/mutations/multi-session/revoke-multi-session-mutation.d.ts +19 -0
  74. package/dist/mutations/multi-session/revoke-multi-session-mutation.js +12 -0
  75. package/dist/mutations/multi-session/set-active-session-mutation.d.ts +19 -0
  76. package/dist/mutations/multi-session/set-active-session-mutation.js +13 -0
  77. package/dist/mutations/organization/accept-invitation-mutation.d.ts +18 -0
  78. package/dist/mutations/organization/accept-invitation-mutation.js +12 -0
  79. package/dist/mutations/organization/cancel-invitation-mutation.d.ts +18 -0
  80. package/dist/mutations/organization/cancel-invitation-mutation.js +12 -0
  81. package/dist/mutations/organization/check-slug-mutation.d.ts +18 -0
  82. package/dist/mutations/organization/check-slug-mutation.js +15 -0
  83. package/dist/mutations/organization/create-organization-mutation.d.ts +38 -0
  84. package/dist/mutations/organization/create-organization-mutation.js +12 -0
  85. package/dist/mutations/organization/delete-organization-mutation.d.ts +18 -0
  86. package/dist/mutations/organization/delete-organization-mutation.js +12 -0
  87. package/dist/mutations/organization/index.d.ts +13 -0
  88. package/dist/mutations/organization/index.js +13 -0
  89. package/dist/mutations/organization/invite-member-mutation.d.ts +30 -0
  90. package/dist/mutations/organization/invite-member-mutation.js +12 -0
  91. package/dist/mutations/organization/leave-organization-mutation.d.ts +18 -0
  92. package/dist/mutations/organization/leave-organization-mutation.js +12 -0
  93. package/dist/mutations/organization/metadata.d.ts +13 -0
  94. package/dist/mutations/organization/metadata.js +27 -0
  95. package/dist/mutations/organization/reject-invitation-mutation.d.ts +18 -0
  96. package/dist/mutations/organization/reject-invitation-mutation.js +12 -0
  97. package/dist/mutations/organization/remove-member-mutation.d.ts +22 -0
  98. package/dist/mutations/organization/remove-member-mutation.js +12 -0
  99. package/dist/mutations/organization/set-active-organization-mutation.d.ts +24 -0
  100. package/dist/mutations/organization/set-active-organization-mutation.js +35 -0
  101. package/dist/mutations/organization/update-member-role-mutation.d.ts +26 -0
  102. package/dist/mutations/organization/update-member-role-mutation.js +12 -0
  103. package/dist/mutations/organization/update-organization-mutation.d.ts +42 -0
  104. package/dist/mutations/organization/update-organization-mutation.js +12 -0
  105. package/dist/mutations/organization/utils.d.ts +8 -0
  106. package/dist/mutations/organization/utils.js +17 -0
  107. package/dist/mutations/passkey/add-passkey-mutation.d.ts +73 -0
  108. package/dist/mutations/passkey/add-passkey-mutation.js +12 -0
  109. package/dist/mutations/passkey/delete-passkey-mutation.d.ts +19 -0
  110. package/dist/mutations/passkey/delete-passkey-mutation.js +12 -0
  111. package/dist/mutations/passkey/sign-in-passkey-mutation.d.ts +50 -0
  112. package/dist/mutations/passkey/sign-in-passkey-mutation.js +9 -0
  113. package/dist/mutations/settings/change-email-mutation.d.ts +11 -0
  114. package/dist/mutations/settings/change-email-mutation.js +8 -0
  115. package/dist/mutations/settings/change-password-mutation.d.ts +13 -0
  116. package/dist/mutations/settings/change-password-mutation.js +8 -0
  117. package/dist/mutations/settings/delete-user-mutation.d.ts +13 -0
  118. package/dist/mutations/settings/delete-user-mutation.js +8 -0
  119. package/dist/mutations/settings/link-social-mutation.d.ts +35 -0
  120. package/dist/mutations/settings/link-social-mutation.js +8 -0
  121. package/dist/mutations/settings/revoke-session-mutation.d.ts +19 -0
  122. package/dist/mutations/settings/revoke-session-mutation.js +12 -0
  123. package/dist/mutations/settings/unlink-account-mutation.d.ts +23 -0
  124. package/dist/mutations/settings/unlink-account-mutation.js +12 -0
  125. package/dist/mutations/settings/update-user-mutation.d.ts +6 -0
  126. package/dist/mutations/settings/update-user-mutation.js +8 -0
  127. package/dist/mutations/use-session-scoped-mutation.d.ts +17 -0
  128. package/dist/mutations/use-session-scoped-mutation.js +17 -0
  129. package/dist/mutations/username/is-username-available-mutation.d.ts +9 -0
  130. package/dist/mutations/username/is-username-available-mutation.js +8 -0
  131. package/dist/mutations/username/sign-in-username-mutation.d.ts +15 -0
  132. package/dist/mutations/username/sign-in-username-mutation.js +9 -0
  133. package/dist/plugins/captcha-plugin.d.ts +29 -0
  134. package/dist/plugins/captcha-plugin.js +26 -0
  135. package/dist/plugins.d.ts +2 -0
  136. package/dist/plugins.js +2 -0
  137. package/dist/queries/api-key/list-api-keys-query.d.ts +44 -0
  138. package/dist/queries/api-key/list-api-keys-query.js +17 -0
  139. package/dist/queries/auth/session-query.d.ts +22 -0
  140. package/dist/queries/auth/session-query.js +32 -0
  141. package/dist/queries/auth-query-options.d.ts +14 -0
  142. package/dist/queries/auth-query-options.js +17 -0
  143. package/dist/queries/create-user-scoped-query.d.ts +25 -0
  144. package/dist/queries/create-user-scoped-query.js +29 -0
  145. package/dist/queries/multi-session/list-device-sessions-query.d.ts +23 -0
  146. package/dist/queries/multi-session/list-device-sessions-query.js +17 -0
  147. package/dist/queries/organization/active-organization-query.d.ts +37 -0
  148. package/dist/queries/organization/active-organization-query.js +26 -0
  149. package/dist/queries/organization/full-organization-query.d.ts +35 -0
  150. package/dist/queries/organization/full-organization-query.js +25 -0
  151. package/dist/queries/organization/has-permission-query.d.ts +23 -0
  152. package/dist/queries/organization/has-permission-query.js +31 -0
  153. package/dist/queries/organization/index.d.ts +7 -0
  154. package/dist/queries/organization/index.js +7 -0
  155. package/dist/queries/organization/list-invitations-query.d.ts +29 -0
  156. package/dist/queries/organization/list-invitations-query.js +29 -0
  157. package/dist/queries/organization/list-members-query.d.ts +53 -0
  158. package/dist/queries/organization/list-members-query.js +29 -0
  159. package/dist/queries/organization/list-organizations-query.d.ts +23 -0
  160. package/dist/queries/organization/list-organizations-query.js +25 -0
  161. package/dist/queries/organization/list-user-invitations-query.d.ts +29 -0
  162. package/dist/queries/organization/list-user-invitations-query.js +25 -0
  163. package/dist/queries/organization/plugin.d.ts +1 -0
  164. package/dist/queries/organization/plugin.js +8 -0
  165. package/dist/queries/organization/utils.d.ts +16 -0
  166. package/dist/queries/organization/utils.js +18 -0
  167. package/dist/queries/passkey/list-passkeys-query.d.ts +23 -0
  168. package/dist/queries/passkey/list-passkeys-query.js +17 -0
  169. package/dist/queries/settings/account-info-query.d.ts +35 -0
  170. package/dist/queries/settings/account-info-query.js +17 -0
  171. package/dist/queries/settings/list-accounts-query.d.ts +23 -0
  172. package/dist/queries/settings/list-accounts-query.js +17 -0
  173. package/dist/queries/settings/list-sessions-query.d.ts +24 -0
  174. package/dist/queries/settings/list-sessions-query.js +17 -0
  175. package/dist/server/queries/auth/session-query.d.ts +19 -0
  176. package/dist/server/queries/auth/session-query.js +13 -0
  177. package/dist/server.d.ts +7 -0
  178. package/dist/server.js +7 -0
  179. package/package.json +63 -0
  180. package/src/components/auth/email/email-changed.tsx +305 -0
  181. package/src/components/auth/email/email-styles.tsx +139 -0
  182. package/src/components/auth/email/email-verification.tsx +249 -0
  183. package/src/components/auth/email/index.ts +9 -0
  184. package/src/components/auth/email/magic-link.tsx +254 -0
  185. package/src/components/auth/email/new-device.tsx +347 -0
  186. package/src/components/auth/email/organization-invitation.tsx +322 -0
  187. package/src/components/auth/email/otp-email.tsx +239 -0
  188. package/src/components/auth/email/password-changed.tsx +279 -0
  189. package/src/components/auth/email/reset-password.tsx +250 -0
  190. package/src/email.ts +49 -0
  191. package/src/hooks/auth/use-authenticate.ts +30 -0
  192. package/src/hooks/auth/use-sign-out.ts +23 -0
  193. package/src/hooks/auth/use-user.ts +19 -0
  194. package/src/hooks/use-auth-mutation.ts +35 -0
  195. package/src/hooks/use-auth-query.ts +33 -0
  196. package/src/index.ts +48 -0
  197. package/src/lib/auth-client.ts +43 -0
  198. package/src/lib/auth-config.ts +46 -0
  199. package/src/lib/auth-plugin.ts +20 -0
  200. package/src/lib/auth-provider.tsx +60 -0
  201. package/src/lib/auth-server.ts +25 -0
  202. package/src/lib/auth-utils.ts +25 -0
  203. package/src/lib/fetch-options-provider.tsx +77 -0
  204. package/src/lib/mutation-invalidator.tsx +82 -0
  205. package/src/lib/provider-icons.ts +10 -0
  206. package/src/mutations/api-key/create-api-key-mutation.ts +40 -0
  207. package/src/mutations/api-key/delete-api-key-mutation.ts +40 -0
  208. package/src/mutations/auth/request-password-reset-mutation.ts +15 -0
  209. package/src/mutations/auth/reset-password-mutation.ts +16 -0
  210. package/src/mutations/auth/send-verification-email-mutation.ts +15 -0
  211. package/src/mutations/auth/sign-in-email-mutation.ts +17 -0
  212. package/src/mutations/auth/sign-in-social-mutation.ts +16 -0
  213. package/src/mutations/auth/sign-out-mutation.ts +13 -0
  214. package/src/mutations/auth/sign-up-email-mutation.ts +17 -0
  215. package/src/mutations/auth-mutation-options.ts +62 -0
  216. package/src/mutations/create-auth-mutation.ts +44 -0
  217. package/src/mutations/magic-link/sign-in-magic-link-mutation.ts +15 -0
  218. package/src/mutations/multi-session/revoke-multi-session-mutation.ts +40 -0
  219. package/src/mutations/multi-session/set-active-session-mutation.ts +43 -0
  220. package/src/mutations/organization/accept-invitation-mutation.ts +38 -0
  221. package/src/mutations/organization/cancel-invitation-mutation.ts +38 -0
  222. package/src/mutations/organization/check-slug-mutation.ts +36 -0
  223. package/src/mutations/organization/create-organization-mutation.ts +37 -0
  224. package/src/mutations/organization/delete-organization-mutation.ts +37 -0
  225. package/src/mutations/organization/index.ts +13 -0
  226. package/src/mutations/organization/invite-member-mutation.ts +38 -0
  227. package/src/mutations/organization/leave-organization-mutation.ts +37 -0
  228. package/src/mutations/organization/metadata.ts +103 -0
  229. package/src/mutations/organization/reject-invitation-mutation.ts +38 -0
  230. package/src/mutations/organization/remove-member-mutation.ts +38 -0
  231. package/src/mutations/organization/set-active-organization-mutation.ts +110 -0
  232. package/src/mutations/organization/update-member-role-mutation.ts +38 -0
  233. package/src/mutations/organization/update-organization-mutation.ts +37 -0
  234. package/src/mutations/organization/utils.ts +51 -0
  235. package/src/mutations/passkey/add-passkey-mutation.ts +40 -0
  236. package/src/mutations/passkey/delete-passkey-mutation.ts +40 -0
  237. package/src/mutations/passkey/sign-in-passkey-mutation.ts +17 -0
  238. package/src/mutations/settings/change-email-mutation.ts +17 -0
  239. package/src/mutations/settings/change-password-mutation.ts +16 -0
  240. package/src/mutations/settings/delete-user-mutation.ts +16 -0
  241. package/src/mutations/settings/link-social-mutation.ts +16 -0
  242. package/src/mutations/settings/revoke-session-mutation.ts +38 -0
  243. package/src/mutations/settings/unlink-account-mutation.ts +38 -0
  244. package/src/mutations/settings/update-user-mutation.ts +17 -0
  245. package/src/mutations/use-session-scoped-mutation.ts +64 -0
  246. package/src/mutations/username/is-username-available-mutation.ts +15 -0
  247. package/src/mutations/username/sign-in-username-mutation.ts +17 -0
  248. package/src/plugins/captcha-plugin.tsx +64 -0
  249. package/src/plugins.ts +2 -0
  250. package/src/queries/api-key/list-api-keys-query.ts +93 -0
  251. package/src/queries/auth/session-query.ts +81 -0
  252. package/src/queries/auth-query-options.ts +57 -0
  253. package/src/queries/create-user-scoped-query.ts +107 -0
  254. package/src/queries/multi-session/list-device-sessions-query.ts +107 -0
  255. package/src/queries/organization/active-organization-query.ts +127 -0
  256. package/src/queries/organization/full-organization-query.ts +111 -0
  257. package/src/queries/organization/has-permission-query.ts +121 -0
  258. package/src/queries/organization/index.ts +7 -0
  259. package/src/queries/organization/list-invitations-query.ts +124 -0
  260. package/src/queries/organization/list-members-query.ts +124 -0
  261. package/src/queries/organization/list-organizations-query.ts +113 -0
  262. package/src/queries/organization/list-user-invitations-query.ts +114 -0
  263. package/src/queries/organization/plugin.ts +11 -0
  264. package/src/queries/organization/utils.ts +88 -0
  265. package/src/queries/passkey/list-passkeys-query.ts +93 -0
  266. package/src/queries/settings/account-info-query.ts +94 -0
  267. package/src/queries/settings/list-accounts-query.ts +94 -0
  268. package/src/queries/settings/list-sessions-query.ts +96 -0
  269. package/src/server/queries/auth/session-query.ts +56 -0
  270. package/src/server.ts +7 -0
@@ -0,0 +1,249 @@
1
+ import {
2
+ Body,
3
+ Button,
4
+ Container,
5
+ Head,
6
+ Heading,
7
+ Hr,
8
+ Html,
9
+ Img,
10
+ Link,
11
+ Preview,
12
+ Section,
13
+ Tailwind,
14
+ Text
15
+ } from "@solidjs-email/main"
16
+ import type { JSX } from "solid-js"
17
+ import { Show } from "solid-js"
18
+ import {
19
+ type EmailClassNames,
20
+ type EmailColors,
21
+ EmailStyles
22
+ } from "./email-styles"
23
+
24
+ function cn(...classes: Array<string | false | null | undefined>) {
25
+ return classes.filter(Boolean).join(" ")
26
+ }
27
+
28
+ const emailVerificationEmailLocalization = {
29
+ VERIFY_YOUR_EMAIL_ADDRESS: "Verify your email address",
30
+ LOGO: "Logo",
31
+ CLICK_BUTTON_TO_VERIFY_EMAIL:
32
+ "Click the button below to verify your email address {emailAddress} for your {appName} account.",
33
+ VERIFY_EMAIL_ADDRESS: "Verify email address",
34
+ OR_COPY_AND_PASTE_URL: "Or copy and paste this URL into your browser:",
35
+ THIS_LINK_EXPIRES_IN_MINUTES:
36
+ "This link expires in {expirationMinutes} minutes.",
37
+ EMAIL_SENT_BY: "Email sent by {appName}.",
38
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL:
39
+ "If you didn't request this email, you can safely ignore it. Someone else might have typed your email address by mistake.",
40
+ POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}"
41
+ }
42
+
43
+ export type EmailVerificationEmailLocalization =
44
+ typeof emailVerificationEmailLocalization
45
+
46
+ export interface EmailVerificationEmailProps {
47
+ url: string
48
+ email?: string
49
+ appName?: string
50
+ expirationMinutes?: number
51
+ logoURL?: string | { light: string; dark: string }
52
+ classNames?: EmailClassNames
53
+ colors?: EmailColors
54
+ poweredBy?: boolean
55
+ darkMode?: boolean
56
+ head?: JSX.Element
57
+ localization?: Partial<EmailVerificationEmailLocalization>
58
+ }
59
+
60
+ function cleanSentence(value: string) {
61
+ return value.replace(/\s{2,}/g, " ").replace(" .", ".")
62
+ }
63
+
64
+ export function EmailVerificationEmail(props: EmailVerificationEmailProps) {
65
+ const expirationMinutes = () => props.expirationMinutes ?? 60
66
+ const darkMode = () => props.darkMode ?? true
67
+ const localization = () => ({
68
+ ...EmailVerificationEmail.localization,
69
+ ...props.localization
70
+ })
71
+ const contentText = () =>
72
+ cleanSentence(
73
+ localization()
74
+ .CLICK_BUTTON_TO_VERIFY_EMAIL.replace("{appName}", props.appName || "")
75
+ .replace("{emailAddress}", props.email || "")
76
+ )
77
+
78
+ return (
79
+ <Html>
80
+ <Head>
81
+ <meta content="light dark" name="color-scheme" />
82
+ <meta content="light dark" name="supported-color-schemes" />
83
+ <EmailStyles colors={props.colors} darkMode={darkMode()} />
84
+ {props.head}
85
+ </Head>
86
+
87
+ <Preview>{localization().VERIFY_YOUR_EMAIL_ADDRESS}</Preview>
88
+
89
+ <Tailwind>
90
+ <Body
91
+ class={cn("bg-background", props.classNames?.body)}
92
+ style={{ "font-family": "Arial, Helvetica, sans-serif" }}
93
+ >
94
+ <Container
95
+ class={cn(
96
+ "mx-auto my-auto max-w-xl px-2 py-10",
97
+ props.classNames?.container
98
+ )}
99
+ >
100
+ <Section
101
+ class={cn(
102
+ "rounded-none border border-border bg-card p-8 text-card-foreground",
103
+ props.classNames?.card
104
+ )}
105
+ >
106
+ {props.logoURL &&
107
+ (typeof props.logoURL === "string" ? (
108
+ <Img
109
+ alt={props.appName || localization().LOGO}
110
+ class={cn("mx-auto mb-8", props.classNames?.logo)}
111
+ height={48}
112
+ src={props.logoURL}
113
+ width={48}
114
+ />
115
+ ) : (
116
+ <>
117
+ <Img
118
+ alt={props.appName || localization().LOGO}
119
+ class={cn(
120
+ "logo-light mx-auto mb-8",
121
+ props.classNames?.logo
122
+ )}
123
+ height={48}
124
+ src={props.logoURL.light}
125
+ width={48}
126
+ />
127
+ <Img
128
+ alt={props.appName || localization().LOGO}
129
+ class={cn(
130
+ "logo-dark hidden mx-auto mb-8",
131
+ props.classNames?.logo
132
+ )}
133
+ height={48}
134
+ src={props.logoURL.dark}
135
+ width={48}
136
+ />
137
+ </>
138
+ ))}
139
+
140
+ <Heading
141
+ class={cn(
142
+ "m-0 mb-5 font-semibold text-2xl",
143
+ props.classNames?.title
144
+ )}
145
+ >
146
+ {localization().VERIFY_EMAIL_ADDRESS}
147
+ </Heading>
148
+
149
+ <Text
150
+ class={cn("font-normal text-sm", props.classNames?.content)}
151
+ >
152
+ {contentText()}
153
+ </Text>
154
+
155
+ <Section class="my-6">
156
+ <Button
157
+ class={cn(
158
+ "inline-block whitespace-nowrap rounded-none bg-primary px-6 py-2.5 font-medium text-primary-foreground text-sm no-underline",
159
+ props.classNames?.button
160
+ )}
161
+ href={props.url}
162
+ >
163
+ {localization().VERIFY_EMAIL_ADDRESS}
164
+ </Button>
165
+ </Section>
166
+
167
+ <Text
168
+ class={cn(
169
+ "mb-3 text-muted-foreground text-xs",
170
+ props.classNames?.description
171
+ )}
172
+ >
173
+ {localization().OR_COPY_AND_PASTE_URL}
174
+ </Text>
175
+
176
+ <Link
177
+ class={cn(
178
+ "break-all text-primary text-xs",
179
+ props.classNames?.link
180
+ )}
181
+ href={props.url}
182
+ >
183
+ {props.url}
184
+ </Link>
185
+
186
+ <Hr
187
+ class={cn(
188
+ "my-6 w-full border border-border border-solid",
189
+ props.classNames?.separator
190
+ )}
191
+ />
192
+
193
+ <Text
194
+ class={cn(
195
+ "mb-3 text-muted-foreground text-xs",
196
+ props.classNames?.description
197
+ )}
198
+ >
199
+ {localization().THIS_LINK_EXPIRES_IN_MINUTES.replace(
200
+ "{expirationMinutes}",
201
+ expirationMinutes().toString()
202
+ )}
203
+ <Show when={props.appName}>
204
+ {(appName) =>
205
+ ` ${localization().EMAIL_SENT_BY.replace("{appName}", appName())}`
206
+ }
207
+ </Show>
208
+ </Text>
209
+
210
+ <Text
211
+ class={cn(
212
+ "mt-3 text-muted-foreground text-xs",
213
+ props.classNames?.description
214
+ )}
215
+ >
216
+ {localization().IF_YOU_DIDNT_REQUEST_THIS_EMAIL}
217
+ </Text>
218
+
219
+ <Show when={props.poweredBy}>
220
+ <Text
221
+ class={cn(
222
+ "mt-4 mb-0 text-center text-[11px] text-muted-foreground",
223
+ props.classNames?.poweredBy
224
+ )}
225
+ >
226
+ {localization().POWERED_BY_BETTER_AUTH.replace(
227
+ "{betterAuth}",
228
+ "better-auth"
229
+ )}
230
+ </Text>
231
+ </Show>
232
+ </Section>
233
+ </Container>
234
+ </Body>
235
+ </Tailwind>
236
+ </Html>
237
+ )
238
+ }
239
+
240
+ EmailVerificationEmail.localization = emailVerificationEmailLocalization
241
+
242
+ EmailVerificationEmail.PreviewProps = {
243
+ url: "https://better-auth-ui.com/auth/verify-email",
244
+ appName: "Better Auth",
245
+ email: "m@example.com",
246
+ darkMode: true
247
+ } satisfies EmailVerificationEmailProps
248
+
249
+ export default EmailVerificationEmail
@@ -0,0 +1,9 @@
1
+ export * from "./email-changed"
2
+ export * from "./email-styles"
3
+ export * from "./email-verification"
4
+ export * from "./magic-link"
5
+ export * from "./new-device"
6
+ export * from "./organization-invitation"
7
+ export * from "./otp-email"
8
+ export * from "./password-changed"
9
+ export * from "./reset-password"
@@ -0,0 +1,254 @@
1
+ import {
2
+ Body,
3
+ Button,
4
+ Container,
5
+ Head,
6
+ Heading,
7
+ Hr,
8
+ Html,
9
+ Img,
10
+ Link,
11
+ Preview,
12
+ Section,
13
+ Tailwind,
14
+ Text
15
+ } from "@solidjs-email/main"
16
+ import type { JSX } from "solid-js"
17
+ import { Show } from "solid-js"
18
+ import {
19
+ type EmailClassNames,
20
+ type EmailColors,
21
+ EmailStyles
22
+ } from "./email-styles"
23
+
24
+ function cn(...classes: Array<string | false | null | undefined>) {
25
+ return classes.filter(Boolean).join(" ")
26
+ }
27
+
28
+ const magicLinkEmailLocalization = {
29
+ SIGN_IN_TO_APP_NAME: "Sign in to {appName}",
30
+ SIGN_IN_TO_YOUR_ACCOUNT: "Sign in to your account",
31
+ YOUR_ACCOUNT: "your account",
32
+ LOGO: "Logo",
33
+ CLICK_BUTTON_TO_SIGN_IN:
34
+ "Click the button below to sign in to your account {emailAddress}.",
35
+ OR_COPY_AND_PASTE_URL: "Or copy and paste this URL into your browser:",
36
+ THIS_LINK_EXPIRES_IN_MINUTES:
37
+ "This link expires in {expirationMinutes} minutes.",
38
+ EMAIL_SENT_BY: "Email sent by {appName}.",
39
+ IF_YOU_DIDNT_REQUEST_THIS_EMAIL:
40
+ "If you didn't request this email, you can safely ignore it. Someone else might have typed your email address by mistake.",
41
+ POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}"
42
+ }
43
+
44
+ export type MagicLinkEmailLocalization = typeof magicLinkEmailLocalization
45
+
46
+ export interface MagicLinkEmailProps {
47
+ url: string
48
+ email?: string
49
+ appName?: string
50
+ expirationMinutes?: number
51
+ logoURL?: string | { light: string; dark: string }
52
+ classNames?: EmailClassNames
53
+ colors?: EmailColors
54
+ poweredBy?: boolean
55
+ darkMode?: boolean
56
+ head?: JSX.Element
57
+ localization?: Partial<MagicLinkEmailLocalization>
58
+ }
59
+
60
+ function cleanSentence(value: string) {
61
+ return value.replace(/\s{2,}/g, " ").replace(" .", ".")
62
+ }
63
+
64
+ export function MagicLinkEmail(props: MagicLinkEmailProps) {
65
+ const expirationMinutes = () => props.expirationMinutes ?? 5
66
+ const darkMode = () => props.darkMode ?? true
67
+ const localization = () => ({
68
+ ...MagicLinkEmail.localization,
69
+ ...props.localization
70
+ })
71
+ const title = () =>
72
+ props.appName
73
+ ? localization().SIGN_IN_TO_APP_NAME.replace("{appName}", props.appName)
74
+ : localization().SIGN_IN_TO_YOUR_ACCOUNT
75
+ const contentText = () =>
76
+ cleanSentence(
77
+ localization().CLICK_BUTTON_TO_SIGN_IN.replace(
78
+ "{emailAddress}",
79
+ props.email || ""
80
+ )
81
+ )
82
+
83
+ return (
84
+ <Html>
85
+ <Head>
86
+ <meta content="light dark" name="color-scheme" />
87
+ <meta content="light dark" name="supported-color-schemes" />
88
+ <EmailStyles colors={props.colors} darkMode={darkMode()} />
89
+ {props.head}
90
+ </Head>
91
+
92
+ <Preview>{title()}</Preview>
93
+
94
+ <Tailwind>
95
+ <Body
96
+ class={cn("bg-background", props.classNames?.body)}
97
+ style={{ "font-family": "Arial, Helvetica, sans-serif" }}
98
+ >
99
+ <Container
100
+ class={cn(
101
+ "mx-auto my-auto max-w-xl px-2 py-10",
102
+ props.classNames?.container
103
+ )}
104
+ >
105
+ <Section
106
+ class={cn(
107
+ "rounded-none border border-border bg-card p-8 text-card-foreground",
108
+ props.classNames?.card
109
+ )}
110
+ >
111
+ {props.logoURL &&
112
+ (typeof props.logoURL === "string" ? (
113
+ <Img
114
+ alt={props.appName || localization().LOGO}
115
+ class={cn("mx-auto mb-8", props.classNames?.logo)}
116
+ height={48}
117
+ src={props.logoURL}
118
+ width={48}
119
+ />
120
+ ) : (
121
+ <>
122
+ <Img
123
+ alt={props.appName || localization().LOGO}
124
+ class={cn(
125
+ "logo-light mx-auto mb-8",
126
+ props.classNames?.logo
127
+ )}
128
+ height={48}
129
+ src={props.logoURL.light}
130
+ width={48}
131
+ />
132
+ <Img
133
+ alt={props.appName || localization().LOGO}
134
+ class={cn(
135
+ "logo-dark hidden mx-auto mb-8",
136
+ props.classNames?.logo
137
+ )}
138
+ height={48}
139
+ src={props.logoURL.dark}
140
+ width={48}
141
+ />
142
+ </>
143
+ ))}
144
+
145
+ <Heading
146
+ class={cn(
147
+ "m-0 mb-5 font-semibold text-2xl",
148
+ props.classNames?.title
149
+ )}
150
+ >
151
+ {title()}
152
+ </Heading>
153
+
154
+ <Text
155
+ class={cn("m-0 font-normal text-sm", props.classNames?.content)}
156
+ >
157
+ {contentText()}
158
+ </Text>
159
+
160
+ <Section class="my-6">
161
+ <Button
162
+ class={cn(
163
+ "inline-block whitespace-nowrap rounded-none bg-primary px-6 py-2.5 font-medium text-primary-foreground text-sm no-underline",
164
+ props.classNames?.button
165
+ )}
166
+ href={props.url}
167
+ >
168
+ {title()}
169
+ </Button>
170
+ </Section>
171
+
172
+ <Text
173
+ class={cn(
174
+ "m-0 mb-3 text-muted-foreground text-xs",
175
+ props.classNames?.description
176
+ )}
177
+ >
178
+ {localization().OR_COPY_AND_PASTE_URL}
179
+ </Text>
180
+
181
+ <Link
182
+ class={cn(
183
+ "break-all text-primary text-xs",
184
+ props.classNames?.link
185
+ )}
186
+ href={props.url}
187
+ >
188
+ {props.url}
189
+ </Link>
190
+
191
+ <Hr
192
+ class={cn(
193
+ "my-6 w-full border border-border border-solid",
194
+ props.classNames?.separator
195
+ )}
196
+ />
197
+
198
+ <Text
199
+ class={cn(
200
+ "m-0 mb-3 text-muted-foreground text-xs",
201
+ props.classNames?.description
202
+ )}
203
+ >
204
+ {localization().THIS_LINK_EXPIRES_IN_MINUTES.replace(
205
+ "{expirationMinutes}",
206
+ expirationMinutes().toString()
207
+ )}
208
+ <Show when={props.appName}>
209
+ {(appName) =>
210
+ ` ${localization().EMAIL_SENT_BY.replace("{appName}", appName())}`
211
+ }
212
+ </Show>
213
+ </Text>
214
+
215
+ <Text
216
+ class={cn(
217
+ "m-0 text-muted-foreground text-xs",
218
+ props.classNames?.description
219
+ )}
220
+ >
221
+ {localization().IF_YOU_DIDNT_REQUEST_THIS_EMAIL}
222
+ </Text>
223
+
224
+ <Show when={props.poweredBy}>
225
+ <Text
226
+ class={cn(
227
+ "m-0 mt-4 text-center text-[11px] text-muted-foreground",
228
+ props.classNames?.poweredBy
229
+ )}
230
+ >
231
+ {localization().POWERED_BY_BETTER_AUTH.replace(
232
+ "{betterAuth}",
233
+ "better-auth"
234
+ )}
235
+ </Text>
236
+ </Show>
237
+ </Section>
238
+ </Container>
239
+ </Body>
240
+ </Tailwind>
241
+ </Html>
242
+ )
243
+ }
244
+
245
+ MagicLinkEmail.localization = magicLinkEmailLocalization
246
+
247
+ MagicLinkEmail.PreviewProps = {
248
+ url: "https://better-auth-ui.com/auth/verify",
249
+ email: "m@example.com",
250
+ appName: "Better Auth",
251
+ darkMode: true
252
+ } satisfies MagicLinkEmailProps
253
+
254
+ export default MagicLinkEmail