@better-auth-ui/heroui 1.6.3 → 1.6.5

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 (204) hide show
  1. package/dist/components/auth/additional-field.d.ts +4 -0
  2. package/dist/components/auth/additional-field.js +270 -0
  3. package/dist/components/auth/auth-provider.d.ts +4 -6
  4. package/dist/components/auth/auth.d.ts +1 -1
  5. package/dist/components/auth/auth.js +54 -28
  6. package/dist/components/{settings/security → auth/delete-user}/danger-zone.d.ts +1 -1
  7. package/dist/components/{settings/security → auth/delete-user}/danger-zone.js +1 -1
  8. package/dist/components/auth/delete-user/delete-user.js +95 -0
  9. package/dist/components/{email → auth/email}/email-changed-email.d.ts +2 -2
  10. package/dist/components/{email → auth/email}/email-changed-email.js +7 -7
  11. package/dist/components/{email → auth/email}/email-verification-email.d.ts +2 -2
  12. package/dist/components/{email → auth/email}/email-verification-email.js +7 -7
  13. package/dist/components/auth/email/magic-link-email.d.ts +3 -0
  14. package/dist/components/{email → auth/email}/magic-link-email.js +7 -7
  15. package/dist/components/auth/email/new-device-email.d.ts +3 -0
  16. package/dist/components/{email → auth/email}/new-device-email.js +7 -7
  17. package/dist/components/auth/email/otp-email.d.ts +3 -0
  18. package/dist/components/{email → auth/email}/otp-email.js +6 -6
  19. package/dist/components/{email → auth/email}/password-changed-email.d.ts +2 -2
  20. package/dist/components/{email → auth/email}/password-changed-email.js +7 -7
  21. package/dist/components/{email → auth/email}/reset-password-email.d.ts +2 -2
  22. package/dist/components/{email → auth/email}/reset-password-email.js +7 -7
  23. package/dist/components/auth/forgot-password.d.ts +1 -1
  24. package/dist/components/auth/forgot-password.js +70 -48
  25. package/dist/components/auth/magic-link/magic-link-button.d.ts +11 -0
  26. package/dist/components/auth/magic-link/magic-link-button.js +20 -0
  27. package/dist/components/auth/magic-link/magic-link.d.ts +16 -0
  28. package/dist/components/auth/magic-link/magic-link.js +87 -0
  29. package/dist/components/{settings/account → auth/multi-session}/manage-account.d.ts +2 -6
  30. package/dist/components/auth/multi-session/manage-account.js +49 -0
  31. package/dist/components/auth/multi-session/manage-accounts.js +34 -0
  32. package/dist/components/{user/switch-account-menu.d.ts → auth/multi-session/switch-account-submenu-content.d.ts} +3 -3
  33. package/dist/components/auth/multi-session/switch-account-submenu-content.js +29 -0
  34. package/dist/components/{user/switch-account-item.d.ts → auth/multi-session/switch-account-submenu-item.d.ts} +2 -2
  35. package/dist/components/auth/multi-session/switch-account-submenu-item.js +20 -0
  36. package/dist/components/auth/multi-session/switch-account-submenu.d.ts +13 -0
  37. package/dist/components/auth/multi-session/switch-account-submenu.js +24 -0
  38. package/dist/components/auth/passkey/passkey-button.d.ts +6 -0
  39. package/dist/components/auth/passkey/passkey-button.js +24 -0
  40. package/dist/components/auth/passkey/passkey.js +45 -0
  41. package/dist/components/auth/passkey/passkeys.js +106 -0
  42. package/dist/components/auth/provider-button.d.ts +6 -8
  43. package/dist/components/auth/provider-button.js +16 -20
  44. package/dist/components/auth/provider-buttons.d.ts +3 -4
  45. package/dist/components/auth/provider-buttons.js +9 -10
  46. package/dist/components/auth/reset-password.js +110 -107
  47. package/dist/components/{settings → auth/settings}/account/account-settings.d.ts +5 -2
  48. package/dist/components/auth/settings/account/account-settings.js +20 -0
  49. package/dist/components/auth/settings/account/change-avatar.js +89 -0
  50. package/dist/components/{settings → auth/settings}/account/change-email.js +17 -17
  51. package/dist/components/{settings → auth/settings}/account/user-profile.d.ts +2 -3
  52. package/dist/components/auth/settings/account/user-profile.js +86 -0
  53. package/dist/components/auth/settings/security/active-session.js +59 -0
  54. package/dist/components/{settings → auth/settings}/security/active-sessions.js +4 -4
  55. package/dist/components/auth/settings/security/change-password.js +189 -0
  56. package/dist/components/auth/settings/security/linked-account.js +56 -0
  57. package/dist/components/{settings → auth/settings}/security/linked-accounts.js +5 -5
  58. package/dist/components/{settings → auth/settings}/security/security-settings.d.ts +1 -1
  59. package/dist/components/auth/settings/security/security-settings.js +22 -0
  60. package/dist/components/auth/settings/settings.js +45 -0
  61. package/dist/components/auth/sign-in.js +66 -85
  62. package/dist/components/auth/sign-out.js +11 -11
  63. package/dist/components/auth/sign-up.js +128 -148
  64. package/dist/components/{settings/account → auth/theme}/appearance.d.ts +3 -6
  65. package/dist/components/auth/theme/appearance.js +72 -0
  66. package/dist/components/auth/theme/theme-toggle-item.d.ts +5 -0
  67. package/dist/components/auth/theme/theme-toggle-item.js +58 -0
  68. package/dist/components/auth/user/user-avatar.js +29 -0
  69. package/dist/components/{user → auth/user}/user-button.d.ts +2 -6
  70. package/dist/components/auth/user/user-button.js +55 -0
  71. package/dist/components/auth/user/user-view.js +37 -0
  72. package/dist/components/auth/username/sign-in-username.d.ts +14 -0
  73. package/dist/components/auth/username/sign-in-username.js +148 -0
  74. package/dist/components/auth/username/username-field.d.ts +8 -0
  75. package/dist/components/auth/username/username-field.js +53 -0
  76. package/dist/email.d.ts +7 -0
  77. package/dist/email.js +9 -0
  78. package/dist/index.d.ts +12 -27
  79. package/dist/index.js +20 -35
  80. package/dist/lib/auth/auth-plugin.d.ts +44 -0
  81. package/dist/lib/auth/delete-user-plugin.d.ts +17 -0
  82. package/dist/lib/auth/delete-user-plugin.js +10 -0
  83. package/dist/lib/auth/magic-link-plugin.d.ts +31 -0
  84. package/dist/lib/auth/magic-link-plugin.js +13 -0
  85. package/dist/lib/auth/multi-session-plugin.d.ts +18 -0
  86. package/dist/lib/auth/multi-session-plugin.js +12 -0
  87. package/dist/lib/auth/passkey-plugin.d.ts +20 -0
  88. package/dist/lib/auth/passkey-plugin.js +12 -0
  89. package/dist/lib/auth/theme-plugin.d.ts +68 -0
  90. package/dist/lib/auth/theme-plugin.js +23 -0
  91. package/dist/lib/auth/username-plugin.d.ts +63 -0
  92. package/dist/lib/auth/username-plugin.js +18 -0
  93. package/dist/plugins.d.ts +20 -0
  94. package/dist/plugins.js +21 -0
  95. package/package.json +19 -21
  96. package/src/components/auth/additional-field.tsx +554 -0
  97. package/src/components/auth/auth-provider.tsx +5 -6
  98. package/src/components/auth/auth.tsx +99 -35
  99. package/src/components/{settings/security → auth/delete-user}/danger-zone.tsx +1 -1
  100. package/src/components/{settings/security → auth/delete-user}/delete-user.tsx +30 -20
  101. package/src/components/{email → auth/email}/email-changed-email.tsx +2 -2
  102. package/src/components/{email → auth/email}/email-verification-email.tsx +2 -2
  103. package/src/components/{email → auth/email}/magic-link-email.tsx +2 -2
  104. package/src/components/{email → auth/email}/new-device-email.tsx +2 -2
  105. package/src/components/{email → auth/email}/otp-email.tsx +2 -2
  106. package/src/components/{email → auth/email}/password-changed-email.tsx +2 -2
  107. package/src/components/{email → auth/email}/reset-password-email.tsx +2 -2
  108. package/src/components/auth/forgot-password.tsx +42 -17
  109. package/src/components/auth/magic-link/magic-link-button.tsx +61 -0
  110. package/src/components/auth/{magic-link.tsx → magic-link/magic-link.tsx} +55 -40
  111. package/src/components/{settings/account → auth/multi-session}/manage-account.tsx +16 -13
  112. package/src/components/{settings/account → auth/multi-session}/manage-accounts.tsx +14 -5
  113. package/src/components/{user/switch-account-menu.tsx → auth/multi-session/switch-account-submenu-content.tsx} +18 -11
  114. package/src/components/{user/switch-account-item.tsx → auth/multi-session/switch-account-submenu-item.tsx} +17 -5
  115. package/src/components/auth/multi-session/switch-account-submenu.tsx +50 -0
  116. package/src/components/auth/passkey/passkey-button.tsx +56 -0
  117. package/src/components/{settings/security → auth/passkey}/passkey.tsx +20 -6
  118. package/src/components/auth/passkey/passkeys.tsx +196 -0
  119. package/src/components/auth/provider-button.tsx +27 -29
  120. package/src/components/auth/provider-buttons.tsx +6 -11
  121. package/src/components/auth/reset-password.tsx +13 -7
  122. package/src/components/{settings → auth/settings}/account/account-settings.tsx +15 -13
  123. package/src/components/{settings → auth/settings}/account/change-avatar.tsx +4 -3
  124. package/src/components/{settings → auth/settings}/account/change-email.tsx +3 -3
  125. package/src/components/auth/settings/account/user-profile.tsx +171 -0
  126. package/src/components/{settings → auth/settings}/security/active-session.tsx +8 -5
  127. package/src/components/{settings → auth/settings}/security/active-sessions.tsx +3 -3
  128. package/src/components/{settings → auth/settings}/security/change-password.tsx +14 -9
  129. package/src/components/{settings → auth/settings}/security/linked-account.tsx +12 -8
  130. package/src/components/{settings → auth/settings}/security/linked-accounts.tsx +2 -2
  131. package/src/components/{settings → auth/settings}/security/security-settings.tsx +7 -6
  132. package/src/components/{settings → auth/settings}/settings.tsx +2 -2
  133. package/src/components/auth/sign-in.tsx +50 -61
  134. package/src/components/auth/sign-out.tsx +2 -2
  135. package/src/components/auth/sign-up.tsx +119 -131
  136. package/src/components/{settings/account → auth/theme}/appearance.tsx +17 -24
  137. package/src/components/auth/theme/theme-toggle-item.tsx +110 -0
  138. package/src/components/{user → auth/user}/user-avatar.tsx +12 -4
  139. package/src/components/{user → auth/user}/user-button.tsx +15 -88
  140. package/src/components/{user → auth/user}/user-view.tsx +12 -4
  141. package/src/components/auth/username/sign-in-username.tsx +299 -0
  142. package/src/components/auth/username/username-field.tsx +124 -0
  143. package/src/email.ts +9 -0
  144. package/src/index.tsx +12 -27
  145. package/src/lib/auth/auth-plugin.ts +67 -0
  146. package/src/lib/auth/delete-user-plugin.ts +15 -0
  147. package/src/lib/auth/magic-link-plugin.ts +26 -0
  148. package/src/lib/auth/multi-session-plugin.ts +17 -0
  149. package/src/lib/auth/passkey-plugin.ts +17 -0
  150. package/src/lib/auth/theme-plugin.ts +86 -0
  151. package/src/lib/auth/username-plugin.tsx +30 -0
  152. package/src/plugins.ts +23 -0
  153. package/dist/components/auth/magic-link-button.d.ts +0 -13
  154. package/dist/components/auth/magic-link-button.js +0 -16
  155. package/dist/components/auth/magic-link.d.ts +0 -17
  156. package/dist/components/auth/magic-link.js +0 -99
  157. package/dist/components/auth/passkey-button.d.ts +0 -4
  158. package/dist/components/auth/passkey-button.js +0 -21
  159. package/dist/components/email/magic-link-email.d.ts +0 -3
  160. package/dist/components/email/new-device-email.d.ts +0 -3
  161. package/dist/components/email/otp-email.d.ts +0 -3
  162. package/dist/components/settings/account/account-settings.js +0 -23
  163. package/dist/components/settings/account/appearance.js +0 -71
  164. package/dist/components/settings/account/change-avatar.js +0 -89
  165. package/dist/components/settings/account/manage-account.js +0 -48
  166. package/dist/components/settings/account/manage-accounts.js +0 -33
  167. package/dist/components/settings/account/user-profile.js +0 -103
  168. package/dist/components/settings/security/active-session.js +0 -59
  169. package/dist/components/settings/security/change-password.js +0 -189
  170. package/dist/components/settings/security/delete-user.js +0 -92
  171. package/dist/components/settings/security/linked-account.js +0 -56
  172. package/dist/components/settings/security/passkey.js +0 -43
  173. package/dist/components/settings/security/passkeys.js +0 -53
  174. package/dist/components/settings/security/security-settings.js +0 -25
  175. package/dist/components/settings/settings.js +0 -45
  176. package/dist/components/user/switch-account-item.js +0 -20
  177. package/dist/components/user/switch-account-menu.js +0 -28
  178. package/dist/components/user/user-avatar.js +0 -29
  179. package/dist/components/user/user-button.js +0 -91
  180. package/dist/components/user/user-view.js +0 -37
  181. package/dist/core.d.ts +0 -1
  182. package/dist/core.js +0 -1
  183. package/dist/react-exports.d.ts +0 -1
  184. package/dist/react-exports.js +0 -1
  185. package/src/components/auth/magic-link-button.tsx +0 -43
  186. package/src/components/auth/passkey-button.tsx +0 -35
  187. package/src/components/settings/account/user-profile.tsx +0 -217
  188. package/src/components/settings/security/passkeys.tsx +0 -96
  189. package/src/core.ts +0 -1
  190. package/src/react-exports.ts +0 -1
  191. /package/dist/components/{settings/security → auth/delete-user}/delete-user.d.ts +0 -0
  192. /package/dist/components/{settings/account → auth/multi-session}/manage-accounts.d.ts +0 -0
  193. /package/dist/components/{settings/security → auth/passkey}/passkey.d.ts +0 -0
  194. /package/dist/components/{settings/security → auth/passkey}/passkeys.d.ts +0 -0
  195. /package/dist/components/{settings → auth/settings}/account/change-avatar.d.ts +0 -0
  196. /package/dist/components/{settings → auth/settings}/account/change-email.d.ts +0 -0
  197. /package/dist/components/{settings → auth/settings}/security/active-session.d.ts +0 -0
  198. /package/dist/components/{settings → auth/settings}/security/active-sessions.d.ts +0 -0
  199. /package/dist/components/{settings → auth/settings}/security/change-password.d.ts +0 -0
  200. /package/dist/components/{settings → auth/settings}/security/linked-account.d.ts +0 -0
  201. /package/dist/components/{settings → auth/settings}/security/linked-accounts.d.ts +0 -0
  202. /package/dist/components/{settings → auth/settings}/settings.d.ts +0 -0
  203. /package/dist/components/{user → auth/user}/user-avatar.d.ts +0 -0
  204. /package/dist/components/{user → auth/user}/user-view.d.ts +0 -0
@@ -43,9 +43,10 @@ export function ChangePassword({
43
43
  variant,
44
44
  ...props
45
45
  }: ChangePasswordProps & Omit<CardProps, "children">) {
46
- const { emailAndPassword, localization } = useAuth()
47
- const { data: session } = useSession()
48
- const { data: accounts, isPending: isAccountsPending } = useListAccounts()
46
+ const { authClient, emailAndPassword, localization } = useAuth()
47
+ const { data: session } = useSession(authClient)
48
+ const { data: accounts, isPending: isAccountsPending } =
49
+ useListAccounts(authClient)
49
50
 
50
51
  const hasCredentialAccount = accounts?.some(
51
52
  (account) => account.providerId === "credential"
@@ -72,12 +73,15 @@ function SetPassword({
72
73
  variant,
73
74
  ...props
74
75
  }: Omit<CardProps, "children">) {
75
- const { localization } = useAuth()
76
- const { data: session } = useSession()
76
+ const { authClient, localization } = useAuth()
77
+ const { data: session } = useSession(authClient)
77
78
 
78
- const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset({
79
- onSuccess: () => toast.success(localization.auth.passwordResetEmailSent)
80
- })
79
+ const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset(
80
+ authClient,
81
+ {
82
+ onSuccess: () => toast.success(localization.auth.passwordResetEmailSent)
83
+ }
84
+ )
81
85
 
82
86
  const handleSetPassword = () => {
83
87
  if (!session?.user.email) return
@@ -129,11 +133,12 @@ function ChangePasswordForm({
129
133
  localization: ReturnType<typeof useAuth>["localization"]
130
134
  session: ReturnType<typeof useSession>["data"]
131
135
  } & Omit<CardProps, "children">) {
136
+ const { authClient } = useAuth()
132
137
  const [currentPassword, setCurrentPassword] = useState("")
133
138
  const [newPassword, setNewPassword] = useState("")
134
139
  const [confirmPassword, setConfirmPassword] = useState("")
135
140
 
136
- const { mutate: changePassword, isPending } = useChangePassword({
141
+ const { mutate: changePassword, isPending } = useChangePassword(authClient, {
137
142
  onError: (error) => {
138
143
  setCurrentPassword("")
139
144
  setNewPassword("")
@@ -26,17 +26,21 @@ export type LinkedAccountProps = {
26
26
  * @returns A JSX element containing the linked account row
27
27
  */
28
28
  export function LinkedAccount({ account, provider }: LinkedAccountProps) {
29
- const { baseURL, localization } = useAuth()
29
+ const { authClient, baseURL, localization } = useAuth()
30
30
 
31
- const { data: accountInfo, isPending: isLoadingInfo } = useAccountInfo({
32
- query: { accountId: account?.accountId }
33
- })
31
+ const { data: accountInfo, isPending: isLoadingInfo } = useAccountInfo(
32
+ authClient,
33
+ { query: { accountId: account?.accountId } }
34
+ )
34
35
 
35
- const { mutate: linkSocial, isPending: isLinking } = useLinkSocial()
36
+ const { mutate: linkSocial, isPending: isLinking } = useLinkSocial(authClient)
36
37
 
37
- const { mutate: unlinkAccount, isPending: isUnlinking } = useUnlinkAccount({
38
- onSuccess: () => toast.success(localization.settings.accountUnlinked)
39
- })
38
+ const { mutate: unlinkAccount, isPending: isUnlinking } = useUnlinkAccount(
39
+ authClient,
40
+ {
41
+ onSuccess: () => toast.success(localization.settings.accountUnlinked)
42
+ }
43
+ )
40
44
 
41
45
  const ProviderIcon = providerIcons[provider]
42
46
  const providerName = getProviderName(provider)
@@ -21,9 +21,9 @@ export function LinkedAccounts({
21
21
  variant,
22
22
  ...props
23
23
  }: LinkedAccountsProps & Omit<CardProps, "children">) {
24
- const { localization, socialProviders } = useAuth()
24
+ const { authClient, localization, socialProviders } = useAuth()
25
25
 
26
- const { data: accounts, isPending } = useListAccounts()
26
+ const { data: accounts, isPending } = useListAccounts(authClient)
27
27
 
28
28
  const linkedAccounts = accounts?.filter(
29
29
  (account) => account.providerId !== "credential"
@@ -4,9 +4,7 @@ import type { ComponentProps } from "react"
4
4
 
5
5
  import { ActiveSessions } from "./active-sessions"
6
6
  import { ChangePassword } from "./change-password"
7
- import { DangerZone } from "./danger-zone"
8
7
  import { LinkedAccounts } from "./linked-accounts"
9
- import { Passkeys } from "./passkeys"
10
8
 
11
9
  export type SecuritySettingsProps = {
12
10
  className?: string
@@ -17,7 +15,7 @@ export type SecuritySettingsProps = {
17
15
  * Renders the security settings layout including password management, linked accounts, and active sessions.
18
16
  *
19
17
  * ChangePassword is rendered when password authentication is enabled; LinkedAccounts is rendered when social providers are present.
20
- * DangerZone is rendered when `deleteUser.enabled` is true in auth config.
18
+ * Each registered auth plugin may contribute `securityCards` (for example delete-user, passkeys).
21
19
  *
22
20
  * @param className - Optional additional CSS class names for the outer container.
23
21
  * @param variant - Card variant forwarded to each security settings card.
@@ -28,7 +26,7 @@ export function SecuritySettings({
28
26
  variant,
29
27
  ...props
30
28
  }: SecuritySettingsProps & ComponentProps<"div">) {
31
- const { deleteUser, emailAndPassword, passkey, socialProviders } = useAuth()
29
+ const { emailAndPassword, plugins, socialProviders } = useAuth()
32
30
 
33
31
  return (
34
32
  <div
@@ -37,9 +35,12 @@ export function SecuritySettings({
37
35
  >
38
36
  {emailAndPassword?.enabled && <ChangePassword variant={variant} />}
39
37
  {!!socialProviders?.length && <LinkedAccounts variant={variant} />}
40
- {passkey && <Passkeys variant={variant} />}
41
38
  <ActiveSessions variant={variant} />
42
- {deleteUser?.enabled && <DangerZone variant={variant} />}
39
+ {plugins.flatMap((plugin) =>
40
+ plugin.securityCards?.map((Card, index) => (
41
+ <Card key={`${plugin.id}-${index.toString()}`} variant={variant} />
42
+ ))
43
+ )}
43
44
  </div>
44
45
  )
45
46
  }
@@ -35,8 +35,8 @@ export function Settings({
35
35
  view,
36
36
  ...props
37
37
  }: SettingsProps & ComponentProps<"div">) {
38
- const { basePaths, localization, viewPaths } = useAuth()
39
- useAuthenticate()
38
+ const { authClient, basePaths, localization, viewPaths } = useAuth()
39
+ useAuthenticate(authClient)
40
40
 
41
41
  if (!view && !path) {
42
42
  throw new Error("[Better Auth UI] Either `view` or `path` must be provided")
@@ -1,8 +1,9 @@
1
+ import { authMutationKeys } from "@better-auth-ui/core"
1
2
  import {
2
3
  useAuth,
4
+ useFetchOptions,
3
5
  useSendVerificationEmail,
4
- useSignInEmail,
5
- useSignInUsername
6
+ useSignInEmail
6
7
  } from "@better-auth-ui/react"
7
8
  import {
8
9
  Button,
@@ -20,11 +21,10 @@ import {
20
21
  TextField,
21
22
  toast
22
23
  } from "@heroui/react"
24
+ import { useIsMutating } from "@tanstack/react-query"
23
25
  import { type SyntheticEvent, useState } from "react"
24
26
 
25
27
  import { FieldSeparator } from "./field-separator"
26
- import { MagicLinkButton } from "./magic-link-button"
27
- import { PasskeyButton } from "./passkey-button"
28
28
  import { ProviderButtons, type SocialLayout } from "./provider-buttons"
29
29
 
30
30
  export interface SignInProps {
@@ -34,10 +34,6 @@ export interface SignInProps {
34
34
  variant?: CardProps["variant"]
35
35
  }
36
36
 
37
- function isEmail(value: string): boolean {
38
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
39
- }
40
-
41
37
  /**
42
38
  * Render the sign-in UI using auth context for configuration and localization.
43
39
  *
@@ -51,26 +47,31 @@ export function SignIn({
51
47
  ...props
52
48
  }: SignInProps & Omit<CardProps, "children">) {
53
49
  const {
50
+ authClient,
54
51
  basePaths,
55
52
  baseURL,
56
53
  emailAndPassword,
57
54
  localization,
58
- magicLink,
59
- passkey,
55
+ plugins,
60
56
  redirectTo,
61
57
  socialProviders,
62
- username: usernameConfig,
63
58
  viewPaths,
64
59
  navigate
65
60
  } = useAuth()
66
61
 
62
+ const { fetchOptions, resetFetchOptions } = useFetchOptions()
63
+
67
64
  const [password, setPassword] = useState("")
68
65
 
69
- const { mutate: sendVerificationEmail } = useSendVerificationEmail({
70
- onSuccess: () => toast.success(localization.auth.verificationEmailSent)
71
- })
66
+ const { mutate: sendVerificationEmail } = useSendVerificationEmail(
67
+ authClient,
68
+ {
69
+ onSuccess: () => toast.success(localization.auth.verificationEmailSent)
70
+ }
71
+ )
72
72
 
73
73
  const { mutate: signInEmail, isPending: signInEmailPending } = useSignInEmail(
74
+ authClient,
74
75
  {
75
76
  onError: (error, { email }) => {
76
77
  setPassword("")
@@ -89,20 +90,13 @@ export function SignIn({
89
90
  } else {
90
91
  toast.danger(error.error?.message || error.message)
91
92
  }
93
+
94
+ resetFetchOptions()
92
95
  },
93
96
  onSuccess: () => navigate({ to: redirectTo })
94
97
  }
95
98
  )
96
99
 
97
- const { mutate: signInUsername, isPending: signInUsernamePending } =
98
- useSignInUsername({
99
- onError: (error) => {
100
- setPassword("")
101
- toast.danger(error.error?.message || error.message)
102
- },
103
- onSuccess: () => navigate({ to: redirectTo })
104
- })
105
-
106
100
  const handleSubmit = (e: SyntheticEvent<HTMLFormElement>) => {
107
101
  e.preventDefault()
108
102
 
@@ -110,21 +104,25 @@ export function SignIn({
110
104
  const email = formData.get("email") as string
111
105
  const rememberMe = formData.get("rememberMe") === "on"
112
106
 
113
- if (usernameConfig?.enabled && !isEmail(email)) {
114
- signInUsername({
115
- username: email,
116
- password
117
- })
118
- } else {
119
- signInEmail({
120
- email,
121
- password,
122
- ...(emailAndPassword?.rememberMe ? { rememberMe } : {})
123
- })
124
- }
107
+ signInEmail({
108
+ email,
109
+ password,
110
+ ...(emailAndPassword?.rememberMe ? { rememberMe } : {}),
111
+ fetchOptions
112
+ })
125
113
  }
126
114
 
127
- const isPending = signInEmailPending || signInUsernamePending
115
+ const signInMutating = useIsMutating({
116
+ mutationKey: authMutationKeys.signIn.all
117
+ })
118
+ const signUpMutating = useIsMutating({
119
+ mutationKey: authMutationKeys.signUp.all
120
+ })
121
+ const isPending = signInMutating + signUpMutating > 0
122
+
123
+ const Captcha = plugins.find(
124
+ (plugin) => plugin.captchaComponent
125
+ )?.captchaComponent
128
126
 
129
127
  const showSeparator = emailAndPassword?.enabled && !!socialProviders?.length
130
128
 
@@ -144,10 +142,7 @@ export function SignIn({
144
142
  {socialPosition === "top" && (
145
143
  <>
146
144
  {!!socialProviders?.length && (
147
- <ProviderButtons
148
- socialLayout={socialLayout}
149
- isPending={isPending}
150
- />
145
+ <ProviderButtons socialLayout={socialLayout} />
151
146
  )}
152
147
 
153
148
  {showSeparator && (
@@ -160,22 +155,14 @@ export function SignIn({
160
155
  <Form onSubmit={handleSubmit} className="flex flex-col gap-4">
161
156
  <TextField
162
157
  name="email"
163
- type={usernameConfig?.enabled ? "text" : "email"}
164
- autoComplete={usernameConfig?.enabled ? "username" : "email"}
158
+ type="email"
159
+ autoComplete="email"
165
160
  isDisabled={isPending}
166
161
  >
167
- <Label>
168
- {usernameConfig?.enabled
169
- ? localization.auth.username
170
- : localization.auth.email}
171
- </Label>
162
+ <Label>{localization.auth.email}</Label>
172
163
 
173
164
  <Input
174
- placeholder={
175
- usernameConfig?.enabled
176
- ? localization.auth.usernameOrEmailPlaceholder
177
- : localization.auth.emailPlaceholder
178
- }
165
+ placeholder={localization.auth.emailPlaceholder}
179
166
  variant={variant === "transparent" ? "primary" : "secondary"}
180
167
  required
181
168
  />
@@ -220,18 +207,23 @@ export function SignIn({
220
207
  </Checkbox>
221
208
  )}
222
209
 
210
+ {Captcha && <div className="flex justify-center">{Captcha}</div>}
211
+
223
212
  <div className="flex flex-col gap-3">
224
213
  <Button type="submit" className="w-full" isPending={isPending}>
225
- {isPending && <Spinner color="current" size="sm" />}
214
+ {signInEmailPending && <Spinner color="current" size="sm" />}
226
215
 
227
216
  {localization.auth.signIn}
228
217
  </Button>
229
218
 
230
- {magicLink && (
231
- <MagicLinkButton view="signIn" isPending={isPending} />
219
+ {plugins.flatMap((plugin) =>
220
+ plugin.authButtons?.map((AuthButton, index) => (
221
+ <AuthButton
222
+ key={`${plugin.id}-${index.toString()}`}
223
+ view="signIn"
224
+ />
225
+ ))
232
226
  )}
233
-
234
- {passkey && <PasskeyButton isPending={isPending} />}
235
227
  </div>
236
228
  </Form>
237
229
  )}
@@ -243,10 +235,7 @@ export function SignIn({
243
235
  )}
244
236
 
245
237
  {!!socialProviders?.length && (
246
- <ProviderButtons
247
- socialLayout={socialLayout}
248
- isPending={isPending}
249
- />
238
+ <ProviderButtons socialLayout={socialLayout} />
250
239
  )}
251
240
  </>
252
241
  )}
@@ -12,9 +12,9 @@ export type SignOutProps = {
12
12
  * @returns A Card containing a centered Spinner shown during the sign-out process
13
13
  */
14
14
  export function SignOut({ className }: SignOutProps) {
15
- const { basePaths, navigate, viewPaths } = useAuth()
15
+ const { authClient, basePaths, navigate, viewPaths } = useAuth()
16
16
 
17
- const { mutate: signOut } = useSignOut({
17
+ const { mutate: signOut } = useSignOut(authClient, {
18
18
  onError: (error) => {
19
19
  toast.danger(error.error?.message || error.message)
20
20
  navigate({