@better-auth/core 1.5.0-beta.16 → 1.5.0-beta.17

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.
@@ -2,7 +2,7 @@
2
2
  const symbol = Symbol.for("better-auth:global");
3
3
  let bind = null;
4
4
  const __context = {};
5
- const __betterAuthVersion = "1.5.0-beta.16";
5
+ const __betterAuthVersion = "1.5.0-beta.17";
6
6
  /**
7
7
  * We store context instance in the globalThis.
8
8
  *
@@ -1,7 +1,7 @@
1
+ import { getAuthTables } from "../get-tables.mjs";
1
2
  import { getColorDepth } from "../../env/color-depth.mjs";
2
3
  import { TTY_COLORS, createLogger } from "../../env/logger.mjs";
3
4
  import "../../env/index.mjs";
4
- import { getAuthTables } from "../get-tables.mjs";
5
5
  import { BetterAuthError } from "../../error/index.mjs";
6
6
  import { safeJSONParse } from "../../utils/json.mjs";
7
7
  import { initGetDefaultModelName } from "./get-default-model-name.mjs";
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Awaitable, AwaitableFunction, LiteralString, LiteralUnion, Prettify, Primitive, UnionToIntersection } from "./types/helper.mjs";
2
2
  import { BetterAuthPlugin, BetterAuthPluginErrorCodePart, HookEndpointContext } from "./types/plugin.mjs";
3
- import { BetterAuthAdvancedOptions, BetterAuthDBOptions, BetterAuthOptions, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, GenerateIdFn, StoreIdentifierOption } from "./types/init-options.mjs";
3
+ import { BaseURLConfig, BetterAuthAdvancedOptions, BetterAuthDBOptions, BetterAuthOptions, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, DynamicBaseURLConfig, GenerateIdFn, StoreIdentifierOption } from "./types/init-options.mjs";
4
4
  import { BetterAuthCookie, BetterAuthCookies } from "./types/cookie.mjs";
5
5
  import { AuthContext, BetterAuthPluginRegistry, BetterAuthPluginRegistryIdentifier, GenericEndpointContext, InfoContext, InternalAdapter, PluginContext } from "./types/context.mjs";
6
6
  import { BetterAuthClientOptions, BetterAuthClientPlugin, ClientAtomListener, ClientFetchOption, ClientStore } from "./types/plugin-client.mjs";
7
7
  import { StandardSchemaV1 } from "./types/index.mjs";
8
- export { AuthContext, Awaitable, AwaitableFunction, BetterAuthAdvancedOptions, BetterAuthClientOptions, BetterAuthClientPlugin, BetterAuthCookie, BetterAuthCookies, BetterAuthDBOptions, BetterAuthOptions, BetterAuthPlugin, BetterAuthPluginErrorCodePart, BetterAuthPluginRegistry, BetterAuthPluginRegistryIdentifier, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, ClientAtomListener, ClientFetchOption, ClientStore, GenerateIdFn, GenericEndpointContext, HookEndpointContext, InfoContext, InternalAdapter, LiteralString, LiteralUnion, PluginContext, Prettify, Primitive, StandardSchemaV1, StoreIdentifierOption, UnionToIntersection };
8
+ export { AuthContext, Awaitable, AwaitableFunction, BaseURLConfig, BetterAuthAdvancedOptions, BetterAuthClientOptions, BetterAuthClientPlugin, BetterAuthCookie, BetterAuthCookies, BetterAuthDBOptions, BetterAuthOptions, BetterAuthPlugin, BetterAuthPluginErrorCodePart, BetterAuthPluginRegistry, BetterAuthPluginRegistryIdentifier, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, ClientAtomListener, ClientFetchOption, ClientStore, DynamicBaseURLConfig, GenerateIdFn, GenericEndpointContext, HookEndpointContext, InfoContext, InternalAdapter, LiteralString, LiteralUnion, PluginContext, Prettify, Primitive, StandardSchemaV1, StoreIdentifierOption, UnionToIntersection };
@@ -1,6 +1,6 @@
1
1
  import { Awaitable, AwaitableFunction, LiteralString, LiteralUnion, Prettify, Primitive, UnionToIntersection } from "./helper.mjs";
2
2
  import { BetterAuthPlugin, BetterAuthPluginErrorCodePart, HookEndpointContext } from "./plugin.mjs";
3
- import { BetterAuthAdvancedOptions, BetterAuthDBOptions, BetterAuthOptions, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, GenerateIdFn, StoreIdentifierOption } from "./init-options.mjs";
3
+ import { BaseURLConfig, BetterAuthAdvancedOptions, BetterAuthDBOptions, BetterAuthOptions, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, DynamicBaseURLConfig, GenerateIdFn, StoreIdentifierOption } from "./init-options.mjs";
4
4
  import { BetterAuthCookie, BetterAuthCookies } from "./cookie.mjs";
5
5
  import { AuthContext, BetterAuthPluginRegistry, BetterAuthPluginRegistryIdentifier, GenericEndpointContext, InfoContext, InternalAdapter, PluginContext } from "./context.mjs";
6
6
  import { BetterAuthClientOptions, BetterAuthClientPlugin, ClientAtomListener, ClientFetchOption, ClientStore } from "./plugin-client.mjs";
@@ -27,6 +27,49 @@ type GenerateIdFn = (options: {
27
27
  model: ModelNames;
28
28
  size?: number | undefined;
29
29
  }) => string | false;
30
+ /**
31
+ * Configuration for dynamic base URL resolution.
32
+ * Allows Better Auth to work with multiple domains (e.g., Vercel preview deployments).
33
+ */
34
+ type DynamicBaseURLConfig = {
35
+ /**
36
+ * List of allowed hostnames. Supports wildcard patterns.
37
+ *
38
+ * The derived host from the request will be validated against this list.
39
+ * Uses the same wildcard matching as `trustedOrigins`.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * allowedHosts: [
44
+ * "myapp.com", // Exact match
45
+ * "*.vercel.app", // Any Vercel preview
46
+ * "preview-*.myapp.com" // Pattern match
47
+ * ]
48
+ * ```
49
+ */
50
+ allowedHosts: string[];
51
+ /**
52
+ * Fallback URL to use if the derived host doesn't match any allowed host.
53
+ * If not set, Better Auth will throw an error when the host doesn't match.
54
+ *
55
+ * @example "https://myapp.com"
56
+ */
57
+ fallback?: string | undefined;
58
+ /**
59
+ * Protocol to use when constructing the URL.
60
+ * - `"https"`: Always use HTTPS (recommended for production)
61
+ * - `"http"`: Always use HTTP (for local development)
62
+ * - `"auto"`: Derive from `x-forwarded-proto` header or default to HTTPS
63
+ *
64
+ * @default "auto"
65
+ */
66
+ protocol?: "http" | "https" | "auto" | undefined;
67
+ };
68
+ /**
69
+ * Base URL configuration.
70
+ * Can be a static string or a dynamic config for multi-domain deployments.
71
+ */
72
+ type BaseURLConfig = string | DynamicBaseURLConfig;
30
73
  interface BetterAuthRateLimitStorage {
31
74
  get: (key: string) => Promise<RateLimit | null | undefined>;
32
75
  set: (key: string, value: RateLimit, update?: boolean | undefined) => Promise<void>;
@@ -281,12 +324,27 @@ type BetterAuthOptions = {
281
324
  /**
282
325
  * Base URL for the Better Auth. This is typically the
283
326
  * root URL where your application server is hosted.
284
- * If not explicitly set,
285
- * the system will check the following environment variable:
286
327
  *
287
- * process.env.BETTER_AUTH_URL
328
+ * Can be configured as:
329
+ * - A static string: `"https://myapp.com"`
330
+ * - A dynamic config with allowed hosts for multi-domain deployments
331
+ *
332
+ * If not explicitly set, the system will check environment variables:
333
+ * `BETTER_AUTH_URL`, `NEXT_PUBLIC_BETTER_AUTH_URL`, etc.
334
+ *
335
+ * @example
336
+ * ```ts
337
+ * // Static URL
338
+ * baseURL: "https://myapp.com"
339
+ *
340
+ * // Dynamic with allowed hosts (for Vercel, multi-domain, etc.)
341
+ * baseURL: {
342
+ * allowedHosts: ["myapp.com", "*.vercel.app", "preview-*.myapp.com"],
343
+ * fallback: "https://myapp.com"
344
+ * }
345
+ * ```
288
346
  */
289
- baseURL?: string | undefined;
347
+ baseURL?: BaseURLConfig | undefined;
290
348
  /**
291
349
  * Base path for the Better Auth. This is typically
292
350
  * the path where the
@@ -398,7 +456,6 @@ type BetterAuthOptions = {
398
456
  * it contains the token as well
399
457
  * @param token the token to send the verification email to
400
458
  */
401
-
402
459
  data: {
403
460
  user: User;
404
461
  url: string;
@@ -407,7 +464,6 @@ type BetterAuthOptions = {
407
464
  /**
408
465
  * The request object
409
466
  */
410
-
411
467
  request?: Request) => Promise<void>;
412
468
  /**
413
469
  * Send a verification email automatically after sign up.
@@ -544,6 +600,20 @@ type BetterAuthOptions = {
544
600
  * @default false
545
601
  */
546
602
  revokeSessionsOnPasswordReset?: boolean;
603
+ /**
604
+ * A callback function that is triggered when a user tries to sign up
605
+ * with an email that already exists. Useful for notifying the existing user
606
+ * that someone attempted to register with their email.
607
+ *
608
+ * This is only called when `requireEmailVerification: true` or `autoSignIn: false`.
609
+ */
610
+ onExistingUserSignUp?: (
611
+ /**
612
+ * @param user the existing user from the database
613
+ */
614
+ data: {
615
+ user: User;
616
+ }, request?: Request) => Promise<void>;
547
617
  } | undefined;
548
618
  /**
549
619
  * list of social providers
@@ -1224,5 +1294,5 @@ type BetterAuthOptions = {
1224
1294
  };
1225
1295
  };
1226
1296
  //#endregion
1227
- export { BetterAuthAdvancedOptions, BetterAuthDBOptions, BetterAuthOptions, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, GenerateIdFn, StoreIdentifierOption };
1297
+ export { BaseURLConfig, BetterAuthAdvancedOptions, BetterAuthDBOptions, BetterAuthOptions, BetterAuthRateLimitOptions, BetterAuthRateLimitRule, BetterAuthRateLimitStorage, DynamicBaseURLConfig, GenerateIdFn, StoreIdentifierOption };
1228
1298
  //# sourceMappingURL=init-options.d.mts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@better-auth/core",
3
- "version": "1.5.0-beta.16",
3
+ "version": "1.5.0-beta.17",
4
4
  "description": "The most comprehensive authentication framework for TypeScript.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -14,12 +14,14 @@ export type {
14
14
  } from "./cookie";
15
15
  export type * from "./helper";
16
16
  export type {
17
+ BaseURLConfig,
17
18
  BetterAuthAdvancedOptions,
18
19
  BetterAuthDBOptions,
19
20
  BetterAuthOptions,
20
21
  BetterAuthRateLimitOptions,
21
22
  BetterAuthRateLimitRule,
22
23
  BetterAuthRateLimitStorage,
24
+ DynamicBaseURLConfig,
23
25
  GenerateIdFn,
24
26
  StoreIdentifierOption,
25
27
  } from "./init-options";
@@ -46,6 +46,53 @@ export type GenerateIdFn = (options: {
46
46
  size?: number | undefined;
47
47
  }) => string | false;
48
48
 
49
+ /**
50
+ * Configuration for dynamic base URL resolution.
51
+ * Allows Better Auth to work with multiple domains (e.g., Vercel preview deployments).
52
+ */
53
+ export type DynamicBaseURLConfig = {
54
+ /**
55
+ * List of allowed hostnames. Supports wildcard patterns.
56
+ *
57
+ * The derived host from the request will be validated against this list.
58
+ * Uses the same wildcard matching as `trustedOrigins`.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * allowedHosts: [
63
+ * "myapp.com", // Exact match
64
+ * "*.vercel.app", // Any Vercel preview
65
+ * "preview-*.myapp.com" // Pattern match
66
+ * ]
67
+ * ```
68
+ */
69
+ allowedHosts: string[];
70
+
71
+ /**
72
+ * Fallback URL to use if the derived host doesn't match any allowed host.
73
+ * If not set, Better Auth will throw an error when the host doesn't match.
74
+ *
75
+ * @example "https://myapp.com"
76
+ */
77
+ fallback?: string | undefined;
78
+
79
+ /**
80
+ * Protocol to use when constructing the URL.
81
+ * - `"https"`: Always use HTTPS (recommended for production)
82
+ * - `"http"`: Always use HTTP (for local development)
83
+ * - `"auto"`: Derive from `x-forwarded-proto` header or default to HTTPS
84
+ *
85
+ * @default "auto"
86
+ */
87
+ protocol?: "http" | "https" | "auto" | undefined;
88
+ };
89
+
90
+ /**
91
+ * Base URL configuration.
92
+ * Can be a static string or a dynamic config for multi-domain deployments.
93
+ */
94
+ export type BaseURLConfig = string | DynamicBaseURLConfig;
95
+
49
96
  export interface BetterAuthRateLimitStorage {
50
97
  get: (key: string) => Promise<RateLimit | null | undefined>;
51
98
  set: (
@@ -346,12 +393,27 @@ export type BetterAuthOptions = {
346
393
  /**
347
394
  * Base URL for the Better Auth. This is typically the
348
395
  * root URL where your application server is hosted.
349
- * If not explicitly set,
350
- * the system will check the following environment variable:
351
396
  *
352
- * process.env.BETTER_AUTH_URL
397
+ * Can be configured as:
398
+ * - A static string: `"https://myapp.com"`
399
+ * - A dynamic config with allowed hosts for multi-domain deployments
400
+ *
401
+ * If not explicitly set, the system will check environment variables:
402
+ * `BETTER_AUTH_URL`, `NEXT_PUBLIC_BETTER_AUTH_URL`, etc.
403
+ *
404
+ * @example
405
+ * ```ts
406
+ * // Static URL
407
+ * baseURL: "https://myapp.com"
408
+ *
409
+ * // Dynamic with allowed hosts (for Vercel, multi-domain, etc.)
410
+ * baseURL: {
411
+ * allowedHosts: ["myapp.com", "*.vercel.app", "preview-*.myapp.com"],
412
+ * fallback: "https://myapp.com"
413
+ * }
414
+ * ```
353
415
  */
354
- baseURL?: string | undefined;
416
+ baseURL?: BaseURLConfig | undefined;
355
417
  /**
356
418
  * Base path for the Better Auth. This is typically
357
419
  * the path where the
@@ -627,6 +689,20 @@ export type BetterAuthOptions = {
627
689
  * @default false
628
690
  */
629
691
  revokeSessionsOnPasswordReset?: boolean;
692
+ /**
693
+ * A callback function that is triggered when a user tries to sign up
694
+ * with an email that already exists. Useful for notifying the existing user
695
+ * that someone attempted to register with their email.
696
+ *
697
+ * This is only called when `requireEmailVerification: true` or `autoSignIn: false`.
698
+ */
699
+ onExistingUserSignUp?: (
700
+ /**
701
+ * @param user the existing user from the database
702
+ */
703
+ data: { user: User },
704
+ request?: Request,
705
+ ) => Promise<void>;
630
706
  }
631
707
  | undefined;
632
708
  /**