@better-auth/core 1.3.26 → 1.3.28

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 (130) hide show
  1. package/.turbo/turbo-build.log +60 -9
  2. package/build.config.ts +7 -0
  3. package/dist/db/adapter/index.cjs +2 -0
  4. package/dist/db/adapter/index.d.cts +14 -0
  5. package/dist/db/adapter/index.d.mts +14 -0
  6. package/dist/db/adapter/index.d.ts +14 -0
  7. package/dist/db/adapter/index.mjs +1 -0
  8. package/dist/db/index.cjs +89 -0
  9. package/dist/db/index.d.cts +16 -107
  10. package/dist/db/index.d.mts +16 -107
  11. package/dist/db/index.d.ts +16 -107
  12. package/dist/db/index.mjs +69 -0
  13. package/dist/env/index.cjs +312 -0
  14. package/dist/env/index.d.cts +36 -0
  15. package/dist/env/index.d.mts +36 -0
  16. package/dist/env/index.d.ts +36 -0
  17. package/dist/env/index.mjs +297 -0
  18. package/dist/error/index.cjs +44 -0
  19. package/dist/error/index.d.cts +33 -0
  20. package/dist/error/index.d.mts +33 -0
  21. package/dist/error/index.d.ts +33 -0
  22. package/dist/error/index.mjs +41 -0
  23. package/dist/index.d.cts +179 -1
  24. package/dist/index.d.mts +179 -1
  25. package/dist/index.d.ts +179 -1
  26. package/dist/middleware/index.cjs +25 -0
  27. package/dist/middleware/index.d.cts +14 -0
  28. package/dist/middleware/index.d.mts +14 -0
  29. package/dist/middleware/index.d.ts +14 -0
  30. package/dist/middleware/index.mjs +21 -0
  31. package/dist/oauth2/index.cjs +368 -0
  32. package/dist/oauth2/index.d.cts +100 -0
  33. package/dist/oauth2/index.d.mts +100 -0
  34. package/dist/oauth2/index.d.ts +100 -0
  35. package/dist/oauth2/index.mjs +357 -0
  36. package/dist/shared/core.BJPBStdk.d.ts +1693 -0
  37. package/dist/shared/core.Bl6TpxyD.d.mts +181 -0
  38. package/dist/shared/core.Bqe5IGAi.d.ts +13 -0
  39. package/dist/shared/core.BwoNUcJQ.d.cts +53 -0
  40. package/dist/shared/core.BwoNUcJQ.d.mts +53 -0
  41. package/dist/shared/core.BwoNUcJQ.d.ts +53 -0
  42. package/dist/shared/core.CajxAutx.d.cts +143 -0
  43. package/dist/shared/core.CajxAutx.d.mts +143 -0
  44. package/dist/shared/core.CajxAutx.d.ts +143 -0
  45. package/dist/shared/core.CkkLHQWc.d.mts +1693 -0
  46. package/dist/shared/core.DkdZ1o38.d.ts +181 -0
  47. package/dist/shared/core.Dl-70uns.d.cts +84 -0
  48. package/dist/shared/core.Dl-70uns.d.mts +84 -0
  49. package/dist/shared/core.Dl-70uns.d.ts +84 -0
  50. package/dist/shared/core.DyEdx0m7.d.cts +181 -0
  51. package/dist/shared/core.E9DfzGLz.d.mts +13 -0
  52. package/dist/shared/core.HqYn20Fi.d.cts +13 -0
  53. package/dist/shared/core.gYIBmdi1.d.cts +1693 -0
  54. package/dist/social-providers/index.cjs +2793 -0
  55. package/dist/social-providers/index.d.cts +3903 -0
  56. package/dist/social-providers/index.d.mts +3903 -0
  57. package/dist/social-providers/index.d.ts +3903 -0
  58. package/dist/social-providers/index.mjs +2743 -0
  59. package/dist/utils/index.cjs +7 -0
  60. package/dist/utils/index.d.cts +10 -0
  61. package/dist/utils/index.d.mts +10 -0
  62. package/dist/utils/index.d.ts +10 -0
  63. package/dist/utils/index.mjs +5 -0
  64. package/package.json +109 -2
  65. package/src/db/adapter/index.ts +448 -0
  66. package/src/db/index.ts +13 -0
  67. package/src/db/plugin.ts +11 -0
  68. package/src/db/schema/account.ts +34 -0
  69. package/src/db/schema/rate-limit.ts +21 -0
  70. package/src/db/schema/session.ts +17 -0
  71. package/src/db/schema/shared.ts +7 -0
  72. package/src/db/schema/user.ts +16 -0
  73. package/src/db/schema/verification.ts +15 -0
  74. package/src/db/type.ts +50 -0
  75. package/src/env/color-depth.ts +172 -0
  76. package/src/env/env-impl.ts +123 -0
  77. package/src/env/index.ts +23 -0
  78. package/src/env/logger.test.ts +33 -0
  79. package/src/env/logger.ts +145 -0
  80. package/src/error/codes.ts +31 -0
  81. package/src/error/index.ts +11 -0
  82. package/src/index.ts +1 -1
  83. package/src/middleware/index.ts +33 -0
  84. package/src/oauth2/client-credentials-token.ts +102 -0
  85. package/src/oauth2/create-authorization-url.ts +85 -0
  86. package/src/oauth2/index.ts +22 -0
  87. package/src/oauth2/oauth-provider.ts +194 -0
  88. package/src/oauth2/refresh-access-token.ts +124 -0
  89. package/src/oauth2/utils.ts +36 -0
  90. package/src/oauth2/validate-authorization-code.ts +156 -0
  91. package/src/social-providers/apple.ts +213 -0
  92. package/src/social-providers/atlassian.ts +130 -0
  93. package/src/social-providers/cognito.ts +269 -0
  94. package/src/social-providers/discord.ts +172 -0
  95. package/src/social-providers/dropbox.ts +112 -0
  96. package/src/social-providers/facebook.ts +204 -0
  97. package/src/social-providers/figma.ts +115 -0
  98. package/src/social-providers/github.ts +154 -0
  99. package/src/social-providers/gitlab.ts +152 -0
  100. package/src/social-providers/google.ts +171 -0
  101. package/src/social-providers/huggingface.ts +116 -0
  102. package/src/social-providers/index.ts +118 -0
  103. package/src/social-providers/kakao.ts +178 -0
  104. package/src/social-providers/kick.ts +95 -0
  105. package/src/social-providers/line.ts +169 -0
  106. package/src/social-providers/linear.ts +120 -0
  107. package/src/social-providers/linkedin.ts +110 -0
  108. package/src/social-providers/microsoft-entra-id.ts +243 -0
  109. package/src/social-providers/naver.ts +112 -0
  110. package/src/social-providers/notion.ts +106 -0
  111. package/src/social-providers/paypal.ts +261 -0
  112. package/src/social-providers/reddit.ts +122 -0
  113. package/src/social-providers/roblox.ts +110 -0
  114. package/src/social-providers/salesforce.ts +157 -0
  115. package/src/social-providers/slack.ts +114 -0
  116. package/src/social-providers/spotify.ts +93 -0
  117. package/src/social-providers/tiktok.ts +211 -0
  118. package/src/social-providers/twitch.ts +111 -0
  119. package/src/social-providers/twitter.ts +194 -0
  120. package/src/social-providers/vk.ts +128 -0
  121. package/src/social-providers/zoom.ts +218 -0
  122. package/src/types/context.ts +313 -0
  123. package/src/types/cookie.ts +7 -0
  124. package/src/types/helper.ts +5 -0
  125. package/src/types/index.ts +20 -1
  126. package/src/types/init-options.ts +1161 -0
  127. package/src/types/plugin-client.ts +69 -0
  128. package/src/types/plugin.ts +134 -0
  129. package/src/utils/error-codes.ts +51 -0
  130. package/src/utils/index.ts +1 -0
@@ -0,0 +1,1693 @@
1
+ import { PostgresPool, MysqlPool, Dialect, Kysely } from 'kysely';
2
+ import { Database } from 'better-sqlite3';
3
+ import * as better_call from 'better-call';
4
+ import { CookieOptions, EndpointContext } from 'better-call';
5
+ import { D as DBFieldAttribute, B as BetterAuthDBSchema, a as LiteralUnion, M as Models, S as SecondaryStorage } from './core.CajxAutx.mjs';
6
+ import { S as Session, U as User, A as Account, V as Verification, R as RateLimit } from './core.Dl-70uns.mjs';
7
+ import { Database as Database$1 } from 'bun:sqlite';
8
+ import { DatabaseSync } from 'node:sqlite';
9
+ import { SocialProviders, SocialProviderList } from '../social-providers/index.mjs';
10
+ import { c as createLogger, L as Logger } from './core.BwoNUcJQ.mjs';
11
+ import { a as OAuthProvider } from './core.Bl6TpxyD.mjs';
12
+ import { BetterAuthPlugin } from '@better-auth/core';
13
+
14
+ type DBAdapterDebugLogOption = boolean | {
15
+ /**
16
+ * Useful when you want to log only certain conditions.
17
+ */
18
+ logCondition?: (() => boolean) | undefined;
19
+ create?: boolean;
20
+ update?: boolean;
21
+ updateMany?: boolean;
22
+ findOne?: boolean;
23
+ findMany?: boolean;
24
+ delete?: boolean;
25
+ deleteMany?: boolean;
26
+ count?: boolean;
27
+ } | {
28
+ /**
29
+ * Only used for adapter tests to show debug logs if a test fails.
30
+ *
31
+ * @deprecated Not actually deprecated. Doing this for IDEs to show this option at the very bottom and stop end-users from using this.
32
+ */
33
+ isRunningAdapterTests: boolean;
34
+ };
35
+ type DBAdapterSchemaCreation = {
36
+ /**
37
+ * Code to be inserted into the file
38
+ */
39
+ code: string;
40
+ /**
41
+ * Path to the file, including the file name and extension.
42
+ * Relative paths are supported, with the current working directory of the developer's project as the base.
43
+ */
44
+ path: string;
45
+ /**
46
+ * Append the file if it already exists.
47
+ * Note: This will not apply if `overwrite` is set to true.
48
+ */
49
+ append?: boolean;
50
+ /**
51
+ * Overwrite the file if it already exists
52
+ */
53
+ overwrite?: boolean;
54
+ };
55
+ interface DBAdapterFactoryConfig<Options extends BetterAuthOptions = BetterAuthOptions> {
56
+ /**
57
+ * Use plural table names.
58
+ *
59
+ * All tables will be named with an `s` at the end.
60
+ *
61
+ * @default false
62
+ */
63
+ usePlural?: boolean;
64
+ /**
65
+ * Enable debug logs.
66
+ *
67
+ * @default false
68
+ */
69
+ debugLogs?: DBAdapterDebugLogOption;
70
+ /**
71
+ * Name of the adapter.
72
+ *
73
+ * This is used to identify the adapter in the debug logs.
74
+ *
75
+ * @default `adapterId`
76
+ */
77
+ adapterName?: string;
78
+ /**
79
+ * Adapter id
80
+ */
81
+ adapterId: string;
82
+ /**
83
+ * If the database supports numeric ids, set this to `true`.
84
+ *
85
+ * @default true
86
+ */
87
+ supportsNumericIds?: boolean;
88
+ /**
89
+ * If the database doesn't support JSON columns, set this to `false`.
90
+ *
91
+ * We will handle the translation between using `JSON` columns, and saving `string`s to the database.
92
+ *
93
+ * @default false
94
+ */
95
+ supportsJSON?: boolean;
96
+ /**
97
+ * If the database doesn't support dates, set this to `false`.
98
+ *
99
+ * We will handle the translation between using `Date` objects, and saving `string`s to the database.
100
+ *
101
+ * @default true
102
+ */
103
+ supportsDates?: boolean;
104
+ /**
105
+ * If the database doesn't support booleans, set this to `false`.
106
+ *
107
+ * We will handle the translation between using `boolean`s, and saving `0`s and `1`s to the database.
108
+ *
109
+ * @default true
110
+ */
111
+ supportsBooleans?: boolean;
112
+ /**
113
+ * Execute multiple operations in a transaction.
114
+ *
115
+ * If the database doesn't support transactions, set this to `false` and operations will be executed sequentially.
116
+ *
117
+ * @default false
118
+ */
119
+ transaction?: false | (<R>(callback: (trx: DBTransactionAdapter<Options>) => Promise<R>) => Promise<R>);
120
+ /**
121
+ * Disable id generation for the `create` method.
122
+ *
123
+ * This is useful for databases that don't support custom id values and would auto-generate them for you.
124
+ *
125
+ * @default false
126
+ */
127
+ disableIdGeneration?: boolean;
128
+ /**
129
+ * Map the keys of the input data.
130
+ *
131
+ * This is useful for databases that expect a different key name for a given situation.
132
+ *
133
+ * For example, MongoDB uses `_id` while in Better-Auth we use `id`.
134
+ *
135
+ *
136
+ * @example
137
+ * Each key represents the old key to replace.
138
+ * The value represents the new key
139
+ *
140
+ * This can be a partial object that only transforms some keys.
141
+ *
142
+ * ```ts
143
+ * mapKeysTransformInput: {
144
+ * id: "_id" // We want to replace `id` to `_id` to save into MongoDB
145
+ * }
146
+ * ```
147
+ */
148
+ mapKeysTransformInput?: Record<string, string>;
149
+ /**
150
+ * Map the keys of the output data.
151
+ *
152
+ * This is useful for databases that expect a different key name for a given situation.
153
+ *
154
+ * For example, MongoDB uses `_id` while in Better-Auth we use `id`.
155
+ *
156
+ * @example
157
+ * Each key represents the old key to replace.
158
+ * The value represents the new key
159
+ *
160
+ * This can be a partial object that only transforms some keys.
161
+ *
162
+ * ```ts
163
+ * mapKeysTransformOutput: {
164
+ * _id: "id" // In MongoDB, we save `id` as `_id`. So we want to replace `_id` with `id` when we get the data back.
165
+ * }
166
+ * ```
167
+ */
168
+ mapKeysTransformOutput?: Record<string, string>;
169
+ /**
170
+ * Custom transform input function.
171
+ *
172
+ * This function is used to transform the input data before it is saved to the database.
173
+ */
174
+ customTransformInput?: (props: {
175
+ data: any;
176
+ /**
177
+ * The fields of the model.
178
+ */
179
+ fieldAttributes: DBFieldAttribute;
180
+ /**
181
+ * The field to transform.
182
+ */
183
+ field: string;
184
+ /**
185
+ * The action which was called from the adapter.
186
+ */
187
+ action: "create" | "update";
188
+ /**
189
+ * The model name.
190
+ */
191
+ model: string;
192
+ /**
193
+ * The schema of the user's Better-Auth instance.
194
+ */
195
+ schema: BetterAuthDBSchema;
196
+ /**
197
+ * The options of the user's Better-Auth instance.
198
+ */
199
+ options: Options;
200
+ }) => any;
201
+ /**
202
+ * Custom transform output function.
203
+ *
204
+ * This function is used to transform the output data before it is returned to the user.
205
+ */
206
+ customTransformOutput?: (props: {
207
+ data: any;
208
+ /**
209
+ * The fields of the model.
210
+ */
211
+ fieldAttributes: DBFieldAttribute;
212
+ /**
213
+ * The field to transform.
214
+ */
215
+ field: string;
216
+ /**
217
+ * The fields to select.
218
+ */
219
+ select: string[];
220
+ /**
221
+ * The model name.
222
+ */
223
+ model: string;
224
+ /**
225
+ * The schema of the user's Better-Auth instance.
226
+ */
227
+ schema: BetterAuthDBSchema;
228
+ /**
229
+ * The options of the user's Better-Auth instance.
230
+ */
231
+ options: Options;
232
+ }) => any;
233
+ /**
234
+ * Custom ID generator function.
235
+ *
236
+ * By default, we can handle ID generation for you, however if the database your adapter is for only supports a specific custom id generation,
237
+ * then you can use this function to generate your own IDs.
238
+ *
239
+ *
240
+ * Notes:
241
+ * - If the user enabled `useNumberId`, then this option will be ignored. Unless this adapter config has `supportsNumericIds` set to `false`.
242
+ * - If `generateId` is `false` in the user's Better-Auth config, then this option will be ignored.
243
+ * - If `generateId` is a function, then it will override this option.
244
+ *
245
+ * @example
246
+ *
247
+ * ```ts
248
+ * customIdGenerator: ({ model }) => {
249
+ * return "my-super-unique-id";
250
+ * }
251
+ * ```
252
+ */
253
+ customIdGenerator?: (props: {
254
+ model: string;
255
+ }) => string;
256
+ /**
257
+ * Whether to disable the transform output.
258
+ * Do not use this option unless you know what you are doing.
259
+ * @default false
260
+ */
261
+ disableTransformOutput?: boolean;
262
+ /**
263
+ * Whether to disable the transform input.
264
+ * Do not use this option unless you know what you are doing.
265
+ * @default false
266
+ */
267
+ disableTransformInput?: boolean;
268
+ }
269
+ type Where = {
270
+ /**
271
+ * @default eq
272
+ */
273
+ operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with";
274
+ value: string | number | boolean | string[] | number[] | Date | null;
275
+ field: string;
276
+ /**
277
+ * @default AND
278
+ */
279
+ connector?: "AND" | "OR";
280
+ };
281
+ type DBTransactionAdapter<Options extends BetterAuthOptions = BetterAuthOptions> = Omit<DBAdapter<Options>, "transaction">;
282
+ type DBAdapter<Options extends BetterAuthOptions = BetterAuthOptions> = {
283
+ id: string;
284
+ create: <T extends Record<string, any>, R = T>(data: {
285
+ model: string;
286
+ data: Omit<T, "id">;
287
+ select?: string[];
288
+ /**
289
+ * By default, any `id` provided in `data` will be ignored.
290
+ *
291
+ * If you want to force the `id` to be the same as the `data.id`, set this to `true`.
292
+ */
293
+ forceAllowId?: boolean;
294
+ }) => Promise<R>;
295
+ findOne: <T>(data: {
296
+ model: string;
297
+ where: Where[];
298
+ select?: string[];
299
+ }) => Promise<T | null>;
300
+ findMany: <T>(data: {
301
+ model: string;
302
+ where?: Where[];
303
+ limit?: number;
304
+ sortBy?: {
305
+ field: string;
306
+ direction: "asc" | "desc";
307
+ };
308
+ offset?: number;
309
+ }) => Promise<T[]>;
310
+ count: (data: {
311
+ model: string;
312
+ where?: Where[];
313
+ }) => Promise<number>;
314
+ /**
315
+ * ⚠︎ Update may not return the updated data
316
+ * if multiple where clauses are provided
317
+ */
318
+ update: <T>(data: {
319
+ model: string;
320
+ where: Where[];
321
+ update: Record<string, any>;
322
+ }) => Promise<T | null>;
323
+ updateMany: (data: {
324
+ model: string;
325
+ where: Where[];
326
+ update: Record<string, any>;
327
+ }) => Promise<number>;
328
+ delete: <T>(data: {
329
+ model: string;
330
+ where: Where[];
331
+ }) => Promise<void>;
332
+ deleteMany: (data: {
333
+ model: string;
334
+ where: Where[];
335
+ }) => Promise<number>;
336
+ /**
337
+ * Execute multiple operations in a transaction.
338
+ * If the adapter doesn't support transactions, operations will be executed sequentially.
339
+ */
340
+ transaction: <R>(callback: (trx: DBTransactionAdapter<Options>) => Promise<R>) => Promise<R>;
341
+ /**
342
+ *
343
+ * @param options
344
+ * @param file - file path if provided by the user
345
+ */
346
+ createSchema?: (options: Options, file?: string) => Promise<DBAdapterSchemaCreation>;
347
+ options?: {
348
+ adapterConfig: DBAdapterFactoryConfig<Options>;
349
+ } & CustomAdapter["options"];
350
+ };
351
+ type CleanedWhere = Required<Where>;
352
+ interface CustomAdapter {
353
+ create: <T extends Record<string, any>>({ data, model, select, }: {
354
+ model: string;
355
+ data: T;
356
+ select?: string[];
357
+ }) => Promise<T>;
358
+ update: <T>(data: {
359
+ model: string;
360
+ where: CleanedWhere[];
361
+ update: T;
362
+ }) => Promise<T | null>;
363
+ updateMany: (data: {
364
+ model: string;
365
+ where: CleanedWhere[];
366
+ update: Record<string, any>;
367
+ }) => Promise<number>;
368
+ findOne: <T>({ model, where, select, }: {
369
+ model: string;
370
+ where: CleanedWhere[];
371
+ select?: string[];
372
+ }) => Promise<T | null>;
373
+ findMany: <T>({ model, where, limit, sortBy, offset, }: {
374
+ model: string;
375
+ where?: CleanedWhere[];
376
+ limit: number;
377
+ sortBy?: {
378
+ field: string;
379
+ direction: "asc" | "desc";
380
+ };
381
+ offset?: number;
382
+ }) => Promise<T[]>;
383
+ delete: ({ model, where, }: {
384
+ model: string;
385
+ where: CleanedWhere[];
386
+ }) => Promise<void>;
387
+ deleteMany: ({ model, where, }: {
388
+ model: string;
389
+ where: CleanedWhere[];
390
+ }) => Promise<number>;
391
+ count: ({ model, where, }: {
392
+ model: string;
393
+ where?: CleanedWhere[];
394
+ }) => Promise<number>;
395
+ createSchema?: (props: {
396
+ /**
397
+ * The file the user may have passed in to the `generate` command as the expected schema file output path.
398
+ */
399
+ file?: string;
400
+ /**
401
+ * The tables from the user's Better-Auth instance schema.
402
+ */
403
+ tables: BetterAuthDBSchema;
404
+ }) => Promise<DBAdapterSchemaCreation>;
405
+ /**
406
+ * Your adapter's options.
407
+ */
408
+ options?: Record<string, any> | undefined;
409
+ }
410
+ interface DBAdapterInstance<Options extends BetterAuthOptions = BetterAuthOptions> {
411
+ (options: BetterAuthOptions): DBAdapter<Options>;
412
+ }
413
+
414
+ type BetterAuthCookies = {
415
+ sessionToken: {
416
+ name: string;
417
+ options: CookieOptions;
418
+ };
419
+ sessionData: {
420
+ name: string;
421
+ options: CookieOptions;
422
+ };
423
+ dontRememberToken: {
424
+ name: string;
425
+ options: CookieOptions;
426
+ };
427
+ };
428
+
429
+ type GenericEndpointContext<Options extends BetterAuthOptions = BetterAuthOptions> = EndpointContext<string, any> & {
430
+ context: AuthContext<Options>;
431
+ };
432
+ interface InternalAdapter<Options extends BetterAuthOptions = BetterAuthOptions> {
433
+ createOAuthUser(user: Omit<User, "id" | "createdAt" | "updatedAt">, account: Omit<Account, "userId" | "id" | "createdAt" | "updatedAt"> & Partial<Account>, context?: GenericEndpointContext<Options>): Promise<{
434
+ user: User;
435
+ account: Account;
436
+ }>;
437
+ createUser<T extends Record<string, any>>(user: Omit<User, "id" | "createdAt" | "updatedAt" | "emailVerified"> & Partial<User> & Record<string, any>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<T & User>;
438
+ createAccount<T extends Record<string, any>>(account: Omit<Account, "id" | "createdAt" | "updatedAt"> & Partial<Account> & T, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<T & Account>;
439
+ listSessions(userId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<Session[]>;
440
+ listUsers(limit?: number, offset?: number, sortBy?: {
441
+ field: string;
442
+ direction: "asc" | "desc";
443
+ }, where?: Where[], trxAdapter?: DBTransactionAdapter<Options>): Promise<User[]>;
444
+ countTotalUsers(where?: Where[], trxAdapter?: DBTransactionAdapter<Options>): Promise<number>;
445
+ deleteUser(userId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
446
+ createSession(userId: string, ctx: GenericEndpointContext<Options>, dontRememberMe?: boolean, override?: Partial<Session> & Record<string, any>, overrideAll?: boolean, trxAdapter?: DBTransactionAdapter<Options>): Promise<Session>;
447
+ findSession(token: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<{
448
+ session: Session & Record<string, any>;
449
+ user: User & Record<string, any>;
450
+ } | null>;
451
+ findSessions(sessionTokens: string[], trxAdapter?: DBTransactionAdapter<Options>): Promise<{
452
+ session: Session;
453
+ user: User;
454
+ }[]>;
455
+ updateSession(sessionToken: string, session: Partial<Session> & Record<string, any>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<Session | null>;
456
+ deleteSession(token: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
457
+ deleteAccounts(userId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
458
+ deleteAccount(accountId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
459
+ deleteSessions(userIdOrSessionTokens: string | string[], trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
460
+ findOAuthUser(email: string, accountId: string, providerId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<{
461
+ user: User;
462
+ accounts: Account[];
463
+ } | null>;
464
+ findUserByEmail(email: string, options?: {
465
+ includeAccounts: boolean;
466
+ }, trxAdapter?: DBTransactionAdapter<Options>): Promise<{
467
+ user: User;
468
+ accounts: Account[];
469
+ } | null>;
470
+ findUserById(userId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<User | null>;
471
+ linkAccount(account: Omit<Account, "id" | "createdAt" | "updatedAt"> & Partial<Account>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<Account>;
472
+ updateUser(userId: string, data: Partial<User> & Record<string, any>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<any>;
473
+ updateUserByEmail(email: string, data: Partial<User & Record<string, any>>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<User>;
474
+ updatePassword(userId: string, password: string, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
475
+ findAccounts(userId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<Account[]>;
476
+ findAccount(accountId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<Account | null>;
477
+ findAccountByProviderId(accountId: string, providerId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<Account | null>;
478
+ findAccountByUserId(userId: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<Account[]>;
479
+ updateAccount(id: string, data: Partial<Account>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<Account>;
480
+ createVerificationValue(data: Omit<Verification, "createdAt" | "id" | "updatedAt"> & Partial<Verification>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<Verification>;
481
+ findVerificationValue(identifier: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<Verification | null>;
482
+ deleteVerificationValue(id: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
483
+ deleteVerificationByIdentifier(identifier: string, trxAdapter?: DBTransactionAdapter<Options>): Promise<void>;
484
+ updateVerificationValue(id: string, data: Partial<Verification>, context?: GenericEndpointContext<Options>, trxAdapter?: DBTransactionAdapter<Options>): Promise<Verification>;
485
+ }
486
+ type CreateCookieGetterFn = (cookieName: string, overrideAttributes?: Partial<CookieOptions>) => {
487
+ name: string;
488
+ attributes: CookieOptions;
489
+ };
490
+ type CheckPasswordFn<Options extends BetterAuthOptions = BetterAuthOptions> = (userId: string, ctx: GenericEndpointContext<Options>) => Promise<boolean>;
491
+ type AuthContext<Options extends BetterAuthOptions = BetterAuthOptions> = {
492
+ options: Options;
493
+ appName: string;
494
+ baseURL: string;
495
+ trustedOrigins: string[];
496
+ oauthConfig?: {
497
+ /**
498
+ * This is dangerous and should only be used in dev or staging environments.
499
+ */
500
+ skipStateCookieCheck?: boolean;
501
+ };
502
+ /**
503
+ * New session that will be set after the request
504
+ * meaning: there is a `set-cookie` header that will set
505
+ * the session cookie. This is the fetched session. And it's set
506
+ * by `setNewSession` method.
507
+ */
508
+ newSession: {
509
+ session: Session & Record<string, any>;
510
+ user: User & Record<string, any>;
511
+ } | null;
512
+ session: {
513
+ session: Session & Record<string, any>;
514
+ user: User & Record<string, any>;
515
+ } | null;
516
+ setNewSession: (session: {
517
+ session: Session & Record<string, any>;
518
+ user: User & Record<string, any>;
519
+ } | null) => void;
520
+ socialProviders: OAuthProvider[];
521
+ authCookies: BetterAuthCookies;
522
+ logger: ReturnType<typeof createLogger>;
523
+ rateLimit: {
524
+ enabled: boolean;
525
+ window: number;
526
+ max: number;
527
+ storage: "memory" | "database" | "secondary-storage";
528
+ } & BetterAuthRateLimitOptions;
529
+ adapter: DBAdapter<Options>;
530
+ internalAdapter: InternalAdapter<Options>;
531
+ createAuthCookie: CreateCookieGetterFn;
532
+ secret: string;
533
+ sessionConfig: {
534
+ updateAge: number;
535
+ expiresIn: number;
536
+ freshAge: number;
537
+ };
538
+ generateId: (options: {
539
+ model: LiteralUnion<Models, string>;
540
+ size?: number;
541
+ }) => string | false;
542
+ secondaryStorage: SecondaryStorage | undefined;
543
+ password: {
544
+ hash: (password: string) => Promise<string>;
545
+ verify: (data: {
546
+ password: string;
547
+ hash: string;
548
+ }) => Promise<boolean>;
549
+ config: {
550
+ minPasswordLength: number;
551
+ maxPasswordLength: number;
552
+ };
553
+ checkPassword: CheckPasswordFn<Options>;
554
+ };
555
+ tables: BetterAuthDBSchema;
556
+ runMigrations: () => Promise<void>;
557
+ publishTelemetry: (event: {
558
+ type: string;
559
+ anonymousId?: string;
560
+ payload: Record<string, any>;
561
+ }) => Promise<void>;
562
+ };
563
+
564
+ declare const optionsMiddleware: <InputCtx extends better_call.MiddlewareInputContext<better_call.MiddlewareOptions>>(inputContext: InputCtx) => Promise<AuthContext>;
565
+ declare const createAuthMiddleware: {
566
+ <Options extends better_call.MiddlewareOptions, R>(options: Options, handler: (ctx: better_call.MiddlewareContext<Options, AuthContext & {
567
+ returned?: unknown;
568
+ responseHeaders?: Headers;
569
+ }>) => Promise<R>): (inputContext: better_call.MiddlewareInputContext<Options>) => Promise<R>;
570
+ <Options extends better_call.MiddlewareOptions, R_1>(handler: (ctx: better_call.MiddlewareContext<Options, AuthContext & {
571
+ returned?: unknown;
572
+ responseHeaders?: Headers;
573
+ }>) => Promise<R_1>): (inputContext: better_call.MiddlewareInputContext<Options>) => Promise<R_1>;
574
+ };
575
+ declare const createAuthEndpoint: <Path extends string, Opts extends better_call.EndpointOptions, R>(path: Path, options: Opts, handler: (ctx: better_call.EndpointContext<Path, Opts, AuthContext>) => Promise<R>) => {
576
+ <AsResponse extends boolean = false, ReturnHeaders extends boolean = false>(...inputCtx: better_call.HasRequiredKeys<better_call.InputContext<Path, Opts & {
577
+ use: any[];
578
+ }>> extends true ? [better_call.InferBodyInput<Opts & {
579
+ use: any[];
580
+ }, (Opts & {
581
+ use: any[];
582
+ })["metadata"] extends {
583
+ $Infer: {
584
+ body: infer B;
585
+ };
586
+ } ? B : (Opts & {
587
+ use: any[];
588
+ })["body"] extends better_call.StandardSchemaV1<unknown, unknown> ? better_call.StandardSchemaV1.InferInput<(Opts & {
589
+ use: any[];
590
+ })["body"]> : undefined> & better_call.InferInputMethod<Opts & {
591
+ use: any[];
592
+ }, (Opts & {
593
+ use: any[];
594
+ })["method"] extends any[] ? (Opts & {
595
+ use: any[];
596
+ })["method"][number] : (Opts & {
597
+ use: any[];
598
+ })["method"] extends "*" ? better_call.HTTPMethod : (Opts & {
599
+ use: any[];
600
+ })["method"] | undefined> & better_call.InferQueryInput<Opts & {
601
+ use: any[];
602
+ }, (Opts & {
603
+ use: any[];
604
+ })["metadata"] extends {
605
+ $Infer: {
606
+ query: infer Query;
607
+ };
608
+ } ? Query : (Opts & {
609
+ use: any[];
610
+ })["query"] extends better_call.StandardSchemaV1<unknown, unknown> ? better_call.StandardSchemaV1.InferInput<(Opts & {
611
+ use: any[];
612
+ })["query"]> : Record<string, any> | undefined> & better_call.InferParamInput<Path> & better_call.InferRequestInput<Opts & {
613
+ use: any[];
614
+ }> & better_call.InferHeadersInput<Opts & {
615
+ use: any[];
616
+ }> & {
617
+ asResponse?: boolean;
618
+ returnHeaders?: boolean;
619
+ use?: better_call.Middleware[];
620
+ path?: string;
621
+ } & {
622
+ asResponse?: AsResponse | undefined;
623
+ returnHeaders?: ReturnHeaders | undefined;
624
+ }] : [((better_call.InferBodyInput<Opts & {
625
+ use: any[];
626
+ }, (Opts & {
627
+ use: any[];
628
+ })["metadata"] extends {
629
+ $Infer: {
630
+ body: infer B_1;
631
+ };
632
+ } ? B_1 : (Opts & {
633
+ use: any[];
634
+ })["body"] extends better_call.StandardSchemaV1<unknown, unknown> ? better_call.StandardSchemaV1.InferInput<(Opts & {
635
+ use: any[];
636
+ })["body"]> : undefined> & better_call.InferInputMethod<Opts & {
637
+ use: any[];
638
+ }, (Opts & {
639
+ use: any[];
640
+ })["method"] extends any[] ? (Opts & {
641
+ use: any[];
642
+ })["method"][number] : (Opts & {
643
+ use: any[];
644
+ })["method"] extends "*" ? better_call.HTTPMethod : (Opts & {
645
+ use: any[];
646
+ })["method"] | undefined> & better_call.InferQueryInput<Opts & {
647
+ use: any[];
648
+ }, (Opts & {
649
+ use: any[];
650
+ })["metadata"] extends {
651
+ $Infer: {
652
+ query: infer Query_1;
653
+ };
654
+ } ? Query_1 : (Opts & {
655
+ use: any[];
656
+ })["query"] extends better_call.StandardSchemaV1<unknown, unknown> ? better_call.StandardSchemaV1.InferInput<(Opts & {
657
+ use: any[];
658
+ })["query"]> : Record<string, any> | undefined> & better_call.InferParamInput<Path> & better_call.InferRequestInput<Opts & {
659
+ use: any[];
660
+ }> & better_call.InferHeadersInput<Opts & {
661
+ use: any[];
662
+ }> & {
663
+ asResponse?: boolean;
664
+ returnHeaders?: boolean;
665
+ use?: better_call.Middleware[];
666
+ path?: string;
667
+ } & {
668
+ asResponse?: AsResponse | undefined;
669
+ returnHeaders?: ReturnHeaders | undefined;
670
+ }) | undefined)?]): Promise<[AsResponse] extends [true] ? Response : [ReturnHeaders] extends [true] ? {
671
+ headers: Headers;
672
+ response: R;
673
+ } : R>;
674
+ options: Opts & {
675
+ use: any[];
676
+ };
677
+ path: Path;
678
+ };
679
+ type AuthEndpoint = ReturnType<typeof createAuthEndpoint>;
680
+ type AuthMiddleware = ReturnType<typeof createAuthMiddleware>;
681
+
682
+ type KyselyDatabaseType = "postgres" | "mysql" | "sqlite" | "mssql";
683
+ type OmitId<T extends {
684
+ id: unknown;
685
+ }> = Omit<T, "id">;
686
+ type GenerateIdFn = (options: {
687
+ model: LiteralUnion<Models, string>;
688
+ size?: number;
689
+ }) => string | false;
690
+ type BetterAuthRateLimitOptions = {
691
+ /**
692
+ * By default, rate limiting is only
693
+ * enabled on production.
694
+ */
695
+ enabled?: boolean;
696
+ /**
697
+ * Default window to use for rate limiting. The value
698
+ * should be in seconds.
699
+ *
700
+ * @default 10 seconds
701
+ */
702
+ window?: number;
703
+ /**
704
+ * The default maximum number of requests allowed within the window.
705
+ *
706
+ * @default 100 requests
707
+ */
708
+ max?: number;
709
+ /**
710
+ * Custom rate limit rules to apply to
711
+ * specific paths.
712
+ */
713
+ customRules?: {
714
+ [key: string]: {
715
+ /**
716
+ * The window to use for the custom rule.
717
+ */
718
+ window: number;
719
+ /**
720
+ * The maximum number of requests allowed within the window.
721
+ */
722
+ max: number;
723
+ } | false | ((request: Request) => {
724
+ window: number;
725
+ max: number;
726
+ } | false | Promise<{
727
+ window: number;
728
+ max: number;
729
+ } | false>);
730
+ };
731
+ /**
732
+ * Storage configuration
733
+ *
734
+ * By default, rate limiting is stored in memory. If you passed a
735
+ * secondary storage, rate limiting will be stored in the secondary
736
+ * storage.
737
+ *
738
+ * @default "memory"
739
+ */
740
+ storage?: "memory" | "database" | "secondary-storage";
741
+ /**
742
+ * If database is used as storage, the name of the table to
743
+ * use for rate limiting.
744
+ *
745
+ * @default "rateLimit"
746
+ */
747
+ modelName?: string;
748
+ /**
749
+ * Custom field names for the rate limit table
750
+ */
751
+ fields?: Record<keyof RateLimit, string>;
752
+ /**
753
+ * custom storage configuration.
754
+ *
755
+ * NOTE: If custom storage is used storage
756
+ * is ignored
757
+ */
758
+ customStorage?: {
759
+ get: (key: string) => Promise<RateLimit | undefined>;
760
+ set: (key: string, value: RateLimit) => Promise<void>;
761
+ };
762
+ };
763
+ type BetterAuthAdvancedOptions = {
764
+ /**
765
+ * Ip address configuration
766
+ */
767
+ ipAddress?: {
768
+ /**
769
+ * List of headers to use for ip address
770
+ *
771
+ * Ip address is used for rate limiting and session tracking
772
+ *
773
+ * @example ["x-client-ip", "x-forwarded-for", "cf-connecting-ip"]
774
+ *
775
+ * @default
776
+ * @link https://github.com/better-auth/better-auth/blob/main/packages/better-auth/src/utils/get-request-ip.ts#L8
777
+ */
778
+ ipAddressHeaders?: string[];
779
+ /**
780
+ * Disable ip tracking
781
+ *
782
+ * ⚠︎ This is a security risk and it may expose your application to abuse
783
+ */
784
+ disableIpTracking?: boolean;
785
+ };
786
+ /**
787
+ * Use secure cookies
788
+ *
789
+ * @default false
790
+ */
791
+ useSecureCookies?: boolean;
792
+ /**
793
+ * Disable trusted origins check
794
+ *
795
+ * ⚠︎ This is a security risk and it may expose your application to CSRF attacks
796
+ */
797
+ disableCSRFCheck?: boolean;
798
+ /**
799
+ * Configure cookies to be cross subdomains
800
+ */
801
+ crossSubDomainCookies?: {
802
+ /**
803
+ * Enable cross subdomain cookies
804
+ */
805
+ enabled: boolean;
806
+ /**
807
+ * Additional cookies to be shared across subdomains
808
+ */
809
+ additionalCookies?: string[];
810
+ /**
811
+ * The domain to use for the cookies
812
+ *
813
+ * By default, the domain will be the root
814
+ * domain from the base URL.
815
+ */
816
+ domain?: string;
817
+ };
818
+ cookies?: {
819
+ [key: string]: {
820
+ name?: string;
821
+ attributes?: CookieOptions;
822
+ };
823
+ };
824
+ defaultCookieAttributes?: CookieOptions;
825
+ /**
826
+ * Prefix for cookies. If a cookie name is provided
827
+ * in cookies config, this will be overridden.
828
+ *
829
+ * @default
830
+ * ```txt
831
+ * "appName" -> which defaults to "better-auth"
832
+ * ```
833
+ */
834
+ cookiePrefix?: string;
835
+ /**
836
+ * Database configuration.
837
+ */
838
+ database?: {
839
+ /**
840
+ * The default number of records to return from the database
841
+ * when using the `findMany` adapter method.
842
+ *
843
+ * @default 100
844
+ */
845
+ defaultFindManyLimit?: number;
846
+ /**
847
+ * If your database auto increments number ids, set this to `true`.
848
+ *
849
+ * 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.
850
+ *
851
+ * @default false
852
+ */
853
+ useNumberId?: boolean;
854
+ /**
855
+ * Custom generateId function.
856
+ *
857
+ * If not provided, random ids will be generated.
858
+ * If set to false, the database's auto generated id will be used.
859
+ */
860
+ generateId?: GenerateIdFn | false;
861
+ };
862
+ /**
863
+ * Custom generateId function.
864
+ *
865
+ * If not provided, random ids will be generated.
866
+ * If set to false, the database's auto generated id will be used.
867
+ *
868
+ * @deprecated Please use `database.generateId` instead. This will be potentially removed in future releases.
869
+ */
870
+ generateId?: GenerateIdFn | false;
871
+ };
872
+ type BetterAuthOptions = {
873
+ /**
874
+ * The name of the application
875
+ *
876
+ * process.env.APP_NAME
877
+ *
878
+ * @default "Better Auth"
879
+ */
880
+ appName?: string;
881
+ /**
882
+ * Base URL for the Better Auth. This is typically the
883
+ * root URL where your application server is hosted.
884
+ * If not explicitly set,
885
+ * the system will check the following environment variable:
886
+ *
887
+ * process.env.BETTER_AUTH_URL
888
+ */
889
+ baseURL?: string;
890
+ /**
891
+ * Base path for the Better Auth. This is typically
892
+ * the path where the
893
+ * Better Auth routes are mounted.
894
+ *
895
+ * @default "/api/auth"
896
+ */
897
+ basePath?: string;
898
+ /**
899
+ * The secret to use for encryption,
900
+ * signing and hashing.
901
+ *
902
+ * By default Better Auth will look for
903
+ * the following environment variables:
904
+ * process.env.BETTER_AUTH_SECRET,
905
+ * process.env.AUTH_SECRET
906
+ * If none of these environment
907
+ * variables are set,
908
+ * it will default to
909
+ * "better-auth-secret-123456789".
910
+ *
911
+ * on production if it's not set
912
+ * it will throw an error.
913
+ *
914
+ * you can generate a good secret
915
+ * using the following command:
916
+ * @example
917
+ * ```bash
918
+ * openssl rand -base64 32
919
+ * ```
920
+ */
921
+ secret?: string;
922
+ /**
923
+ * Database configuration
924
+ */
925
+ database?: PostgresPool | MysqlPool | Database | Dialect | DBAdapterInstance | Database$1 | DatabaseSync | {
926
+ dialect: Dialect;
927
+ type: KyselyDatabaseType;
928
+ /**
929
+ * casing for table names
930
+ *
931
+ * @default "camel"
932
+ */
933
+ casing?: "snake" | "camel";
934
+ /**
935
+ * Enable debug logs for the adapter
936
+ *
937
+ * @default false
938
+ */
939
+ debugLogs?: DBAdapterDebugLogOption;
940
+ /**
941
+ * Whether to execute multiple operations in a transaction.
942
+ * If the database doesn't support transactions,
943
+ * set this to `false` and operations will be executed sequentially.
944
+ * @default true
945
+ */
946
+ transaction?: boolean;
947
+ } | {
948
+ /**
949
+ * Kysely instance
950
+ */
951
+ db: Kysely<any>;
952
+ /**
953
+ * Database type between postgres, mysql and sqlite
954
+ */
955
+ type: KyselyDatabaseType;
956
+ /**
957
+ * casing for table names
958
+ *
959
+ * @default "camel"
960
+ */
961
+ casing?: "snake" | "camel";
962
+ /**
963
+ * Enable debug logs for the adapter
964
+ *
965
+ * @default false
966
+ */
967
+ debugLogs?: DBAdapterDebugLogOption;
968
+ /**
969
+ * Whether to execute multiple operations in a transaction.
970
+ * If the database doesn't support transactions,
971
+ * set this to `false` and operations will be executed sequentially.
972
+ * @default true
973
+ */
974
+ transaction?: boolean;
975
+ };
976
+ /**
977
+ * Secondary storage configuration
978
+ *
979
+ * This is used to store session and rate limit data.
980
+ */
981
+ secondaryStorage?: SecondaryStorage;
982
+ /**
983
+ * Email verification configuration
984
+ */
985
+ emailVerification?: {
986
+ /**
987
+ * Send a verification email
988
+ * @param data the data object
989
+ * @param request the request object
990
+ */
991
+ sendVerificationEmail?: (
992
+ /**
993
+ * @param user the user to send the
994
+ * verification email to
995
+ * @param url the URL to send the verification email to
996
+ * it contains the token as well
997
+ * @param token the token to send the verification email to
998
+ */
999
+ data: {
1000
+ user: User;
1001
+ url: string;
1002
+ token: string;
1003
+ },
1004
+ /**
1005
+ * The request object
1006
+ */
1007
+ request?: Request) => Promise<void>;
1008
+ /**
1009
+ * Send a verification email automatically
1010
+ * after sign up
1011
+ *
1012
+ * @default false
1013
+ */
1014
+ sendOnSignUp?: boolean;
1015
+ /**
1016
+ * Send a verification email automatically
1017
+ * on sign in when the user's email is not verified
1018
+ *
1019
+ * @default false
1020
+ */
1021
+ sendOnSignIn?: boolean;
1022
+ /**
1023
+ * Auto signin the user after they verify their email
1024
+ */
1025
+ autoSignInAfterVerification?: boolean;
1026
+ /**
1027
+ * Number of seconds the verification token is
1028
+ * valid for.
1029
+ * @default 3600 seconds (1 hour)
1030
+ */
1031
+ expiresIn?: number;
1032
+ /**
1033
+ * A function that is called when a user verifies their email
1034
+ * @param user the user that verified their email
1035
+ * @param request the request object
1036
+ */
1037
+ onEmailVerification?: (user: User, request?: Request) => Promise<void>;
1038
+ /**
1039
+ * A function that is called when a user's email is updated to verified
1040
+ * @param user the user that verified their email
1041
+ * @param request the request object
1042
+ */
1043
+ afterEmailVerification?: (user: User, request?: Request) => Promise<void>;
1044
+ };
1045
+ /**
1046
+ * Email and password authentication
1047
+ */
1048
+ emailAndPassword?: {
1049
+ /**
1050
+ * Enable email and password authentication
1051
+ *
1052
+ * @default false
1053
+ */
1054
+ enabled: boolean;
1055
+ /**
1056
+ * Disable email and password sign up
1057
+ *
1058
+ * @default false
1059
+ */
1060
+ disableSignUp?: boolean;
1061
+ /**
1062
+ * Require email verification before a session
1063
+ * can be created for the user.
1064
+ *
1065
+ * if the user is not verified, the user will not be able to sign in
1066
+ * and on sign in attempts, the user will be prompted to verify their email.
1067
+ */
1068
+ requireEmailVerification?: boolean;
1069
+ /**
1070
+ * The maximum length of the password.
1071
+ *
1072
+ * @default 128
1073
+ */
1074
+ maxPasswordLength?: number;
1075
+ /**
1076
+ * The minimum length of the password.
1077
+ *
1078
+ * @default 8
1079
+ */
1080
+ minPasswordLength?: number;
1081
+ /**
1082
+ * send reset password
1083
+ */
1084
+ sendResetPassword?: (
1085
+ /**
1086
+ * @param user the user to send the
1087
+ * reset password email to
1088
+ * @param url the URL to send the reset password email to
1089
+ * @param token the token to send to the user (could be used instead of sending the url
1090
+ * if you need to redirect the user to custom route)
1091
+ */
1092
+ data: {
1093
+ user: User;
1094
+ url: string;
1095
+ token: string;
1096
+ },
1097
+ /**
1098
+ * The request object
1099
+ */
1100
+ request?: Request) => Promise<void>;
1101
+ /**
1102
+ * Number of seconds the reset password token is
1103
+ * valid for.
1104
+ * @default 1 hour (60 * 60)
1105
+ */
1106
+ resetPasswordTokenExpiresIn?: number;
1107
+ /**
1108
+ * A callback function that is triggered
1109
+ * when a user's password is changed successfully.
1110
+ */
1111
+ onPasswordReset?: (data: {
1112
+ user: User;
1113
+ }, request?: Request) => Promise<void>;
1114
+ /**
1115
+ * Password hashing and verification
1116
+ *
1117
+ * By default Scrypt is used for password hashing and
1118
+ * verification. You can provide your own hashing and
1119
+ * verification function. if you want to use a
1120
+ * different algorithm.
1121
+ */
1122
+ password?: {
1123
+ hash?: (password: string) => Promise<string>;
1124
+ verify?: (data: {
1125
+ hash: string;
1126
+ password: string;
1127
+ }) => Promise<boolean>;
1128
+ };
1129
+ /**
1130
+ * Automatically sign in the user after sign up
1131
+ *
1132
+ * @default true
1133
+ */
1134
+ autoSignIn?: boolean;
1135
+ /**
1136
+ * Whether to revoke all other sessions when resetting password
1137
+ * @default false
1138
+ */
1139
+ revokeSessionsOnPasswordReset?: boolean;
1140
+ };
1141
+ /**
1142
+ * list of social providers
1143
+ */
1144
+ socialProviders?: SocialProviders;
1145
+ /**
1146
+ * List of Better Auth plugins
1147
+ */
1148
+ plugins?: [] | BetterAuthPlugin[];
1149
+ /**
1150
+ * User configuration
1151
+ */
1152
+ user?: {
1153
+ /**
1154
+ * The model name for the user. Defaults to "user".
1155
+ */
1156
+ modelName?: string;
1157
+ /**
1158
+ * Map fields
1159
+ *
1160
+ * @example
1161
+ * ```ts
1162
+ * {
1163
+ * userId: "user_id"
1164
+ * }
1165
+ * ```
1166
+ */
1167
+ fields?: Partial<Record<keyof OmitId<User>, string>>;
1168
+ /**
1169
+ * Additional fields for the user
1170
+ */
1171
+ additionalFields?: {
1172
+ [key: string]: DBFieldAttribute;
1173
+ };
1174
+ /**
1175
+ * Changing email configuration
1176
+ */
1177
+ changeEmail?: {
1178
+ /**
1179
+ * Enable changing email
1180
+ * @default false
1181
+ */
1182
+ enabled: boolean;
1183
+ /**
1184
+ * Send a verification email when the user changes their email.
1185
+ * @param data the data object
1186
+ * @param request the request object
1187
+ */
1188
+ sendChangeEmailVerification?: (data: {
1189
+ user: User;
1190
+ newEmail: string;
1191
+ url: string;
1192
+ token: string;
1193
+ }, request?: Request) => Promise<void>;
1194
+ };
1195
+ /**
1196
+ * User deletion configuration
1197
+ */
1198
+ deleteUser?: {
1199
+ /**
1200
+ * Enable user deletion
1201
+ */
1202
+ enabled?: boolean;
1203
+ /**
1204
+ * Send a verification email when the user deletes their account.
1205
+ *
1206
+ * if this is not set, the user will be deleted immediately.
1207
+ * @param data the data object
1208
+ * @param request the request object
1209
+ */
1210
+ sendDeleteAccountVerification?: (data: {
1211
+ user: User;
1212
+ url: string;
1213
+ token: string;
1214
+ }, request?: Request) => Promise<void>;
1215
+ /**
1216
+ * A function that is called before a user is deleted.
1217
+ *
1218
+ * to interrupt with error you can throw `APIError`
1219
+ */
1220
+ beforeDelete?: (user: User, request?: Request) => Promise<void>;
1221
+ /**
1222
+ * A function that is called after a user is deleted.
1223
+ *
1224
+ * This is useful for cleaning up user data
1225
+ */
1226
+ afterDelete?: (user: User, request?: Request) => Promise<void>;
1227
+ /**
1228
+ * The expiration time for the delete token.
1229
+ *
1230
+ * @default 1 day (60 * 60 * 24) in seconds
1231
+ */
1232
+ deleteTokenExpiresIn?: number;
1233
+ };
1234
+ };
1235
+ session?: {
1236
+ /**
1237
+ * The model name for the session.
1238
+ *
1239
+ * @default "session"
1240
+ */
1241
+ modelName?: string;
1242
+ /**
1243
+ * Map fields
1244
+ *
1245
+ * @example
1246
+ * ```ts
1247
+ * {
1248
+ * userId: "user_id"
1249
+ * }
1250
+ */
1251
+ fields?: Partial<Record<keyof OmitId<Session>, string>>;
1252
+ /**
1253
+ * Expiration time for the session token. The value
1254
+ * should be in seconds.
1255
+ * @default 7 days (60 * 60 * 24 * 7)
1256
+ */
1257
+ expiresIn?: number;
1258
+ /**
1259
+ * How often the session should be refreshed. The value
1260
+ * should be in seconds.
1261
+ * If set 0 the session will be refreshed every time it is used.
1262
+ * @default 1 day (60 * 60 * 24)
1263
+ */
1264
+ updateAge?: number;
1265
+ /**
1266
+ * Disable session refresh so that the session is not updated
1267
+ * regardless of the `updateAge` option.
1268
+ *
1269
+ * @default false
1270
+ */
1271
+ disableSessionRefresh?: boolean;
1272
+ /**
1273
+ * Additional fields for the session
1274
+ */
1275
+ additionalFields?: {
1276
+ [key: string]: DBFieldAttribute;
1277
+ };
1278
+ /**
1279
+ * By default if secondary storage is provided
1280
+ * the session is stored in the secondary storage.
1281
+ *
1282
+ * Set this to true to store the session in the database
1283
+ * as well.
1284
+ *
1285
+ * Reads are always done from the secondary storage.
1286
+ *
1287
+ * @default false
1288
+ */
1289
+ storeSessionInDatabase?: boolean;
1290
+ /**
1291
+ * By default, sessions are deleted from the database when secondary storage
1292
+ * is provided when session is revoked.
1293
+ *
1294
+ * Set this to true to preserve session records in the database,
1295
+ * even if they are deleted from the secondary storage.
1296
+ *
1297
+ * @default false
1298
+ */
1299
+ preserveSessionInDatabase?: boolean;
1300
+ /**
1301
+ * Enable caching session in cookie
1302
+ */
1303
+ cookieCache?: {
1304
+ /**
1305
+ * max age of the cookie
1306
+ * @default 5 minutes (5 * 60)
1307
+ */
1308
+ maxAge?: number;
1309
+ /**
1310
+ * Enable caching session in cookie
1311
+ * @default false
1312
+ */
1313
+ enabled?: boolean;
1314
+ };
1315
+ /**
1316
+ * The age of the session to consider it fresh.
1317
+ *
1318
+ * This is used to check if the session is fresh
1319
+ * for sensitive operations. (e.g. deleting an account)
1320
+ *
1321
+ * If the session is not fresh, the user should be prompted
1322
+ * to sign in again.
1323
+ *
1324
+ * If set to 0, the session will be considered fresh every time. (⚠︎ not recommended)
1325
+ *
1326
+ * @default 1 day (60 * 60 * 24)
1327
+ */
1328
+ freshAge?: number;
1329
+ };
1330
+ account?: {
1331
+ /**
1332
+ * The model name for the account. Defaults to "account".
1333
+ */
1334
+ modelName?: string;
1335
+ /**
1336
+ * Map fields
1337
+ */
1338
+ fields?: Partial<Record<keyof OmitId<Account>, string>>;
1339
+ /**
1340
+ * Additional fields for the account
1341
+ */
1342
+ additionalFields?: {
1343
+ [key: string]: DBFieldAttribute;
1344
+ };
1345
+ /**
1346
+ * When enabled (true), the user account data (accessToken, idToken, refreshToken, etc.)
1347
+ * will be updated on sign in with the latest data from the provider.
1348
+ *
1349
+ * @default true
1350
+ */
1351
+ updateAccountOnSignIn?: boolean;
1352
+ /**
1353
+ * Configuration for account linking.
1354
+ */
1355
+ accountLinking?: {
1356
+ /**
1357
+ * Enable account linking
1358
+ *
1359
+ * @default true
1360
+ */
1361
+ enabled?: boolean;
1362
+ /**
1363
+ * List of trusted providers
1364
+ */
1365
+ trustedProviders?: Array<LiteralUnion<SocialProviderList[number] | "email-password", string>>;
1366
+ /**
1367
+ * If enabled (true), this will allow users to manually linking accounts with different email addresses than the main user.
1368
+ *
1369
+ * @default false
1370
+ *
1371
+ * ⚠️ Warning: enabling this might lead to account takeovers, so proceed with caution.
1372
+ */
1373
+ allowDifferentEmails?: boolean;
1374
+ /**
1375
+ * If enabled (true), this will allow users to unlink all accounts.
1376
+ *
1377
+ * @default false
1378
+ */
1379
+ allowUnlinkingAll?: boolean;
1380
+ /**
1381
+ * If enabled (true), this will update the user information based on the newly linked account
1382
+ *
1383
+ * @default false
1384
+ */
1385
+ updateUserInfoOnLink?: boolean;
1386
+ };
1387
+ /**
1388
+ * Encrypt OAuth tokens
1389
+ *
1390
+ * By default, OAuth tokens (access tokens, refresh tokens, ID tokens) are stored in plain text in the database.
1391
+ * This poses a security risk if your database is compromised, as attackers could gain access to user accounts
1392
+ * on external services.
1393
+ *
1394
+ * When enabled, tokens are encrypted using AES-256-GCM before storage, providing protection against:
1395
+ * - Database breaches and unauthorized access to raw token data
1396
+ * - Internal threats from database administrators or compromised credentials
1397
+ * - Token exposure in database backups and logs
1398
+ * @default false
1399
+ */
1400
+ encryptOAuthTokens?: boolean;
1401
+ };
1402
+ /**
1403
+ * Verification configuration
1404
+ */
1405
+ verification?: {
1406
+ /**
1407
+ * Change the modelName of the verification table
1408
+ */
1409
+ modelName?: string;
1410
+ /**
1411
+ * Map verification fields
1412
+ */
1413
+ fields?: Partial<Record<keyof OmitId<Verification>, string>>;
1414
+ /**
1415
+ * disable cleaning up expired values when a verification value is
1416
+ * fetched
1417
+ */
1418
+ disableCleanup?: boolean;
1419
+ };
1420
+ /**
1421
+ * List of trusted origins.
1422
+ */
1423
+ trustedOrigins?: string[] | ((request: Request) => string[] | Promise<string[]>);
1424
+ /**
1425
+ * Rate limiting configuration
1426
+ */
1427
+ rateLimit?: BetterAuthRateLimitOptions;
1428
+ /**
1429
+ * Advanced options
1430
+ */
1431
+ advanced?: BetterAuthAdvancedOptions & {
1432
+ /**
1433
+ * @deprecated Please use `database.generateId` instead.
1434
+ */
1435
+ generateId?: GenerateIdFn | false;
1436
+ };
1437
+ logger?: Logger;
1438
+ /**
1439
+ * allows you to define custom hooks that can be
1440
+ * executed during lifecycle of core database
1441
+ * operations.
1442
+ */
1443
+ databaseHooks?: {
1444
+ /**
1445
+ * User hooks
1446
+ */
1447
+ user?: {
1448
+ create?: {
1449
+ /**
1450
+ * Hook that is called before a user is created.
1451
+ * if the hook returns false, the user will not be created.
1452
+ * If the hook returns an object, it'll be used instead of the original data
1453
+ */
1454
+ before?: (user: User & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1455
+ data: Partial<User> & Record<string, any>;
1456
+ }>;
1457
+ /**
1458
+ * Hook that is called after a user is created.
1459
+ */
1460
+ after?: (user: User & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1461
+ };
1462
+ update?: {
1463
+ /**
1464
+ * Hook that is called before a user is updated.
1465
+ * if the hook returns false, the user will not be updated.
1466
+ * If the hook returns an object, it'll be used instead of the original data
1467
+ */
1468
+ before?: (user: Partial<User> & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1469
+ data: Partial<User & Record<string, any>>;
1470
+ }>;
1471
+ /**
1472
+ * Hook that is called after a user is updated.
1473
+ */
1474
+ after?: (user: User & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1475
+ };
1476
+ delete?: {
1477
+ /**
1478
+ * Hook that is called before a user is deleted.
1479
+ * if the hook returns false, the user will not be deleted.
1480
+ */
1481
+ before?: (user: User & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void>;
1482
+ /**
1483
+ * Hook that is called after a user is deleted.
1484
+ */
1485
+ after?: (user: User & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1486
+ };
1487
+ };
1488
+ /**
1489
+ * Session Hook
1490
+ */
1491
+ session?: {
1492
+ create?: {
1493
+ /**
1494
+ * Hook that is called before a session is created.
1495
+ * if the hook returns false, the session will not be created.
1496
+ * If the hook returns an object, it'll be used instead of the original data
1497
+ */
1498
+ before?: (session: Session & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1499
+ data: Partial<Session> & Record<string, any>;
1500
+ }>;
1501
+ /**
1502
+ * Hook that is called after a session is created.
1503
+ */
1504
+ after?: (session: Session & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1505
+ };
1506
+ /**
1507
+ * Update hook
1508
+ */
1509
+ update?: {
1510
+ /**
1511
+ * Hook that is called before a user is updated.
1512
+ * if the hook returns false, the session will not be updated.
1513
+ * If the hook returns an object, it'll be used instead of the original data
1514
+ */
1515
+ before?: (session: Partial<Session> & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1516
+ data: Partial<Session & Record<string, any>>;
1517
+ }>;
1518
+ /**
1519
+ * Hook that is called after a session is updated.
1520
+ */
1521
+ after?: (session: Session & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1522
+ };
1523
+ delete?: {
1524
+ /**
1525
+ * Hook that is called before a session is deleted.
1526
+ * if the hook returns false, the session will not be deleted.
1527
+ */
1528
+ before?: (session: Session & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void>;
1529
+ /**
1530
+ * Hook that is called after a session is deleted.
1531
+ */
1532
+ after?: (session: Session & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1533
+ };
1534
+ };
1535
+ /**
1536
+ * Account Hook
1537
+ */
1538
+ account?: {
1539
+ create?: {
1540
+ /**
1541
+ * Hook that is called before a account is created.
1542
+ * If the hook returns false, the account will not be created.
1543
+ * If the hook returns an object, it'll be used instead of the original data
1544
+ */
1545
+ before?: (account: Account, context?: GenericEndpointContext) => Promise<boolean | void | {
1546
+ data: Partial<Account> & Record<string, any>;
1547
+ }>;
1548
+ /**
1549
+ * Hook that is called after a account is created.
1550
+ */
1551
+ after?: (account: Account, context?: GenericEndpointContext) => Promise<void>;
1552
+ };
1553
+ /**
1554
+ * Update hook
1555
+ */
1556
+ update?: {
1557
+ /**
1558
+ * Hook that is called before a account is update.
1559
+ * If the hook returns false, the user will not be updated.
1560
+ * If the hook returns an object, it'll be used instead of the original data
1561
+ */
1562
+ before?: (account: Partial<Account> & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1563
+ data: Partial<Account & Record<string, any>>;
1564
+ }>;
1565
+ /**
1566
+ * Hook that is called after a account is updated.
1567
+ */
1568
+ after?: (account: Account & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1569
+ };
1570
+ delete?: {
1571
+ /**
1572
+ * Hook that is called before an account is deleted.
1573
+ * if the hook returns false, the account will not be deleted.
1574
+ */
1575
+ before?: (account: Account & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void>;
1576
+ /**
1577
+ * Hook that is called after an account is deleted.
1578
+ */
1579
+ after?: (account: Account & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1580
+ };
1581
+ };
1582
+ /**
1583
+ * Verification Hook
1584
+ */
1585
+ verification?: {
1586
+ create?: {
1587
+ /**
1588
+ * Hook that is called before a verification is created.
1589
+ * if the hook returns false, the verification will not be created.
1590
+ * If the hook returns an object, it'll be used instead of the original data
1591
+ */
1592
+ before?: (verification: Verification & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1593
+ data: Partial<Verification> & Record<string, any>;
1594
+ }>;
1595
+ /**
1596
+ * Hook that is called after a verification is created.
1597
+ */
1598
+ after?: (verification: Verification & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1599
+ };
1600
+ update?: {
1601
+ /**
1602
+ * Hook that is called before a verification is updated.
1603
+ * if the hook returns false, the verification will not be updated.
1604
+ * If the hook returns an object, it'll be used instead of the original data
1605
+ */
1606
+ before?: (verification: Partial<Verification> & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void | {
1607
+ data: Partial<Verification & Record<string, any>>;
1608
+ }>;
1609
+ /**
1610
+ * Hook that is called after a verification is updated.
1611
+ */
1612
+ after?: (verification: Verification & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1613
+ };
1614
+ delete?: {
1615
+ /**
1616
+ * Hook that is called before a verification is deleted.
1617
+ * if the hook returns false, the verification will not be deleted.
1618
+ */
1619
+ before?: (verification: Verification & Record<string, unknown>, context?: GenericEndpointContext) => Promise<boolean | void>;
1620
+ /**
1621
+ * Hook that is called after a verification is deleted.
1622
+ */
1623
+ after?: (verification: Verification & Record<string, unknown>, context?: GenericEndpointContext) => Promise<void>;
1624
+ };
1625
+ };
1626
+ };
1627
+ /**
1628
+ * API error handling
1629
+ */
1630
+ onAPIError?: {
1631
+ /**
1632
+ * Throw an error on API error
1633
+ *
1634
+ * @default false
1635
+ */
1636
+ throw?: boolean;
1637
+ /**
1638
+ * Custom error handler
1639
+ *
1640
+ * @param error
1641
+ * @param ctx - Auth context
1642
+ */
1643
+ onError?: (error: unknown, ctx: AuthContext) => void | Promise<void>;
1644
+ /**
1645
+ * The URL to redirect to on error
1646
+ *
1647
+ * When errorURL is provided, the error will be added to the URL as a query parameter
1648
+ * and the user will be redirected to the errorURL.
1649
+ *
1650
+ * @default - "/api/auth/error"
1651
+ */
1652
+ errorURL?: string;
1653
+ };
1654
+ /**
1655
+ * Hooks
1656
+ */
1657
+ hooks?: {
1658
+ /**
1659
+ * Before a request is processed
1660
+ */
1661
+ before?: AuthMiddleware;
1662
+ /**
1663
+ * After a request is processed
1664
+ */
1665
+ after?: AuthMiddleware;
1666
+ };
1667
+ /**
1668
+ * Disabled paths
1669
+ *
1670
+ * Paths you want to disable.
1671
+ */
1672
+ disabledPaths?: string[];
1673
+ /**
1674
+ * Telemetry configuration
1675
+ */
1676
+ telemetry?: {
1677
+ /**
1678
+ * Enable telemetry collection
1679
+ *
1680
+ * @default false
1681
+ */
1682
+ enabled?: boolean;
1683
+ /**
1684
+ * Enable debug mode
1685
+ *
1686
+ * @default false
1687
+ */
1688
+ debug?: boolean;
1689
+ };
1690
+ };
1691
+
1692
+ export { createAuthMiddleware as l, createAuthEndpoint as m, optionsMiddleware as o };
1693
+ export type { AuthContext as A, BetterAuthOptions as B, CleanedWhere as C, DBAdapterDebugLogOption as D, GenerateIdFn as G, InternalAdapter as I, Where as W, AuthMiddleware as a, BetterAuthAdvancedOptions as b, BetterAuthRateLimitOptions as c, BetterAuthCookies as d, GenericEndpointContext as e, DBAdapterSchemaCreation as f, DBAdapterFactoryConfig as g, DBTransactionAdapter as h, DBAdapter as i, CustomAdapter as j, DBAdapterInstance as k, AuthEndpoint as n };