@delmaredigital/payload-better-auth 0.3.8 → 0.3.9

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 (42) hide show
  1. package/package.json +34 -91
  2. package/src/adapter/collections.ts +0 -621
  3. package/src/adapter/index.ts +0 -712
  4. package/src/components/BeforeLogin.tsx +0 -39
  5. package/src/components/LoginView.tsx +0 -1516
  6. package/src/components/LoginViewWrapper.tsx +0 -35
  7. package/src/components/LogoutButton.tsx +0 -58
  8. package/src/components/PasskeyRegisterButton.tsx +0 -105
  9. package/src/components/PasskeySignInButton.tsx +0 -96
  10. package/src/components/auth/ForgotPasswordView.tsx +0 -274
  11. package/src/components/auth/ResetPasswordView.tsx +0 -331
  12. package/src/components/auth/index.ts +0 -8
  13. package/src/components/management/ApiKeysManagementClient.tsx +0 -988
  14. package/src/components/management/PasskeysManagementClient.tsx +0 -409
  15. package/src/components/management/SecurityNavLinks.tsx +0 -117
  16. package/src/components/management/TwoFactorManagementClient.tsx +0 -560
  17. package/src/components/management/index.ts +0 -20
  18. package/src/components/management/views/ApiKeysView.tsx +0 -57
  19. package/src/components/management/views/PasskeysView.tsx +0 -42
  20. package/src/components/management/views/TwoFactorView.tsx +0 -42
  21. package/src/components/management/views/index.ts +0 -10
  22. package/src/components/twoFactor/TwoFactorSetupView.tsx +0 -515
  23. package/src/components/twoFactor/TwoFactorVerifyView.tsx +0 -238
  24. package/src/components/twoFactor/index.ts +0 -8
  25. package/src/exports/client.ts +0 -77
  26. package/src/exports/components.ts +0 -30
  27. package/src/exports/management.ts +0 -25
  28. package/src/exports/rsc.ts +0 -11
  29. package/src/generated-types.ts +0 -269
  30. package/src/index.ts +0 -135
  31. package/src/plugin/index.ts +0 -834
  32. package/src/scripts/generate-types.ts +0 -269
  33. package/src/types/apiKey.ts +0 -63
  34. package/src/types/betterAuth.ts +0 -253
  35. package/src/utils/access.ts +0 -410
  36. package/src/utils/apiKeyAccess.ts +0 -443
  37. package/src/utils/betterAuthDefaults.ts +0 -102
  38. package/src/utils/detectAuthConfig.ts +0 -47
  39. package/src/utils/detectEnabledPlugins.ts +0 -69
  40. package/src/utils/firstUserAdmin.ts +0 -164
  41. package/src/utils/generateScopes.ts +0 -150
  42. package/src/utils/session.ts +0 -91
@@ -1,269 +0,0 @@
1
- /**
2
- * Type generation script for Better Auth schema.
3
- *
4
- * Generates TypeScript types by introspecting Better Auth's schema
5
- * and diffing plugin additions against the base schema.
6
- *
7
- * Run with: pnpm generate:types
8
- */
9
-
10
- import { passkey } from '@better-auth/passkey'
11
- import type { DBFieldAttribute } from 'better-auth/db'
12
- import { getSchema } from 'better-auth/db'
13
- import {
14
- admin,
15
- anonymous,
16
- apiKey,
17
- bearer,
18
- emailOTP,
19
- genericOAuth,
20
- jwt,
21
- magicLink,
22
- multiSession,
23
- oidcProvider,
24
- oneTap,
25
- oneTimeToken,
26
- openAPI,
27
- organization,
28
- phoneNumber,
29
- twoFactor,
30
- username,
31
- } from 'better-auth/plugins'
32
- import fs from 'node:fs/promises'
33
- import path from 'node:path'
34
- import { fileURLToPath } from 'node:url'
35
-
36
- type Schema = Record<string, { fields: Record<string, DBFieldAttribute> }>
37
-
38
- // Plugins to include in type generation
39
- // Add new plugins here as they become supported
40
- const plugins = [
41
- username(),
42
- admin(),
43
- apiKey(),
44
- passkey(),
45
- bearer(),
46
- emailOTP({ sendVerificationOTP: async () => {} }),
47
- magicLink({ sendMagicLink: async () => {} }),
48
- phoneNumber({ sendOTP: async () => {} }),
49
- oneTap(),
50
- anonymous(),
51
- multiSession(),
52
- oneTimeToken(),
53
- oidcProvider({ loginPage: '' }),
54
- genericOAuth({
55
- config: [
56
- {
57
- providerId: 'generic',
58
- clientId: 'generic',
59
- clientSecret: 'generic',
60
- },
61
- ],
62
- }),
63
- openAPI(),
64
- organization({
65
- teams: { enabled: true },
66
- }),
67
- jwt(),
68
- twoFactor(),
69
- ]
70
-
71
- const betterAuthConfig = {
72
- emailAndPassword: { enabled: true },
73
- user: {
74
- additionalFields: {
75
- role: { type: 'string' as const, defaultValue: 'user', input: false },
76
- },
77
- },
78
- plugins,
79
- }
80
-
81
- const baseSchema = getSchema({ ...betterAuthConfig, plugins: [] })
82
-
83
- /**
84
- * Map Better Auth field types to TypeScript types
85
- */
86
- function mapType(t: string): string {
87
- switch (t) {
88
- case 'boolean':
89
- return 'boolean'
90
- case 'date':
91
- return 'Date'
92
- case 'number':
93
- return 'number'
94
- case 'string':
95
- return 'string'
96
- case 'number[]':
97
- return 'number[]'
98
- case 'string[]':
99
- return 'string[]'
100
- default:
101
- return 'unknown'
102
- }
103
- }
104
-
105
- /**
106
- * Convert string to PascalCase
107
- */
108
- function pascal(s: string): string {
109
- return s
110
- .split(/[-_]/g)
111
- .map((p) => p.charAt(0).toUpperCase() + p.slice(1))
112
- .join('')
113
- }
114
-
115
- /**
116
- * Find fields added by a plugin compared to base schema
117
- */
118
- function diff(
119
- base: Schema,
120
- target: Schema
121
- ): Record<string, Record<string, DBFieldAttribute>> {
122
- const d: Record<string, Record<string, DBFieldAttribute>> = {}
123
- for (const [m, { fields }] of Object.entries(target)) {
124
- const added = Object.entries(fields).filter(
125
- ([k]) => !(k in (base[m]?.fields ?? {}))
126
- )
127
- if (added.length) d[m] = Object.fromEntries(added)
128
- }
129
- return d
130
- }
131
-
132
- /**
133
- * Generate TypeScript type definitions
134
- */
135
- function generate(): string {
136
- let out = `/**
137
- * Auto-generated Better Auth types.
138
- * DO NOT EDIT - Run \`pnpm generate:types\` to regenerate.
139
- *
140
- * Generated from Better Auth schema introspection.
141
- * Contains types for all supported plugins and their field additions.
142
- */
143
-
144
- `
145
-
146
- const pluginAdds: Record<
147
- string,
148
- Record<string, Record<string, DBFieldAttribute>>
149
- > = {}
150
- const seen = new Set<string>()
151
-
152
- // Diff each plugin's schema against base to find additions
153
- for (const pl of plugins) {
154
- const id = (pl as { id?: string }).id
155
- if (!id || seen.has(id)) continue
156
- seen.add(id)
157
- const adds = diff(
158
- baseSchema,
159
- getSchema({ ...betterAuthConfig, plugins: [pl] })
160
- )
161
- for (const [m, f] of Object.entries(adds)) {
162
- pluginAdds[m] ??= {}
163
- pluginAdds[m][id] = f
164
- }
165
- }
166
-
167
- // Collect all models from base and plugins
168
- const models = new Set<string>([
169
- ...Object.keys(baseSchema),
170
- ...Object.keys(pluginAdds),
171
- ])
172
-
173
- // Generate types for each model
174
- for (const model of models) {
175
- const P = pascal(model)
176
- const base = baseSchema[model]?.fields ?? {}
177
- const pluginsForModel = pluginAdds[model] ?? {}
178
- const pluginIds = Object.keys(pluginsForModel)
179
-
180
- // Base fields type
181
- if (Object.keys(base).length) {
182
- out += `export type Base${P}Fields = {\n`
183
- for (const [k, f] of Object.entries(base)) {
184
- const fieldName = f.fieldName ?? k
185
- const optional = f.required ? '' : '?'
186
- out += ` ${fieldName}${optional}: ${mapType(f.type as string)}\n`
187
- }
188
- out += '}\n\n'
189
- }
190
-
191
- // Plugin fields mapping
192
- const needPluginMap = pluginIds.length > 1 || Object.keys(base).length
193
- if (needPluginMap && pluginIds.length) {
194
- out += `export type ${P}PluginFields = {\n`
195
- for (const [pid, flds] of Object.entries(pluginsForModel)) {
196
- out += ` ${JSON.stringify(pid)}: {\n`
197
- for (const [k, f] of Object.entries(flds)) {
198
- const fieldName = f.fieldName ?? k
199
- const optional = f.required ? '' : '?'
200
- out += ` ${fieldName}${optional}: ${mapType(f.type as string)}\n`
201
- }
202
- out += ' }\n'
203
- }
204
- out += '}\n\n'
205
- }
206
-
207
- // Handle single-plugin-only models
208
- if (!Object.keys(base).length && pluginIds.length === 1) {
209
- const only = pluginIds[0]
210
- out += `export type ${P}Fields = {\n`
211
- for (const [k, f] of Object.entries(pluginsForModel[only])) {
212
- const fieldName = f.fieldName ?? k
213
- const optional = f.required ? '' : '?'
214
- out += ` ${fieldName}${optional}: ${mapType(f.type as string)}\n`
215
- }
216
- out += '}\n\n'
217
- out += `export type ${P} = ${P}Fields\n\n`
218
- continue
219
- }
220
-
221
- // Combined type as intersection
222
- const parts: string[] = []
223
- if (Object.keys(base).length) parts.push(`Base${P}Fields`)
224
- if (pluginIds.length) {
225
- const mapName = needPluginMap ? `${P}PluginFields` : undefined
226
- parts.push(
227
- ...pluginIds.map((id) =>
228
- mapName ? `${mapName}[${JSON.stringify(id)}]` : 'never'
229
- )
230
- )
231
- }
232
- out += `export type ${P} = ${parts.join(' & ')}\n\n`
233
- }
234
-
235
- // Plugin ID union type
236
- const pluginIdUnion = [...seen].map((id) => JSON.stringify(id)).join(' | ')
237
- out += `/**
238
- * Union of all supported plugin identifiers.
239
- */
240
- export type PluginId = ${pluginIdUnion}\n\n`
241
-
242
- // Full schema mapping
243
- out += `/**
244
- * Complete schema mapping of all models to their types.
245
- */
246
- export type BetterAuthFullSchema = {\n`
247
- for (const model of models) {
248
- const P = pascal(model)
249
- out += ` ${JSON.stringify(model)}: ${P}\n`
250
- }
251
- out += '}\n\n'
252
-
253
- // Model key union
254
- out += `/**
255
- * Union of all model names in the schema.
256
- */
257
- export type ModelKey = keyof BetterAuthFullSchema\n`
258
-
259
- return out
260
- }
261
-
262
- // Generate and write types
263
- const generated = generate()
264
-
265
- const __dirname = path.dirname(fileURLToPath(import.meta.url))
266
- const outputFile = path.resolve(__dirname, '../generated-types.ts')
267
-
268
- await fs.writeFile(outputFile, generated, 'utf8')
269
- console.log(`Generated types written to ${outputFile}`)
@@ -1,63 +0,0 @@
1
- /**
2
- * API Key Scope Types
3
- *
4
- * Provides typed configuration for API key permission scopes.
5
- */
6
-
7
- /**
8
- * A single permission scope definition.
9
- * Scopes are human-readable permission groups (like GitHub OAuth scopes).
10
- */
11
- export type ScopeDefinition = {
12
- /** Human-readable label for the scope (e.g., "Read Content") */
13
- label: string
14
- /** Description of what this scope allows (e.g., "View posts, pages, and comments") */
15
- description: string
16
- /**
17
- * Permission mapping: { resourceType: ['action1', 'action2'] }
18
- * Maps to Better Auth's permission format.
19
- * Use '*' for resource to match all resources.
20
- * Use '*' in actions array to grant all actions on a resource.
21
- */
22
- permissions: Record<string, string[]>
23
- /** If true, only admin users can create keys with this scope */
24
- adminOnly?: boolean
25
- }
26
-
27
- /**
28
- * Configuration options for API key scopes.
29
- * Can be used in plugin options to customize available scopes.
30
- */
31
- export type ApiKeyScopesConfig = {
32
- /**
33
- * Custom scope definitions.
34
- * Key is the scope ID (e.g., 'content:read'), value is the scope definition.
35
- */
36
- scopes?: Record<string, ScopeDefinition>
37
- /**
38
- * Include auto-generated collection scopes.
39
- * When true (default), generates {collection}:read, {collection}:write, {collection}:delete
40
- * for each Payload collection.
41
- * @default true when no custom scopes provided, false when custom scopes provided
42
- */
43
- includeCollectionScopes?: boolean
44
- /**
45
- * Collections to exclude from auto-generated scopes.
46
- * Useful for hiding sensitive collections like 'sessions' or 'verifications'.
47
- * @default ['sessions', 'verifications', 'accounts', 'twoFactors']
48
- */
49
- excludeCollections?: string[]
50
- /**
51
- * Default scopes assigned to new API keys when user doesn't select any.
52
- * If not provided, keys without scopes will have no permissions.
53
- */
54
- defaultScopes?: string[]
55
- }
56
-
57
- /**
58
- * Scope data passed to the API keys management client component.
59
- */
60
- export type AvailableScope = ScopeDefinition & {
61
- /** The scope ID (e.g., 'content:read') */
62
- id: string
63
- }
@@ -1,253 +0,0 @@
1
- /**
2
- * Enhanced TypeScript types for Better Auth integration.
3
- *
4
- * Provides improved type inference for the Better Auth instance,
5
- * including session/user types, API methods, and error codes.
6
- */
7
-
8
- import type { AuthContext } from 'better-auth'
9
- import { router } from 'better-auth/api'
10
- import type {
11
- BetterAuthOptions,
12
- BetterAuthPlugin,
13
- InferAPI,
14
- InferPluginTypes,
15
- InferSession,
16
- InferUser,
17
- } from 'better-auth/types'
18
- import type { BasePayload, Endpoint, PayloadRequest } from 'payload'
19
-
20
- /**
21
- * Base error codes from Better Auth core.
22
- */
23
- type BaseErrorCodes = {
24
- FAILED_TO_GET_USER_INFO: string
25
- USER_ALREADY_EXISTS: string
26
- INVALID_PASSWORD: string
27
- FAILED_TO_CREATE_USER: string
28
- FAILED_TO_CREATE_SESSION: string
29
- FAILED_TO_UPDATE_USER: string
30
- FAILED_TO_GET_SESSION: string
31
- INVALID_EMAIL_OR_PASSWORD: string
32
- SOCIAL_ACCOUNT_ALREADY_LINKED: string
33
- PROVIDER_NOT_FOUND: string
34
- INVALID_TOKEN: string
35
- ID_TOKEN_NOT_SUPPORTED: string
36
- FAILED_TO_GET_USER_INFO_OPENID: string
37
- UNEXPECTED_PROVIDER_RESPONSE: string
38
- TOKEN_REFRESH_FAILED: string
39
- FAILED_TO_UNLINK: string
40
- ACCOUNT_NOT_FOUND: string
41
- SESSION_EXPIRED: string
42
- INTERNAL_SERVER_ERROR: string
43
- VALIDATION_ERROR: string
44
- }
45
-
46
- /**
47
- * Union to intersection utility type.
48
- */
49
- type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (
50
- k: infer I
51
- ) => void
52
- ? I
53
- : never
54
-
55
- /**
56
- * Deeply prettify a type for better IDE display.
57
- * Flattens intersections and preserves functions/arrays/dates.
58
- */
59
- type PrettifyDeep<T> = {
60
- [K in keyof T]: T[K] extends (...args: unknown[]) => unknown
61
- ? T[K]
62
- : T[K] extends object
63
- ? T[K] extends Array<unknown>
64
- ? T[K]
65
- : T[K] extends Date
66
- ? T[K]
67
- : PrettifyDeep<T[K]>
68
- : T[K]
69
- } & {}
70
-
71
- /**
72
- * Infer error codes from enabled plugins.
73
- */
74
- type InferPluginErrorCodes<O extends BetterAuthOptions> =
75
- O['plugins'] extends Array<infer P>
76
- ? UnionToIntersection<
77
- P extends BetterAuthPlugin
78
- ? P['$ERROR_CODES'] extends Record<string, unknown>
79
- ? P['$ERROR_CODES']
80
- : never
81
- : never
82
- > extends infer R
83
- ? [R] extends [never]
84
- ? object
85
- : R
86
- : object
87
- : object
88
-
89
- /**
90
- * Role array type with configurable roles.
91
- */
92
- export type RoleArray<O extends readonly string[] = readonly ['user']> =
93
- | O[number][]
94
- | null
95
-
96
- /**
97
- * Override role field in a type with configured roles.
98
- */
99
- type OverrideRole<T, O extends readonly string[]> = T extends object
100
- ? Omit<T, 'role'> & { role: RoleArray<O> }
101
- : T
102
-
103
- /**
104
- * The return type of a Better Auth instance.
105
- *
106
- * This provides full type inference for:
107
- * - API endpoints and their return types
108
- * - Session/user types based on enabled plugins
109
- * - Error codes from all enabled plugins
110
- * - Auth context for advanced use cases
111
- *
112
- * @template O - Better Auth options type for inference
113
- *
114
- * @example
115
- * ```ts
116
- * // Access inferred types
117
- * type MySession = typeof payload.betterAuth.$Infer.Session
118
- *
119
- * // Type-safe API calls
120
- * const result = await payload.betterAuth.api.getSession({ headers })
121
- * ```
122
- */
123
- export type BetterAuthReturn<O extends BetterAuthOptions = BetterAuthOptions> = {
124
- /** The request handler for auth endpoints */
125
- handler: (request: Request) => Promise<Response>
126
- /** Type-safe API methods */
127
- api: InferAPI<ReturnType<typeof router<O>>>['endpoints']
128
- /** The resolved options */
129
- options: O
130
- /** All error codes from enabled plugins */
131
- $ERROR_CODES: InferPluginErrorCodes<O> & BaseErrorCodes
132
- /** Auth context (async) for advanced use cases */
133
- $context: Promise<AuthContext>
134
- /** Inferred types for Session and User */
135
- $Infer: InferPluginTypes<O> extends { Session: unknown }
136
- ? InferPluginTypes<O>
137
- : {
138
- Session: {
139
- session: PrettifyDeep<InferSession<O>>
140
- user: PrettifyDeep<InferUser<O>>
141
- }
142
- } & InferPluginTypes<O>
143
- }
144
-
145
- /**
146
- * Payload instance with Better Auth attached.
147
- *
148
- * After initialization, the Payload instance is extended with
149
- * the `betterAuth` property containing the auth instance.
150
- *
151
- * @template O - Better Auth options type for inference
152
- *
153
- * @example
154
- * ```ts
155
- * // In a server action or API route
156
- * const payload = await getPayload({ config })
157
- * const payloadWithAuth = payload as PayloadWithAuth
158
- *
159
- * const session = await payloadWithAuth.betterAuth.api.getSession({ headers })
160
- * ```
161
- */
162
- export type PayloadWithAuth<O extends BetterAuthOptions = BetterAuthOptions> =
163
- BasePayload & {
164
- betterAuth: BetterAuthReturn<O>
165
- }
166
-
167
- /**
168
- * Extended Payload request with Better Auth instance.
169
- *
170
- * Use this type in hooks and endpoints to get type-safe
171
- * access to the Better Auth instance.
172
- *
173
- * @template O - Better Auth options type for inference
174
- *
175
- * @example
176
- * ```ts
177
- * const myHook: CollectionBeforeChangeHook = async ({ req }) => {
178
- * const typedReq = req as PayloadRequestWithBetterAuth<typeof myBetterAuthOptions>
179
- * const session = await typedReq.payload.betterAuth.api.getSession({
180
- * headers: req.headers,
181
- * })
182
- * // ...
183
- * }
184
- * ```
185
- */
186
- export interface PayloadRequestWithBetterAuth<
187
- O extends BetterAuthOptions = BetterAuthOptions,
188
- > extends PayloadRequest {
189
- payload: PayloadWithAuth<O>
190
- }
191
-
192
- /**
193
- * Type utility for collection hooks with Better Auth context.
194
- *
195
- * Transforms a standard Payload hook type to include Better Auth
196
- * on the request's payload instance.
197
- *
198
- * @template O - Better Auth options type for inference
199
- * @template T - The original hook function type
200
- *
201
- * @example
202
- * ```ts
203
- * import type { CollectionBeforeChangeHook } from 'payload'
204
- *
205
- * const beforeChange: CollectionHookWithBetterAuth<
206
- * typeof myOptions,
207
- * CollectionBeforeChangeHook
208
- * > = async ({ req, data }) => {
209
- * // req.payload.betterAuth is fully typed
210
- * const session = await req.payload.betterAuth.api.getSession({
211
- * headers: req.headers,
212
- * })
213
- * return data
214
- * }
215
- * ```
216
- */
217
- export type CollectionHookWithBetterAuth<
218
- O extends BetterAuthOptions,
219
- T extends (args: Record<string, unknown>) => unknown,
220
- > = T extends (args: infer A) => infer R
221
- ? (
222
- args: Omit<A, 'req'> & { req: PayloadRequestWithBetterAuth<O> }
223
- ) => R
224
- : never
225
-
226
- /**
227
- * Payload endpoint type with Better Auth context.
228
- *
229
- * Use this for custom endpoints that need access to Better Auth.
230
- *
231
- * @template O - Better Auth options type for inference
232
- *
233
- * @example
234
- * ```ts
235
- * const myEndpoint: EndpointWithBetterAuth<typeof myOptions> = {
236
- * path: '/custom-auth',
237
- * method: 'post',
238
- * handler: async (req) => {
239
- * // req.payload.betterAuth is fully typed
240
- * const session = await req.payload.betterAuth.api.getSession({
241
- * headers: req.headers,
242
- * })
243
- * return Response.json({ session })
244
- * },
245
- * }
246
- * ```
247
- */
248
- export type EndpointWithBetterAuth<O extends BetterAuthOptions> = Omit<
249
- Endpoint,
250
- 'handler'
251
- > & {
252
- handler: (req: PayloadRequestWithBetterAuth<O>) => Promise<Response> | Response
253
- }