@delmaredigital/payload-better-auth 0.3.6 → 0.3.8

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 (164) hide show
  1. package/README.md +60 -12
  2. package/dist/adapter/collections.d.ts.map +1 -1
  3. package/dist/adapter/collections.js +126 -88
  4. package/dist/adapter/collections.js.map +1 -1
  5. package/dist/adapter/index.js +197 -150
  6. package/dist/adapter/index.js.map +1 -1
  7. package/dist/components/BeforeLogin.d.ts +1 -1
  8. package/dist/components/BeforeLogin.d.ts.map +1 -1
  9. package/dist/components/BeforeLogin.js +15 -7
  10. package/dist/components/BeforeLogin.js.map +1 -1
  11. package/dist/components/LoginView.d.ts +2 -2
  12. package/dist/components/LoginView.d.ts.map +1 -1
  13. package/dist/components/LoginView.js +660 -218
  14. package/dist/components/LoginView.js.map +1 -1
  15. package/dist/components/LoginViewWrapper.d.ts +1 -1
  16. package/dist/components/LoginViewWrapper.d.ts.map +1 -1
  17. package/dist/components/LoginViewWrapper.js +14 -4
  18. package/dist/components/LoginViewWrapper.js.map +1 -1
  19. package/dist/components/LogoutButton.d.ts +1 -1
  20. package/dist/components/LogoutButton.d.ts.map +1 -1
  21. package/dist/components/LogoutButton.js +19 -11
  22. package/dist/components/LogoutButton.js.map +1 -1
  23. package/dist/components/PasskeyRegisterButton.d.ts +2 -2
  24. package/dist/components/PasskeyRegisterButton.d.ts.map +1 -1
  25. package/dist/components/PasskeyRegisterButton.js +20 -16
  26. package/dist/components/PasskeyRegisterButton.js.map +1 -1
  27. package/dist/components/PasskeySignInButton.d.ts +2 -2
  28. package/dist/components/PasskeySignInButton.d.ts.map +1 -1
  29. package/dist/components/PasskeySignInButton.js +14 -12
  30. package/dist/components/PasskeySignInButton.js.map +1 -1
  31. package/dist/components/auth/ForgotPasswordView.d.ts +1 -1
  32. package/dist/components/auth/ForgotPasswordView.d.ts.map +1 -1
  33. package/dist/components/auth/ForgotPasswordView.js +133 -43
  34. package/dist/components/auth/ForgotPasswordView.js.map +1 -1
  35. package/dist/components/auth/ResetPasswordView.d.ts +1 -1
  36. package/dist/components/auth/ResetPasswordView.d.ts.map +1 -1
  37. package/dist/components/auth/ResetPasswordView.js +154 -50
  38. package/dist/components/auth/ResetPasswordView.js.map +1 -1
  39. package/dist/components/auth/index.js +2 -2
  40. package/dist/components/auth/index.js.map +1 -1
  41. package/dist/components/management/ApiKeysManagementClient.d.ts +2 -2
  42. package/dist/components/management/ApiKeysManagementClient.d.ts.map +1 -1
  43. package/dist/components/management/ApiKeysManagementClient.js +539 -222
  44. package/dist/components/management/ApiKeysManagementClient.js.map +1 -1
  45. package/dist/components/management/PasskeysManagementClient.d.ts +2 -2
  46. package/dist/components/management/PasskeysManagementClient.d.ts.map +1 -1
  47. package/dist/components/management/PasskeysManagementClient.js +215 -92
  48. package/dist/components/management/PasskeysManagementClient.js.map +1 -1
  49. package/dist/components/management/SecurityNavLinks.d.ts +1 -1
  50. package/dist/components/management/SecurityNavLinks.d.ts.map +1 -1
  51. package/dist/components/management/SecurityNavLinks.js +51 -24
  52. package/dist/components/management/SecurityNavLinks.js.map +1 -1
  53. package/dist/components/management/TwoFactorManagementClient.d.ts +2 -2
  54. package/dist/components/management/TwoFactorManagementClient.d.ts.map +1 -1
  55. package/dist/components/management/TwoFactorManagementClient.js +270 -111
  56. package/dist/components/management/TwoFactorManagementClient.js.map +1 -1
  57. package/dist/components/management/index.js +2 -2
  58. package/dist/components/management/index.js.map +1 -1
  59. package/dist/components/management/views/ApiKeysView.d.ts +1 -1
  60. package/dist/components/management/views/ApiKeysView.d.ts.map +1 -1
  61. package/dist/components/management/views/ApiKeysView.js +19 -4
  62. package/dist/components/management/views/ApiKeysView.js.map +1 -1
  63. package/dist/components/management/views/PasskeysView.d.ts +1 -1
  64. package/dist/components/management/views/PasskeysView.d.ts.map +1 -1
  65. package/dist/components/management/views/PasskeysView.js +16 -4
  66. package/dist/components/management/views/PasskeysView.js.map +1 -1
  67. package/dist/components/management/views/TwoFactorView.d.ts +1 -1
  68. package/dist/components/management/views/TwoFactorView.d.ts.map +1 -1
  69. package/dist/components/management/views/TwoFactorView.js +16 -4
  70. package/dist/components/management/views/TwoFactorView.js.map +1 -1
  71. package/dist/components/management/views/index.js +2 -2
  72. package/dist/components/management/views/index.js.map +1 -1
  73. package/dist/components/twoFactor/TwoFactorSetupView.d.ts +1 -1
  74. package/dist/components/twoFactor/TwoFactorSetupView.d.ts.map +1 -1
  75. package/dist/components/twoFactor/TwoFactorSetupView.js +240 -87
  76. package/dist/components/twoFactor/TwoFactorSetupView.js.map +1 -1
  77. package/dist/components/twoFactor/TwoFactorVerifyView.d.ts +1 -1
  78. package/dist/components/twoFactor/TwoFactorVerifyView.d.ts.map +1 -1
  79. package/dist/components/twoFactor/TwoFactorVerifyView.js +108 -45
  80. package/dist/components/twoFactor/TwoFactorVerifyView.js.map +1 -1
  81. package/dist/components/twoFactor/index.js +2 -2
  82. package/dist/components/twoFactor/index.js.map +1 -1
  83. package/dist/exports/client.d.ts +2356 -2
  84. package/dist/exports/client.d.ts.map +1 -1
  85. package/dist/exports/client.js +48 -8
  86. package/dist/exports/client.js.map +1 -1
  87. package/dist/exports/components.js +2 -2
  88. package/dist/exports/components.js.map +1 -1
  89. package/dist/exports/management.js +3 -3
  90. package/dist/exports/management.js.map +1 -1
  91. package/dist/exports/rsc.js +2 -2
  92. package/dist/exports/rsc.js.map +1 -1
  93. package/dist/generated-types.js +4 -2
  94. package/dist/generated-types.js.map +1 -1
  95. package/dist/index.js +6 -6
  96. package/dist/index.js.map +1 -1
  97. package/dist/plugin/index.d.ts +35 -2
  98. package/dist/plugin/index.d.ts.map +1 -1
  99. package/dist/plugin/index.js +198 -162
  100. package/dist/plugin/index.js.map +1 -1
  101. package/dist/scripts/generate-types.js +66 -50
  102. package/dist/scripts/generate-types.js.map +1 -1
  103. package/dist/types/apiKey.js +7 -2
  104. package/dist/types/apiKey.js.map +1 -1
  105. package/dist/types/betterAuth.js +23 -2
  106. package/dist/types/betterAuth.js.map +1 -1
  107. package/dist/utils/access.js +78 -81
  108. package/dist/utils/access.js.map +1 -1
  109. package/dist/utils/apiKeyAccess.js +65 -72
  110. package/dist/utils/apiKeyAccess.js.map +1 -1
  111. package/dist/utils/betterAuthDefaults.js +8 -8
  112. package/dist/utils/betterAuthDefaults.js.map +1 -1
  113. package/dist/utils/detectAuthConfig.js +8 -11
  114. package/dist/utils/detectAuthConfig.js.map +1 -1
  115. package/dist/utils/detectEnabledPlugins.js +6 -7
  116. package/dist/utils/detectEnabledPlugins.js.map +1 -1
  117. package/dist/utils/firstUserAdmin.js +18 -20
  118. package/dist/utils/firstUserAdmin.js.map +1 -1
  119. package/dist/utils/generateScopes.js +40 -41
  120. package/dist/utils/generateScopes.js.map +1 -1
  121. package/dist/utils/session.js +8 -9
  122. package/dist/utils/session.js.map +1 -1
  123. package/package.json +97 -26
  124. package/src/adapter/collections.ts +621 -0
  125. package/src/adapter/index.ts +712 -0
  126. package/src/components/BeforeLogin.tsx +39 -0
  127. package/src/components/LoginView.tsx +1516 -0
  128. package/src/components/LoginViewWrapper.tsx +35 -0
  129. package/src/components/LogoutButton.tsx +58 -0
  130. package/src/components/PasskeyRegisterButton.tsx +105 -0
  131. package/src/components/PasskeySignInButton.tsx +96 -0
  132. package/src/components/auth/ForgotPasswordView.tsx +274 -0
  133. package/src/components/auth/ResetPasswordView.tsx +331 -0
  134. package/src/components/auth/index.ts +8 -0
  135. package/src/components/management/ApiKeysManagementClient.tsx +988 -0
  136. package/src/components/management/PasskeysManagementClient.tsx +409 -0
  137. package/src/components/management/SecurityNavLinks.tsx +117 -0
  138. package/src/components/management/TwoFactorManagementClient.tsx +560 -0
  139. package/src/components/management/index.ts +20 -0
  140. package/src/components/management/views/ApiKeysView.tsx +57 -0
  141. package/src/components/management/views/PasskeysView.tsx +42 -0
  142. package/src/components/management/views/TwoFactorView.tsx +42 -0
  143. package/src/components/management/views/index.ts +10 -0
  144. package/src/components/twoFactor/TwoFactorSetupView.tsx +515 -0
  145. package/src/components/twoFactor/TwoFactorVerifyView.tsx +238 -0
  146. package/src/components/twoFactor/index.ts +8 -0
  147. package/src/exports/client.ts +77 -0
  148. package/src/exports/components.ts +30 -0
  149. package/src/exports/management.ts +25 -0
  150. package/src/exports/rsc.ts +11 -0
  151. package/src/generated-types.ts +269 -0
  152. package/src/index.ts +135 -0
  153. package/src/plugin/index.ts +834 -0
  154. package/src/scripts/generate-types.ts +269 -0
  155. package/src/types/apiKey.ts +63 -0
  156. package/src/types/betterAuth.ts +253 -0
  157. package/src/utils/access.ts +410 -0
  158. package/src/utils/apiKeyAccess.ts +443 -0
  159. package/src/utils/betterAuthDefaults.ts +102 -0
  160. package/src/utils/detectAuthConfig.ts +47 -0
  161. package/src/utils/detectEnabledPlugins.ts +69 -0
  162. package/src/utils/firstUserAdmin.ts +164 -0
  163. package/src/utils/generateScopes.ts +150 -0
  164. package/src/utils/session.ts +91 -0
@@ -2,10 +2,9 @@
2
2
  * Payload Plugins for Better Auth
3
3
  *
4
4
  * @packageDocumentation
5
- */
6
- import { detectAuthConfig } from '../utils/detectAuthConfig.js';
7
- import { detectEnabledPlugins, } from '../utils/detectEnabledPlugins.js';
8
- import { buildAvailableScopes, scopesToPermissions, } from '../utils/generateScopes.js';
5
+ */ import { detectAuthConfig } from '../utils/detectAuthConfig.js';
6
+ import { detectEnabledPlugins } from '../utils/detectEnabledPlugins.js';
7
+ import { buildAvailableScopes, scopesToPermissions } from '../utils/generateScopes.js';
9
8
  // Track auth instance for HMR
10
9
  let authInstance = null;
11
10
  // Store API key scopes config for access by management views
@@ -13,20 +12,27 @@ let apiKeyScopesConfig = undefined;
13
12
  /**
14
13
  * Get the configured API key scopes config.
15
14
  * Used by the ApiKeysView to build available scopes.
16
- */
17
- export function getApiKeyScopesConfig() {
15
+ */ export function getApiKeyScopesConfig() {
18
16
  return apiKeyScopesConfig;
19
17
  }
20
18
  /**
21
19
  * Handle API key creation with scopes server-side.
22
20
  * Converts scopes to permissions and calls Better Auth's server API.
23
- */
24
- async function handleApiKeyCreateWithScopes(authApi, payload, headers, body) {
21
+ */ async function handleApiKeyCreateWithScopes(authApi, payload, headers, body) {
25
22
  try {
26
23
  // Get the current session to find the user
27
- const session = await authApi.getSession({ headers });
24
+ const session = await authApi.getSession({
25
+ headers
26
+ });
28
27
  if (!session?.user?.id) {
29
- return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
28
+ return new Response(JSON.stringify({
29
+ error: 'Unauthorized'
30
+ }), {
31
+ status: 401,
32
+ headers: {
33
+ 'Content-Type': 'application/json'
34
+ }
35
+ });
30
36
  }
31
37
  // Extract scopes from the request body
32
38
  const scopes = body.scopes ?? [];
@@ -45,61 +51,83 @@ async function handleApiKeyCreateWithScopes(authApi, payload, headers, body) {
45
51
  expiresIn: body.expiresIn,
46
52
  prefix: body.prefix,
47
53
  permissions: permissions && Object.keys(permissions).length > 0 ? permissions : undefined,
48
- metadata: scopes.length > 0
49
- ? { ...body.metadata, scopes }
50
- : body.metadata,
51
- },
54
+ metadata: scopes.length > 0 ? {
55
+ ...body.metadata,
56
+ scopes
57
+ } : body.metadata
58
+ }
52
59
  };
53
60
  // Call Better Auth's server-side API
54
61
  if (typeof authApi.createApiKey !== 'function') {
55
- return new Response(JSON.stringify({ error: 'API key plugin not enabled' }), { status: 400, headers: { 'Content-Type': 'application/json' } });
62
+ return new Response(JSON.stringify({
63
+ error: 'API key plugin not enabled'
64
+ }), {
65
+ status: 400,
66
+ headers: {
67
+ 'Content-Type': 'application/json'
68
+ }
69
+ });
56
70
  }
57
71
  try {
58
72
  const result = await authApi.createApiKey(createOptions);
59
73
  return new Response(JSON.stringify(result), {
60
74
  status: 200,
61
- headers: { 'Content-Type': 'application/json' },
75
+ headers: {
76
+ 'Content-Type': 'application/json'
77
+ }
62
78
  });
63
- }
64
- catch (createError) {
79
+ } catch (createError) {
65
80
  // Check if error is due to metadata being disabled
66
81
  const errorMessage = createError instanceof Error ? createError.message : String(createError);
67
- const isMetadataDisabled = errorMessage.toLowerCase().includes('metadata') &&
68
- errorMessage.toLowerCase().includes('disabled');
82
+ const isMetadataDisabled = errorMessage.toLowerCase().includes('metadata') && errorMessage.toLowerCase().includes('disabled');
69
83
  if (isMetadataDisabled && createOptions.body.metadata) {
70
84
  // Retry without metadata - key will still work, just won't show scopes in UI
71
85
  console.warn('[better-auth] Metadata disabled, creating API key without scope metadata. Enable metadata with apiKeyWithDefaults() for better UX.');
72
86
  const optionsWithoutMetadata = {
73
87
  body: {
74
88
  ...createOptions.body,
75
- metadata: undefined,
76
- },
89
+ metadata: undefined
90
+ }
77
91
  };
78
92
  const result = await authApi.createApiKey(optionsWithoutMetadata);
79
93
  return new Response(JSON.stringify(result), {
80
94
  status: 200,
81
- headers: { 'Content-Type': 'application/json' },
95
+ headers: {
96
+ 'Content-Type': 'application/json'
97
+ }
82
98
  });
83
99
  }
84
100
  // Re-throw other errors
85
101
  throw createError;
86
102
  }
87
- }
88
- catch (error) {
103
+ } catch (error) {
89
104
  console.error('[better-auth] API key creation error:', error);
90
105
  const message = error instanceof Error ? error.message : 'Failed to create API key';
91
- return new Response(JSON.stringify({ error: message }), { status: 500, headers: { 'Content-Type': 'application/json' } });
106
+ return new Response(JSON.stringify({
107
+ error: message
108
+ }), {
109
+ status: 500,
110
+ headers: {
111
+ 'Content-Type': 'application/json'
112
+ }
113
+ });
92
114
  }
93
115
  }
94
116
  /**
95
117
  * Creates the auth endpoint handler that proxies requests to Better Auth.
96
- */
97
- function createAuthEndpointHandler() {
98
- return async (req) => {
118
+ */ function createAuthEndpointHandler() {
119
+ return async (req)=>{
99
120
  const payloadWithAuth = req.payload;
100
121
  const auth = payloadWithAuth.betterAuth;
101
122
  if (!auth) {
102
- return new Response(JSON.stringify({ error: 'Better Auth not initialized' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
123
+ return new Response(JSON.stringify({
124
+ error: 'Better Auth not initialized'
125
+ }), {
126
+ status: 500,
127
+ headers: {
128
+ 'Content-Type': 'application/json'
129
+ }
130
+ });
103
131
  }
104
132
  try {
105
133
  // Construct the full URL for Better Auth
@@ -107,9 +135,7 @@ function createAuthEndpointHandler() {
107
135
  const protocol = req.headers.get('x-forwarded-proto') || 'http';
108
136
  const host = req.headers.get('host') || 'localhost';
109
137
  const pathname = req.pathname || '';
110
- const search = req.search ||
111
- req.url?.split('?')[1] ||
112
- '';
138
+ const search = req.search || req.url?.split('?')[1] || '';
113
139
  const url = new URL(pathname, `${protocol}://${host}`);
114
140
  if (search) {
115
141
  url.search = search.startsWith('?') ? search : `?${search}`;
@@ -117,7 +143,10 @@ function createAuthEndpointHandler() {
117
143
  // Get request body for non-GET methods
118
144
  let body;
119
145
  let parsedBody;
120
- if (req.method && !['GET', 'HEAD'].includes(req.method)) {
146
+ if (req.method && ![
147
+ 'GET',
148
+ 'HEAD'
149
+ ].includes(req.method)) {
121
150
  try {
122
151
  // Try to get body from request
123
152
  if (typeof req.text === 'function') {
@@ -125,18 +154,15 @@ function createAuthEndpointHandler() {
125
154
  if (body) {
126
155
  try {
127
156
  parsedBody = JSON.parse(body);
128
- }
129
- catch {
130
- // Not JSON, that's okay
157
+ } catch {
158
+ // Not JSON, that's okay
131
159
  }
132
160
  }
133
- }
134
- else if (req.data) {
161
+ } else if (req.data) {
135
162
  parsedBody = req.data;
136
163
  body = JSON.stringify(parsedBody);
137
164
  }
138
- }
139
- catch {
165
+ } catch {
140
166
  // Body might already be consumed, try data property
141
167
  if (req.data) {
142
168
  parsedBody = req.data;
@@ -146,10 +172,7 @@ function createAuthEndpointHandler() {
146
172
  }
147
173
  // Intercept API key creation requests with scopes
148
174
  // Better Auth's API key create endpoint is POST /api-key/create
149
- const isApiKeyCreate = req.method === 'POST' &&
150
- pathname.endsWith('/api-key/create') &&
151
- parsedBody?.scopes &&
152
- Array.isArray(parsedBody.scopes);
175
+ const isApiKeyCreate = req.method === 'POST' && pathname.endsWith('/api-key/create') && parsedBody?.scopes && Array.isArray(parsedBody.scopes);
153
176
  if (isApiKeyCreate && parsedBody) {
154
177
  return handleApiKeyCreateWithScopes(auth.api, req.payload, req.headers, parsedBody);
155
178
  }
@@ -157,69 +180,71 @@ function createAuthEndpointHandler() {
157
180
  const request = new Request(url.toString(), {
158
181
  method: req.method || 'GET',
159
182
  headers: req.headers,
160
- body,
183
+ body
161
184
  });
162
185
  const response = await auth.handler(request);
163
186
  return response;
164
- }
165
- catch (error) {
187
+ } catch (error) {
166
188
  console.error('[better-auth] Endpoint handler error:', error);
167
- return new Response(JSON.stringify({ error: 'Internal server error' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
189
+ return new Response(JSON.stringify({
190
+ error: 'Internal server error'
191
+ }), {
192
+ status: 500,
193
+ headers: {
194
+ 'Content-Type': 'application/json'
195
+ }
196
+ });
168
197
  }
169
198
  };
170
199
  }
171
200
  /**
172
201
  * Generates Payload endpoints for Better Auth.
173
- */
174
- function generateAuthEndpoints(basePath) {
202
+ */ function generateAuthEndpoints(basePath) {
175
203
  const handler = createAuthEndpointHandler();
176
- const methods = ['get', 'post', 'patch', 'put', 'delete'];
177
- return methods.map((method) => ({
178
- path: `${basePath}/:path*`,
179
- method,
180
- handler,
181
- }));
204
+ const methods = [
205
+ 'get',
206
+ 'post',
207
+ 'patch',
208
+ 'put',
209
+ 'delete'
210
+ ];
211
+ return methods.map((method)=>({
212
+ path: `${basePath}/:path*`,
213
+ method,
214
+ handler
215
+ }));
182
216
  }
183
217
  /**
184
218
  * Injects admin components into the Payload config when disableLocalStrategy is detected.
185
- */
186
- function injectAdminComponents(config, options) {
219
+ */ function injectAdminComponents(config, options) {
187
220
  const authDetection = detectAuthConfig(config);
188
221
  // Skip if not using disableLocalStrategy or auto-injection is disabled
189
- if (!authDetection.hasDisableLocalStrategy ||
190
- options.autoInjectAdminComponents === false) {
222
+ if (!authDetection.hasDisableLocalStrategy || options.autoInjectAdminComponents === false) {
191
223
  return config;
192
224
  }
193
225
  const adminOptions = options.admin ?? {};
194
226
  const existingComponents = config.admin?.components ?? {};
195
227
  // Build logout button config
196
- const logoutButton = adminOptions.disableLogoutButton
197
- ? existingComponents.logout?.Button
198
- : adminOptions.logoutButtonComponent ??
199
- '@delmaredigital/payload-better-auth/components#LogoutButton';
228
+ const logoutButton = adminOptions.disableLogoutButton ? existingComponents.logout?.Button : adminOptions.logoutButtonComponent ?? '@delmaredigital/payload-better-auth/components#LogoutButton';
200
229
  // Build beforeLogin config
201
230
  const existingBeforeLogin = existingComponents.beforeLogin ?? [];
202
- const beforeLogin = adminOptions.disableBeforeLogin
203
- ? existingBeforeLogin
204
- : [
205
- ...(Array.isArray(existingBeforeLogin)
206
- ? existingBeforeLogin
207
- : [existingBeforeLogin]),
208
- adminOptions.beforeLoginComponent ??
209
- '@delmaredigital/payload-better-auth/components#BeforeLogin',
210
- ];
231
+ const beforeLogin = adminOptions.disableBeforeLogin ? existingBeforeLogin : [
232
+ ...Array.isArray(existingBeforeLogin) ? existingBeforeLogin : [
233
+ existingBeforeLogin
234
+ ],
235
+ adminOptions.beforeLoginComponent ?? '@delmaredigital/payload-better-auth/components#BeforeLogin'
236
+ ];
211
237
  // Build login view config
212
238
  const existingViews = existingComponents.views ?? {};
213
- const newLoginView = adminOptions.disableLoginView
214
- ? undefined
215
- : {
216
- Component: adminOptions.loginViewComponent ??
217
- '@delmaredigital/payload-better-auth/rsc#LoginViewWrapper',
218
- path: '/login',
219
- };
239
+ const newLoginView = adminOptions.disableLoginView ? undefined : {
240
+ Component: adminOptions.loginViewComponent ?? '@delmaredigital/payload-better-auth/rsc#LoginViewWrapper',
241
+ path: '/login'
242
+ };
220
243
  const views = {
221
244
  ...existingViews,
222
- ...(newLoginView ? { login: newLoginView } : {}),
245
+ ...newLoginView ? {
246
+ login: newLoginView
247
+ } : {}
223
248
  };
224
249
  // Store login config in config.custom for the RSC wrapper to read
225
250
  const loginConfig = adminOptions.login ?? {};
@@ -230,31 +255,26 @@ function injectAdminComponents(config, options) {
230
255
  ...config.custom,
231
256
  betterAuth: {
232
257
  ...config.custom?.betterAuth,
233
- login: loginConfig,
234
- },
258
+ login: loginConfig
259
+ }
235
260
  },
236
261
  admin: {
237
262
  ...config.admin,
238
263
  components: {
239
264
  ...existingComponents,
240
- logout: logoutButton
241
- ? {
242
- ...(typeof existingComponents.logout === 'object'
243
- ? existingComponents.logout
244
- : {}),
245
- Button: logoutButton,
246
- }
247
- : existingComponents.logout,
265
+ logout: logoutButton ? {
266
+ ...typeof existingComponents.logout === 'object' ? existingComponents.logout : {},
267
+ Button: logoutButton
268
+ } : existingComponents.logout,
248
269
  beforeLogin,
249
- views,
250
- },
251
- },
270
+ views
271
+ }
272
+ }
252
273
  };
253
274
  }
254
275
  /**
255
276
  * Injects management UI components into the Payload config based on enabled plugins.
256
- */
257
- function injectManagementComponents(config, options) {
277
+ */ function injectManagementComponents(config, options) {
258
278
  const adminOptions = options.admin ?? {};
259
279
  // Skip if management UI is disabled
260
280
  if (adminOptions.enableManagementUI === false) {
@@ -266,7 +286,7 @@ function injectManagementComponents(config, options) {
266
286
  const paths = {
267
287
  twoFactor: adminOptions.managementPaths?.twoFactor ?? '/security/two-factor',
268
288
  apiKeys: adminOptions.managementPaths?.apiKeys ?? '/security/api-keys',
269
- passkeys: adminOptions.managementPaths?.passkeys ?? '/security/passkeys',
289
+ passkeys: adminOptions.managementPaths?.passkeys ?? '/security/passkeys'
270
290
  };
271
291
  const existingComponents = config.admin?.components ?? {};
272
292
  const existingViews = existingComponents.views ?? {};
@@ -278,41 +298,39 @@ function injectManagementComponents(config, options) {
278
298
  if (enabledPlugins.hasTwoFactor) {
279
299
  managementViews.securityTwoFactor = {
280
300
  Component: '@delmaredigital/payload-better-auth/rsc#TwoFactorView',
281
- path: paths.twoFactor,
301
+ path: paths.twoFactor
282
302
  };
283
303
  }
284
304
  // API keys (if enabled)
285
305
  if (enabledPlugins.hasApiKey) {
286
306
  managementViews.securityApiKeys = {
287
307
  Component: '@delmaredigital/payload-better-auth/rsc#ApiKeysView',
288
- path: paths.apiKeys,
308
+ path: paths.apiKeys
289
309
  };
290
310
  }
291
311
  // Passkeys (if enabled)
292
312
  if (enabledPlugins.hasPasskey) {
293
313
  managementViews.securityPasskeys = {
294
314
  Component: '@delmaredigital/payload-better-auth/rsc#PasskeysView',
295
- path: paths.passkeys,
315
+ path: paths.passkeys
296
316
  };
297
317
  }
298
318
  // Only add nav links if at least one plugin is enabled
299
319
  const hasAnyPlugin = enabledPlugins.hasTwoFactor || enabledPlugins.hasApiKey || enabledPlugins.hasPasskey;
300
320
  // Add SecurityNavLinks to afterNavLinks with clientProps for enabled plugins
301
- const afterNavLinks = hasAnyPlugin
302
- ? [
303
- ...(Array.isArray(existingAfterNavLinks)
304
- ? existingAfterNavLinks
305
- : [existingAfterNavLinks]),
306
- {
307
- path: '@delmaredigital/payload-better-auth/components/management#SecurityNavLinks',
308
- clientProps: {
309
- showTwoFactor: enabledPlugins.hasTwoFactor,
310
- showApiKeys: enabledPlugins.hasApiKey,
311
- showPasskeys: enabledPlugins.hasPasskey,
312
- },
313
- },
314
- ]
315
- : existingAfterNavLinks;
321
+ const afterNavLinks = hasAnyPlugin ? [
322
+ ...Array.isArray(existingAfterNavLinks) ? existingAfterNavLinks : [
323
+ existingAfterNavLinks
324
+ ],
325
+ {
326
+ path: '@delmaredigital/payload-better-auth/components/management#SecurityNavLinks',
327
+ clientProps: {
328
+ showTwoFactor: enabledPlugins.hasTwoFactor,
329
+ showApiKeys: enabledPlugins.hasApiKey,
330
+ showPasskeys: enabledPlugins.hasPasskey
331
+ }
332
+ }
333
+ ] : existingAfterNavLinks;
316
334
  return {
317
335
  ...config,
318
336
  admin: {
@@ -321,11 +339,11 @@ function injectManagementComponents(config, options) {
321
339
  ...existingComponents,
322
340
  views: {
323
341
  ...existingViews,
324
- ...managementViews,
342
+ ...managementViews
325
343
  },
326
- afterNavLinks,
327
- },
328
- },
344
+ afterNavLinks
345
+ }
346
+ }
329
347
  };
330
348
  }
331
349
  /**
@@ -356,30 +374,28 @@ function injectManagementComponents(config, options) {
356
374
  * ],
357
375
  * })
358
376
  * ```
359
- */
360
- export function createBetterAuthPlugin(options) {
361
- const { createAuth, authBasePath = '/auth', autoRegisterEndpoints = true, autoInjectAdminComponents = true, } = options;
377
+ */ export function createBetterAuthPlugin(options) {
378
+ const { createAuth, authBasePath = '/auth', autoRegisterEndpoints = true, autoInjectAdminComponents = true } = options;
362
379
  // Store API key scopes config for access by management views
363
380
  apiKeyScopesConfig = options.admin?.apiKey;
364
- return (incomingConfig) => {
381
+ return (incomingConfig)=>{
365
382
  // Inject admin components if enabled
366
- let config = autoInjectAdminComponents
367
- ? injectAdminComponents(incomingConfig, options)
368
- : incomingConfig;
383
+ let config = autoInjectAdminComponents ? injectAdminComponents(incomingConfig, options) : incomingConfig;
369
384
  // Inject management UI components
370
385
  config = injectManagementComponents(config, options);
371
386
  // Generate auth endpoints if enabled
372
- const authEndpoints = autoRegisterEndpoints
373
- ? generateAuthEndpoints(authBasePath)
374
- : [];
387
+ const authEndpoints = autoRegisterEndpoints ? generateAuthEndpoints(authBasePath) : [];
375
388
  // Merge endpoints
376
389
  const existingEndpoints = config.endpoints ?? [];
377
390
  // Get existing onInit
378
391
  const existingOnInit = config.onInit;
379
392
  return {
380
393
  ...config,
381
- endpoints: [...existingEndpoints, ...authEndpoints],
382
- onInit: async (payload) => {
394
+ endpoints: [
395
+ ...existingEndpoints,
396
+ ...authEndpoints
397
+ ],
398
+ onInit: async (payload)=>{
383
399
  if (existingOnInit) {
384
400
  await existingOnInit(payload);
385
401
  }
@@ -391,8 +407,7 @@ export function createBetterAuthPlugin(options) {
391
407
  if (!authInstance) {
392
408
  try {
393
409
  authInstance = createAuth(payload);
394
- }
395
- catch (error) {
410
+ } catch (error) {
396
411
  console.error('[better-auth] Failed to create auth:', error);
397
412
  throw error;
398
413
  }
@@ -402,9 +417,9 @@ export function createBetterAuthPlugin(options) {
402
417
  value: authInstance,
403
418
  writable: false,
404
419
  enumerable: false,
405
- configurable: false,
420
+ configurable: false
406
421
  });
407
- },
422
+ }
408
423
  };
409
424
  };
410
425
  }
@@ -443,31 +458,42 @@ export function createBetterAuthPlugin(options) {
443
458
  * }
444
459
  * }
445
460
  * ```
446
- */
447
- export function betterAuthStrategy(options = {}) {
461
+ */ export function betterAuthStrategy(options = {}) {
448
462
  const { usersCollection = 'users', membersCollection = 'members' } = options;
449
463
  return {
450
464
  name: 'better-auth',
451
- authenticate: async ({ payload, headers, }) => {
465
+ authenticate: async ({ payload, headers })=>{
452
466
  try {
453
467
  const payloadWithAuth = payload;
454
468
  const auth = payloadWithAuth.betterAuth;
455
469
  if (!auth) {
456
470
  console.error('Better Auth not initialized on payload instance');
457
- return { user: null };
471
+ return {
472
+ user: null
473
+ };
458
474
  }
459
- const sessionData = await auth.api.getSession({ headers });
475
+ const sessionData = await auth.api.getSession({
476
+ headers
477
+ });
460
478
  if (!sessionData?.user?.id) {
461
- return { user: null };
479
+ return {
480
+ user: null
481
+ };
462
482
  }
463
483
  const users = await payload.find({
464
484
  collection: usersCollection,
465
- where: { id: { equals: sessionData.user.id } },
485
+ where: {
486
+ id: {
487
+ equals: sessionData.user.id
488
+ }
489
+ },
466
490
  limit: 1,
467
- depth: 0,
491
+ depth: 0
468
492
  });
469
493
  if (users.docs.length === 0) {
470
- return { user: null };
494
+ return {
495
+ user: null
496
+ };
471
497
  }
472
498
  // Extract session fields to merge onto user (e.g., activeOrganizationId from org plugin)
473
499
  // Exclude fields that might conflict with user fields
@@ -480,42 +506,52 @@ export function betterAuthStrategy(options = {}) {
480
506
  collection: membersCollection,
481
507
  where: {
482
508
  and: [
483
- { user: { equals: sessionData.user.id } },
484
- { organization: { equals: sessionFields.activeOrganizationId } },
485
- ],
509
+ {
510
+ user: {
511
+ equals: sessionData.user.id
512
+ }
513
+ },
514
+ {
515
+ organization: {
516
+ equals: sessionFields.activeOrganizationId
517
+ }
518
+ }
519
+ ]
486
520
  },
487
521
  limit: 1,
488
- depth: 0,
522
+ depth: 0
489
523
  });
490
524
  if (memberships.docs.length > 0) {
491
525
  organizationRole = memberships.docs[0].role;
492
526
  }
493
- }
494
- catch {
495
- // Members collection might not exist (org plugin not used), silently ignore
527
+ } catch {
528
+ // Members collection might not exist (org plugin not used), silently ignore
496
529
  }
497
530
  }
498
531
  return {
499
532
  user: {
500
533
  ...users.docs[0],
501
- ...sessionFields, // Merge session fields (activeOrganizationId, etc.)
502
- ...(organizationRole && { organizationRole }), // Add org role if found
534
+ ...sessionFields,
535
+ ...organizationRole && {
536
+ organizationRole
537
+ },
503
538
  collection: usersCollection,
504
- _strategy: 'better-auth',
505
- },
539
+ _strategy: 'better-auth'
540
+ }
506
541
  };
507
- }
508
- catch (error) {
542
+ } catch (error) {
509
543
  console.error('Better Auth strategy error:', error);
510
- return { user: null };
544
+ return {
545
+ user: null
546
+ };
511
547
  }
512
- },
548
+ }
513
549
  };
514
550
  }
515
551
  /**
516
552
  * Reset the auth instance (useful for testing)
517
- */
518
- export function resetAuthInstance() {
553
+ */ export function resetAuthInstance() {
519
554
  authInstance = null;
520
555
  }
556
+
521
557
  //# sourceMappingURL=index.js.map