@delmaredigital/payload-better-auth 0.3.8 → 0.3.10

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 (206) hide show
  1. package/dist/adapter/collections.d.ts +0 -1
  2. package/dist/adapter/collections.js +0 -2
  3. package/dist/adapter/index.d.ts +0 -1
  4. package/dist/adapter/index.js +0 -2
  5. package/dist/components/BeforeLogin.d.ts +0 -1
  6. package/dist/components/BeforeLogin.js +0 -2
  7. package/dist/components/LoginView.d.ts +0 -1
  8. package/dist/components/LoginView.js +0 -2
  9. package/dist/components/LoginViewWrapper.d.ts +0 -1
  10. package/dist/components/LoginViewWrapper.js +0 -2
  11. package/dist/components/LogoutButton.d.ts +0 -1
  12. package/dist/components/LogoutButton.js +0 -2
  13. package/dist/components/PasskeyRegisterButton.d.ts +0 -1
  14. package/dist/components/PasskeyRegisterButton.js +0 -2
  15. package/dist/components/PasskeySignInButton.d.ts +0 -1
  16. package/dist/components/PasskeySignInButton.js +0 -2
  17. package/dist/components/auth/ForgotPasswordView.d.ts +0 -1
  18. package/dist/components/auth/ForgotPasswordView.js +0 -2
  19. package/dist/components/auth/ResetPasswordView.d.ts +0 -1
  20. package/dist/components/auth/ResetPasswordView.js +0 -2
  21. package/dist/components/auth/index.d.ts +0 -1
  22. package/dist/components/auth/index.js +0 -2
  23. package/dist/components/management/ApiKeysManagementClient.d.ts +0 -1
  24. package/dist/components/management/ApiKeysManagementClient.js +0 -2
  25. package/dist/components/management/PasskeysManagementClient.d.ts +0 -1
  26. package/dist/components/management/PasskeysManagementClient.js +0 -2
  27. package/dist/components/management/SecurityNavLinks.d.ts +0 -1
  28. package/dist/components/management/SecurityNavLinks.js +0 -2
  29. package/dist/components/management/TwoFactorManagementClient.d.ts +0 -1
  30. package/dist/components/management/TwoFactorManagementClient.js +0 -2
  31. package/dist/components/management/index.d.ts +0 -1
  32. package/dist/components/management/index.js +0 -2
  33. package/dist/components/management/views/ApiKeysView.d.ts +0 -1
  34. package/dist/components/management/views/ApiKeysView.js +0 -2
  35. package/dist/components/management/views/PasskeysView.d.ts +0 -1
  36. package/dist/components/management/views/PasskeysView.js +0 -2
  37. package/dist/components/management/views/TwoFactorView.d.ts +0 -1
  38. package/dist/components/management/views/TwoFactorView.js +0 -2
  39. package/dist/components/management/views/index.d.ts +0 -1
  40. package/dist/components/management/views/index.js +0 -2
  41. package/dist/components/twoFactor/TwoFactorSetupView.d.ts +0 -1
  42. package/dist/components/twoFactor/TwoFactorSetupView.js +0 -2
  43. package/dist/components/twoFactor/TwoFactorVerifyView.d.ts +0 -1
  44. package/dist/components/twoFactor/TwoFactorVerifyView.js +0 -2
  45. package/dist/components/twoFactor/index.d.ts +0 -1
  46. package/dist/components/twoFactor/index.js +0 -2
  47. package/dist/exports/client.d.ts +0 -1
  48. package/dist/exports/client.js +0 -2
  49. package/dist/exports/components.d.ts +0 -1
  50. package/dist/exports/components.js +0 -2
  51. package/dist/exports/management.d.ts +0 -1
  52. package/dist/exports/management.js +0 -2
  53. package/dist/exports/rsc.d.ts +0 -1
  54. package/dist/exports/rsc.js +0 -2
  55. package/dist/generated-types.d.ts +0 -1
  56. package/dist/generated-types.js +0 -2
  57. package/dist/index.d.ts +0 -1
  58. package/dist/index.js +0 -2
  59. package/dist/plugin/index.d.ts +0 -1
  60. package/dist/plugin/index.js +0 -2
  61. package/dist/scripts/generate-types.d.ts +0 -1
  62. package/dist/scripts/generate-types.js +0 -2
  63. package/dist/types/apiKey.d.ts +0 -1
  64. package/dist/types/apiKey.js +0 -2
  65. package/dist/types/betterAuth.d.ts +0 -1
  66. package/dist/types/betterAuth.js +0 -2
  67. package/dist/utils/access.d.ts +0 -1
  68. package/dist/utils/access.js +0 -2
  69. package/dist/utils/apiKeyAccess.d.ts +0 -1
  70. package/dist/utils/apiKeyAccess.js +0 -2
  71. package/dist/utils/betterAuthDefaults.d.ts +0 -1
  72. package/dist/utils/betterAuthDefaults.js +0 -2
  73. package/dist/utils/detectAuthConfig.d.ts +0 -1
  74. package/dist/utils/detectAuthConfig.js +0 -2
  75. package/dist/utils/detectEnabledPlugins.d.ts +0 -1
  76. package/dist/utils/detectEnabledPlugins.js +0 -2
  77. package/dist/utils/firstUserAdmin.d.ts +0 -1
  78. package/dist/utils/firstUserAdmin.js +0 -2
  79. package/dist/utils/generateScopes.d.ts +0 -1
  80. package/dist/utils/generateScopes.js +0 -2
  81. package/dist/utils/session.d.ts +0 -1
  82. package/dist/utils/session.js +0 -2
  83. package/package.json +34 -91
  84. package/dist/adapter/collections.d.ts.map +0 -1
  85. package/dist/adapter/collections.js.map +0 -1
  86. package/dist/adapter/index.d.ts.map +0 -1
  87. package/dist/adapter/index.js.map +0 -1
  88. package/dist/components/BeforeLogin.d.ts.map +0 -1
  89. package/dist/components/BeforeLogin.js.map +0 -1
  90. package/dist/components/LoginView.d.ts.map +0 -1
  91. package/dist/components/LoginView.js.map +0 -1
  92. package/dist/components/LoginViewWrapper.d.ts.map +0 -1
  93. package/dist/components/LoginViewWrapper.js.map +0 -1
  94. package/dist/components/LogoutButton.d.ts.map +0 -1
  95. package/dist/components/LogoutButton.js.map +0 -1
  96. package/dist/components/PasskeyRegisterButton.d.ts.map +0 -1
  97. package/dist/components/PasskeyRegisterButton.js.map +0 -1
  98. package/dist/components/PasskeySignInButton.d.ts.map +0 -1
  99. package/dist/components/PasskeySignInButton.js.map +0 -1
  100. package/dist/components/auth/ForgotPasswordView.d.ts.map +0 -1
  101. package/dist/components/auth/ForgotPasswordView.js.map +0 -1
  102. package/dist/components/auth/ResetPasswordView.d.ts.map +0 -1
  103. package/dist/components/auth/ResetPasswordView.js.map +0 -1
  104. package/dist/components/auth/index.d.ts.map +0 -1
  105. package/dist/components/auth/index.js.map +0 -1
  106. package/dist/components/management/ApiKeysManagementClient.d.ts.map +0 -1
  107. package/dist/components/management/ApiKeysManagementClient.js.map +0 -1
  108. package/dist/components/management/PasskeysManagementClient.d.ts.map +0 -1
  109. package/dist/components/management/PasskeysManagementClient.js.map +0 -1
  110. package/dist/components/management/SecurityNavLinks.d.ts.map +0 -1
  111. package/dist/components/management/SecurityNavLinks.js.map +0 -1
  112. package/dist/components/management/TwoFactorManagementClient.d.ts.map +0 -1
  113. package/dist/components/management/TwoFactorManagementClient.js.map +0 -1
  114. package/dist/components/management/index.d.ts.map +0 -1
  115. package/dist/components/management/index.js.map +0 -1
  116. package/dist/components/management/views/ApiKeysView.d.ts.map +0 -1
  117. package/dist/components/management/views/ApiKeysView.js.map +0 -1
  118. package/dist/components/management/views/PasskeysView.d.ts.map +0 -1
  119. package/dist/components/management/views/PasskeysView.js.map +0 -1
  120. package/dist/components/management/views/TwoFactorView.d.ts.map +0 -1
  121. package/dist/components/management/views/TwoFactorView.js.map +0 -1
  122. package/dist/components/management/views/index.d.ts.map +0 -1
  123. package/dist/components/management/views/index.js.map +0 -1
  124. package/dist/components/twoFactor/TwoFactorSetupView.d.ts.map +0 -1
  125. package/dist/components/twoFactor/TwoFactorSetupView.js.map +0 -1
  126. package/dist/components/twoFactor/TwoFactorVerifyView.d.ts.map +0 -1
  127. package/dist/components/twoFactor/TwoFactorVerifyView.js.map +0 -1
  128. package/dist/components/twoFactor/index.d.ts.map +0 -1
  129. package/dist/components/twoFactor/index.js.map +0 -1
  130. package/dist/exports/client.d.ts.map +0 -1
  131. package/dist/exports/client.js.map +0 -1
  132. package/dist/exports/components.d.ts.map +0 -1
  133. package/dist/exports/components.js.map +0 -1
  134. package/dist/exports/management.d.ts.map +0 -1
  135. package/dist/exports/management.js.map +0 -1
  136. package/dist/exports/rsc.d.ts.map +0 -1
  137. package/dist/exports/rsc.js.map +0 -1
  138. package/dist/generated-types.d.ts.map +0 -1
  139. package/dist/generated-types.js.map +0 -1
  140. package/dist/index.d.ts.map +0 -1
  141. package/dist/index.js.map +0 -1
  142. package/dist/plugin/index.d.ts.map +0 -1
  143. package/dist/plugin/index.js.map +0 -1
  144. package/dist/scripts/generate-types.d.ts.map +0 -1
  145. package/dist/scripts/generate-types.js.map +0 -1
  146. package/dist/types/apiKey.d.ts.map +0 -1
  147. package/dist/types/apiKey.js.map +0 -1
  148. package/dist/types/betterAuth.d.ts.map +0 -1
  149. package/dist/types/betterAuth.js.map +0 -1
  150. package/dist/utils/access.d.ts.map +0 -1
  151. package/dist/utils/access.js.map +0 -1
  152. package/dist/utils/apiKeyAccess.d.ts.map +0 -1
  153. package/dist/utils/apiKeyAccess.js.map +0 -1
  154. package/dist/utils/betterAuthDefaults.d.ts.map +0 -1
  155. package/dist/utils/betterAuthDefaults.js.map +0 -1
  156. package/dist/utils/detectAuthConfig.d.ts.map +0 -1
  157. package/dist/utils/detectAuthConfig.js.map +0 -1
  158. package/dist/utils/detectEnabledPlugins.d.ts.map +0 -1
  159. package/dist/utils/detectEnabledPlugins.js.map +0 -1
  160. package/dist/utils/firstUserAdmin.d.ts.map +0 -1
  161. package/dist/utils/firstUserAdmin.js.map +0 -1
  162. package/dist/utils/generateScopes.d.ts.map +0 -1
  163. package/dist/utils/generateScopes.js.map +0 -1
  164. package/dist/utils/session.d.ts.map +0 -1
  165. package/dist/utils/session.js.map +0 -1
  166. package/src/adapter/collections.ts +0 -621
  167. package/src/adapter/index.ts +0 -712
  168. package/src/components/BeforeLogin.tsx +0 -39
  169. package/src/components/LoginView.tsx +0 -1516
  170. package/src/components/LoginViewWrapper.tsx +0 -35
  171. package/src/components/LogoutButton.tsx +0 -58
  172. package/src/components/PasskeyRegisterButton.tsx +0 -105
  173. package/src/components/PasskeySignInButton.tsx +0 -96
  174. package/src/components/auth/ForgotPasswordView.tsx +0 -274
  175. package/src/components/auth/ResetPasswordView.tsx +0 -331
  176. package/src/components/auth/index.ts +0 -8
  177. package/src/components/management/ApiKeysManagementClient.tsx +0 -988
  178. package/src/components/management/PasskeysManagementClient.tsx +0 -409
  179. package/src/components/management/SecurityNavLinks.tsx +0 -117
  180. package/src/components/management/TwoFactorManagementClient.tsx +0 -560
  181. package/src/components/management/index.ts +0 -20
  182. package/src/components/management/views/ApiKeysView.tsx +0 -57
  183. package/src/components/management/views/PasskeysView.tsx +0 -42
  184. package/src/components/management/views/TwoFactorView.tsx +0 -42
  185. package/src/components/management/views/index.ts +0 -10
  186. package/src/components/twoFactor/TwoFactorSetupView.tsx +0 -515
  187. package/src/components/twoFactor/TwoFactorVerifyView.tsx +0 -238
  188. package/src/components/twoFactor/index.ts +0 -8
  189. package/src/exports/client.ts +0 -77
  190. package/src/exports/components.ts +0 -30
  191. package/src/exports/management.ts +0 -25
  192. package/src/exports/rsc.ts +0 -11
  193. package/src/generated-types.ts +0 -269
  194. package/src/index.ts +0 -135
  195. package/src/plugin/index.ts +0 -834
  196. package/src/scripts/generate-types.ts +0 -269
  197. package/src/types/apiKey.ts +0 -63
  198. package/src/types/betterAuth.ts +0 -253
  199. package/src/utils/access.ts +0 -410
  200. package/src/utils/apiKeyAccess.ts +0 -443
  201. package/src/utils/betterAuthDefaults.ts +0 -102
  202. package/src/utils/detectAuthConfig.ts +0 -47
  203. package/src/utils/detectEnabledPlugins.ts +0 -69
  204. package/src/utils/firstUserAdmin.ts +0 -164
  205. package/src/utils/generateScopes.ts +0 -150
  206. package/src/utils/session.ts +0 -91
@@ -1,560 +0,0 @@
1
- 'use client'
2
-
3
- import { useState, useEffect, type FormEvent } from 'react'
4
- import {
5
- createPayloadAuthClient,
6
- type PayloadAuthClient,
7
- } from '../../exports/client.js'
8
-
9
- export type TwoFactorManagementClientProps = {
10
- /** Optional pre-configured auth client */
11
- authClient?: PayloadAuthClient
12
- /** Page title. Default: 'Two-Factor Authentication' */
13
- title?: string
14
- }
15
-
16
- /**
17
- * Client component for two-factor authentication management.
18
- * Shows 2FA status and allows enabling/disabling.
19
- */
20
- export function TwoFactorManagementClient({
21
- authClient: providedClient,
22
- title = 'Two-Factor Authentication',
23
- }: TwoFactorManagementClientProps = {}) {
24
- const [isEnabled, setIsEnabled] = useState(false)
25
- const [loading, setLoading] = useState(true)
26
- const [error, setError] = useState<string | null>(null)
27
- const [step, setStep] = useState<'status' | 'password' | 'setup' | 'verify' | 'backup'>('status')
28
- const [totpUri, setTotpUri] = useState<string | null>(null)
29
- const [secret, setSecret] = useState<string | null>(null)
30
- const [backupCodes, setBackupCodes] = useState<string[]>([])
31
- const [verificationCode, setVerificationCode] = useState('')
32
- const [password, setPassword] = useState('')
33
- const [actionLoading, setActionLoading] = useState(false)
34
-
35
- const getClient = () => providedClient ?? createPayloadAuthClient()
36
-
37
- useEffect(() => {
38
- checkStatus()
39
- // eslint-disable-next-line react-hooks/exhaustive-deps
40
- }, [])
41
-
42
- async function checkStatus() {
43
- setLoading(true)
44
- try {
45
- const client = getClient()
46
- const result = await client.getSession()
47
-
48
- if (result.data?.user) {
49
- setIsEnabled((result.data.user as { twoFactorEnabled?: boolean }).twoFactorEnabled ?? false)
50
- } else {
51
- setIsEnabled(false)
52
- }
53
- } catch {
54
- setError('Failed to check 2FA status')
55
- } finally {
56
- setLoading(false)
57
- }
58
- }
59
-
60
- function handleEnableClick() {
61
- // Show password prompt first
62
- setStep('password')
63
- setPassword('')
64
- setError(null)
65
- }
66
-
67
- async function handleEnableWithPassword(e: FormEvent) {
68
- e.preventDefault()
69
- setActionLoading(true)
70
- setError(null)
71
-
72
- try {
73
- const client = getClient()
74
- const result = await client.twoFactor.enable({ password })
75
-
76
- if (result.error) {
77
- setError(result.error.message ?? 'Failed to enable 2FA')
78
- } else if (result.data) {
79
- setTotpUri(result.data.totpURI)
80
- // Secret is embedded in the totpURI, extract it for manual entry option
81
- const secretMatch = result.data.totpURI.match(/secret=([A-Z2-7]+)/i)
82
- setSecret(secretMatch ? secretMatch[1] : null)
83
- setBackupCodes(result.data.backupCodes ?? [])
84
- setPassword('') // Clear password
85
- setStep('setup')
86
- }
87
- } catch {
88
- setError('Failed to enable 2FA')
89
- } finally {
90
- setActionLoading(false)
91
- }
92
- }
93
-
94
- async function handleVerify(e: FormEvent) {
95
- e.preventDefault()
96
- setActionLoading(true)
97
- setError(null)
98
-
99
- try {
100
- const client = getClient()
101
- const result = await client.twoFactor.verifyTotp({ code: verificationCode })
102
-
103
- if (result.error) {
104
- setError(result.error.message ?? 'Invalid verification code')
105
- } else {
106
- if (backupCodes.length > 0) {
107
- setStep('backup')
108
- } else {
109
- setIsEnabled(true)
110
- setStep('status')
111
- }
112
- }
113
- } catch {
114
- setError('Verification failed')
115
- } finally {
116
- setActionLoading(false)
117
- }
118
- }
119
-
120
- async function handleDisable() {
121
- if (!confirm('Are you sure you want to disable two-factor authentication?')) {
122
- return
123
- }
124
-
125
- setActionLoading(true)
126
- setError(null)
127
-
128
- try {
129
- const client = getClient()
130
- const result = await client.twoFactor.disable({ password: '' })
131
-
132
- if (result.error) {
133
- setError(result.error.message ?? 'Failed to disable 2FA')
134
- } else {
135
- setIsEnabled(false)
136
- }
137
- } catch {
138
- setError('Failed to disable 2FA')
139
- } finally {
140
- setActionLoading(false)
141
- }
142
- }
143
-
144
- function handleBackupContinue() {
145
- setIsEnabled(true)
146
- setStep('status')
147
- }
148
-
149
- if (loading) {
150
- return (
151
- <div
152
- style={{
153
- display: 'flex',
154
- alignItems: 'center',
155
- justifyContent: 'center',
156
- padding: 'calc(var(--base) * 3)',
157
- }}
158
- >
159
- <div style={{ color: 'var(--theme-text)', opacity: 0.7 }}>
160
- Loading...
161
- </div>
162
- </div>
163
- )
164
- }
165
-
166
- return (
167
- <div
168
- style={{
169
- maxWidth: '600px',
170
- margin: '0 auto',
171
- padding: 'calc(var(--base) * 2)',
172
- }}
173
- >
174
-
175
- <h1
176
- style={{
177
- color: 'var(--theme-text)',
178
- fontSize: 'var(--font-size-h2)',
179
- fontWeight: 600,
180
- margin: '0 0 calc(var(--base) * 2) 0',
181
- }}
182
- >
183
- {title}
184
- </h1>
185
-
186
- {error && (
187
- <div
188
- style={{
189
- color: 'var(--theme-error-500)',
190
- marginBottom: 'var(--base)',
191
- fontSize: 'var(--font-size-small)',
192
- padding: 'calc(var(--base) * 0.75)',
193
- background: 'var(--theme-error-50)',
194
- borderRadius: 'var(--style-radius-s)',
195
- border: '1px solid var(--theme-error-200)',
196
- }}
197
- >
198
- {error}
199
- </div>
200
- )}
201
-
202
- {step === 'status' && (
203
- <div
204
- style={{
205
- background: 'var(--theme-elevation-50)',
206
- padding: 'calc(var(--base) * 1.5)',
207
- borderRadius: 'var(--style-radius-m)',
208
- border: '1px solid var(--theme-elevation-100)',
209
- }}
210
- >
211
- <div
212
- style={{
213
- display: 'flex',
214
- justifyContent: 'space-between',
215
- alignItems: 'center',
216
- }}
217
- >
218
- <div>
219
- <div
220
- style={{
221
- color: 'var(--theme-text)',
222
- fontWeight: 500,
223
- marginBottom: 'calc(var(--base) * 0.25)',
224
- }}
225
- >
226
- Status
227
- </div>
228
- <div
229
- style={{
230
- color: isEnabled
231
- ? 'var(--theme-success-500)'
232
- : 'var(--theme-elevation-600)',
233
- fontSize: 'var(--font-size-small)',
234
- }}
235
- >
236
- {isEnabled ? '✓ Enabled' : 'Not enabled'}
237
- </div>
238
- </div>
239
-
240
- <button
241
- onClick={isEnabled ? handleDisable : handleEnableClick}
242
- disabled={actionLoading}
243
- style={{
244
- padding: 'calc(var(--base) * 0.5) calc(var(--base) * 1)',
245
- background: isEnabled
246
- ? 'var(--theme-error-500)'
247
- : 'var(--theme-elevation-800)',
248
- border: 'none',
249
- borderRadius: 'var(--style-radius-s)',
250
- color: 'var(--theme-elevation-50)',
251
- fontSize: 'var(--font-size-small)',
252
- cursor: actionLoading ? 'not-allowed' : 'pointer',
253
- opacity: actionLoading ? 0.7 : 1,
254
- }}
255
- >
256
- {actionLoading
257
- ? 'Loading...'
258
- : isEnabled
259
- ? 'Disable'
260
- : 'Enable'}
261
- </button>
262
- </div>
263
- </div>
264
- )}
265
-
266
- {step === 'password' && (
267
- <div
268
- style={{
269
- background: 'var(--theme-elevation-50)',
270
- padding: 'calc(var(--base) * 2)',
271
- borderRadius: 'var(--style-radius-m)',
272
- border: '1px solid var(--theme-elevation-100)',
273
- }}
274
- >
275
- <h2
276
- style={{
277
- color: 'var(--theme-text)',
278
- fontSize: 'var(--font-size-h4)',
279
- fontWeight: 500,
280
- margin: '0 0 var(--base) 0',
281
- }}
282
- >
283
- Confirm Your Password
284
- </h2>
285
- <p
286
- style={{
287
- color: 'var(--theme-text)',
288
- opacity: 0.7,
289
- fontSize: 'var(--font-size-small)',
290
- marginBottom: 'calc(var(--base) * 1.5)',
291
- }}
292
- >
293
- Enter your password to enable two-factor authentication.
294
- </p>
295
- <form onSubmit={handleEnableWithPassword}>
296
- <input
297
- type="password"
298
- value={password}
299
- onChange={(e) => setPassword(e.target.value)}
300
- placeholder="Enter your password"
301
- required
302
- style={{
303
- width: '100%',
304
- padding: 'calc(var(--base) * 0.75)',
305
- background: 'var(--theme-input-bg)',
306
- border: '1px solid var(--theme-elevation-150)',
307
- borderRadius: 'var(--style-radius-s)',
308
- color: 'var(--theme-text)',
309
- fontSize: 'var(--font-size-base)',
310
- marginBottom: 'var(--base)',
311
- boxSizing: 'border-box',
312
- }}
313
- />
314
- <div style={{ display: 'flex', gap: 'calc(var(--base) * 0.5)' }}>
315
- <button
316
- type="submit"
317
- disabled={actionLoading || !password}
318
- style={{
319
- padding: 'calc(var(--base) * 0.75) calc(var(--base) * 1.5)',
320
- background: 'var(--theme-elevation-800)',
321
- border: 'none',
322
- borderRadius: 'var(--style-radius-s)',
323
- color: 'var(--theme-elevation-50)',
324
- fontSize: 'var(--font-size-base)',
325
- cursor: actionLoading || !password ? 'not-allowed' : 'pointer',
326
- opacity: actionLoading || !password ? 0.7 : 1,
327
- }}
328
- >
329
- {actionLoading ? 'Enabling...' : 'Continue'}
330
- </button>
331
- <button
332
- type="button"
333
- onClick={() => setStep('status')}
334
- style={{
335
- padding: 'calc(var(--base) * 0.75) calc(var(--base) * 1.5)',
336
- background: 'transparent',
337
- border: '1px solid var(--theme-elevation-200)',
338
- borderRadius: 'var(--style-radius-s)',
339
- color: 'var(--theme-text)',
340
- fontSize: 'var(--font-size-base)',
341
- cursor: 'pointer',
342
- }}
343
- >
344
- Cancel
345
- </button>
346
- </div>
347
- </form>
348
- </div>
349
- )}
350
-
351
- {step === 'setup' && totpUri && (
352
- <div
353
- style={{
354
- background: 'var(--theme-elevation-50)',
355
- padding: 'calc(var(--base) * 2)',
356
- borderRadius: 'var(--style-radius-m)',
357
- textAlign: 'center',
358
- }}
359
- >
360
- <p
361
- style={{
362
- color: 'var(--theme-text)',
363
- opacity: 0.7,
364
- marginBottom: 'calc(var(--base) * 1.5)',
365
- }}
366
- >
367
- Scan this QR code with your authenticator app:
368
- </p>
369
-
370
- <img
371
- src={`https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(totpUri)}`}
372
- alt="QR Code"
373
- style={{
374
- width: '200px',
375
- height: '200px',
376
- border: '1px solid var(--theme-elevation-150)',
377
- borderRadius: 'var(--style-radius-s)',
378
- marginBottom: 'var(--base)',
379
- }}
380
- />
381
-
382
- {secret && (
383
- <div style={{ marginBottom: 'calc(var(--base) * 1.5)' }}>
384
- <p
385
- style={{
386
- color: 'var(--theme-text)',
387
- opacity: 0.7,
388
- fontSize: 'var(--font-size-small)',
389
- marginBottom: 'calc(var(--base) * 0.5)',
390
- }}
391
- >
392
- Or enter manually:
393
- </p>
394
- <code
395
- style={{
396
- display: 'inline-block',
397
- padding: 'calc(var(--base) * 0.5)',
398
- background: 'var(--theme-elevation-100)',
399
- borderRadius: 'var(--style-radius-s)',
400
- fontFamily: 'monospace',
401
- fontSize: 'var(--font-size-small)',
402
- color: 'var(--theme-text)',
403
- }}
404
- >
405
- {secret}
406
- </code>
407
- </div>
408
- )}
409
-
410
- <form onSubmit={handleVerify}>
411
- <input
412
- type="text"
413
- inputMode="numeric"
414
- pattern="[0-9]*"
415
- value={verificationCode}
416
- onChange={(e) =>
417
- setVerificationCode(e.target.value.replace(/\D/g, '').slice(0, 6))
418
- }
419
- placeholder="Enter 6-digit code"
420
- style={{
421
- width: '100%',
422
- maxWidth: '200px',
423
- padding: 'calc(var(--base) * 0.75)',
424
- background: 'var(--theme-input-bg)',
425
- border: '1px solid var(--theme-elevation-150)',
426
- borderRadius: 'var(--style-radius-s)',
427
- color: 'var(--theme-text)',
428
- fontSize: 'var(--font-size-h4)',
429
- fontFamily: 'monospace',
430
- textAlign: 'center',
431
- letterSpacing: '0.5em',
432
- marginBottom: 'var(--base)',
433
- boxSizing: 'border-box',
434
- }}
435
- />
436
- <br />
437
- <button
438
- type="submit"
439
- disabled={actionLoading || verificationCode.length !== 6}
440
- style={{
441
- padding: 'calc(var(--base) * 0.75) calc(var(--base) * 2)',
442
- background: 'var(--theme-elevation-800)',
443
- border: 'none',
444
- borderRadius: 'var(--style-radius-s)',
445
- color: 'var(--theme-elevation-50)',
446
- fontSize: 'var(--font-size-base)',
447
- cursor:
448
- actionLoading || verificationCode.length !== 6
449
- ? 'not-allowed'
450
- : 'pointer',
451
- opacity:
452
- actionLoading || verificationCode.length !== 6 ? 0.7 : 1,
453
- }}
454
- >
455
- {actionLoading ? 'Verifying...' : 'Verify'}
456
- </button>
457
- </form>
458
- </div>
459
- )}
460
-
461
- {step === 'backup' && (
462
- <div
463
- style={{
464
- background: 'var(--theme-elevation-50)',
465
- padding: 'calc(var(--base) * 2)',
466
- borderRadius: 'var(--style-radius-m)',
467
- }}
468
- >
469
- <h2
470
- style={{
471
- color: 'var(--theme-text)',
472
- fontSize: 'var(--font-size-h3)',
473
- fontWeight: 600,
474
- margin: '0 0 var(--base) 0',
475
- textAlign: 'center',
476
- }}
477
- >
478
- Save Your Backup Codes
479
- </h2>
480
- <p
481
- style={{
482
- color: 'var(--theme-text)',
483
- opacity: 0.7,
484
- fontSize: 'var(--font-size-small)',
485
- textAlign: 'center',
486
- marginBottom: 'calc(var(--base) * 1.5)',
487
- }}
488
- >
489
- Store these codes safely. Use them if you lose your authenticator.
490
- </p>
491
-
492
- <div
493
- style={{
494
- background: 'var(--theme-elevation-100)',
495
- padding: 'var(--base)',
496
- borderRadius: 'var(--style-radius-s)',
497
- marginBottom: 'var(--base)',
498
- fontFamily: 'monospace',
499
- }}
500
- >
501
- <div
502
- style={{
503
- display: 'grid',
504
- gridTemplateColumns: 'repeat(2, 1fr)',
505
- gap: 'calc(var(--base) * 0.5)',
506
- }}
507
- >
508
- {backupCodes.map((code, index) => (
509
- <div
510
- key={index}
511
- style={{
512
- color: 'var(--theme-text)',
513
- padding: 'calc(var(--base) * 0.25)',
514
- }}
515
- >
516
- {code}
517
- </div>
518
- ))}
519
- </div>
520
- </div>
521
-
522
- <button
523
- onClick={() => navigator.clipboard.writeText(backupCodes.join('\n'))}
524
- style={{
525
- width: '100%',
526
- padding: 'calc(var(--base) * 0.5)',
527
- background: 'var(--theme-elevation-150)',
528
- border: 'none',
529
- borderRadius: 'var(--style-radius-s)',
530
- color: 'var(--theme-text)',
531
- fontSize: 'var(--font-size-small)',
532
- cursor: 'pointer',
533
- marginBottom: 'var(--base)',
534
- }}
535
- >
536
- Copy to Clipboard
537
- </button>
538
-
539
- <button
540
- onClick={handleBackupContinue}
541
- style={{
542
- width: '100%',
543
- padding: 'calc(var(--base) * 0.75)',
544
- background: 'var(--theme-elevation-800)',
545
- border: 'none',
546
- borderRadius: 'var(--style-radius-s)',
547
- color: 'var(--theme-elevation-50)',
548
- fontSize: 'var(--font-size-base)',
549
- cursor: 'pointer',
550
- }}
551
- >
552
- I've Saved My Codes
553
- </button>
554
- </div>
555
- )}
556
- </div>
557
- )
558
- }
559
-
560
- export default TwoFactorManagementClient
@@ -1,20 +0,0 @@
1
- /**
2
- * Management UI Components for Better Auth
3
- *
4
- * Client components for security feature management.
5
- * These are used within the server component views.
6
- */
7
-
8
- // Client components
9
- export { TwoFactorManagementClient } from './TwoFactorManagementClient.js'
10
- export type { TwoFactorManagementClientProps } from './TwoFactorManagementClient.js'
11
-
12
- export { ApiKeysManagementClient } from './ApiKeysManagementClient.js'
13
- export type { ApiKeysManagementClientProps } from './ApiKeysManagementClient.js'
14
-
15
- export { PasskeysManagementClient } from './PasskeysManagementClient.js'
16
- export type { PasskeysManagementClientProps } from './PasskeysManagementClient.js'
17
-
18
- // Nav links (client component)
19
- export { SecurityNavLinks } from './SecurityNavLinks.js'
20
- export type { SecurityNavLinksProps } from './SecurityNavLinks.js'
@@ -1,57 +0,0 @@
1
- import type { AdminViewProps, Locale } from 'payload'
2
- import { DefaultTemplate } from '@payloadcms/next/templates'
3
- import { getVisibleEntities } from '@payloadcms/ui/shared'
4
- import { ApiKeysManagementClient } from '../ApiKeysManagementClient.js'
5
- import { getApiKeyScopesConfig } from '../../../plugin/index.js'
6
- import { buildAvailableScopes } from '../../../utils/generateScopes.js'
7
-
8
- type ApiKeysViewProps = AdminViewProps
9
-
10
- /**
11
- * API Keys management view for Payload admin panel.
12
- * Server component that provides the admin layout.
13
- */
14
- export async function ApiKeysView({
15
- initPageResult,
16
- params,
17
- searchParams,
18
- }: ApiKeysViewProps) {
19
- const { req } = initPageResult
20
- const { payload } = req
21
-
22
- // Await params/searchParams for Next.js 15+ compatibility
23
- const resolvedParams = params ? await params : undefined
24
- const resolvedSearchParams = searchParams ? await searchParams : undefined
25
-
26
- const visibleEntities = getVisibleEntities({ req })
27
-
28
- // Build available scopes from plugin config and collections
29
- const scopesConfig = getApiKeyScopesConfig()
30
- const availableScopes = buildAvailableScopes(
31
- payload.config.collections,
32
- scopesConfig
33
- )
34
-
35
- // Get default scopes from config
36
- const defaultScopes = scopesConfig?.defaultScopes ?? []
37
-
38
- return (
39
- <DefaultTemplate
40
- i18n={req.i18n}
41
- locale={req.locale as Locale | undefined}
42
- params={resolvedParams}
43
- payload={payload}
44
- permissions={initPageResult.permissions}
45
- searchParams={resolvedSearchParams}
46
- user={req.user ?? undefined}
47
- visibleEntities={visibleEntities}
48
- >
49
- <ApiKeysManagementClient
50
- availableScopes={availableScopes}
51
- defaultScopes={defaultScopes}
52
- />
53
- </DefaultTemplate>
54
- )
55
- }
56
-
57
- export default ApiKeysView
@@ -1,42 +0,0 @@
1
- import type { AdminViewProps, Locale } from 'payload'
2
- import { DefaultTemplate } from '@payloadcms/next/templates'
3
- import { getVisibleEntities } from '@payloadcms/ui/shared'
4
- import { PasskeysManagementClient } from '../PasskeysManagementClient.js'
5
-
6
- type PasskeysViewProps = AdminViewProps
7
-
8
- /**
9
- * Passkeys management view for Payload admin panel.
10
- * Server component that provides the admin layout.
11
- */
12
- export async function PasskeysView({
13
- initPageResult,
14
- params,
15
- searchParams,
16
- }: PasskeysViewProps) {
17
- const { req } = initPageResult
18
- const { payload } = req
19
-
20
- // Await params/searchParams for Next.js 15+ compatibility
21
- const resolvedParams = params ? await params : undefined
22
- const resolvedSearchParams = searchParams ? await searchParams : undefined
23
-
24
- const visibleEntities = getVisibleEntities({ req })
25
-
26
- return (
27
- <DefaultTemplate
28
- i18n={req.i18n}
29
- locale={req.locale as Locale | undefined}
30
- params={resolvedParams}
31
- payload={payload}
32
- permissions={initPageResult.permissions}
33
- searchParams={resolvedSearchParams}
34
- user={req.user ?? undefined}
35
- visibleEntities={visibleEntities}
36
- >
37
- <PasskeysManagementClient />
38
- </DefaultTemplate>
39
- )
40
- }
41
-
42
- export default PasskeysView