@better-auth/core 1.4.12-beta.2 → 1.4.13

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 (185) hide show
  1. package/.turbo/turbo-build.log +172 -35
  2. package/dist/api/index.d.mts +178 -1
  3. package/dist/api/index.mjs +2 -1
  4. package/dist/context/endpoint-context.d.mts +19 -0
  5. package/dist/context/endpoint-context.mjs +31 -0
  6. package/dist/context/global.d.mts +7 -0
  7. package/dist/context/global.mjs +37 -0
  8. package/dist/context/index.d.mts +5 -53
  9. package/dist/context/index.mjs +5 -2
  10. package/dist/context/request-state.d.mts +27 -0
  11. package/dist/context/request-state.mjs +49 -0
  12. package/dist/context/transaction.d.mts +16 -0
  13. package/dist/context/transaction.mjs +52 -0
  14. package/dist/db/adapter/factory.d.mts +27 -0
  15. package/dist/db/adapter/factory.mjs +738 -0
  16. package/dist/db/adapter/get-default-field-name.d.mts +18 -0
  17. package/dist/db/adapter/get-default-field-name.mjs +38 -0
  18. package/dist/db/adapter/get-default-model-name.d.mts +12 -0
  19. package/dist/db/adapter/get-default-model-name.mjs +32 -0
  20. package/dist/db/adapter/get-field-attributes.d.mts +29 -0
  21. package/dist/db/adapter/get-field-attributes.mjs +39 -0
  22. package/dist/db/adapter/get-field-name.d.mts +18 -0
  23. package/dist/db/adapter/get-field-name.mjs +33 -0
  24. package/dist/db/adapter/get-id-field.d.mts +39 -0
  25. package/dist/db/adapter/get-id-field.mjs +68 -0
  26. package/dist/db/adapter/get-model-name.d.mts +12 -0
  27. package/dist/db/adapter/get-model-name.mjs +23 -0
  28. package/dist/db/adapter/index.d.mts +513 -1
  29. package/dist/db/adapter/index.mjs +8 -970
  30. package/dist/db/adapter/types.d.mts +139 -0
  31. package/dist/db/adapter/utils.d.mts +7 -0
  32. package/dist/db/adapter/utils.mjs +38 -0
  33. package/dist/db/get-tables.d.mts +8 -0
  34. package/dist/{get-tables-CMc_Emww.mjs → db/get-tables.mjs} +1 -1
  35. package/dist/db/index.d.mts +10 -2
  36. package/dist/db/index.mjs +7 -60
  37. package/dist/db/plugin.d.mts +12 -0
  38. package/dist/db/schema/account.d.mts +26 -0
  39. package/dist/db/schema/account.mjs +19 -0
  40. package/dist/db/schema/rate-limit.d.mts +14 -0
  41. package/dist/db/schema/rate-limit.mjs +11 -0
  42. package/dist/db/schema/session.d.mts +21 -0
  43. package/dist/db/schema/session.mjs +14 -0
  44. package/dist/db/schema/shared.d.mts +10 -0
  45. package/dist/db/schema/shared.mjs +11 -0
  46. package/dist/db/schema/user.d.mts +20 -0
  47. package/dist/db/schema/user.mjs +13 -0
  48. package/dist/db/schema/verification.d.mts +19 -0
  49. package/dist/db/schema/verification.mjs +12 -0
  50. package/dist/db/type.d.mts +143 -0
  51. package/dist/env/color-depth.d.mts +4 -0
  52. package/dist/env/color-depth.mjs +88 -0
  53. package/dist/env/env-impl.d.mts +32 -0
  54. package/dist/env/env-impl.mjs +82 -0
  55. package/dist/env/index.d.mts +4 -2
  56. package/dist/env/index.mjs +3 -1
  57. package/dist/{index-BRBu0-5h.d.mts → env/logger.d.mts} +1 -35
  58. package/dist/env/logger.mjs +81 -0
  59. package/dist/error/codes.d.mts +48 -0
  60. package/dist/{error-DP1xOn7P.mjs → error/codes.mjs} +3 -14
  61. package/dist/error/index.d.mts +5 -48
  62. package/dist/error/index.mjs +12 -3
  63. package/dist/index.d.mts +8 -2
  64. package/dist/oauth2/client-credentials-token.d.mts +36 -0
  65. package/dist/oauth2/client-credentials-token.mjs +54 -0
  66. package/dist/oauth2/create-authorization-url.d.mts +45 -0
  67. package/dist/oauth2/create-authorization-url.mjs +42 -0
  68. package/dist/oauth2/index.d.mts +8 -2
  69. package/dist/oauth2/index.mjs +6 -2
  70. package/dist/oauth2/oauth-provider.d.mts +194 -0
  71. package/dist/oauth2/refresh-access-token.d.mts +36 -0
  72. package/dist/oauth2/refresh-access-token.mjs +58 -0
  73. package/dist/oauth2/utils.d.mts +7 -0
  74. package/dist/oauth2/utils.mjs +27 -0
  75. package/dist/oauth2/validate-authorization-code.d.mts +55 -0
  76. package/dist/oauth2/validate-authorization-code.mjs +71 -0
  77. package/dist/oauth2/verify.d.mts +49 -0
  78. package/dist/oauth2/verify.mjs +95 -0
  79. package/dist/social-providers/apple.d.mts +119 -0
  80. package/dist/social-providers/apple.mjs +102 -0
  81. package/dist/social-providers/atlassian.d.mts +72 -0
  82. package/dist/social-providers/atlassian.mjs +83 -0
  83. package/dist/social-providers/cognito.d.mts +87 -0
  84. package/dist/social-providers/cognito.mjs +166 -0
  85. package/dist/social-providers/discord.d.mts +126 -0
  86. package/dist/social-providers/discord.mjs +64 -0
  87. package/dist/social-providers/dropbox.d.mts +71 -0
  88. package/dist/social-providers/dropbox.mjs +75 -0
  89. package/dist/social-providers/facebook.d.mts +81 -0
  90. package/dist/social-providers/facebook.mjs +120 -0
  91. package/dist/social-providers/figma.d.mts +63 -0
  92. package/dist/social-providers/figma.mjs +84 -0
  93. package/dist/social-providers/github.d.mts +104 -0
  94. package/dist/social-providers/github.mjs +80 -0
  95. package/dist/social-providers/gitlab.d.mts +125 -0
  96. package/dist/social-providers/gitlab.mjs +82 -0
  97. package/dist/social-providers/google.d.mts +99 -0
  98. package/dist/social-providers/google.mjs +109 -0
  99. package/dist/social-providers/huggingface.d.mts +85 -0
  100. package/dist/social-providers/huggingface.mjs +75 -0
  101. package/dist/social-providers/index.d.mts +1723 -1
  102. package/dist/social-providers/index.mjs +33 -2570
  103. package/dist/social-providers/kakao.d.mts +163 -0
  104. package/dist/social-providers/kakao.mjs +72 -0
  105. package/dist/social-providers/kick.d.mts +75 -0
  106. package/dist/social-providers/kick.mjs +71 -0
  107. package/dist/social-providers/line.d.mts +107 -0
  108. package/dist/social-providers/line.mjs +113 -0
  109. package/dist/social-providers/linear.d.mts +70 -0
  110. package/dist/social-providers/linear.mjs +88 -0
  111. package/dist/social-providers/linkedin.d.mts +69 -0
  112. package/dist/social-providers/linkedin.mjs +76 -0
  113. package/dist/social-providers/microsoft-entra-id.d.mts +174 -0
  114. package/dist/social-providers/microsoft-entra-id.mjs +106 -0
  115. package/dist/social-providers/naver.d.mts +104 -0
  116. package/dist/social-providers/naver.mjs +67 -0
  117. package/dist/social-providers/notion.d.mts +66 -0
  118. package/dist/social-providers/notion.mjs +75 -0
  119. package/dist/social-providers/paybin.d.mts +73 -0
  120. package/dist/social-providers/paybin.mjs +85 -0
  121. package/dist/social-providers/paypal.d.mts +131 -0
  122. package/dist/social-providers/paypal.mjs +144 -0
  123. package/dist/social-providers/polar.d.mts +76 -0
  124. package/dist/social-providers/polar.mjs +73 -0
  125. package/dist/social-providers/reddit.d.mts +64 -0
  126. package/dist/social-providers/reddit.mjs +83 -0
  127. package/dist/social-providers/roblox.d.mts +72 -0
  128. package/dist/social-providers/roblox.mjs +59 -0
  129. package/dist/social-providers/salesforce.d.mts +81 -0
  130. package/dist/social-providers/salesforce.mjs +91 -0
  131. package/dist/social-providers/slack.d.mts +85 -0
  132. package/dist/social-providers/slack.mjs +68 -0
  133. package/dist/social-providers/spotify.d.mts +65 -0
  134. package/dist/social-providers/spotify.mjs +71 -0
  135. package/dist/social-providers/tiktok.d.mts +171 -0
  136. package/dist/social-providers/tiktok.mjs +62 -0
  137. package/dist/social-providers/twitch.d.mts +81 -0
  138. package/dist/social-providers/twitch.mjs +78 -0
  139. package/dist/social-providers/twitter.d.mts +140 -0
  140. package/dist/social-providers/twitter.mjs +87 -0
  141. package/dist/social-providers/vercel.d.mts +64 -0
  142. package/dist/social-providers/vercel.mjs +61 -0
  143. package/dist/social-providers/vk.d.mts +72 -0
  144. package/dist/social-providers/vk.mjs +83 -0
  145. package/dist/social-providers/zoom.d.mts +173 -0
  146. package/dist/social-providers/zoom.mjs +72 -0
  147. package/dist/types/context.d.mts +215 -0
  148. package/dist/types/cookie.d.mts +15 -0
  149. package/dist/types/helper.d.mts +8 -0
  150. package/dist/types/index.d.mts +8 -0
  151. package/dist/types/init-options.d.mts +1266 -0
  152. package/dist/types/plugin-client.d.mts +103 -0
  153. package/dist/types/plugin.d.mts +121 -0
  154. package/dist/utils/deprecate.d.mts +10 -0
  155. package/dist/utils/deprecate.mjs +17 -0
  156. package/dist/utils/error-codes.d.mts +9 -0
  157. package/dist/utils/error-codes.mjs +7 -0
  158. package/dist/utils/id.d.mts +4 -0
  159. package/dist/utils/id.mjs +9 -0
  160. package/dist/utils/index.d.mts +5 -26
  161. package/dist/utils/index.mjs +5 -2
  162. package/dist/utils/json.d.mts +4 -0
  163. package/dist/utils/json.mjs +25 -0
  164. package/dist/utils/string.d.mts +4 -0
  165. package/dist/utils/string.mjs +7 -0
  166. package/package.json +1 -1
  167. package/src/context/endpoint-context.ts +7 -15
  168. package/src/context/global.ts +57 -0
  169. package/src/context/index.ts +1 -0
  170. package/src/context/request-state.ts +7 -12
  171. package/src/context/transaction.ts +7 -16
  172. package/src/db/adapter/factory.ts +13 -13
  173. package/src/db/adapter/get-default-model-name.ts +1 -1
  174. package/src/db/adapter/get-id-field.ts +2 -2
  175. package/src/error/index.ts +2 -3
  176. package/src/social-providers/gitlab.ts +1 -1
  177. package/src/types/context.ts +137 -131
  178. package/src/types/cookie.ts +6 -4
  179. package/src/types/index.ts +2 -1
  180. package/tsdown.config.ts +9 -0
  181. package/dist/context-BGZ8V6DD.mjs +0 -126
  182. package/dist/env-DbssmzoK.mjs +0 -245
  183. package/dist/index-zgYuzZ7O.d.mts +0 -8020
  184. package/dist/oauth2-COJkghlT.mjs +0 -326
  185. package/dist/utils-U2L7n92V.mjs +0 -59
@@ -0,0 +1,1266 @@
1
+ import { DBFieldAttribute, ModelNames, SecondaryStorage } from "../db/type.mjs";
2
+ import { Account } from "../db/schema/account.mjs";
3
+ import { RateLimit } from "../db/schema/rate-limit.mjs";
4
+ import { Session } from "../db/schema/session.mjs";
5
+ import { User } from "../db/schema/user.mjs";
6
+ import { Verification } from "../db/schema/verification.mjs";
7
+ import "../db/index.mjs";
8
+ import { Awaitable, LiteralUnion } from "./helper.mjs";
9
+ import { DBAdapterDebugLogOption, DBAdapterInstance } from "../db/adapter/index.mjs";
10
+ import { Logger } from "../env/logger.mjs";
11
+ import { SocialProviderList, SocialProviders } from "../social-providers/index.mjs";
12
+ import { BetterAuthPlugin } from "./plugin.mjs";
13
+ import { AuthContext, GenericEndpointContext } from "./context.mjs";
14
+ import { AuthMiddleware } from "../api/index.mjs";
15
+ import { CookieOptions } from "better-call";
16
+ import { Database } from "bun:sqlite";
17
+ import { DatabaseSync } from "node:sqlite";
18
+ import { Dialect, Kysely, MysqlPool, PostgresPool, SqliteDatabase } from "kysely";
19
+
20
+ //#region src/types/init-options.d.ts
21
+ type KyselyDatabaseType = "postgres" | "mysql" | "sqlite" | "mssql";
22
+ type OmitId<T extends {
23
+ id: unknown;
24
+ }> = Omit<T, "id">;
25
+ type Optional<T> = { [P in keyof T]?: T[P] | undefined };
26
+ type GenerateIdFn = (options: {
27
+ model: ModelNames;
28
+ size?: number | undefined;
29
+ }) => string | false;
30
+ type BetterAuthRateLimitOptions = {
31
+ /**
32
+ * By default, rate limiting is only
33
+ * enabled on production.
34
+ */
35
+ enabled?: boolean | undefined;
36
+ /**
37
+ * Default window to use for rate limiting. The value
38
+ * should be in seconds.
39
+ *
40
+ * @default 10 seconds
41
+ */
42
+ window?: number | undefined;
43
+ /**
44
+ * The default maximum number of requests allowed within the window.
45
+ *
46
+ * @default 100 requests
47
+ */
48
+ max?: number | undefined;
49
+ /**
50
+ * Custom rate limit rules to apply to
51
+ * specific paths.
52
+ */
53
+ customRules?: {
54
+ [key: string]: {
55
+ /**
56
+ * The window to use for the custom rule.
57
+ */
58
+ window: number;
59
+ /**
60
+ * The maximum number of requests allowed within the window.
61
+ */
62
+ max: number;
63
+ } | false | ((request: Request) => {
64
+ window: number;
65
+ max: number;
66
+ } | false | Promise<{
67
+ window: number;
68
+ max: number;
69
+ } | false>);
70
+ } | undefined;
71
+ /**
72
+ * Storage configuration
73
+ *
74
+ * By default, rate limiting is stored in memory. If you passed a
75
+ * secondary storage, rate limiting will be stored in the secondary
76
+ * storage.
77
+ *
78
+ * @default "memory"
79
+ */
80
+ storage?: ("memory" | "database" | "secondary-storage") | undefined;
81
+ /**
82
+ * If database is used as storage, the name of the table to
83
+ * use for rate limiting.
84
+ *
85
+ * @default "rateLimit"
86
+ */
87
+ modelName?: string | undefined;
88
+ /**
89
+ * Custom field names for the rate limit table
90
+ */
91
+ fields?: Partial<Record<keyof RateLimit, string>> | undefined;
92
+ /**
93
+ * custom storage configuration.
94
+ *
95
+ * NOTE: If custom storage is used storage
96
+ * is ignored
97
+ */
98
+ customStorage?: {
99
+ get: (key: string) => Promise<RateLimit | undefined>;
100
+ set: (key: string, value: RateLimit) => Promise<void>;
101
+ };
102
+ };
103
+ type BetterAuthAdvancedOptions = {
104
+ /**
105
+ * Ip address configuration
106
+ */
107
+ ipAddress?: {
108
+ /**
109
+ * List of headers to use for ip address
110
+ *
111
+ * Ip address is used for rate limiting and session tracking
112
+ *
113
+ * @example ["x-client-ip", "x-forwarded-for", "cf-connecting-ip"]
114
+ *
115
+ * @default
116
+ * @link https://github.com/better-auth/better-auth/blob/main/packages/better-auth/src/utils/get-request-ip.ts#L8
117
+ */
118
+ ipAddressHeaders?: string[];
119
+ /**
120
+ * Disable ip tracking
121
+ *
122
+ * ⚠︎ This is a security risk and it may expose your application to abuse
123
+ */
124
+ disableIpTracking?: boolean;
125
+ } | undefined;
126
+ /**
127
+ * Use secure cookies
128
+ *
129
+ * @default false
130
+ */
131
+ useSecureCookies?: boolean | undefined;
132
+ /**
133
+ * Disable all CSRF protection.
134
+ *
135
+ * When enabled, this disables:
136
+ * - Origin header validation when cookies are present
137
+ * - Fetch Metadata checks (Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest)
138
+ * - Cross-site navigation blocking for first-login scenarios
139
+ *
140
+ * ⚠︎ This is a security risk and it may expose your application to
141
+ * CSRF attacks
142
+ *
143
+ * @default false
144
+ */
145
+ disableCSRFCheck?: boolean | undefined;
146
+ /**
147
+ * Disable URL validation against trustedOrigins.
148
+ *
149
+ * When enabled, this disables validation of:
150
+ * - callbackURL
151
+ * - redirectTo
152
+ * - errorCallbackURL
153
+ * - newUserCallbackURL
154
+ *
155
+ * ⚠︎ This may allow open redirects and could lead to security
156
+ * vulnerabilities.
157
+ *
158
+ * @default false
159
+ */
160
+ disableOriginCheck?: boolean | undefined;
161
+ /**
162
+ * Configure cookies to be cross subdomains
163
+ */
164
+ crossSubDomainCookies?: {
165
+ /**
166
+ * Enable cross subdomain cookies
167
+ */
168
+ enabled: boolean;
169
+ /**
170
+ * Additional cookies to be shared across subdomains
171
+ */
172
+ additionalCookies?: string[];
173
+ /**
174
+ * The domain to use for the cookies
175
+ *
176
+ * By default, the domain will be the root
177
+ * domain from the base URL.
178
+ */
179
+ domain?: string;
180
+ } | undefined;
181
+ cookies?: {
182
+ [key: string]: {
183
+ name?: string;
184
+ attributes?: CookieOptions;
185
+ };
186
+ } | undefined;
187
+ defaultCookieAttributes?: CookieOptions | undefined;
188
+ /**
189
+ * Prefix for cookies. If a cookie name is provided
190
+ * in cookies config, this will be overridden.
191
+ *
192
+ * @default
193
+ * ```txt
194
+ * "appName" -> which defaults to "better-auth"
195
+ * ```
196
+ */
197
+ cookiePrefix?: string | undefined;
198
+ /**
199
+ * Database configuration.
200
+ */
201
+ database?: {
202
+ /**
203
+ * The default number of records to return from the database
204
+ * when using the `findMany` adapter method.
205
+ *
206
+ * @default 100
207
+ */
208
+ defaultFindManyLimit?: number;
209
+ /**
210
+ * If your database auto increments number ids, set this to `true`.
211
+ *
212
+ * Note: If enabled, we will not handle ID generation (including if you use `generateId`), and it would be expected that your database will provide the ID automatically.
213
+ *
214
+ * @default false
215
+ *
216
+ * @deprecated Please use `generateId` instead. This will be removed in future
217
+ * releases.
218
+ */
219
+ useNumberId?: boolean;
220
+ /**
221
+ * Custom generateId function.
222
+ *
223
+ * If not provided, random ids will be generated.
224
+ * If set to false, the database's auto generated id
225
+ * will be used.
226
+ *
227
+ * If set to "serial", the database's auto generated
228
+ * id will be used.
229
+ *
230
+ * If set to "uuid", we generate a random UUID for
231
+ * the id. If postgres, we use the `gen_random_uuid()
232
+ * ` function. If mysql or mssql, we use the `uuid()`
233
+ * function.
234
+ */
235
+ generateId?: GenerateIdFn | false | "serial" | "uuid";
236
+ } | undefined;
237
+ /**
238
+ * Trusted proxy headers
239
+ *
240
+ * - `x-forwarded-host`
241
+ * - `x-forwarded-proto`
242
+ *
243
+ * If set to `true` and no `baseURL` option is provided, we will use the headers to infer the
244
+ * base URL.
245
+ *
246
+ * ⚠︎ This may expose your application to security vulnerabilities if not
247
+ * used correctly. Please use this with caution.
248
+ */
249
+ trustedProxyHeaders?: boolean | undefined;
250
+ /**
251
+ * Configure background task handling for deferred operations.
252
+ *
253
+ * Background tasks allow non-critical operations (like cleanup, analytics,
254
+ * or timing-attack mitigation) to run after the response is sent.
255
+ *
256
+ * Use `waitUntil` from `@vercel/functions` on Vercel,
257
+ * or `ctx.waitUntil` on Cloudflare Workers.
258
+ *
259
+ * @example
260
+ * // Vercel
261
+ * import { waitUntil } from "@vercel/functions";
262
+ * advanced: { backgroundTasks: { handler: waitUntil } }
263
+ *
264
+ * @example
265
+ * // Cloudflare Workers (with AsyncLocalStorage)
266
+ * advanced: {
267
+ * backgroundTasks: {
268
+ * handler: (p) => execCtxStorage.getStore()?.waitUntil(p)
269
+ * }
270
+ * }
271
+ */
272
+ backgroundTasks?: {
273
+ handler: (promise: Promise<void>) => void;
274
+ };
275
+ };
276
+ type BetterAuthOptions = {
277
+ /**
278
+ * The name of the application
279
+ *
280
+ * process.env.APP_NAME
281
+ *
282
+ * @default "Better Auth"
283
+ */
284
+ appName?: string | undefined;
285
+ /**
286
+ * Base URL for the Better Auth. This is typically the
287
+ * root URL where your application server is hosted.
288
+ * If not explicitly set,
289
+ * the system will check the following environment variable:
290
+ *
291
+ * process.env.BETTER_AUTH_URL
292
+ */
293
+ baseURL?: string | undefined;
294
+ /**
295
+ * Base path for the Better Auth. This is typically
296
+ * the path where the
297
+ * Better Auth routes are mounted.
298
+ *
299
+ * @default "/api/auth"
300
+ */
301
+ basePath?: string | undefined;
302
+ /**
303
+ * The secret to use for encryption,
304
+ * signing and hashing.
305
+ *
306
+ * By default Better Auth will look for
307
+ * the following environment variables:
308
+ * process.env.BETTER_AUTH_SECRET,
309
+ * process.env.AUTH_SECRET
310
+ * If none of these environment
311
+ * variables are set,
312
+ * it will default to
313
+ * "better-auth-secret-123456789".
314
+ *
315
+ * on production if it's not set
316
+ * it will throw an error.
317
+ *
318
+ * you can generate a good secret
319
+ * using the following command:
320
+ * @example
321
+ * ```bash
322
+ * openssl rand -base64 32
323
+ * ```
324
+ */
325
+ secret?: string | undefined;
326
+ /**
327
+ * Database configuration
328
+ */
329
+ database?: (PostgresPool | MysqlPool | SqliteDatabase | Dialect | DBAdapterInstance | Database | DatabaseSync | {
330
+ dialect: Dialect;
331
+ type: KyselyDatabaseType;
332
+ /**
333
+ * casing for table names
334
+ *
335
+ * @default "camel"
336
+ */
337
+ casing?: "snake" | "camel";
338
+ /**
339
+ * Enable debug logs for the adapter
340
+ *
341
+ * @default false
342
+ */
343
+ debugLogs?: DBAdapterDebugLogOption;
344
+ /**
345
+ * Whether to execute multiple operations in a transaction.
346
+ * If the database doesn't support transactions,
347
+ * set this to `false` and operations will be executed sequentially.
348
+ *
349
+ * @default false
350
+ */
351
+ transaction?: boolean;
352
+ } | {
353
+ /**
354
+ * Kysely instance
355
+ */
356
+ db: Kysely<any>;
357
+ /**
358
+ * Database type between postgres, mysql and sqlite
359
+ */
360
+ type: KyselyDatabaseType;
361
+ /**
362
+ * casing for table names
363
+ *
364
+ * @default "camel"
365
+ */
366
+ casing?: "snake" | "camel";
367
+ /**
368
+ * Enable debug logs for the adapter
369
+ *
370
+ * @default false
371
+ */
372
+ debugLogs?: DBAdapterDebugLogOption;
373
+ /**
374
+ * Whether to execute multiple operations in a transaction.
375
+ * If the database doesn't support transactions,
376
+ * set this to `false` and operations will be executed sequentially.
377
+ *
378
+ * @default false
379
+ */
380
+ transaction?: boolean;
381
+ }) | undefined;
382
+ /**
383
+ * Secondary storage configuration
384
+ *
385
+ * This is used to store session and rate limit data.
386
+ */
387
+ secondaryStorage?: SecondaryStorage | undefined;
388
+ /**
389
+ * Email verification configuration
390
+ */
391
+ emailVerification?: {
392
+ /**
393
+ * Send a verification email
394
+ * @param data the data object
395
+ * @param request the request object
396
+ */
397
+ sendVerificationEmail?: (
398
+ /**
399
+ * @param user the user to send the
400
+ * verification email to
401
+ * @param url the URL to send the verification email to
402
+ * it contains the token as well
403
+ * @param token the token to send the verification email to
404
+ */
405
+ data: {
406
+ user: User;
407
+ url: string;
408
+ token: string;
409
+ },
410
+ /**
411
+ * The request object
412
+ */
413
+ request?: Request) => Promise<void>;
414
+ /**
415
+ * Send a verification email automatically
416
+ * after sign up
417
+ *
418
+ * @default false
419
+ */
420
+ sendOnSignUp?: boolean;
421
+ /**
422
+ * Send a verification email automatically
423
+ * on sign in when the user's email is not verified
424
+ *
425
+ * @default false
426
+ */
427
+ sendOnSignIn?: boolean;
428
+ /**
429
+ * Auto signin the user after they verify their email
430
+ */
431
+ autoSignInAfterVerification?: boolean;
432
+ /**
433
+ * Number of seconds the verification token is
434
+ * valid for.
435
+ * @default 3600 seconds (1 hour)
436
+ */
437
+ expiresIn?: number;
438
+ /**
439
+ * A function that is called when a user verifies their email
440
+ * @param user the user that verified their email
441
+ * @param request the request object
442
+ * @deprecated Use `beforeEmailVerification` or `afterEmailVerification` instead. This will be removed in 1.5
443
+ */
444
+ onEmailVerification?: (user: User, request?: Request) => Promise<void>;
445
+ /**
446
+ * A function that is called before a user verifies their email
447
+ * @param user the user that verified their email
448
+ * @param request the request object
449
+ */
450
+ beforeEmailVerification?: (user: User, request?: Request) => Promise<void>;
451
+ /**
452
+ * A function that is called when a user's email is updated to verified
453
+ * @param user the user that verified their email
454
+ * @param request the request object
455
+ */
456
+ afterEmailVerification?: (user: User, request?: Request) => Promise<void>;
457
+ } | undefined;
458
+ /**
459
+ * Email and password authentication
460
+ */
461
+ emailAndPassword?: {
462
+ /**
463
+ * Enable email and password authentication
464
+ *
465
+ * @default false
466
+ */
467
+ enabled: boolean;
468
+ /**
469
+ * Disable email and password sign up
470
+ *
471
+ * @default false
472
+ */
473
+ disableSignUp?: boolean;
474
+ /**
475
+ * Require email verification before a session
476
+ * can be created for the user.
477
+ *
478
+ * if the user is not verified, the user will not be able to sign in
479
+ * and on sign in attempts, the user will be prompted to verify their email.
480
+ */
481
+ requireEmailVerification?: boolean;
482
+ /**
483
+ * The maximum length of the password.
484
+ *
485
+ * @default 128
486
+ */
487
+ maxPasswordLength?: number;
488
+ /**
489
+ * The minimum length of the password.
490
+ *
491
+ * @default 8
492
+ */
493
+ minPasswordLength?: number;
494
+ /**
495
+ * send reset password
496
+ */
497
+ sendResetPassword?: (
498
+ /**
499
+ * @param user the user to send the
500
+ * reset password email to
501
+ * @param url the URL to send the reset password email to
502
+ * @param token the token to send to the user (could be used instead of sending the url
503
+ * if you need to redirect the user to custom route)
504
+ */
505
+ data: {
506
+ user: User;
507
+ url: string;
508
+ token: string;
509
+ },
510
+ /**
511
+ * The request object
512
+ */
513
+ request?: Request) => Promise<void>;
514
+ /**
515
+ * Number of seconds the reset password token is
516
+ * valid for.
517
+ * @default 1 hour (60 * 60)
518
+ */
519
+ resetPasswordTokenExpiresIn?: number;
520
+ /**
521
+ * A callback function that is triggered
522
+ * when a user's password is changed successfully.
523
+ */
524
+ onPasswordReset?: (data: {
525
+ user: User;
526
+ }, request?: Request) => Promise<void>;
527
+ /**
528
+ * Password hashing and verification
529
+ *
530
+ * By default Scrypt is used for password hashing and
531
+ * verification. You can provide your own hashing and
532
+ * verification function. if you want to use a
533
+ * different algorithm.
534
+ */
535
+ password?: {
536
+ hash?: (password: string) => Promise<string>;
537
+ verify?: (data: {
538
+ hash: string;
539
+ password: string;
540
+ }) => Promise<boolean>;
541
+ };
542
+ /**
543
+ * Automatically sign in the user after sign up
544
+ *
545
+ * @default true
546
+ */
547
+ autoSignIn?: boolean;
548
+ /**
549
+ * Whether to revoke all other sessions when resetting password
550
+ * @default false
551
+ */
552
+ revokeSessionsOnPasswordReset?: boolean;
553
+ } | undefined;
554
+ /**
555
+ * list of social providers
556
+ */
557
+ socialProviders?: SocialProviders | undefined;
558
+ /**
559
+ * List of Better Auth plugins
560
+ */
561
+ plugins?: ([] | BetterAuthPlugin[]) | undefined;
562
+ /**
563
+ * User configuration
564
+ */
565
+ user?: {
566
+ /**
567
+ * The model name for the user. Defaults to "user".
568
+ */
569
+ modelName?: string;
570
+ /**
571
+ * Map fields
572
+ *
573
+ * @example
574
+ * ```ts
575
+ * {
576
+ * userId: "user_id"
577
+ * }
578
+ * ```
579
+ */
580
+ fields?: Partial<Record<keyof OmitId<User>, string>>;
581
+ /**
582
+ * Additional fields for the user
583
+ */
584
+ additionalFields?: {
585
+ [key: string]: DBFieldAttribute;
586
+ };
587
+ /**
588
+ * Changing email configuration
589
+ */
590
+ changeEmail?: {
591
+ /**
592
+ * Enable changing email
593
+ * @default false
594
+ */
595
+ enabled: boolean;
596
+ /**
597
+ * Send a verification email when the user changes their email.
598
+ * @param data the data object
599
+ * @param request the request object
600
+ * @deprecated Use `sendChangeEmailConfirmation` instead
601
+ */
602
+ sendChangeEmailVerification?: (data: {
603
+ user: User;
604
+ newEmail: string;
605
+ url: string;
606
+ token: string;
607
+ }, request?: Request) => Promise<void>;
608
+ /**
609
+ * Send a confirmation email to the old email address when the user changes their email.
610
+ * @param data the data object
611
+ * @param request the request object
612
+ */
613
+ sendChangeEmailConfirmation?: (data: {
614
+ user: User;
615
+ newEmail: string;
616
+ url: string;
617
+ token: string;
618
+ }, request?: Request) => Promise<void>;
619
+ /**
620
+ * Update the email without verification if the user is not verified.
621
+ * @default false
622
+ */
623
+ updateEmailWithoutVerification?: boolean;
624
+ };
625
+ /**
626
+ * User deletion configuration
627
+ */
628
+ deleteUser?: {
629
+ /**
630
+ * Enable user deletion
631
+ */
632
+ enabled?: boolean;
633
+ /**
634
+ * Send a verification email when the user deletes their account.
635
+ *
636
+ * if this is not set, the user will be deleted immediately.
637
+ * @param data the data object
638
+ * @param request the request object
639
+ */
640
+ sendDeleteAccountVerification?: (data: {
641
+ user: User;
642
+ url: string;
643
+ token: string;
644
+ }, request?: Request) => Promise<void>;
645
+ /**
646
+ * A function that is called before a user is deleted.
647
+ *
648
+ * to interrupt with error you can throw `APIError`
649
+ */
650
+ beforeDelete?: (user: User, request?: Request) => Promise<void>;
651
+ /**
652
+ * A function that is called after a user is deleted.
653
+ *
654
+ * This is useful for cleaning up user data
655
+ */
656
+ afterDelete?: (user: User, request?: Request) => Promise<void>;
657
+ /**
658
+ * The expiration time for the delete token.
659
+ *
660
+ * @default 1 day (60 * 60 * 24) in seconds
661
+ */
662
+ deleteTokenExpiresIn?: number;
663
+ };
664
+ } | undefined;
665
+ session?: {
666
+ /**
667
+ * The model name for the session.
668
+ *
669
+ * @default "session"
670
+ */
671
+ modelName?: string;
672
+ /**
673
+ * Map fields
674
+ *
675
+ * @example
676
+ * ```ts
677
+ * {
678
+ * userId: "user_id"
679
+ * }
680
+ */
681
+ fields?: Partial<Record<keyof OmitId<Session>, string>>;
682
+ /**
683
+ * Expiration time for the session token. The value
684
+ * should be in seconds.
685
+ * @default 7 days (60 * 60 * 24 * 7)
686
+ */
687
+ expiresIn?: number;
688
+ /**
689
+ * How often the session should be refreshed. The value
690
+ * should be in seconds.
691
+ * If set 0 the session will be refreshed every time it is used.
692
+ * @default 1 day (60 * 60 * 24)
693
+ */
694
+ updateAge?: number;
695
+ /**
696
+ * Disable session refresh so that the session is not updated
697
+ * regardless of the `updateAge` option.
698
+ *
699
+ * @default false
700
+ */
701
+ disableSessionRefresh?: boolean;
702
+ /**
703
+ * Additional fields for the session
704
+ */
705
+ additionalFields?: {
706
+ [key: string]: DBFieldAttribute;
707
+ };
708
+ /**
709
+ * By default if secondary storage is provided
710
+ * the session is stored in the secondary storage.
711
+ *
712
+ * Set this to true to store the session in the database
713
+ * as well.
714
+ *
715
+ * Reads are always done from the secondary storage.
716
+ *
717
+ * @default false
718
+ */
719
+ storeSessionInDatabase?: boolean;
720
+ /**
721
+ * By default, sessions are deleted from the database when secondary storage
722
+ * is provided when session is revoked.
723
+ *
724
+ * Set this to true to preserve session records in the database,
725
+ * even if they are deleted from the secondary storage.
726
+ *
727
+ * @default false
728
+ */
729
+ preserveSessionInDatabase?: boolean;
730
+ /**
731
+ * Enable caching session in cookie
732
+ */
733
+ cookieCache?: {
734
+ /**
735
+ * max age of the cookie
736
+ * @default 5 minutes (5 * 60)
737
+ */
738
+ maxAge?: number;
739
+ /**
740
+ * Enable caching session in cookie
741
+ * @default false
742
+ */
743
+ enabled?: boolean;
744
+ /**
745
+ * Strategy for encoding/decoding cookie cache
746
+ *
747
+ * - "compact": Uses base64url encoding with HMAC-SHA256 signature (compact format, no JWT spec overhead)
748
+ * - "jwt": Uses JWT with HMAC signature (no encryption, follows JWT spec)
749
+ * - "jwe": Uses JWE (JSON Web Encryption) with A256CBC-HS512 and HKDF key derivation for secure encrypted tokens
750
+ *
751
+ * @default "compact"
752
+ */
753
+ strategy?: "compact" | "jwt" | "jwe";
754
+ /**
755
+ * Controls stateless cookie cache refresh behavior.
756
+ *
757
+ * When enabled, the cookie cache will be automatically refreshed before expiry
758
+ * WITHOUT querying the database. This is essential for fully stateless or DB-less scenarios.
759
+ *
760
+ * - `false`: Disable automatic refresh. Cache is only invalidated when it reaches maxAge expiry.
761
+ * - `true`: Enable automatic refresh with default settings (refreshes when 80% of maxAge is reached).
762
+ * - `object`: Custom refresh configuration with either `updateAge` or `shouldRefresh` function
763
+ *
764
+ * Note: When the cache expires (reaches maxAge), it will attempt to fetch from database if available.
765
+ * The refreshCache option is specifically for refreshing BEFORE expiry in a stateless manner.
766
+ *
767
+ * @default false
768
+ */
769
+ refreshCache?: boolean | {
770
+ /**
771
+ * Time in seconds before expiry when the cache should be refreshed.
772
+ * For example, if maxAge is 300 (5 minutes) and updateAge is 60,
773
+ * the cache will be refreshed when it has 60 seconds left before expiry.
774
+ *
775
+ * @default 20% of maxAge
776
+ */
777
+ updateAge?: number;
778
+ };
779
+ /**
780
+ * Version of the cookie cache
781
+ *
782
+ * If a cookie cache version is changed, all existing cookie caches with the old version
783
+ * will be invalidated.
784
+ *
785
+ * It can be a string or a function that returns a string or a promise that returns a string.
786
+ * If it's a function, it will be called with the session and user data
787
+ *
788
+ * @default "1"
789
+ */
790
+ version?: string | ((session: Session & Record<string, any>, user: User & Record<string, any>) => string) | ((session: Session & Record<string, any>, user: User & Record<string, any>) => Promise<string>);
791
+ };
792
+ /**
793
+ * The age of the session to consider it fresh.
794
+ *
795
+ * This is used to check if the session is fresh
796
+ * for sensitive operations. (e.g. deleting an account)
797
+ *
798
+ * If the session is not fresh, the user should be prompted
799
+ * to sign in again.
800
+ *
801
+ * If set to 0, the session will be considered fresh every time. (⚠︎ not recommended)
802
+ *
803
+ * @default 1 day (60 * 60 * 24)
804
+ */
805
+ freshAge?: number;
806
+ } | undefined;
807
+ account?: {
808
+ /**
809
+ * The model name for the account. Defaults to "account".
810
+ */
811
+ modelName?: string;
812
+ /**
813
+ * Map fields
814
+ */
815
+ fields?: Partial<Record<keyof OmitId<Account>, string>>;
816
+ /**
817
+ * Additional fields for the account
818
+ */
819
+ additionalFields?: {
820
+ [key: string]: DBFieldAttribute;
821
+ };
822
+ /**
823
+ * When enabled (true), the user account data (accessToken, idToken, refreshToken, etc.)
824
+ * will be updated on sign in with the latest data from the provider.
825
+ *
826
+ * @default true
827
+ */
828
+ updateAccountOnSignIn?: boolean;
829
+ /**
830
+ * Configuration for account linking.
831
+ */
832
+ accountLinking?: {
833
+ /**
834
+ * Enable account linking
835
+ *
836
+ * @default true
837
+ */
838
+ enabled?: boolean;
839
+ /**
840
+ * List of trusted providers
841
+ */
842
+ trustedProviders?: Array<LiteralUnion<SocialProviderList[number] | "email-password", string>>;
843
+ /**
844
+ * If enabled (true), this will allow users to manually linking accounts with different email addresses than the main user.
845
+ *
846
+ * @default false
847
+ *
848
+ * ⚠️ Warning: enabling this might lead to account takeovers, so proceed with caution.
849
+ */
850
+ allowDifferentEmails?: boolean;
851
+ /**
852
+ * If enabled (true), this will allow users to unlink all accounts.
853
+ *
854
+ * @default false
855
+ */
856
+ allowUnlinkingAll?: boolean;
857
+ /**
858
+ * If enabled (true), this will update the user information based on the newly linked account
859
+ *
860
+ * @default false
861
+ */
862
+ updateUserInfoOnLink?: boolean;
863
+ };
864
+ /**
865
+ * Encrypt OAuth tokens
866
+ *
867
+ * By default, OAuth tokens (access tokens, refresh tokens, ID tokens) are stored in plain text in the database.
868
+ * This poses a security risk if your database is compromised, as attackers could gain access to user accounts
869
+ * on external services.
870
+ *
871
+ * When enabled, tokens are encrypted using AES-256-GCM before storage, providing protection against:
872
+ * - Database breaches and unauthorized access to raw token data
873
+ * - Internal threats from database administrators or compromised credentials
874
+ * - Token exposure in database backups and logs
875
+ * @default false
876
+ */
877
+ encryptOAuthTokens?: boolean;
878
+ /**
879
+ * Skip state cookie check
880
+ *
881
+ * ⚠︎ this has security implications and should only be enabled if you know what you are doing.
882
+ * @default false
883
+ */
884
+ skipStateCookieCheck?: boolean;
885
+ /**
886
+ * Strategy for storing OAuth state
887
+ *
888
+ * - "cookie": Store state in an encrypted cookie (stateless)
889
+ * - "database": Store state in the database
890
+ *
891
+ * @default "cookie"
892
+ */
893
+ storeStateStrategy?: "database" | "cookie";
894
+ /**
895
+ * Store account data after oauth flow on a cookie
896
+ *
897
+ * This is useful for database-less flow
898
+ *
899
+ * @default false
900
+ *
901
+ * @note This is automatically set to true if you haven't passed a database
902
+ */
903
+ storeAccountCookie?: boolean;
904
+ } | undefined;
905
+ /**
906
+ * Verification configuration
907
+ */
908
+ verification?: {
909
+ /**
910
+ * Change the modelName of the verification table
911
+ */
912
+ modelName?: string;
913
+ /**
914
+ * Map verification fields
915
+ */
916
+ fields?: Partial<Record<keyof OmitId<Verification>, string>>;
917
+ /**
918
+ * Additional fields for the verification
919
+ */
920
+ additionalFields?: {
921
+ [key: string]: DBFieldAttribute;
922
+ };
923
+ /**
924
+ * disable cleaning up expired values when a verification value is
925
+ * fetched
926
+ */
927
+ disableCleanup?: boolean;
928
+ } | undefined;
929
+ /**
930
+ * List of trusted origins.
931
+ *
932
+ * @param request - The request object.
933
+ * It'll be undefined if no request was
934
+ * made. Like during a create context call
935
+ * or `auth.api` call.
936
+ *
937
+ * Trusted origins will be dynamically
938
+ * calculated based on the request.
939
+ *
940
+ * @example
941
+ * ```ts
942
+ * trustedOrigins: async (request) => {
943
+ * return [
944
+ * "https://better-auth.com",
945
+ * "https://*.better-auth.com",
946
+ * request.headers.get("x-custom-origin")
947
+ * ];
948
+ * }
949
+ * ```
950
+ * @returns An array of trusted origins.
951
+ */
952
+ trustedOrigins?: (string[] | ((request?: Request | undefined) => Awaitable<(string | undefined | null)[]>)) | undefined;
953
+ /**
954
+ * Rate limiting configuration
955
+ */
956
+ rateLimit?: BetterAuthRateLimitOptions | undefined;
957
+ /**
958
+ * Advanced options
959
+ */
960
+ advanced?: BetterAuthAdvancedOptions | undefined;
961
+ logger?: Logger | undefined;
962
+ /**
963
+ * allows you to define custom hooks that can be
964
+ * executed during lifecycle of core database
965
+ * operations.
966
+ */
967
+ databaseHooks?: {
968
+ /**
969
+ * User hooks
970
+ */
971
+ user?: {
972
+ create?: {
973
+ /**
974
+ * Hook that is called before a user is created.
975
+ * if the hook returns false, the user will not be created.
976
+ * If the hook returns an object, it'll be used instead of the original data
977
+ */
978
+ before?: (user: User & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
979
+ data: Optional<User> & Record<string, any>;
980
+ }>;
981
+ /**
982
+ * Hook that is called after a user is created.
983
+ */
984
+ after?: (user: User & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
985
+ };
986
+ update?: {
987
+ /**
988
+ * Hook that is called before a user is updated.
989
+ * if the hook returns false, the user will not be updated.
990
+ * If the hook returns an object, it'll be used instead of the original data
991
+ */
992
+ before?: (user: Partial<User> & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
993
+ data: Optional<User & Record<string, any>>;
994
+ }>;
995
+ /**
996
+ * Hook that is called after a user is updated.
997
+ */
998
+ after?: (user: User & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
999
+ };
1000
+ delete?: {
1001
+ /**
1002
+ * Hook that is called before a user is deleted.
1003
+ * if the hook returns false, the user will not be deleted.
1004
+ */
1005
+ before?: (user: User & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void>;
1006
+ /**
1007
+ * Hook that is called after a user is deleted.
1008
+ */
1009
+ after?: (user: User & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1010
+ };
1011
+ };
1012
+ /**
1013
+ * Session Hook
1014
+ */
1015
+ session?: {
1016
+ create?: {
1017
+ /**
1018
+ * Hook that is called before a session is created.
1019
+ * if the hook returns false, the session will not be created.
1020
+ * If the hook returns an object, it'll be used instead of the original data
1021
+ */
1022
+ before?: (session: Session & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
1023
+ data: Optional<Session> & Record<string, any>;
1024
+ }>;
1025
+ /**
1026
+ * Hook that is called after a session is created.
1027
+ */
1028
+ after?: (session: Session & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1029
+ };
1030
+ /**
1031
+ * Update hook
1032
+ */
1033
+ update?: {
1034
+ /**
1035
+ * Hook that is called before a user is updated.
1036
+ * if the hook returns false, the session will not be updated.
1037
+ * If the hook returns an object, it'll be used instead of the original data
1038
+ */
1039
+ before?: (session: Partial<Session> & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
1040
+ data: Optional<Session & Record<string, any>>;
1041
+ }>;
1042
+ /**
1043
+ * Hook that is called after a session is updated.
1044
+ */
1045
+ after?: (session: Session & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1046
+ };
1047
+ delete?: {
1048
+ /**
1049
+ * Hook that is called before a session is deleted.
1050
+ * if the hook returns false, the session will not be deleted.
1051
+ */
1052
+ before?: (session: Session & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void>;
1053
+ /**
1054
+ * Hook that is called after a session is deleted.
1055
+ */
1056
+ after?: (session: Session & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1057
+ };
1058
+ };
1059
+ /**
1060
+ * Account Hook
1061
+ */
1062
+ account?: {
1063
+ create?: {
1064
+ /**
1065
+ * Hook that is called before a account is created.
1066
+ * If the hook returns false, the account will not be created.
1067
+ * If the hook returns an object, it'll be used instead of the original data
1068
+ */
1069
+ before?: (account: Account, context: GenericEndpointContext | null) => Promise<boolean | void | {
1070
+ data: Optional<Account> & Record<string, any>;
1071
+ }>;
1072
+ /**
1073
+ * Hook that is called after a account is created.
1074
+ */
1075
+ after?: (account: Account, context: GenericEndpointContext | null) => Promise<void>;
1076
+ };
1077
+ /**
1078
+ * Update hook
1079
+ */
1080
+ update?: {
1081
+ /**
1082
+ * Hook that is called before a account is update.
1083
+ * If the hook returns false, the user will not be updated.
1084
+ * If the hook returns an object, it'll be used instead of the original data
1085
+ */
1086
+ before?: (account: Partial<Account> & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
1087
+ data: Optional<Account & Record<string, any>>;
1088
+ }>;
1089
+ /**
1090
+ * Hook that is called after a account is updated.
1091
+ */
1092
+ after?: (account: Account & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1093
+ };
1094
+ delete?: {
1095
+ /**
1096
+ * Hook that is called before an account is deleted.
1097
+ * if the hook returns false, the account will not be deleted.
1098
+ */
1099
+ before?: (account: Account & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void>;
1100
+ /**
1101
+ * Hook that is called after an account is deleted.
1102
+ */
1103
+ after?: (account: Account & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1104
+ };
1105
+ };
1106
+ /**
1107
+ * Verification Hook
1108
+ */
1109
+ verification?: {
1110
+ create?: {
1111
+ /**
1112
+ * Hook that is called before a verification is created.
1113
+ * if the hook returns false, the verification will not be created.
1114
+ * If the hook returns an object, it'll be used instead of the original data
1115
+ */
1116
+ before?: (verification: Verification & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
1117
+ data: Optional<Verification> & Record<string, any>;
1118
+ }>;
1119
+ /**
1120
+ * Hook that is called after a verification is created.
1121
+ */
1122
+ after?: (verification: Verification & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1123
+ };
1124
+ update?: {
1125
+ /**
1126
+ * Hook that is called before a verification is updated.
1127
+ * if the hook returns false, the verification will not be updated.
1128
+ * If the hook returns an object, it'll be used instead of the original data
1129
+ */
1130
+ before?: (verification: Partial<Verification> & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void | {
1131
+ data: Optional<Verification & Record<string, any>>;
1132
+ }>;
1133
+ /**
1134
+ * Hook that is called after a verification is updated.
1135
+ */
1136
+ after?: (verification: Verification & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1137
+ };
1138
+ delete?: {
1139
+ /**
1140
+ * Hook that is called before a verification is deleted.
1141
+ * if the hook returns false, the verification will not be deleted.
1142
+ */
1143
+ before?: (verification: Verification & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<boolean | void>;
1144
+ /**
1145
+ * Hook that is called after a verification is deleted.
1146
+ */
1147
+ after?: (verification: Verification & Record<string, unknown>, context: GenericEndpointContext | null) => Promise<void>;
1148
+ };
1149
+ };
1150
+ } | undefined;
1151
+ /**
1152
+ * API error handling
1153
+ */
1154
+ onAPIError?: {
1155
+ /**
1156
+ * Throw an error on API error
1157
+ *
1158
+ * @default false
1159
+ */
1160
+ throw?: boolean;
1161
+ /**
1162
+ * Custom error handler
1163
+ *
1164
+ * @param error
1165
+ * @param ctx - Auth context
1166
+ */
1167
+ onError?: (error: unknown, ctx: AuthContext) => void | Promise<void>;
1168
+ /**
1169
+ * The URL to redirect to on error
1170
+ *
1171
+ * When errorURL is provided, the error will be added to the URL as a query parameter
1172
+ * and the user will be redirected to the errorURL.
1173
+ *
1174
+ * @default - "/api/auth/error"
1175
+ */
1176
+ errorURL?: string;
1177
+ /**
1178
+ * Configure the default error page provided by Better-Auth
1179
+ * Start your dev server and go to /api/auth/error to see the error page.
1180
+ */
1181
+ customizeDefaultErrorPage?: {
1182
+ colors?: {
1183
+ background?: string;
1184
+ foreground?: string;
1185
+ primary?: string;
1186
+ primaryForeground?: string;
1187
+ mutedForeground?: string;
1188
+ border?: string;
1189
+ destructive?: string;
1190
+ titleBorder?: string;
1191
+ titleColor?: string;
1192
+ gridColor?: string;
1193
+ cardBackground?: string;
1194
+ cornerBorder?: string;
1195
+ };
1196
+ size?: {
1197
+ radiusSm?: string;
1198
+ radiusMd?: string;
1199
+ radiusLg?: string;
1200
+ textSm?: string;
1201
+ text2xl?: string;
1202
+ text4xl?: string;
1203
+ text6xl?: string;
1204
+ };
1205
+ font?: {
1206
+ defaultFamily?: string;
1207
+ monoFamily?: string;
1208
+ };
1209
+ disableTitleBorder?: boolean;
1210
+ disableCornerDecorations?: boolean;
1211
+ disableBackgroundGrid?: boolean;
1212
+ };
1213
+ } | undefined;
1214
+ /**
1215
+ * Hooks
1216
+ */
1217
+ hooks?: {
1218
+ /**
1219
+ * Before a request is processed
1220
+ */
1221
+ before?: AuthMiddleware;
1222
+ /**
1223
+ * After a request is processed
1224
+ */
1225
+ after?: AuthMiddleware;
1226
+ } | undefined;
1227
+ /**
1228
+ * Disabled paths
1229
+ *
1230
+ * Paths you want to disable.
1231
+ */
1232
+ disabledPaths?: string[] | undefined;
1233
+ /**
1234
+ * Telemetry configuration
1235
+ */
1236
+ telemetry?: {
1237
+ /**
1238
+ * Enable telemetry collection
1239
+ *
1240
+ * @default false
1241
+ */
1242
+ enabled?: boolean;
1243
+ /**
1244
+ * Enable debug mode
1245
+ *
1246
+ * @default false
1247
+ */
1248
+ debug?: boolean;
1249
+ } | undefined;
1250
+ /**
1251
+ * Experimental features
1252
+ */
1253
+ experimental?: {
1254
+ /**
1255
+ * Enable experimental joins for your database adapter.
1256
+ *
1257
+ * Please read the adapter documentation for more information regarding joins before enabling this.
1258
+ * Not all adapters support joins.
1259
+ *
1260
+ * @default false
1261
+ */
1262
+ joins?: boolean;
1263
+ };
1264
+ };
1265
+ //#endregion
1266
+ export { BetterAuthAdvancedOptions, BetterAuthOptions, BetterAuthRateLimitOptions, GenerateIdFn };