better-auth 1.4.18 → 1.4.19
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.
- package/dist/adapters/drizzle-adapter/drizzle-adapter.mjs +37 -5
- package/dist/adapters/drizzle-adapter/drizzle-adapter.mjs.map +1 -1
- package/dist/adapters/kysely-adapter/kysely-adapter.mjs +13 -3
- package/dist/adapters/kysely-adapter/kysely-adapter.mjs.map +1 -1
- package/dist/adapters/memory-adapter/memory-adapter.mjs +21 -17
- package/dist/adapters/memory-adapter/memory-adapter.mjs.map +1 -1
- package/dist/adapters/mongodb-adapter/mongodb-adapter.mjs +12 -1
- package/dist/adapters/mongodb-adapter/mongodb-adapter.mjs.map +1 -1
- package/dist/adapters/prisma-adapter/prisma-adapter.mjs +2 -2
- package/dist/adapters/prisma-adapter/prisma-adapter.mjs.map +1 -1
- package/dist/api/index.d.mts +407 -407
- package/dist/api/routes/account.d.mts +11 -11
- package/dist/api/routes/account.mjs +1 -1
- package/dist/api/routes/account.mjs.map +1 -1
- package/dist/api/routes/callback.d.mts +2 -2
- package/dist/api/routes/callback.mjs +1 -1
- package/dist/api/routes/callback.mjs.map +1 -1
- package/dist/api/routes/email-verification.d.mts +4 -4
- package/dist/api/routes/email-verification.mjs +1 -1
- package/dist/api/routes/email-verification.mjs.map +1 -1
- package/dist/api/routes/error.d.mts +2 -2
- package/dist/api/routes/ok.d.mts +2 -2
- package/dist/api/routes/password.d.mts +7 -7
- package/dist/api/routes/session.d.mts +14 -14
- package/dist/api/routes/sign-in.d.mts +4 -4
- package/dist/api/routes/sign-out.d.mts +2 -2
- package/dist/api/routes/sign-up.d.mts +3 -3
- package/dist/api/routes/update-user.d.mts +13 -13
- package/dist/api/routes/update-user.mjs +1 -1
- package/dist/api/routes/update-user.mjs.map +1 -1
- package/dist/client/react/index.d.mts +13 -13
- package/dist/client/svelte/index.d.mts +15 -15
- package/dist/client/vanilla.d.mts +15 -15
- package/dist/client/vue/index.d.mts +15 -15
- package/dist/context/create-context.mjs +1 -1
- package/dist/context/create-context.mjs.map +1 -1
- package/dist/cookies/index.d.mts +6 -6
- package/dist/cookies/index.mjs +5 -8
- package/dist/cookies/index.mjs.map +1 -1
- package/dist/db/field.d.mts +10 -10
- package/dist/db/field.mjs.map +1 -1
- package/dist/db/internal-adapter.mjs +1 -1
- package/dist/db/internal-adapter.mjs.map +1 -1
- package/dist/integrations/next-js.d.mts +4 -4
- package/dist/integrations/svelte-kit.d.mts +2 -2
- package/dist/integrations/tanstack-start-solid.d.mts +4 -4
- package/dist/integrations/tanstack-start.d.mts +4 -4
- package/dist/plugins/access/types.d.mts +1 -1
- package/dist/plugins/admin/admin.d.mts +114 -119
- package/dist/plugins/admin/admin.mjs +1 -1
- package/dist/plugins/admin/admin.mjs.map +1 -1
- package/dist/plugins/admin/routes.mjs +1 -1
- package/dist/plugins/admin/routes.mjs.map +1 -1
- package/dist/plugins/anonymous/index.d.mts +7 -7
- package/dist/plugins/api-key/index.d.mts +95 -80
- package/dist/plugins/api-key/routes/verify-api-key.mjs +1 -0
- package/dist/plugins/api-key/routes/verify-api-key.mjs.map +1 -1
- package/dist/plugins/bearer/index.d.mts +6 -6
- package/dist/plugins/captcha/index.d.mts +2 -2
- package/dist/plugins/custom-session/index.d.mts +5 -5
- package/dist/plugins/custom-session/index.mjs +13 -5
- package/dist/plugins/custom-session/index.mjs.map +1 -1
- package/dist/plugins/device-authorization/index.d.mts +6 -6
- package/dist/plugins/email-otp/index.d.mts +16 -16
- package/dist/plugins/email-otp/routes.mjs +1 -1
- package/dist/plugins/email-otp/routes.mjs.map +1 -1
- package/dist/plugins/generic-oauth/error-codes.mjs +3 -1
- package/dist/plugins/generic-oauth/error-codes.mjs.map +1 -1
- package/dist/plugins/generic-oauth/index.d.mts +32 -29
- package/dist/plugins/generic-oauth/index.mjs +8 -0
- package/dist/plugins/generic-oauth/index.mjs.map +1 -1
- package/dist/plugins/generic-oauth/routes.mjs +19 -2
- package/dist/plugins/generic-oauth/routes.mjs.map +1 -1
- package/dist/plugins/generic-oauth/types.d.mts +14 -0
- package/dist/plugins/haveibeenpwned/index.d.mts +3 -3
- package/dist/plugins/jwt/client.d.mts +2 -2
- package/dist/plugins/jwt/index.d.mts +9 -9
- package/dist/plugins/last-login-method/index.d.mts +4 -4
- package/dist/plugins/magic-link/index.d.mts +4 -4
- package/dist/plugins/mcp/authorize.mjs +1 -1
- package/dist/plugins/mcp/authorize.mjs.map +1 -1
- package/dist/plugins/mcp/index.d.mts +10 -10
- package/dist/plugins/multi-session/index.d.mts +9 -9
- package/dist/plugins/oauth-proxy/index.d.mts +8 -8
- package/dist/plugins/oidc-provider/authorize.mjs +1 -1
- package/dist/plugins/oidc-provider/authorize.mjs.map +1 -1
- package/dist/plugins/oidc-provider/index.d.mts +15 -15
- package/dist/plugins/one-tap/client.d.mts +5 -5
- package/dist/plugins/one-tap/index.d.mts +2 -2
- package/dist/plugins/one-time-token/index.d.mts +5 -5
- package/dist/plugins/open-api/index.d.mts +3 -3
- package/dist/plugins/organization/client.d.mts +9 -9
- package/dist/plugins/organization/error-codes.d.mts +1 -0
- package/dist/plugins/organization/error-codes.mjs +2 -1
- package/dist/plugins/organization/error-codes.mjs.map +1 -1
- package/dist/plugins/organization/organization.d.mts +4 -4
- package/dist/plugins/organization/routes/crud-access-control.d.mts +22 -22
- package/dist/plugins/organization/routes/crud-access-control.mjs +22 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs.map +1 -1
- package/dist/plugins/organization/routes/crud-invites.d.mts +70 -70
- package/dist/plugins/organization/routes/crud-invites.mjs +0 -4
- package/dist/plugins/organization/routes/crud-invites.mjs.map +1 -1
- package/dist/plugins/organization/routes/crud-members.d.mts +67 -67
- package/dist/plugins/organization/routes/crud-org.d.mts +59 -59
- package/dist/plugins/organization/routes/crud-team.d.mts +79 -79
- package/dist/plugins/phone-number/index.d.mts +33 -33
- package/dist/plugins/phone-number/routes.mjs +6 -2
- package/dist/plugins/phone-number/routes.mjs.map +1 -1
- package/dist/plugins/siwe/index.d.mts +3 -3
- package/dist/plugins/two-factor/backup-codes/index.d.mts +5 -5
- package/dist/plugins/two-factor/client.d.mts +2 -2
- package/dist/plugins/two-factor/index.d.mts +18 -18
- package/dist/plugins/two-factor/otp/index.d.mts +3 -3
- package/dist/plugins/two-factor/totp/index.d.mts +5 -5
- package/dist/plugins/username/index.d.mts +12 -12
- package/dist/plugins/username/schema.d.mts +3 -3
- package/dist/test-utils/test-instance.d.mts +1242 -1242
- package/package.json +3 -3
|
@@ -2,9 +2,9 @@ import { DeepPartial, Expand, HasRequiredKeys, LiteralNumber, LiteralUnion, Omit
|
|
|
2
2
|
import { InferActions, InferClientAPI, InferErrorCodes, IsSignal, SessionQueryParams } from "../types.mjs";
|
|
3
3
|
import { BetterAuthClientOptions, BetterAuthClientPlugin } from "@better-auth/core";
|
|
4
4
|
import { BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
5
|
-
import * as
|
|
5
|
+
import * as nanostores0 from "nanostores";
|
|
6
6
|
import { Atom } from "nanostores";
|
|
7
|
-
import * as
|
|
7
|
+
import * as _better_fetch_fetch0 from "@better-fetch/fetch";
|
|
8
8
|
import { BetterFetchError } from "@better-fetch/fetch";
|
|
9
9
|
export * from "nanostores";
|
|
10
10
|
export * from "@better-fetch/fetch";
|
|
@@ -35,21 +35,21 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
35
35
|
query?: SessionQueryParams;
|
|
36
36
|
} | undefined) => Promise<void>;
|
|
37
37
|
}>;
|
|
38
|
-
$fetch:
|
|
39
|
-
plugins: (
|
|
38
|
+
$fetch: _better_fetch_fetch0.BetterFetch<{
|
|
39
|
+
plugins: (_better_fetch_fetch0.BetterFetchPlugin<Record<string, any>> | {
|
|
40
40
|
id: string;
|
|
41
41
|
name: string;
|
|
42
42
|
hooks: {
|
|
43
|
-
onSuccess(context:
|
|
43
|
+
onSuccess(context: _better_fetch_fetch0.SuccessContext<any>): void;
|
|
44
44
|
};
|
|
45
45
|
} | {
|
|
46
46
|
id: string;
|
|
47
47
|
name: string;
|
|
48
48
|
hooks: {
|
|
49
|
-
onSuccess: ((context:
|
|
50
|
-
onError: ((context:
|
|
51
|
-
onRequest: (<T extends Record<string, any>>(context:
|
|
52
|
-
onResponse: ((context:
|
|
49
|
+
onSuccess: ((context: _better_fetch_fetch0.SuccessContext<any>) => Promise<void> | void) | undefined;
|
|
50
|
+
onError: ((context: _better_fetch_fetch0.ErrorContext) => Promise<void> | void) | undefined;
|
|
51
|
+
onRequest: (<T extends Record<string, any>>(context: _better_fetch_fetch0.RequestContext<T>) => Promise<_better_fetch_fetch0.RequestContext | void> | _better_fetch_fetch0.RequestContext | void) | undefined;
|
|
52
|
+
onResponse: ((context: _better_fetch_fetch0.ResponseContext) => Promise<Response | void | _better_fetch_fetch0.ResponseContext> | Response | _better_fetch_fetch0.ResponseContext | void) | undefined;
|
|
53
53
|
};
|
|
54
54
|
})[];
|
|
55
55
|
cache?: RequestCache | undefined;
|
|
@@ -69,12 +69,12 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
69
69
|
referrer?: string | undefined;
|
|
70
70
|
referrerPolicy?: ReferrerPolicy | undefined;
|
|
71
71
|
signal?: (AbortSignal | null) | undefined;
|
|
72
|
-
onRetry?: ((response:
|
|
72
|
+
onRetry?: ((response: _better_fetch_fetch0.ResponseContext) => Promise<void> | void) | undefined;
|
|
73
73
|
hookOptions?: {
|
|
74
74
|
cloneResponse?: boolean;
|
|
75
75
|
} | undefined;
|
|
76
76
|
timeout?: number | undefined;
|
|
77
|
-
customFetchImpl:
|
|
77
|
+
customFetchImpl: _better_fetch_fetch0.FetchEsque;
|
|
78
78
|
baseURL: string;
|
|
79
79
|
throw?: boolean | undefined;
|
|
80
80
|
auth?: ({
|
|
@@ -94,17 +94,17 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
94
94
|
params?: any;
|
|
95
95
|
duplex?: "full" | "half" | undefined;
|
|
96
96
|
jsonParser: (text: string) => Promise<any> | any;
|
|
97
|
-
retry?:
|
|
97
|
+
retry?: _better_fetch_fetch0.RetryOptions | undefined;
|
|
98
98
|
retryAttempt?: number | undefined;
|
|
99
|
-
output?: (
|
|
100
|
-
errorSchema?:
|
|
99
|
+
output?: (_better_fetch_fetch0.StandardSchemaV1 | typeof Blob | typeof File) | undefined;
|
|
100
|
+
errorSchema?: _better_fetch_fetch0.StandardSchemaV1 | undefined;
|
|
101
101
|
disableValidation?: boolean | undefined;
|
|
102
102
|
disableSignal?: boolean | undefined;
|
|
103
103
|
}, unknown, unknown, {}>;
|
|
104
104
|
$store: {
|
|
105
105
|
notify: (signal?: (Omit<string, "$sessionSignal"> | "$sessionSignal") | undefined) => void;
|
|
106
106
|
listen: (signal: Omit<string, "$sessionSignal"> | "$sessionSignal", listener: (value: boolean, oldValue?: boolean | undefined) => void) => void;
|
|
107
|
-
atoms: Record<string,
|
|
107
|
+
atoms: Record<string, nanostores0.WritableAtom<any>>;
|
|
108
108
|
};
|
|
109
109
|
$Infer: {
|
|
110
110
|
Session: NonNullable<InferClientAPI<Option> extends {
|
|
@@ -2,9 +2,9 @@ import { PrettifyDeep, UnionToIntersection } from "../types/helper.mjs";
|
|
|
2
2
|
import { InferActions, InferClientAPI, InferErrorCodes, IsSignal, SessionQueryParams } from "./types.mjs";
|
|
3
3
|
import { BetterAuthClientOptions, BetterAuthClientPlugin } from "@better-auth/core";
|
|
4
4
|
import { BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
5
|
-
import * as
|
|
5
|
+
import * as nanostores5 from "nanostores";
|
|
6
6
|
import { Atom } from "nanostores";
|
|
7
|
-
import * as
|
|
7
|
+
import * as _better_fetch_fetch95 from "@better-fetch/fetch";
|
|
8
8
|
import { BetterFetchError } from "@better-fetch/fetch";
|
|
9
9
|
|
|
10
10
|
//#region src/client/vanilla.d.ts
|
|
@@ -33,21 +33,21 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
33
33
|
query?: SessionQueryParams;
|
|
34
34
|
} | undefined) => Promise<void>;
|
|
35
35
|
}>;
|
|
36
|
-
$fetch:
|
|
37
|
-
plugins: (
|
|
36
|
+
$fetch: _better_fetch_fetch95.BetterFetch<{
|
|
37
|
+
plugins: (_better_fetch_fetch95.BetterFetchPlugin<Record<string, any>> | {
|
|
38
38
|
id: string;
|
|
39
39
|
name: string;
|
|
40
40
|
hooks: {
|
|
41
|
-
onSuccess(context:
|
|
41
|
+
onSuccess(context: _better_fetch_fetch95.SuccessContext<any>): void;
|
|
42
42
|
};
|
|
43
43
|
} | {
|
|
44
44
|
id: string;
|
|
45
45
|
name: string;
|
|
46
46
|
hooks: {
|
|
47
|
-
onSuccess: ((context:
|
|
48
|
-
onError: ((context:
|
|
49
|
-
onRequest: (<T extends Record<string, any>>(context:
|
|
50
|
-
onResponse: ((context:
|
|
47
|
+
onSuccess: ((context: _better_fetch_fetch95.SuccessContext<any>) => Promise<void> | void) | undefined;
|
|
48
|
+
onError: ((context: _better_fetch_fetch95.ErrorContext) => Promise<void> | void) | undefined;
|
|
49
|
+
onRequest: (<T extends Record<string, any>>(context: _better_fetch_fetch95.RequestContext<T>) => Promise<_better_fetch_fetch95.RequestContext | void> | _better_fetch_fetch95.RequestContext | void) | undefined;
|
|
50
|
+
onResponse: ((context: _better_fetch_fetch95.ResponseContext) => Promise<Response | void | _better_fetch_fetch95.ResponseContext> | Response | _better_fetch_fetch95.ResponseContext | void) | undefined;
|
|
51
51
|
};
|
|
52
52
|
})[];
|
|
53
53
|
cache?: RequestCache | undefined;
|
|
@@ -67,12 +67,12 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
67
67
|
referrer?: string | undefined;
|
|
68
68
|
referrerPolicy?: ReferrerPolicy | undefined;
|
|
69
69
|
signal?: (AbortSignal | null) | undefined;
|
|
70
|
-
onRetry?: ((response:
|
|
70
|
+
onRetry?: ((response: _better_fetch_fetch95.ResponseContext) => Promise<void> | void) | undefined;
|
|
71
71
|
hookOptions?: {
|
|
72
72
|
cloneResponse?: boolean;
|
|
73
73
|
} | undefined;
|
|
74
74
|
timeout?: number | undefined;
|
|
75
|
-
customFetchImpl:
|
|
75
|
+
customFetchImpl: _better_fetch_fetch95.FetchEsque;
|
|
76
76
|
baseURL: string;
|
|
77
77
|
throw?: boolean | undefined;
|
|
78
78
|
auth?: ({
|
|
@@ -92,17 +92,17 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
92
92
|
params?: any;
|
|
93
93
|
duplex?: "full" | "half" | undefined;
|
|
94
94
|
jsonParser: (text: string) => Promise<any> | any;
|
|
95
|
-
retry?:
|
|
95
|
+
retry?: _better_fetch_fetch95.RetryOptions | undefined;
|
|
96
96
|
retryAttempt?: number | undefined;
|
|
97
|
-
output?: (
|
|
98
|
-
errorSchema?:
|
|
97
|
+
output?: (_better_fetch_fetch95.StandardSchemaV1 | typeof Blob | typeof File) | undefined;
|
|
98
|
+
errorSchema?: _better_fetch_fetch95.StandardSchemaV1 | undefined;
|
|
99
99
|
disableValidation?: boolean | undefined;
|
|
100
100
|
disableSignal?: boolean | undefined;
|
|
101
101
|
}, unknown, unknown, {}>;
|
|
102
102
|
$store: {
|
|
103
103
|
notify: (signal?: (Omit<string, "$sessionSignal"> | "$sessionSignal") | undefined) => void;
|
|
104
104
|
listen: (signal: Omit<string, "$sessionSignal"> | "$sessionSignal", listener: (value: boolean, oldValue?: boolean | undefined) => void) => void;
|
|
105
|
-
atoms: Record<string,
|
|
105
|
+
atoms: Record<string, nanostores5.WritableAtom<any>>;
|
|
106
106
|
};
|
|
107
107
|
$Infer: {
|
|
108
108
|
Session: NonNullable<InferClientAPI<Option> extends {
|
|
@@ -2,8 +2,8 @@ import { DeepPartial, Expand, HasRequiredKeys, LiteralNumber, LiteralUnion, Omit
|
|
|
2
2
|
import { InferActions, InferClientAPI, InferErrorCodes, IsSignal, SessionQueryParams } from "../types.mjs";
|
|
3
3
|
import { BetterAuthClientOptions, BetterAuthClientPlugin } from "@better-auth/core";
|
|
4
4
|
import { BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
5
|
+
import * as nanostores1 from "nanostores";
|
|
6
|
+
import * as _better_fetch_fetch31 from "@better-fetch/fetch";
|
|
7
7
|
import { BetterFetchError } from "@better-fetch/fetch";
|
|
8
8
|
import { DeepReadonly, Ref } from "vue";
|
|
9
9
|
export * from "nanostores";
|
|
@@ -73,21 +73,21 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
73
73
|
error: null;
|
|
74
74
|
} ? S : Res extends Record<string, any> ? Res : never : never>;
|
|
75
75
|
};
|
|
76
|
-
$fetch:
|
|
77
|
-
plugins: (
|
|
76
|
+
$fetch: _better_fetch_fetch31.BetterFetch<{
|
|
77
|
+
plugins: (_better_fetch_fetch31.BetterFetchPlugin<Record<string, any>> | {
|
|
78
78
|
id: string;
|
|
79
79
|
name: string;
|
|
80
80
|
hooks: {
|
|
81
|
-
onSuccess(context:
|
|
81
|
+
onSuccess(context: _better_fetch_fetch31.SuccessContext<any>): void;
|
|
82
82
|
};
|
|
83
83
|
} | {
|
|
84
84
|
id: string;
|
|
85
85
|
name: string;
|
|
86
86
|
hooks: {
|
|
87
|
-
onSuccess: ((context:
|
|
88
|
-
onError: ((context:
|
|
89
|
-
onRequest: (<T extends Record<string, any>>(context:
|
|
90
|
-
onResponse: ((context:
|
|
87
|
+
onSuccess: ((context: _better_fetch_fetch31.SuccessContext<any>) => Promise<void> | void) | undefined;
|
|
88
|
+
onError: ((context: _better_fetch_fetch31.ErrorContext) => Promise<void> | void) | undefined;
|
|
89
|
+
onRequest: (<T extends Record<string, any>>(context: _better_fetch_fetch31.RequestContext<T>) => Promise<_better_fetch_fetch31.RequestContext | void> | _better_fetch_fetch31.RequestContext | void) | undefined;
|
|
90
|
+
onResponse: ((context: _better_fetch_fetch31.ResponseContext) => Promise<Response | void | _better_fetch_fetch31.ResponseContext> | Response | _better_fetch_fetch31.ResponseContext | void) | undefined;
|
|
91
91
|
};
|
|
92
92
|
})[];
|
|
93
93
|
cache?: RequestCache | undefined;
|
|
@@ -107,12 +107,12 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
107
107
|
referrer?: string | undefined;
|
|
108
108
|
referrerPolicy?: ReferrerPolicy | undefined;
|
|
109
109
|
signal?: (AbortSignal | null) | undefined;
|
|
110
|
-
onRetry?: ((response:
|
|
110
|
+
onRetry?: ((response: _better_fetch_fetch31.ResponseContext) => Promise<void> | void) | undefined;
|
|
111
111
|
hookOptions?: {
|
|
112
112
|
cloneResponse?: boolean;
|
|
113
113
|
} | undefined;
|
|
114
114
|
timeout?: number | undefined;
|
|
115
|
-
customFetchImpl:
|
|
115
|
+
customFetchImpl: _better_fetch_fetch31.FetchEsque;
|
|
116
116
|
baseURL: string;
|
|
117
117
|
throw?: boolean | undefined;
|
|
118
118
|
auth?: ({
|
|
@@ -132,17 +132,17 @@ declare function createAuthClient<Option extends BetterAuthClientOptions>(option
|
|
|
132
132
|
params?: any;
|
|
133
133
|
duplex?: "full" | "half" | undefined;
|
|
134
134
|
jsonParser: (text: string) => Promise<any> | any;
|
|
135
|
-
retry?:
|
|
135
|
+
retry?: _better_fetch_fetch31.RetryOptions | undefined;
|
|
136
136
|
retryAttempt?: number | undefined;
|
|
137
|
-
output?: (
|
|
138
|
-
errorSchema?:
|
|
137
|
+
output?: (_better_fetch_fetch31.StandardSchemaV1 | typeof Blob | typeof File) | undefined;
|
|
138
|
+
errorSchema?: _better_fetch_fetch31.StandardSchemaV1 | undefined;
|
|
139
139
|
disableValidation?: boolean | undefined;
|
|
140
140
|
disableSignal?: boolean | undefined;
|
|
141
141
|
}, unknown, unknown, {}>;
|
|
142
142
|
$store: {
|
|
143
143
|
notify: (signal?: (Omit<string, "$sessionSignal"> | "$sessionSignal") | undefined) => void;
|
|
144
144
|
listen: (signal: Omit<string, "$sessionSignal"> | "$sessionSignal", listener: (value: boolean, oldValue?: boolean | undefined) => void) => void;
|
|
145
|
-
atoms: Record<string,
|
|
145
|
+
atoms: Record<string, nanostores1.WritableAtom<any>>;
|
|
146
146
|
};
|
|
147
147
|
$ERROR_CODES: PrettifyDeep<InferErrorCodes<Option> & typeof BASE_ERROR_CODES>;
|
|
148
148
|
};
|
|
@@ -58,7 +58,7 @@ async function createAuthContext(adapter, options, getDatabaseType) {
|
|
|
58
58
|
const internalPlugins = getInternalPlugins(options);
|
|
59
59
|
const logger$1 = createLogger(options.logger);
|
|
60
60
|
const baseURL = getBaseURL(options.baseURL, options.basePath);
|
|
61
|
-
if (!baseURL) logger$1.warn(`[better-auth] Base URL could not be determined. Please set a valid base URL using the baseURL config option or the
|
|
61
|
+
if (!baseURL) logger$1.warn(`[better-auth] Base URL could not be determined. Please set a valid base URL using the baseURL config option or the BETTER_AUTH_URL environment variable. Without this, callbacks and redirects may not work correctly.`);
|
|
62
62
|
if (adapter.id === "memory" && options.advanced?.database?.generateId === false) logger$1.error(`[better-auth] Misconfiguration detected.
|
|
63
63
|
You are using the memory DB with generateId: false.
|
|
64
64
|
This will cause no id to be generated for any model.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-context.mjs","names":["logger","providers: OAuthProvider[]","generateIdFunc: AuthContext[\"generateId\"]","generateId","context: AuthContext"],"sources":["../../src/context/create-context.ts"],"sourcesContent":["import type {\n\tAuthContext,\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n} from \"@better-auth/core\";\nimport { getBetterAuthVersion } from \"@better-auth/core/context\";\nimport { getAuthTables } from \"@better-auth/core/db\";\nimport type { DBAdapter } from \"@better-auth/core/db/adapter\";\nimport { createLogger, env, isProduction, isTest } from \"@better-auth/core/env\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport type { OAuthProvider } from \"@better-auth/core/oauth2\";\nimport type { SocialProviders } from \"@better-auth/core/social-providers\";\nimport { socialProviders } from \"@better-auth/core/social-providers\";\nimport { deprecate } from \"@better-auth/core/utils\";\nimport { createTelemetry } from \"@better-auth/telemetry\";\nimport defu from \"defu\";\nimport type { Entries } from \"type-fest\";\nimport { checkEndpointConflicts } from \"../api\";\nimport { matchesOriginPattern } from \"../auth/trusted-origins\";\nimport { createCookieGetter, getCookies } from \"../cookies\";\nimport { hashPassword, verifyPassword } from \"../crypto/password\";\nimport { createInternalAdapter } from \"../db/internal-adapter\";\nimport { generateId } from \"../utils\";\nimport { DEFAULT_SECRET } from \"../utils/constants\";\nimport { isPromise } from \"../utils/is-promise\";\nimport { checkPassword } from \"../utils/password\";\nimport { getBaseURL } from \"../utils/url\";\nimport {\n\tgetInternalPlugins,\n\tgetTrustedOrigins,\n\trunPluginInit,\n} from \"./helpers\";\n\n/**\n * Estimates the entropy of a string in bits.\n * This is a simple approximation that helps detect low-entropy secrets.\n */\nfunction estimateEntropy(str: string): number {\n\tconst unique = new Set(str).size;\n\tif (unique === 0) return 0;\n\treturn Math.log2(Math.pow(unique, str.length));\n}\n\n/**\n * Validates that the secret meets minimum security requirements.\n * Throws BetterAuthError if the secret is invalid.\n * Skips validation for DEFAULT_SECRET in test environments only.\n * Only throws for DEFAULT_SECRET in production environment.\n */\nfunction validateSecret(\n\tsecret: string,\n\tlogger: ReturnType<typeof createLogger>,\n): void {\n\tconst isDefaultSecret = secret === DEFAULT_SECRET;\n\n\tif (isTest()) {\n\t\treturn;\n\t}\n\n\tif (isDefaultSecret && isProduction) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"You are using the default secret. Please set `BETTER_AUTH_SECRET` in your environment variables or pass `secret` in your auth config.\",\n\t\t);\n\t}\n\n\tif (!secret) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"BETTER_AUTH_SECRET is missing. Set it in your environment or pass `secret` to betterAuth({ secret }).\",\n\t\t);\n\t}\n\n\tif (secret.length < 32) {\n\t\tlogger.warn(\n\t\t\t`[better-auth] Warning: your BETTER_AUTH_SECRET should be at least 32 characters long for adequate security. Generate one with \\`npx @better-auth/cli secret\\` or \\`openssl rand -base64 32\\`.`,\n\t\t);\n\t}\n\n\t// Optional high-entropy check: warn if entropy appears low\n\tconst entropy = estimateEntropy(secret);\n\tif (entropy < 120) {\n\t\tlogger.warn(\n\t\t\t\"[better-auth] Warning: your BETTER_AUTH_SECRET appears low-entropy. Use a randomly generated secret for production.\",\n\t\t);\n\t}\n}\n\nexport async function createAuthContext(\n\tadapter: DBAdapter<BetterAuthOptions>,\n\toptions: BetterAuthOptions,\n\tgetDatabaseType: (database: BetterAuthOptions[\"database\"]) => string,\n): Promise<AuthContext> {\n\t//set default options for stateless mode\n\tif (!options.database) {\n\t\toptions = defu(options, {\n\t\t\tsession: {\n\t\t\t\tcookieCache: {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tstrategy: \"jwe\" as const,\n\t\t\t\t\trefreshCache: true,\n\t\t\t\t},\n\t\t\t},\n\t\t\taccount: {\n\t\t\t\tstoreStateStrategy: \"cookie\" as const,\n\t\t\t\tstoreAccountCookie: true,\n\t\t\t},\n\t\t});\n\t}\n\tconst plugins = options.plugins || [];\n\tconst internalPlugins = getInternalPlugins(options);\n\tconst logger = createLogger(options.logger);\n\tconst baseURL = getBaseURL(options.baseURL, options.basePath);\n\n\tif (!baseURL) {\n\t\tlogger.warn(\n\t\t\t`[better-auth] Base URL could not be determined. Please set a valid base URL using the baseURL config option or the BETTER_AUTH_BASE_URL environment variable. Without this, callbacks and redirects may not work correctly.`,\n\t\t);\n\t}\n\n\tif (\n\t\tadapter.id === \"memory\" &&\n\t\toptions.advanced?.database?.generateId === false\n\t) {\n\t\tlogger.error(\n\t\t\t`[better-auth] Misconfiguration detected.\nYou are using the memory DB with generateId: false.\nThis will cause no id to be generated for any model.\nMost of the features of Better Auth will not work correctly.`,\n\t\t);\n\t}\n\n\tconst secret =\n\t\toptions.secret ||\n\t\tenv.BETTER_AUTH_SECRET ||\n\t\tenv.AUTH_SECRET ||\n\t\tDEFAULT_SECRET;\n\n\tvalidateSecret(secret, logger);\n\n\toptions = {\n\t\t...options,\n\t\tsecret,\n\t\tbaseURL: baseURL ? new URL(baseURL).origin : \"\",\n\t\tbasePath: options.basePath || \"/api/auth\",\n\t\tplugins: plugins.concat(internalPlugins),\n\t};\n\n\tcheckEndpointConflicts(options, logger);\n\tconst cookies = getCookies(options);\n\tconst tables = getAuthTables(options);\n\tconst providers: OAuthProvider[] = (\n\t\tObject.entries(\n\t\t\toptions.socialProviders || {},\n\t\t) as unknown as Entries<SocialProviders>\n\t)\n\t\t.map(([key, config]) => {\n\t\t\tif (config == null) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (config.enabled === false) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!config.clientId) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Social provider ${key} is missing clientId or clientSecret`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst provider = socialProviders[key](config as never);\n\t\t\t(provider as OAuthProvider).disableImplicitSignUp =\n\t\t\t\tconfig.disableImplicitSignUp;\n\t\t\treturn provider;\n\t\t})\n\t\t.filter((x) => x !== null);\n\n\tconst generateIdFunc: AuthContext[\"generateId\"] = ({ model, size }) => {\n\t\tif (typeof (options.advanced as any)?.generateId === \"function\") {\n\t\t\treturn (options.advanced as any).generateId({ model, size });\n\t\t}\n\t\tconst dbGenerateId = options?.advanced?.database?.generateId;\n\t\tif (typeof dbGenerateId === \"function\") {\n\t\t\treturn dbGenerateId({ model, size });\n\t\t}\n\t\tif (dbGenerateId === \"uuid\") {\n\t\t\treturn crypto.randomUUID();\n\t\t}\n\t\tif (dbGenerateId === \"serial\" || dbGenerateId === false) {\n\t\t\treturn false;\n\t\t}\n\t\treturn generateId(size);\n\t};\n\n\tconst { publish } = await createTelemetry(options, {\n\t\tadapter: adapter.id,\n\t\tdatabase:\n\t\t\ttypeof options.database === \"function\"\n\t\t\t\t? \"adapter\"\n\t\t\t\t: getDatabaseType(options.database),\n\t});\n\n\tconst trustedOrigins = await getTrustedOrigins(options);\n\n\tconst ctx: AuthContext = {\n\t\tappName: options.appName || \"Better Auth\",\n\t\tbaseURL: baseURL || \"\",\n\t\tversion: getBetterAuthVersion(),\n\t\tsocialProviders: providers,\n\t\toptions,\n\t\toauthConfig: {\n\t\t\tstoreStateStrategy:\n\t\t\t\toptions.account?.storeStateStrategy ||\n\t\t\t\t(options.database ? \"database\" : \"cookie\"),\n\t\t\tskipStateCookieCheck: !!options.account?.skipStateCookieCheck,\n\t\t},\n\t\ttables,\n\t\ttrustedOrigins,\n\t\tisTrustedOrigin(\n\t\t\turl: string,\n\t\t\tsettings?: {\n\t\t\t\tallowRelativePaths: boolean;\n\t\t\t},\n\t\t) {\n\t\t\treturn this.trustedOrigins.some((origin) =>\n\t\t\t\tmatchesOriginPattern(url, origin, settings),\n\t\t\t);\n\t\t},\n\t\tsessionConfig: {\n\t\t\tupdateAge:\n\t\t\t\toptions.session?.updateAge !== undefined\n\t\t\t\t\t? options.session.updateAge\n\t\t\t\t\t: 24 * 60 * 60,\n\t\t\texpiresIn: options.session?.expiresIn || 60 * 60 * 24 * 7,\n\t\t\tfreshAge:\n\t\t\t\toptions.session?.freshAge === undefined\n\t\t\t\t\t? 60 * 60 * 24\n\t\t\t\t\t: options.session.freshAge,\n\t\t\tcookieRefreshCache: (() => {\n\t\t\t\tconst refreshCache = options.session?.cookieCache?.refreshCache;\n\t\t\t\tconst maxAge = options.session?.cookieCache?.maxAge || 60 * 5;\n\n\t\t\t\t// `refreshCache` is intended for fully stateless / DB-less setups.\n\t\t\t\t// If a server-side store is configured, prefer fetching/refreshing from that source\n\t\t\t\t// and disable stateless refresh behavior to avoid confusing/unsafe configurations.\n\t\t\t\tconst isStateful = !!options.database || !!options.secondaryStorage;\n\t\t\t\tif (isStateful && refreshCache) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"[better-auth] `session.cookieCache.refreshCache` is enabled while `database` or `secondaryStorage` is configured. `refreshCache` is meant for stateless (DB-less) setups. Disabling `refreshCache` — remove it from your config to silence this warning.\",\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (refreshCache === false || refreshCache === undefined) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (refreshCache === true) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\tupdateAge: Math.floor(maxAge * 0.2),\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tupdateAge:\n\t\t\t\t\t\trefreshCache.updateAge !== undefined\n\t\t\t\t\t\t\t? refreshCache.updateAge\n\t\t\t\t\t\t\t: Math.floor(maxAge * 0.2),\n\t\t\t\t};\n\t\t\t})(),\n\t\t},\n\t\tsecret,\n\t\trateLimit: {\n\t\t\t...options.rateLimit,\n\t\t\tenabled: options.rateLimit?.enabled ?? isProduction,\n\t\t\twindow: options.rateLimit?.window || 10,\n\t\t\tmax: options.rateLimit?.max || 100,\n\t\t\tstorage:\n\t\t\t\toptions.rateLimit?.storage ||\n\t\t\t\t(options.secondaryStorage ? \"secondary-storage\" : \"memory\"),\n\t\t},\n\t\tauthCookies: cookies,\n\t\tlogger,\n\t\tgenerateId: generateIdFunc,\n\t\tsession: null,\n\t\tsecondaryStorage: options.secondaryStorage,\n\t\tpassword: {\n\t\t\thash: options.emailAndPassword?.password?.hash || hashPassword,\n\t\t\tverify: options.emailAndPassword?.password?.verify || verifyPassword,\n\t\t\tconfig: {\n\t\t\t\tminPasswordLength: options.emailAndPassword?.minPasswordLength || 8,\n\t\t\t\tmaxPasswordLength: options.emailAndPassword?.maxPasswordLength || 128,\n\t\t\t},\n\t\t\tcheckPassword,\n\t\t},\n\t\tsetNewSession(session) {\n\t\t\tthis.newSession = session;\n\t\t},\n\t\tnewSession: null,\n\t\tadapter: adapter,\n\t\tinternalAdapter: createInternalAdapter(adapter, {\n\t\t\toptions,\n\t\t\tlogger,\n\t\t\thooks: options.databaseHooks ? [options.databaseHooks] : [],\n\t\t\tgenerateId: generateIdFunc,\n\t\t}),\n\t\tcreateAuthCookie: createCookieGetter(options),\n\t\tasync runMigrations() {\n\t\t\tthrow new BetterAuthError(\n\t\t\t\t\"runMigrations will be set by the specific init implementation\",\n\t\t\t);\n\t\t},\n\t\tpublishTelemetry: publish,\n\t\tskipCSRFCheck: !!options.advanced?.disableCSRFCheck,\n\t\tskipOriginCheck:\n\t\t\toptions.advanced?.disableOriginCheck !== undefined\n\t\t\t\t? options.advanced.disableOriginCheck\n\t\t\t\t: isTest()\n\t\t\t\t\t? true\n\t\t\t\t\t: false,\n\t\trunInBackground:\n\t\t\toptions.advanced?.backgroundTasks?.handler ??\n\t\t\t((p) => {\n\t\t\t\tp.catch(() => {});\n\t\t\t}),\n\t\tasync runInBackgroundOrAwait(\n\t\t\tpromise: Promise<unknown> | Promise<void> | void | unknown,\n\t\t) {\n\t\t\ttry {\n\t\t\t\tif (options.advanced?.backgroundTasks?.handler) {\n\t\t\t\t\tif (promise instanceof Promise) {\n\t\t\t\t\t\toptions.advanced.backgroundTasks.handler(\n\t\t\t\t\t\t\tpromise.catch((e) => {\n\t\t\t\t\t\t\t\tlogger.error(\"Failed to run background task:\", e);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tawait promise;\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(\"Failed to run background task:\", e);\n\t\t\t}\n\t\t},\n\t\tgetPlugin: <Plugin extends BetterAuthPlugin>(id: Plugin[\"id\"]) =>\n\t\t\t(options.plugins!.find((p): p is Plugin => p.id === id) as\n\t\t\t\t| Plugin\n\t\t\t\t| undefined) ?? null,\n\t};\n\n\tconst initOrPromise = runPluginInit(ctx);\n\tlet context: AuthContext;\n\tif (isPromise(initOrPromise)) {\n\t\t({ context } = await initOrPromise);\n\t} else {\n\t\t({ context } = initOrPromise);\n\t}\n\n\tif (\n\t\ttypeof context.options.emailVerification?.onEmailVerification === \"function\"\n\t) {\n\t\tcontext.options.emailVerification.onEmailVerification = deprecate(\n\t\t\tcontext.options.emailVerification.onEmailVerification,\n\t\t\t\"Use `afterEmailVerification` instead. This will be removed in 1.5\",\n\t\t\tcontext.logger,\n\t\t);\n\t}\n\n\treturn context;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"create-context.mjs","names":["logger","providers: OAuthProvider[]","generateIdFunc: AuthContext[\"generateId\"]","generateId","context: AuthContext"],"sources":["../../src/context/create-context.ts"],"sourcesContent":["import type {\n\tAuthContext,\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n} from \"@better-auth/core\";\nimport { getBetterAuthVersion } from \"@better-auth/core/context\";\nimport { getAuthTables } from \"@better-auth/core/db\";\nimport type { DBAdapter } from \"@better-auth/core/db/adapter\";\nimport { createLogger, env, isProduction, isTest } from \"@better-auth/core/env\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport type { OAuthProvider } from \"@better-auth/core/oauth2\";\nimport type { SocialProviders } from \"@better-auth/core/social-providers\";\nimport { socialProviders } from \"@better-auth/core/social-providers\";\nimport { deprecate } from \"@better-auth/core/utils\";\nimport { createTelemetry } from \"@better-auth/telemetry\";\nimport defu from \"defu\";\nimport type { Entries } from \"type-fest\";\nimport { checkEndpointConflicts } from \"../api\";\nimport { matchesOriginPattern } from \"../auth/trusted-origins\";\nimport { createCookieGetter, getCookies } from \"../cookies\";\nimport { hashPassword, verifyPassword } from \"../crypto/password\";\nimport { createInternalAdapter } from \"../db/internal-adapter\";\nimport { generateId } from \"../utils\";\nimport { DEFAULT_SECRET } from \"../utils/constants\";\nimport { isPromise } from \"../utils/is-promise\";\nimport { checkPassword } from \"../utils/password\";\nimport { getBaseURL } from \"../utils/url\";\nimport {\n\tgetInternalPlugins,\n\tgetTrustedOrigins,\n\trunPluginInit,\n} from \"./helpers\";\n\n/**\n * Estimates the entropy of a string in bits.\n * This is a simple approximation that helps detect low-entropy secrets.\n */\nfunction estimateEntropy(str: string): number {\n\tconst unique = new Set(str).size;\n\tif (unique === 0) return 0;\n\treturn Math.log2(Math.pow(unique, str.length));\n}\n\n/**\n * Validates that the secret meets minimum security requirements.\n * Throws BetterAuthError if the secret is invalid.\n * Skips validation for DEFAULT_SECRET in test environments only.\n * Only throws for DEFAULT_SECRET in production environment.\n */\nfunction validateSecret(\n\tsecret: string,\n\tlogger: ReturnType<typeof createLogger>,\n): void {\n\tconst isDefaultSecret = secret === DEFAULT_SECRET;\n\n\tif (isTest()) {\n\t\treturn;\n\t}\n\n\tif (isDefaultSecret && isProduction) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"You are using the default secret. Please set `BETTER_AUTH_SECRET` in your environment variables or pass `secret` in your auth config.\",\n\t\t);\n\t}\n\n\tif (!secret) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"BETTER_AUTH_SECRET is missing. Set it in your environment or pass `secret` to betterAuth({ secret }).\",\n\t\t);\n\t}\n\n\tif (secret.length < 32) {\n\t\tlogger.warn(\n\t\t\t`[better-auth] Warning: your BETTER_AUTH_SECRET should be at least 32 characters long for adequate security. Generate one with \\`npx @better-auth/cli secret\\` or \\`openssl rand -base64 32\\`.`,\n\t\t);\n\t}\n\n\t// Optional high-entropy check: warn if entropy appears low\n\tconst entropy = estimateEntropy(secret);\n\tif (entropy < 120) {\n\t\tlogger.warn(\n\t\t\t\"[better-auth] Warning: your BETTER_AUTH_SECRET appears low-entropy. Use a randomly generated secret for production.\",\n\t\t);\n\t}\n}\n\nexport async function createAuthContext(\n\tadapter: DBAdapter<BetterAuthOptions>,\n\toptions: BetterAuthOptions,\n\tgetDatabaseType: (database: BetterAuthOptions[\"database\"]) => string,\n): Promise<AuthContext> {\n\t//set default options for stateless mode\n\tif (!options.database) {\n\t\toptions = defu(options, {\n\t\t\tsession: {\n\t\t\t\tcookieCache: {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tstrategy: \"jwe\" as const,\n\t\t\t\t\trefreshCache: true,\n\t\t\t\t},\n\t\t\t},\n\t\t\taccount: {\n\t\t\t\tstoreStateStrategy: \"cookie\" as const,\n\t\t\t\tstoreAccountCookie: true,\n\t\t\t},\n\t\t});\n\t}\n\tconst plugins = options.plugins || [];\n\tconst internalPlugins = getInternalPlugins(options);\n\tconst logger = createLogger(options.logger);\n\tconst baseURL = getBaseURL(options.baseURL, options.basePath);\n\n\tif (!baseURL) {\n\t\tlogger.warn(\n\t\t\t`[better-auth] Base URL could not be determined. Please set a valid base URL using the baseURL config option or the BETTER_AUTH_URL environment variable. Without this, callbacks and redirects may not work correctly.`,\n\t\t);\n\t}\n\n\tif (\n\t\tadapter.id === \"memory\" &&\n\t\toptions.advanced?.database?.generateId === false\n\t) {\n\t\tlogger.error(\n\t\t\t`[better-auth] Misconfiguration detected.\nYou are using the memory DB with generateId: false.\nThis will cause no id to be generated for any model.\nMost of the features of Better Auth will not work correctly.`,\n\t\t);\n\t}\n\n\tconst secret =\n\t\toptions.secret ||\n\t\tenv.BETTER_AUTH_SECRET ||\n\t\tenv.AUTH_SECRET ||\n\t\tDEFAULT_SECRET;\n\n\tvalidateSecret(secret, logger);\n\n\toptions = {\n\t\t...options,\n\t\tsecret,\n\t\tbaseURL: baseURL ? new URL(baseURL).origin : \"\",\n\t\tbasePath: options.basePath || \"/api/auth\",\n\t\tplugins: plugins.concat(internalPlugins),\n\t};\n\n\tcheckEndpointConflicts(options, logger);\n\tconst cookies = getCookies(options);\n\tconst tables = getAuthTables(options);\n\tconst providers: OAuthProvider[] = (\n\t\tObject.entries(\n\t\t\toptions.socialProviders || {},\n\t\t) as unknown as Entries<SocialProviders>\n\t)\n\t\t.map(([key, config]) => {\n\t\t\tif (config == null) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (config.enabled === false) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (!config.clientId) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Social provider ${key} is missing clientId or clientSecret`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst provider = socialProviders[key](config as never);\n\t\t\t(provider as OAuthProvider).disableImplicitSignUp =\n\t\t\t\tconfig.disableImplicitSignUp;\n\t\t\treturn provider;\n\t\t})\n\t\t.filter((x) => x !== null);\n\n\tconst generateIdFunc: AuthContext[\"generateId\"] = ({ model, size }) => {\n\t\tif (typeof (options.advanced as any)?.generateId === \"function\") {\n\t\t\treturn (options.advanced as any).generateId({ model, size });\n\t\t}\n\t\tconst dbGenerateId = options?.advanced?.database?.generateId;\n\t\tif (typeof dbGenerateId === \"function\") {\n\t\t\treturn dbGenerateId({ model, size });\n\t\t}\n\t\tif (dbGenerateId === \"uuid\") {\n\t\t\treturn crypto.randomUUID();\n\t\t}\n\t\tif (dbGenerateId === \"serial\" || dbGenerateId === false) {\n\t\t\treturn false;\n\t\t}\n\t\treturn generateId(size);\n\t};\n\n\tconst { publish } = await createTelemetry(options, {\n\t\tadapter: adapter.id,\n\t\tdatabase:\n\t\t\ttypeof options.database === \"function\"\n\t\t\t\t? \"adapter\"\n\t\t\t\t: getDatabaseType(options.database),\n\t});\n\n\tconst trustedOrigins = await getTrustedOrigins(options);\n\n\tconst ctx: AuthContext = {\n\t\tappName: options.appName || \"Better Auth\",\n\t\tbaseURL: baseURL || \"\",\n\t\tversion: getBetterAuthVersion(),\n\t\tsocialProviders: providers,\n\t\toptions,\n\t\toauthConfig: {\n\t\t\tstoreStateStrategy:\n\t\t\t\toptions.account?.storeStateStrategy ||\n\t\t\t\t(options.database ? \"database\" : \"cookie\"),\n\t\t\tskipStateCookieCheck: !!options.account?.skipStateCookieCheck,\n\t\t},\n\t\ttables,\n\t\ttrustedOrigins,\n\t\tisTrustedOrigin(\n\t\t\turl: string,\n\t\t\tsettings?: {\n\t\t\t\tallowRelativePaths: boolean;\n\t\t\t},\n\t\t) {\n\t\t\treturn this.trustedOrigins.some((origin) =>\n\t\t\t\tmatchesOriginPattern(url, origin, settings),\n\t\t\t);\n\t\t},\n\t\tsessionConfig: {\n\t\t\tupdateAge:\n\t\t\t\toptions.session?.updateAge !== undefined\n\t\t\t\t\t? options.session.updateAge\n\t\t\t\t\t: 24 * 60 * 60,\n\t\t\texpiresIn: options.session?.expiresIn || 60 * 60 * 24 * 7,\n\t\t\tfreshAge:\n\t\t\t\toptions.session?.freshAge === undefined\n\t\t\t\t\t? 60 * 60 * 24\n\t\t\t\t\t: options.session.freshAge,\n\t\t\tcookieRefreshCache: (() => {\n\t\t\t\tconst refreshCache = options.session?.cookieCache?.refreshCache;\n\t\t\t\tconst maxAge = options.session?.cookieCache?.maxAge || 60 * 5;\n\n\t\t\t\t// `refreshCache` is intended for fully stateless / DB-less setups.\n\t\t\t\t// If a server-side store is configured, prefer fetching/refreshing from that source\n\t\t\t\t// and disable stateless refresh behavior to avoid confusing/unsafe configurations.\n\t\t\t\tconst isStateful = !!options.database || !!options.secondaryStorage;\n\t\t\t\tif (isStateful && refreshCache) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\"[better-auth] `session.cookieCache.refreshCache` is enabled while `database` or `secondaryStorage` is configured. `refreshCache` is meant for stateless (DB-less) setups. Disabling `refreshCache` — remove it from your config to silence this warning.\",\n\t\t\t\t\t);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (refreshCache === false || refreshCache === undefined) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (refreshCache === true) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\tupdateAge: Math.floor(maxAge * 0.2),\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tenabled: true,\n\t\t\t\t\tupdateAge:\n\t\t\t\t\t\trefreshCache.updateAge !== undefined\n\t\t\t\t\t\t\t? refreshCache.updateAge\n\t\t\t\t\t\t\t: Math.floor(maxAge * 0.2),\n\t\t\t\t};\n\t\t\t})(),\n\t\t},\n\t\tsecret,\n\t\trateLimit: {\n\t\t\t...options.rateLimit,\n\t\t\tenabled: options.rateLimit?.enabled ?? isProduction,\n\t\t\twindow: options.rateLimit?.window || 10,\n\t\t\tmax: options.rateLimit?.max || 100,\n\t\t\tstorage:\n\t\t\t\toptions.rateLimit?.storage ||\n\t\t\t\t(options.secondaryStorage ? \"secondary-storage\" : \"memory\"),\n\t\t},\n\t\tauthCookies: cookies,\n\t\tlogger,\n\t\tgenerateId: generateIdFunc,\n\t\tsession: null,\n\t\tsecondaryStorage: options.secondaryStorage,\n\t\tpassword: {\n\t\t\thash: options.emailAndPassword?.password?.hash || hashPassword,\n\t\t\tverify: options.emailAndPassword?.password?.verify || verifyPassword,\n\t\t\tconfig: {\n\t\t\t\tminPasswordLength: options.emailAndPassword?.minPasswordLength || 8,\n\t\t\t\tmaxPasswordLength: options.emailAndPassword?.maxPasswordLength || 128,\n\t\t\t},\n\t\t\tcheckPassword,\n\t\t},\n\t\tsetNewSession(session) {\n\t\t\tthis.newSession = session;\n\t\t},\n\t\tnewSession: null,\n\t\tadapter: adapter,\n\t\tinternalAdapter: createInternalAdapter(adapter, {\n\t\t\toptions,\n\t\t\tlogger,\n\t\t\thooks: options.databaseHooks ? [options.databaseHooks] : [],\n\t\t\tgenerateId: generateIdFunc,\n\t\t}),\n\t\tcreateAuthCookie: createCookieGetter(options),\n\t\tasync runMigrations() {\n\t\t\tthrow new BetterAuthError(\n\t\t\t\t\"runMigrations will be set by the specific init implementation\",\n\t\t\t);\n\t\t},\n\t\tpublishTelemetry: publish,\n\t\tskipCSRFCheck: !!options.advanced?.disableCSRFCheck,\n\t\tskipOriginCheck:\n\t\t\toptions.advanced?.disableOriginCheck !== undefined\n\t\t\t\t? options.advanced.disableOriginCheck\n\t\t\t\t: isTest()\n\t\t\t\t\t? true\n\t\t\t\t\t: false,\n\t\trunInBackground:\n\t\t\toptions.advanced?.backgroundTasks?.handler ??\n\t\t\t((p) => {\n\t\t\t\tp.catch(() => {});\n\t\t\t}),\n\t\tasync runInBackgroundOrAwait(\n\t\t\tpromise: Promise<unknown> | Promise<void> | void | unknown,\n\t\t) {\n\t\t\ttry {\n\t\t\t\tif (options.advanced?.backgroundTasks?.handler) {\n\t\t\t\t\tif (promise instanceof Promise) {\n\t\t\t\t\t\toptions.advanced.backgroundTasks.handler(\n\t\t\t\t\t\t\tpromise.catch((e) => {\n\t\t\t\t\t\t\t\tlogger.error(\"Failed to run background task:\", e);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tawait promise;\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(\"Failed to run background task:\", e);\n\t\t\t}\n\t\t},\n\t\tgetPlugin: <Plugin extends BetterAuthPlugin>(id: Plugin[\"id\"]) =>\n\t\t\t(options.plugins!.find((p): p is Plugin => p.id === id) as\n\t\t\t\t| Plugin\n\t\t\t\t| undefined) ?? null,\n\t};\n\n\tconst initOrPromise = runPluginInit(ctx);\n\tlet context: AuthContext;\n\tif (isPromise(initOrPromise)) {\n\t\t({ context } = await initOrPromise);\n\t} else {\n\t\t({ context } = initOrPromise);\n\t}\n\n\tif (\n\t\ttypeof context.options.emailVerification?.onEmailVerification === \"function\"\n\t) {\n\t\tcontext.options.emailVerification.onEmailVerification = deprecate(\n\t\t\tcontext.options.emailVerification.onEmailVerification,\n\t\t\t\"Use `afterEmailVerification` instead. This will be removed in 1.5\",\n\t\t\tcontext.logger,\n\t\t);\n\t}\n\n\treturn context;\n}\n"],"mappings":"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"}
|
package/dist/cookies/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@ import "../types/index.mjs";
|
|
|
3
3
|
import { HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, parseSetCookieHeader, setCookieToHeader, splitSetCookieHeader, stripSecureCookiePrefix } from "./cookie-utils.mjs";
|
|
4
4
|
import { createSessionStore, getChunkedCookie } from "./session-store.mjs";
|
|
5
5
|
import { BetterAuthCookie, BetterAuthCookies, BetterAuthOptions, GenericEndpointContext } from "@better-auth/core";
|
|
6
|
-
import * as
|
|
6
|
+
import * as better_call239 from "better-call";
|
|
7
7
|
import { CookieOptions } from "better-call";
|
|
8
8
|
|
|
9
9
|
//#region src/cookies/index.d.ts
|
|
@@ -18,7 +18,7 @@ declare function createCookieGetter(options: BetterAuthOptions): (cookieName: st
|
|
|
18
18
|
secure: boolean;
|
|
19
19
|
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
20
20
|
partitioned?: boolean;
|
|
21
|
-
prefix?:
|
|
21
|
+
prefix?: better_call239.CookiePrefixOptions;
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
declare function getCookies(options: BetterAuthOptions): {
|
|
@@ -33,7 +33,7 @@ declare function getCookies(options: BetterAuthOptions): {
|
|
|
33
33
|
secure: boolean;
|
|
34
34
|
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
35
35
|
partitioned?: boolean;
|
|
36
|
-
prefix?:
|
|
36
|
+
prefix?: better_call239.CookiePrefixOptions;
|
|
37
37
|
};
|
|
38
38
|
};
|
|
39
39
|
/**
|
|
@@ -51,7 +51,7 @@ declare function getCookies(options: BetterAuthOptions): {
|
|
|
51
51
|
secure: boolean;
|
|
52
52
|
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
53
53
|
partitioned?: boolean;
|
|
54
|
-
prefix?:
|
|
54
|
+
prefix?: better_call239.CookiePrefixOptions;
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
57
|
dontRememberToken: {
|
|
@@ -65,7 +65,7 @@ declare function getCookies(options: BetterAuthOptions): {
|
|
|
65
65
|
secure: boolean;
|
|
66
66
|
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
67
67
|
partitioned?: boolean;
|
|
68
|
-
prefix?:
|
|
68
|
+
prefix?: better_call239.CookiePrefixOptions;
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
71
|
accountData: {
|
|
@@ -79,7 +79,7 @@ declare function getCookies(options: BetterAuthOptions): {
|
|
|
79
79
|
secure: boolean;
|
|
80
80
|
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
81
81
|
partitioned?: boolean;
|
|
82
|
-
prefix?:
|
|
82
|
+
prefix?: better_call239.CookiePrefixOptions;
|
|
83
83
|
};
|
|
84
84
|
};
|
|
85
85
|
};
|
package/dist/cookies/index.mjs
CHANGED
|
@@ -164,20 +164,17 @@ function parseCookies(cookieHeader) {
|
|
|
164
164
|
return cookieMap;
|
|
165
165
|
}
|
|
166
166
|
const getSessionCookie = (request, config) => {
|
|
167
|
-
|
|
168
|
-
else config.cookiePrefix = `${config.cookiePrefix}.`;
|
|
169
|
-
const cookies = ("headers" in request ? request.headers : request).get("cookie");
|
|
167
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
170
168
|
if (!cookies) return null;
|
|
171
|
-
const { cookieName = "session_token", cookiePrefix = "better-auth
|
|
172
|
-
const name = `${cookiePrefix}${cookieName}`;
|
|
173
|
-
const secureCookieName = `${SECURE_COOKIE_PREFIX}${name}`;
|
|
169
|
+
const { cookieName = "session_token", cookiePrefix = "better-auth" } = config || {};
|
|
174
170
|
const parsedCookie = parseCookies(cookies);
|
|
175
|
-
const
|
|
171
|
+
const getCookie = (name) => parsedCookie.get(name) || parsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);
|
|
172
|
+
const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
|
|
176
173
|
if (sessionToken) return sessionToken;
|
|
177
174
|
return null;
|
|
178
175
|
};
|
|
179
176
|
const getCookieCache = async (request, config) => {
|
|
180
|
-
const cookies = (request instanceof Headers ? request : request.headers).get("cookie");
|
|
177
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
181
178
|
if (!cookies) return null;
|
|
182
179
|
const { cookieName = "session_data", cookiePrefix = "better-auth" } = config || {};
|
|
183
180
|
const name = config?.isSecure !== void 0 ? config.isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}` : isProduction ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["data: string","cleanCookies","chunks: Array<{ index: number; value: string }>","cookieName"],"sources":["../../src/cookies/index.ts"],"sourcesContent":["import type {\n\tBetterAuthCookie,\n\tBetterAuthCookies,\n\tBetterAuthOptions,\n\tGenericEndpointContext,\n} from \"@better-auth/core\";\nimport { env, isProduction } from \"@better-auth/core/env\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport { filterOutputFields, safeJSONParse } from \"@better-auth/core/utils\";\nimport { base64Url } from \"@better-auth/utils/base64\";\nimport { binary } from \"@better-auth/utils/binary\";\nimport { createHMAC } from \"@better-auth/utils/hmac\";\nimport type { CookieOptions } from \"better-call\";\nimport {\n\tsignJWT,\n\tsymmetricDecodeJWT,\n\tsymmetricEncodeJWT,\n\tverifyJWT,\n} from \"../crypto/jwt\";\nimport { parseUserOutput } from \"../db/schema\";\nimport type { Session, User } from \"../types\";\nimport { getDate } from \"../utils/date\";\nimport { isPromise } from \"../utils/is-promise\";\nimport { sec } from \"../utils/time\";\nimport { SECURE_COOKIE_PREFIX } from \"./cookie-utils\";\nimport {\n\tcreateAccountStore,\n\tcreateSessionStore,\n\tgetAccountCookie,\n\tsetAccountCookie,\n} from \"./session-store\";\n\nexport function createCookieGetter(options: BetterAuthOptions) {\n\tconst secure =\n\t\toptions.advanced?.useSecureCookies !== undefined\n\t\t\t? options.advanced?.useSecureCookies\n\t\t\t: options.baseURL\n\t\t\t\t? options.baseURL.startsWith(\"https://\")\n\t\t\t\t\t? true\n\t\t\t\t\t: false\n\t\t\t\t: isProduction;\n\tconst secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : \"\";\n\tconst crossSubdomainEnabled =\n\t\t!!options.advanced?.crossSubDomainCookies?.enabled;\n\tconst domain = crossSubdomainEnabled\n\t\t? options.advanced?.crossSubDomainCookies?.domain ||\n\t\t\t(options.baseURL ? new URL(options.baseURL).hostname : undefined)\n\t\t: undefined;\n\tif (crossSubdomainEnabled && !domain) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"baseURL is required when crossSubdomainCookies are enabled\",\n\t\t);\n\t}\n\tfunction createCookie(\n\t\tcookieName: string,\n\t\toverrideAttributes: Partial<CookieOptions> = {},\n\t) {\n\t\tconst prefix = options.advanced?.cookiePrefix || \"better-auth\";\n\t\tconst name =\n\t\t\toptions.advanced?.cookies?.[cookieName as \"session_token\"]?.name ||\n\t\t\t`${prefix}.${cookieName}`;\n\n\t\tconst attributes =\n\t\t\toptions.advanced?.cookies?.[cookieName as \"session_token\"]?.attributes;\n\n\t\treturn {\n\t\t\tname: `${secureCookiePrefix}${name}`,\n\t\t\tattributes: {\n\t\t\t\tsecure: !!secureCookiePrefix,\n\t\t\t\tsameSite: \"lax\",\n\t\t\t\tpath: \"/\",\n\t\t\t\thttpOnly: true,\n\t\t\t\t...(crossSubdomainEnabled ? { domain } : {}),\n\t\t\t\t...options.advanced?.defaultCookieAttributes,\n\t\t\t\t...overrideAttributes,\n\t\t\t\t...attributes,\n\t\t\t},\n\t\t} satisfies BetterAuthCookie;\n\t}\n\treturn createCookie;\n}\n\nexport function getCookies(options: BetterAuthOptions) {\n\tconst createCookie = createCookieGetter(options);\n\tconst sessionMaxAge = options.session?.expiresIn || sec(\"7d\");\n\tconst sessionToken = createCookie(\"session_token\", {\n\t\tmaxAge: sessionMaxAge,\n\t});\n\tconst sessionData = createCookie(\"session_data\", {\n\t\tmaxAge: options.session?.cookieCache?.maxAge || 60 * 5,\n\t});\n\tconst accountData = createCookie(\"account_data\", {\n\t\tmaxAge: options.session?.cookieCache?.maxAge || 60 * 5,\n\t});\n\tconst dontRememberToken = createCookie(\"dont_remember\");\n\treturn {\n\t\tsessionToken: {\n\t\t\tname: sessionToken.name,\n\t\t\tattributes: sessionToken.attributes,\n\t\t},\n\t\t/**\n\t\t * This cookie is used to store the session data in the cookie\n\t\t * This is useful for when you want to cache the session in the cookie\n\t\t */\n\t\tsessionData: {\n\t\t\tname: sessionData.name,\n\t\t\tattributes: sessionData.attributes,\n\t\t},\n\t\tdontRememberToken: {\n\t\t\tname: dontRememberToken.name,\n\t\t\tattributes: dontRememberToken.attributes,\n\t\t},\n\t\taccountData: {\n\t\t\tname: accountData.name,\n\t\t\tattributes: accountData.attributes,\n\t\t},\n\t};\n}\n\nexport async function setCookieCache(\n\tctx: GenericEndpointContext,\n\tsession: {\n\t\tsession: Session & Record<string, any>;\n\t\tuser: User;\n\t},\n\tdontRememberMe: boolean,\n) {\n\tif (!ctx.context.options.session?.cookieCache?.enabled) {\n\t\treturn;\n\t}\n\n\tconst filteredSession = filterOutputFields(\n\t\tsession.session,\n\t\tctx.context.options.session?.additionalFields,\n\t);\n\n\tconst filteredUser = parseUserOutput(ctx.context.options, session.user);\n\n\tconst versionConfig = ctx.context.options.session?.cookieCache?.version;\n\tlet version = \"1\";\n\tif (versionConfig) {\n\t\tif (typeof versionConfig === \"string\") {\n\t\t\tversion = versionConfig;\n\t\t} else if (typeof versionConfig === \"function\") {\n\t\t\tconst result = versionConfig(session.session, session.user);\n\t\t\tversion = isPromise(result) ? await result : result;\n\t\t}\n\t}\n\n\tconst sessionData = {\n\t\tsession: filteredSession,\n\t\tuser: filteredUser,\n\t\tupdatedAt: Date.now(),\n\t\tversion,\n\t};\n\n\tconst options = {\n\t\t...ctx.context.authCookies.sessionData.attributes,\n\t\tmaxAge: dontRememberMe\n\t\t\t? undefined\n\t\t\t: ctx.context.authCookies.sessionData.attributes.maxAge,\n\t};\n\n\tconst expiresAtDate = getDate(options.maxAge || 60, \"sec\").getTime();\n\tconst strategy =\n\t\tctx.context.options.session?.cookieCache?.strategy || \"compact\";\n\n\tlet data: string;\n\n\tif (strategy === \"jwe\") {\n\t\t// Use JWE strategy (JSON Web Encryption) with A256CBC-HS512 + HKDF\n\t\tdata = await symmetricEncodeJWT(\n\t\t\tsessionData,\n\t\t\tctx.context.secret,\n\t\t\t\"better-auth-session\",\n\t\t\toptions.maxAge || 60 * 5,\n\t\t);\n\t} else if (strategy === \"jwt\") {\n\t\t// Use JWT strategy with HMAC-SHA256 signature (HS256), no encryption\n\t\tdata = await signJWT(\n\t\t\tsessionData,\n\t\t\tctx.context.secret,\n\t\t\toptions.maxAge || 60 * 5,\n\t\t);\n\t} else {\n\t\t// Use compact strategy (base64url + HMAC, no JWT spec overhead)\n\t\t// Also handles legacy \"base64-hmac\" for backward compatibility\n\t\tdata = base64Url.encode(\n\t\t\tJSON.stringify({\n\t\t\t\tsession: sessionData,\n\t\t\t\texpiresAt: expiresAtDate,\n\t\t\t\tsignature: await createHMAC(\"SHA-256\", \"base64urlnopad\").sign(\n\t\t\t\t\tctx.context.secret,\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t...sessionData,\n\t\t\t\t\t\texpiresAt: expiresAtDate,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t\t{\n\t\t\t\tpadding: false,\n\t\t\t},\n\t\t);\n\t}\n\n\t// Check if we need to chunk the cookie (only if it exceeds 4093 bytes)\n\tif (data.length > 4093) {\n\t\tconst sessionStore = createSessionStore(\n\t\t\tctx.context.authCookies.sessionData.name,\n\t\t\toptions,\n\t\t\tctx,\n\t\t);\n\t\tconst cookies = sessionStore.chunk(data, options);\n\t\tsessionStore.setCookies(cookies);\n\t} else {\n\t\tconst sessionStore = createSessionStore(\n\t\t\tctx.context.authCookies.sessionData.name,\n\t\t\toptions,\n\t\t\tctx,\n\t\t);\n\t\tif (sessionStore.hasChunks()) {\n\t\t\tconst cleanCookies = sessionStore.clean();\n\t\t\tsessionStore.setCookies(cleanCookies);\n\t\t}\n\t\tctx.setCookie(ctx.context.authCookies.sessionData.name, data, options);\n\t}\n\n\t// Refresh account cookie to keep it in sync\n\tif (ctx.context.options.account?.storeAccountCookie) {\n\t\tconst accountData = await getAccountCookie(ctx);\n\t\tif (accountData) {\n\t\t\tawait setAccountCookie(ctx, accountData);\n\t\t}\n\t}\n}\n\nexport async function setSessionCookie(\n\tctx: GenericEndpointContext,\n\tsession: {\n\t\tsession: Session & Record<string, any>;\n\t\tuser: User;\n\t},\n\tdontRememberMe?: boolean | undefined,\n\toverrides?: Partial<CookieOptions> | undefined,\n) {\n\tconst dontRememberMeCookie = await ctx.getSignedCookie(\n\t\tctx.context.authCookies.dontRememberToken.name,\n\t\tctx.context.secret,\n\t);\n\t// if dontRememberMe is not set, use the cookie value\n\tdontRememberMe =\n\t\tdontRememberMe !== undefined ? dontRememberMe : !!dontRememberMeCookie;\n\n\tconst options = ctx.context.authCookies.sessionToken.attributes;\n\tconst maxAge = dontRememberMe\n\t\t? undefined\n\t\t: ctx.context.sessionConfig.expiresIn;\n\tawait ctx.setSignedCookie(\n\t\tctx.context.authCookies.sessionToken.name,\n\t\tsession.session.token,\n\t\tctx.context.secret,\n\t\t{\n\t\t\t...options,\n\t\t\tmaxAge,\n\t\t\t...overrides,\n\t\t},\n\t);\n\n\tif (dontRememberMe) {\n\t\tawait ctx.setSignedCookie(\n\t\t\tctx.context.authCookies.dontRememberToken.name,\n\t\t\t\"true\",\n\t\t\tctx.context.secret,\n\t\t\tctx.context.authCookies.dontRememberToken.attributes,\n\t\t);\n\t}\n\tawait setCookieCache(ctx, session, dontRememberMe);\n\tctx.context.setNewSession(session);\n}\n\n/**\n * Expires a cookie by setting `maxAge: 0` while preserving its attributes\n */\nexport function expireCookie(\n\tctx: GenericEndpointContext,\n\tcookie: BetterAuthCookie,\n) {\n\tctx.setCookie(cookie.name, \"\", {\n\t\t...cookie.attributes,\n\t\tmaxAge: 0,\n\t});\n}\n\nexport function deleteSessionCookie(\n\tctx: GenericEndpointContext,\n\tskipDontRememberMe?: boolean | undefined,\n) {\n\texpireCookie(ctx, ctx.context.authCookies.sessionToken);\n\texpireCookie(ctx, ctx.context.authCookies.sessionData);\n\n\tif (ctx.context.options.account?.storeAccountCookie) {\n\t\texpireCookie(ctx, ctx.context.authCookies.accountData);\n\n\t\t//clean up the account data chunks\n\t\tconst accountStore = createAccountStore(\n\t\t\tctx.context.authCookies.accountData.name,\n\t\t\tctx.context.authCookies.accountData.attributes,\n\t\t\tctx,\n\t\t);\n\t\tconst cleanCookies = accountStore.clean();\n\t\taccountStore.setCookies(cleanCookies);\n\t}\n\n\tif (ctx.context.oauthConfig.storeStateStrategy === \"cookie\") {\n\t\tconst stateCookie = ctx.context.createAuthCookie(\"oauth_state\");\n\t\texpireCookie(ctx, stateCookie);\n\t}\n\n\t// Use createSessionStore to clean up all session data chunks\n\tconst sessionStore = createSessionStore(\n\t\tctx.context.authCookies.sessionData.name,\n\t\tctx.context.authCookies.sessionData.attributes,\n\t\tctx,\n\t);\n\tconst cleanCookies = sessionStore.clean();\n\tsessionStore.setCookies(cleanCookies);\n\n\tif (!skipDontRememberMe) {\n\t\texpireCookie(ctx, ctx.context.authCookies.dontRememberToken);\n\t}\n}\n\nexport function parseCookies(cookieHeader: string) {\n\tconst cookies = cookieHeader.split(\"; \");\n\tconst cookieMap = new Map<string, string>();\n\n\tcookies.forEach((cookie) => {\n\t\tconst [name, value] = cookie.split(/=(.*)/s);\n\t\tcookieMap.set(name!, value!);\n\t});\n\treturn cookieMap;\n}\n\nexport type EligibleCookies = (string & {}) | (keyof BetterAuthCookies & {});\n\nexport const getSessionCookie = (\n\trequest: Request | Headers,\n\tconfig?:\n\t\t| {\n\t\t\t\tcookiePrefix?: string;\n\t\t\t\tcookieName?: string;\n\t\t\t\tpath?: string;\n\t\t }\n\t\t| undefined,\n) => {\n\tif (config?.cookiePrefix) {\n\t\tif (config.cookieName) {\n\t\t\tconfig.cookiePrefix = `${config.cookiePrefix}-`;\n\t\t} else {\n\t\t\tconfig.cookiePrefix = `${config.cookiePrefix}.`;\n\t\t}\n\t}\n\tconst headers = \"headers\" in request ? request.headers : request;\n\tconst cookies = headers.get(\"cookie\");\n\tif (!cookies) {\n\t\treturn null;\n\t}\n\tconst { cookieName = \"session_token\", cookiePrefix = \"better-auth.\" } =\n\t\tconfig || {};\n\tconst name = `${cookiePrefix}${cookieName}`;\n\tconst secureCookieName = `${SECURE_COOKIE_PREFIX}${name}`;\n\tconst parsedCookie = parseCookies(cookies);\n\tconst sessionToken =\n\t\tparsedCookie.get(name) || parsedCookie.get(secureCookieName);\n\tif (sessionToken) {\n\t\treturn sessionToken;\n\t}\n\n\treturn null;\n};\n\nexport const getCookieCache = async <\n\tS extends {\n\t\tsession: Session & Record<string, any>;\n\t\tuser: User & Record<string, any>;\n\t\tupdatedAt: number;\n\t\tversion?: string;\n\t},\n>(\n\trequest: Request | Headers,\n\tconfig?:\n\t\t| {\n\t\t\t\tcookiePrefix?: string;\n\t\t\t\tcookieName?: string;\n\t\t\t\tisSecure?: boolean;\n\t\t\t\tsecret?: string;\n\t\t\t\tstrategy?: \"compact\" | \"jwt\" | \"jwe\"; // base64-hmac for backward compatibility\n\t\t\t\tversion?:\n\t\t\t\t\t| string\n\t\t\t\t\t| ((\n\t\t\t\t\t\t\tsession: Session & Record<string, any>,\n\t\t\t\t\t\t\tuser: User & Record<string, any>,\n\t\t\t\t\t ) => string)\n\t\t\t\t\t| ((\n\t\t\t\t\t\t\tsession: Session & Record<string, any>,\n\t\t\t\t\t\t\tuser: User & Record<string, any>,\n\t\t\t\t\t ) => Promise<string>);\n\t\t }\n\t\t| undefined,\n) => {\n\tconst headers = request instanceof Headers ? request : request.headers;\n\tconst cookies = headers.get(\"cookie\");\n\tif (!cookies) {\n\t\treturn null;\n\t}\n\tconst { cookieName = \"session_data\", cookiePrefix = \"better-auth\" } =\n\t\tconfig || {};\n\tconst name =\n\t\tconfig?.isSecure !== undefined\n\t\t\t? config.isSecure\n\t\t\t\t? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}`\n\t\t\t\t: `${cookiePrefix}.${cookieName}`\n\t\t\t: isProduction\n\t\t\t\t? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}`\n\t\t\t\t: `${cookiePrefix}.${cookieName}`;\n\tconst parsedCookie = parseCookies(cookies);\n\n\t// Check for chunked cookies\n\tlet sessionData = parsedCookie.get(name);\n\tif (!sessionData) {\n\t\t// Try to reconstruct from chunks\n\t\tconst chunks: Array<{ index: number; value: string }> = [];\n\t\tfor (const [cookieName, value] of parsedCookie.entries()) {\n\t\t\tif (cookieName.startsWith(name + \".\")) {\n\t\t\t\tconst parts = cookieName.split(\".\");\n\t\t\t\tconst indexStr = parts[parts.length - 1];\n\t\t\t\tconst index = parseInt(indexStr || \"0\", 10);\n\t\t\t\tif (!isNaN(index)) {\n\t\t\t\t\tchunks.push({ index, value });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (chunks.length > 0) {\n\t\t\t// Sort by index and join\n\t\t\tchunks.sort((a, b) => a.index - b.index);\n\t\t\tsessionData = chunks.map((c) => c.value).join(\"\");\n\t\t}\n\t}\n\n\tif (sessionData) {\n\t\tconst secret = config?.secret || env.BETTER_AUTH_SECRET;\n\t\tif (!secret) {\n\t\t\tthrow new BetterAuthError(\n\t\t\t\t\"getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable\",\n\t\t\t);\n\t\t}\n\n\t\tconst strategy = config?.strategy || \"compact\";\n\n\t\tif (strategy === \"jwe\") {\n\t\t\t// Use JWE strategy (encrypted)\n\t\t\tconst payload = await symmetricDecodeJWT<S>(\n\t\t\t\tsessionData,\n\t\t\t\tsecret,\n\t\t\t\t\"better-auth-session\",\n\t\t\t);\n\n\t\t\tif (payload && payload.session && payload.user) {\n\t\t\t\t// Validate version if provided\n\t\t\t\tif (config?.version) {\n\t\t\t\t\tconst cookieVersion = payload.version || \"1\";\n\t\t\t\t\tlet expectedVersion = \"1\";\n\t\t\t\t\tif (typeof config.version === \"string\") {\n\t\t\t\t\t\texpectedVersion = config.version;\n\t\t\t\t\t} else if (typeof config.version === \"function\") {\n\t\t\t\t\t\tconst result = config.version(payload.session, payload.user);\n\t\t\t\t\t\texpectedVersion = isPromise(result) ? await result : result;\n\t\t\t\t\t}\n\t\t\t\t\tif (cookieVersion !== expectedVersion) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn null;\n\t\t} else if (strategy === \"jwt\") {\n\t\t\t// Use JWT strategy with HMAC signature (HS256), no encryption\n\t\t\tconst payload = await verifyJWT<S>(sessionData, secret);\n\n\t\t\tif (payload && payload.session && payload.user) {\n\t\t\t\t// Validate version if provided\n\t\t\t\tif (config?.version) {\n\t\t\t\t\tconst cookieVersion = payload.version || \"1\";\n\t\t\t\t\tlet expectedVersion = \"1\";\n\t\t\t\t\tif (typeof config.version === \"string\") {\n\t\t\t\t\t\texpectedVersion = config.version;\n\t\t\t\t\t} else if (typeof config.version === \"function\") {\n\t\t\t\t\t\tconst result = config.version(payload.session, payload.user);\n\t\t\t\t\t\texpectedVersion = isPromise(result) ? await result : result;\n\t\t\t\t\t}\n\t\t\t\t\tif (cookieVersion !== expectedVersion) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn null;\n\t\t} else {\n\t\t\t// Use compact strategy (or legacy base64-hmac)\n\t\t\tconst sessionDataPayload = safeJSONParse<{\n\t\t\t\tsession: S;\n\t\t\t\texpiresAt: number;\n\t\t\t\tsignature: string;\n\t\t\t}>(binary.decode(base64Url.decode(sessionData)));\n\t\t\tif (!sessionDataPayload) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst isValid = await createHMAC(\"SHA-256\", \"base64urlnopad\").verify(\n\t\t\t\tsecret,\n\t\t\t\tJSON.stringify({\n\t\t\t\t\t...sessionDataPayload.session,\n\t\t\t\t\texpiresAt: sessionDataPayload.expiresAt,\n\t\t\t\t}),\n\t\t\t\tsessionDataPayload.signature,\n\t\t\t);\n\t\t\tif (!isValid) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Validate version if provided\n\t\t\tif (config?.version && sessionDataPayload.session) {\n\t\t\t\tconst cookieVersion = sessionDataPayload.session.version || \"1\";\n\t\t\t\tlet expectedVersion = \"1\";\n\t\t\t\tif (typeof config.version === \"string\") {\n\t\t\t\t\texpectedVersion = config.version;\n\t\t\t\t} else if (typeof config.version === \"function\") {\n\t\t\t\t\tconst result = config.version(\n\t\t\t\t\t\tsessionDataPayload.session.session,\n\t\t\t\t\t\tsessionDataPayload.session.user,\n\t\t\t\t\t);\n\t\t\t\t\texpectedVersion = isPromise(result) ? await result : result;\n\t\t\t\t}\n\t\t\t\tif (cookieVersion !== expectedVersion) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn sessionDataPayload.session;\n\t\t}\n\t}\n\treturn null;\n};\n\nexport * from \"./cookie-utils\";\nexport { createSessionStore, getChunkedCookie } from \"./session-store\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["data: string","cleanCookies","chunks: Array<{ index: number; value: string }>","cookieName"],"sources":["../../src/cookies/index.ts"],"sourcesContent":["import type {\n\tBetterAuthCookie,\n\tBetterAuthCookies,\n\tBetterAuthOptions,\n\tGenericEndpointContext,\n} from \"@better-auth/core\";\nimport { env, isProduction } from \"@better-auth/core/env\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport { filterOutputFields, safeJSONParse } from \"@better-auth/core/utils\";\nimport { base64Url } from \"@better-auth/utils/base64\";\nimport { binary } from \"@better-auth/utils/binary\";\nimport { createHMAC } from \"@better-auth/utils/hmac\";\nimport type { CookieOptions } from \"better-call\";\nimport {\n\tsignJWT,\n\tsymmetricDecodeJWT,\n\tsymmetricEncodeJWT,\n\tverifyJWT,\n} from \"../crypto/jwt\";\nimport { parseUserOutput } from \"../db/schema\";\nimport type { Session, User } from \"../types\";\nimport { getDate } from \"../utils/date\";\nimport { isPromise } from \"../utils/is-promise\";\nimport { sec } from \"../utils/time\";\nimport { SECURE_COOKIE_PREFIX } from \"./cookie-utils\";\nimport {\n\tcreateAccountStore,\n\tcreateSessionStore,\n\tgetAccountCookie,\n\tsetAccountCookie,\n} from \"./session-store\";\n\nexport function createCookieGetter(options: BetterAuthOptions) {\n\tconst secure =\n\t\toptions.advanced?.useSecureCookies !== undefined\n\t\t\t? options.advanced?.useSecureCookies\n\t\t\t: options.baseURL\n\t\t\t\t? options.baseURL.startsWith(\"https://\")\n\t\t\t\t\t? true\n\t\t\t\t\t: false\n\t\t\t\t: isProduction;\n\tconst secureCookiePrefix = secure ? SECURE_COOKIE_PREFIX : \"\";\n\tconst crossSubdomainEnabled =\n\t\t!!options.advanced?.crossSubDomainCookies?.enabled;\n\tconst domain = crossSubdomainEnabled\n\t\t? options.advanced?.crossSubDomainCookies?.domain ||\n\t\t\t(options.baseURL ? new URL(options.baseURL).hostname : undefined)\n\t\t: undefined;\n\tif (crossSubdomainEnabled && !domain) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"baseURL is required when crossSubdomainCookies are enabled\",\n\t\t);\n\t}\n\tfunction createCookie(\n\t\tcookieName: string,\n\t\toverrideAttributes: Partial<CookieOptions> = {},\n\t) {\n\t\tconst prefix = options.advanced?.cookiePrefix || \"better-auth\";\n\t\tconst name =\n\t\t\toptions.advanced?.cookies?.[cookieName as \"session_token\"]?.name ||\n\t\t\t`${prefix}.${cookieName}`;\n\n\t\tconst attributes =\n\t\t\toptions.advanced?.cookies?.[cookieName as \"session_token\"]?.attributes;\n\n\t\treturn {\n\t\t\tname: `${secureCookiePrefix}${name}`,\n\t\t\tattributes: {\n\t\t\t\tsecure: !!secureCookiePrefix,\n\t\t\t\tsameSite: \"lax\",\n\t\t\t\tpath: \"/\",\n\t\t\t\thttpOnly: true,\n\t\t\t\t...(crossSubdomainEnabled ? { domain } : {}),\n\t\t\t\t...options.advanced?.defaultCookieAttributes,\n\t\t\t\t...overrideAttributes,\n\t\t\t\t...attributes,\n\t\t\t},\n\t\t} satisfies BetterAuthCookie;\n\t}\n\treturn createCookie;\n}\n\nexport function getCookies(options: BetterAuthOptions) {\n\tconst createCookie = createCookieGetter(options);\n\tconst sessionMaxAge = options.session?.expiresIn || sec(\"7d\");\n\tconst sessionToken = createCookie(\"session_token\", {\n\t\tmaxAge: sessionMaxAge,\n\t});\n\tconst sessionData = createCookie(\"session_data\", {\n\t\tmaxAge: options.session?.cookieCache?.maxAge || 60 * 5,\n\t});\n\tconst accountData = createCookie(\"account_data\", {\n\t\tmaxAge: options.session?.cookieCache?.maxAge || 60 * 5,\n\t});\n\tconst dontRememberToken = createCookie(\"dont_remember\");\n\treturn {\n\t\tsessionToken: {\n\t\t\tname: sessionToken.name,\n\t\t\tattributes: sessionToken.attributes,\n\t\t},\n\t\t/**\n\t\t * This cookie is used to store the session data in the cookie\n\t\t * This is useful for when you want to cache the session in the cookie\n\t\t */\n\t\tsessionData: {\n\t\t\tname: sessionData.name,\n\t\t\tattributes: sessionData.attributes,\n\t\t},\n\t\tdontRememberToken: {\n\t\t\tname: dontRememberToken.name,\n\t\t\tattributes: dontRememberToken.attributes,\n\t\t},\n\t\taccountData: {\n\t\t\tname: accountData.name,\n\t\t\tattributes: accountData.attributes,\n\t\t},\n\t};\n}\n\nexport async function setCookieCache(\n\tctx: GenericEndpointContext,\n\tsession: {\n\t\tsession: Session & Record<string, any>;\n\t\tuser: User;\n\t},\n\tdontRememberMe: boolean,\n) {\n\tif (!ctx.context.options.session?.cookieCache?.enabled) {\n\t\treturn;\n\t}\n\n\tconst filteredSession = filterOutputFields(\n\t\tsession.session,\n\t\tctx.context.options.session?.additionalFields,\n\t);\n\n\tconst filteredUser = parseUserOutput(ctx.context.options, session.user);\n\n\tconst versionConfig = ctx.context.options.session?.cookieCache?.version;\n\tlet version = \"1\";\n\tif (versionConfig) {\n\t\tif (typeof versionConfig === \"string\") {\n\t\t\tversion = versionConfig;\n\t\t} else if (typeof versionConfig === \"function\") {\n\t\t\tconst result = versionConfig(session.session, session.user);\n\t\t\tversion = isPromise(result) ? await result : result;\n\t\t}\n\t}\n\n\tconst sessionData = {\n\t\tsession: filteredSession,\n\t\tuser: filteredUser,\n\t\tupdatedAt: Date.now(),\n\t\tversion,\n\t};\n\n\tconst options = {\n\t\t...ctx.context.authCookies.sessionData.attributes,\n\t\tmaxAge: dontRememberMe\n\t\t\t? undefined\n\t\t\t: ctx.context.authCookies.sessionData.attributes.maxAge,\n\t};\n\n\tconst expiresAtDate = getDate(options.maxAge || 60, \"sec\").getTime();\n\tconst strategy =\n\t\tctx.context.options.session?.cookieCache?.strategy || \"compact\";\n\n\tlet data: string;\n\n\tif (strategy === \"jwe\") {\n\t\t// Use JWE strategy (JSON Web Encryption) with A256CBC-HS512 + HKDF\n\t\tdata = await symmetricEncodeJWT(\n\t\t\tsessionData,\n\t\t\tctx.context.secret,\n\t\t\t\"better-auth-session\",\n\t\t\toptions.maxAge || 60 * 5,\n\t\t);\n\t} else if (strategy === \"jwt\") {\n\t\t// Use JWT strategy with HMAC-SHA256 signature (HS256), no encryption\n\t\tdata = await signJWT(\n\t\t\tsessionData,\n\t\t\tctx.context.secret,\n\t\t\toptions.maxAge || 60 * 5,\n\t\t);\n\t} else {\n\t\t// Use compact strategy (base64url + HMAC, no JWT spec overhead)\n\t\t// Also handles legacy \"base64-hmac\" for backward compatibility\n\t\tdata = base64Url.encode(\n\t\t\tJSON.stringify({\n\t\t\t\tsession: sessionData,\n\t\t\t\texpiresAt: expiresAtDate,\n\t\t\t\tsignature: await createHMAC(\"SHA-256\", \"base64urlnopad\").sign(\n\t\t\t\t\tctx.context.secret,\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\t...sessionData,\n\t\t\t\t\t\texpiresAt: expiresAtDate,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t}),\n\t\t\t{\n\t\t\t\tpadding: false,\n\t\t\t},\n\t\t);\n\t}\n\n\t// Check if we need to chunk the cookie (only if it exceeds 4093 bytes)\n\tif (data.length > 4093) {\n\t\tconst sessionStore = createSessionStore(\n\t\t\tctx.context.authCookies.sessionData.name,\n\t\t\toptions,\n\t\t\tctx,\n\t\t);\n\t\tconst cookies = sessionStore.chunk(data, options);\n\t\tsessionStore.setCookies(cookies);\n\t} else {\n\t\tconst sessionStore = createSessionStore(\n\t\t\tctx.context.authCookies.sessionData.name,\n\t\t\toptions,\n\t\t\tctx,\n\t\t);\n\t\tif (sessionStore.hasChunks()) {\n\t\t\tconst cleanCookies = sessionStore.clean();\n\t\t\tsessionStore.setCookies(cleanCookies);\n\t\t}\n\t\tctx.setCookie(ctx.context.authCookies.sessionData.name, data, options);\n\t}\n\n\t// Refresh account cookie to keep it in sync\n\tif (ctx.context.options.account?.storeAccountCookie) {\n\t\tconst accountData = await getAccountCookie(ctx);\n\t\tif (accountData) {\n\t\t\tawait setAccountCookie(ctx, accountData);\n\t\t}\n\t}\n}\n\nexport async function setSessionCookie(\n\tctx: GenericEndpointContext,\n\tsession: {\n\t\tsession: Session & Record<string, any>;\n\t\tuser: User;\n\t},\n\tdontRememberMe?: boolean | undefined,\n\toverrides?: Partial<CookieOptions> | undefined,\n) {\n\tconst dontRememberMeCookie = await ctx.getSignedCookie(\n\t\tctx.context.authCookies.dontRememberToken.name,\n\t\tctx.context.secret,\n\t);\n\t// if dontRememberMe is not set, use the cookie value\n\tdontRememberMe =\n\t\tdontRememberMe !== undefined ? dontRememberMe : !!dontRememberMeCookie;\n\n\tconst options = ctx.context.authCookies.sessionToken.attributes;\n\tconst maxAge = dontRememberMe\n\t\t? undefined\n\t\t: ctx.context.sessionConfig.expiresIn;\n\tawait ctx.setSignedCookie(\n\t\tctx.context.authCookies.sessionToken.name,\n\t\tsession.session.token,\n\t\tctx.context.secret,\n\t\t{\n\t\t\t...options,\n\t\t\tmaxAge,\n\t\t\t...overrides,\n\t\t},\n\t);\n\n\tif (dontRememberMe) {\n\t\tawait ctx.setSignedCookie(\n\t\t\tctx.context.authCookies.dontRememberToken.name,\n\t\t\t\"true\",\n\t\t\tctx.context.secret,\n\t\t\tctx.context.authCookies.dontRememberToken.attributes,\n\t\t);\n\t}\n\tawait setCookieCache(ctx, session, dontRememberMe);\n\tctx.context.setNewSession(session);\n}\n\n/**\n * Expires a cookie by setting `maxAge: 0` while preserving its attributes\n */\nexport function expireCookie(\n\tctx: GenericEndpointContext,\n\tcookie: BetterAuthCookie,\n) {\n\tctx.setCookie(cookie.name, \"\", {\n\t\t...cookie.attributes,\n\t\tmaxAge: 0,\n\t});\n}\n\nexport function deleteSessionCookie(\n\tctx: GenericEndpointContext,\n\tskipDontRememberMe?: boolean | undefined,\n) {\n\texpireCookie(ctx, ctx.context.authCookies.sessionToken);\n\texpireCookie(ctx, ctx.context.authCookies.sessionData);\n\n\tif (ctx.context.options.account?.storeAccountCookie) {\n\t\texpireCookie(ctx, ctx.context.authCookies.accountData);\n\n\t\t//clean up the account data chunks\n\t\tconst accountStore = createAccountStore(\n\t\t\tctx.context.authCookies.accountData.name,\n\t\t\tctx.context.authCookies.accountData.attributes,\n\t\t\tctx,\n\t\t);\n\t\tconst cleanCookies = accountStore.clean();\n\t\taccountStore.setCookies(cleanCookies);\n\t}\n\n\tif (ctx.context.oauthConfig.storeStateStrategy === \"cookie\") {\n\t\tconst stateCookie = ctx.context.createAuthCookie(\"oauth_state\");\n\t\texpireCookie(ctx, stateCookie);\n\t}\n\n\t// Use createSessionStore to clean up all session data chunks\n\tconst sessionStore = createSessionStore(\n\t\tctx.context.authCookies.sessionData.name,\n\t\tctx.context.authCookies.sessionData.attributes,\n\t\tctx,\n\t);\n\tconst cleanCookies = sessionStore.clean();\n\tsessionStore.setCookies(cleanCookies);\n\n\tif (!skipDontRememberMe) {\n\t\texpireCookie(ctx, ctx.context.authCookies.dontRememberToken);\n\t}\n}\n\nexport function parseCookies(cookieHeader: string) {\n\tconst cookies = cookieHeader.split(\"; \");\n\tconst cookieMap = new Map<string, string>();\n\n\tcookies.forEach((cookie) => {\n\t\tconst [name, value] = cookie.split(/=(.*)/s);\n\t\tcookieMap.set(name!, value!);\n\t});\n\treturn cookieMap;\n}\n\nexport type EligibleCookies = (string & {}) | (keyof BetterAuthCookies & {});\n\nexport const getSessionCookie = (\n\trequest: Request | Headers,\n\tconfig?:\n\t\t| {\n\t\t\t\tcookiePrefix?: string;\n\t\t\t\tcookieName?: string;\n\t\t\t\tpath?: string;\n\t\t }\n\t\t| undefined,\n) => {\n\tconst headers =\n\t\trequest instanceof Headers || !(\"headers\" in request)\n\t\t\t? request\n\t\t\t: request.headers;\n\tconst cookies = headers.get(\"cookie\");\n\tif (!cookies) {\n\t\treturn null;\n\t}\n\tconst { cookieName = \"session_token\", cookiePrefix = \"better-auth\" } =\n\t\tconfig || {};\n\tconst parsedCookie = parseCookies(cookies);\n\tconst getCookie = (name: string) =>\n\t\tparsedCookie.get(name) ||\n\t\tparsedCookie.get(`${SECURE_COOKIE_PREFIX}${name}`);\n\n\tconst sessionToken =\n\t\tgetCookie(`${cookiePrefix}.${cookieName}`) ||\n\t\tgetCookie(`${cookiePrefix}-${cookieName}`);\n\tif (sessionToken) {\n\t\treturn sessionToken;\n\t}\n\n\treturn null;\n};\n\nexport const getCookieCache = async <\n\tS extends {\n\t\tsession: Session & Record<string, any>;\n\t\tuser: User & Record<string, any>;\n\t\tupdatedAt: number;\n\t\tversion?: string;\n\t},\n>(\n\trequest: Request | Headers,\n\tconfig?:\n\t\t| {\n\t\t\t\tcookiePrefix?: string;\n\t\t\t\tcookieName?: string;\n\t\t\t\tisSecure?: boolean;\n\t\t\t\tsecret?: string;\n\t\t\t\tstrategy?: \"compact\" | \"jwt\" | \"jwe\"; // base64-hmac for backward compatibility\n\t\t\t\tversion?:\n\t\t\t\t\t| string\n\t\t\t\t\t| ((\n\t\t\t\t\t\t\tsession: Session & Record<string, any>,\n\t\t\t\t\t\t\tuser: User & Record<string, any>,\n\t\t\t\t\t ) => string)\n\t\t\t\t\t| ((\n\t\t\t\t\t\t\tsession: Session & Record<string, any>,\n\t\t\t\t\t\t\tuser: User & Record<string, any>,\n\t\t\t\t\t ) => Promise<string>);\n\t\t }\n\t\t| undefined,\n) => {\n\tconst headers =\n\t\trequest instanceof Headers || !(\"headers\" in request)\n\t\t\t? request\n\t\t\t: request.headers;\n\tconst cookies = headers.get(\"cookie\");\n\tif (!cookies) {\n\t\treturn null;\n\t}\n\tconst { cookieName = \"session_data\", cookiePrefix = \"better-auth\" } =\n\t\tconfig || {};\n\tconst name =\n\t\tconfig?.isSecure !== undefined\n\t\t\t? config.isSecure\n\t\t\t\t? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}`\n\t\t\t\t: `${cookiePrefix}.${cookieName}`\n\t\t\t: isProduction\n\t\t\t\t? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}`\n\t\t\t\t: `${cookiePrefix}.${cookieName}`;\n\tconst parsedCookie = parseCookies(cookies);\n\n\t// Check for chunked cookies\n\tlet sessionData = parsedCookie.get(name);\n\tif (!sessionData) {\n\t\t// Try to reconstruct from chunks\n\t\tconst chunks: Array<{ index: number; value: string }> = [];\n\t\tfor (const [cookieName, value] of parsedCookie.entries()) {\n\t\t\tif (cookieName.startsWith(name + \".\")) {\n\t\t\t\tconst parts = cookieName.split(\".\");\n\t\t\t\tconst indexStr = parts[parts.length - 1];\n\t\t\t\tconst index = parseInt(indexStr || \"0\", 10);\n\t\t\t\tif (!isNaN(index)) {\n\t\t\t\t\tchunks.push({ index, value });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (chunks.length > 0) {\n\t\t\t// Sort by index and join\n\t\t\tchunks.sort((a, b) => a.index - b.index);\n\t\t\tsessionData = chunks.map((c) => c.value).join(\"\");\n\t\t}\n\t}\n\n\tif (sessionData) {\n\t\tconst secret = config?.secret || env.BETTER_AUTH_SECRET;\n\t\tif (!secret) {\n\t\t\tthrow new BetterAuthError(\n\t\t\t\t\"getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable\",\n\t\t\t);\n\t\t}\n\n\t\tconst strategy = config?.strategy || \"compact\";\n\n\t\tif (strategy === \"jwe\") {\n\t\t\t// Use JWE strategy (encrypted)\n\t\t\tconst payload = await symmetricDecodeJWT<S>(\n\t\t\t\tsessionData,\n\t\t\t\tsecret,\n\t\t\t\t\"better-auth-session\",\n\t\t\t);\n\n\t\t\tif (payload && payload.session && payload.user) {\n\t\t\t\t// Validate version if provided\n\t\t\t\tif (config?.version) {\n\t\t\t\t\tconst cookieVersion = payload.version || \"1\";\n\t\t\t\t\tlet expectedVersion = \"1\";\n\t\t\t\t\tif (typeof config.version === \"string\") {\n\t\t\t\t\t\texpectedVersion = config.version;\n\t\t\t\t\t} else if (typeof config.version === \"function\") {\n\t\t\t\t\t\tconst result = config.version(payload.session, payload.user);\n\t\t\t\t\t\texpectedVersion = isPromise(result) ? await result : result;\n\t\t\t\t\t}\n\t\t\t\t\tif (cookieVersion !== expectedVersion) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn null;\n\t\t} else if (strategy === \"jwt\") {\n\t\t\t// Use JWT strategy with HMAC signature (HS256), no encryption\n\t\t\tconst payload = await verifyJWT<S>(sessionData, secret);\n\n\t\t\tif (payload && payload.session && payload.user) {\n\t\t\t\t// Validate version if provided\n\t\t\t\tif (config?.version) {\n\t\t\t\t\tconst cookieVersion = payload.version || \"1\";\n\t\t\t\t\tlet expectedVersion = \"1\";\n\t\t\t\t\tif (typeof config.version === \"string\") {\n\t\t\t\t\t\texpectedVersion = config.version;\n\t\t\t\t\t} else if (typeof config.version === \"function\") {\n\t\t\t\t\t\tconst result = config.version(payload.session, payload.user);\n\t\t\t\t\t\texpectedVersion = isPromise(result) ? await result : result;\n\t\t\t\t\t}\n\t\t\t\t\tif (cookieVersion !== expectedVersion) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn null;\n\t\t} else {\n\t\t\t// Use compact strategy (or legacy base64-hmac)\n\t\t\tconst sessionDataPayload = safeJSONParse<{\n\t\t\t\tsession: S;\n\t\t\t\texpiresAt: number;\n\t\t\t\tsignature: string;\n\t\t\t}>(binary.decode(base64Url.decode(sessionData)));\n\t\t\tif (!sessionDataPayload) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst isValid = await createHMAC(\"SHA-256\", \"base64urlnopad\").verify(\n\t\t\t\tsecret,\n\t\t\t\tJSON.stringify({\n\t\t\t\t\t...sessionDataPayload.session,\n\t\t\t\t\texpiresAt: sessionDataPayload.expiresAt,\n\t\t\t\t}),\n\t\t\t\tsessionDataPayload.signature,\n\t\t\t);\n\t\t\tif (!isValid) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Validate version if provided\n\t\t\tif (config?.version && sessionDataPayload.session) {\n\t\t\t\tconst cookieVersion = sessionDataPayload.session.version || \"1\";\n\t\t\t\tlet expectedVersion = \"1\";\n\t\t\t\tif (typeof config.version === \"string\") {\n\t\t\t\t\texpectedVersion = config.version;\n\t\t\t\t} else if (typeof config.version === \"function\") {\n\t\t\t\t\tconst result = config.version(\n\t\t\t\t\t\tsessionDataPayload.session.session,\n\t\t\t\t\t\tsessionDataPayload.session.user,\n\t\t\t\t\t);\n\t\t\t\t\texpectedVersion = isPromise(result) ? await result : result;\n\t\t\t\t}\n\t\t\t\tif (cookieVersion !== expectedVersion) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn sessionDataPayload.session;\n\t\t}\n\t}\n\treturn null;\n};\n\nexport * from \"./cookie-utils\";\nexport { createSessionStore, getChunkedCookie } from \"./session-store\";\n"],"mappings":"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"}
|
package/dist/db/field.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _better_auth_core36 from "@better-auth/core";
|
|
2
2
|
import { BetterAuthOptions } from "@better-auth/core";
|
|
3
|
-
import * as
|
|
3
|
+
import * as _better_auth_core_db16 from "@better-auth/core/db";
|
|
4
4
|
import { DBFieldAttribute, DBFieldAttributeConfig, DBFieldType } from "@better-auth/core/db";
|
|
5
5
|
import * as _standard_schema_spec0 from "@standard-schema/spec";
|
|
6
6
|
|
|
@@ -9,11 +9,11 @@ declare const createFieldAttribute: <T extends DBFieldType, C extends DBFieldAtt
|
|
|
9
9
|
required?: boolean | undefined;
|
|
10
10
|
returned?: boolean | undefined;
|
|
11
11
|
input?: boolean | undefined;
|
|
12
|
-
defaultValue?: (
|
|
13
|
-
onUpdate?: (() =>
|
|
12
|
+
defaultValue?: (_better_auth_core_db16.DBPrimitive | (() => _better_auth_core_db16.DBPrimitive)) | undefined;
|
|
13
|
+
onUpdate?: (() => _better_auth_core_db16.DBPrimitive) | undefined;
|
|
14
14
|
transform?: {
|
|
15
|
-
input?: (value:
|
|
16
|
-
output?: (value:
|
|
15
|
+
input?: (value: _better_auth_core_db16.DBPrimitive) => _better_auth_core36.Awaitable<_better_auth_core_db16.DBPrimitive>;
|
|
16
|
+
output?: (value: _better_auth_core_db16.DBPrimitive) => _better_auth_core36.Awaitable<_better_auth_core_db16.DBPrimitive>;
|
|
17
17
|
} | undefined;
|
|
18
18
|
references?: {
|
|
19
19
|
model: string;
|
|
@@ -45,10 +45,10 @@ type InferFieldOutput<T extends DBFieldAttribute> = T["returned"] extends false
|
|
|
45
45
|
*/
|
|
46
46
|
type FieldAttributeToObject<Fields extends Record<string, DBFieldAttribute>> = AddOptionalFields<{ [K in keyof Fields]: InferValueType<Fields[K]["type"]> }, Fields>;
|
|
47
47
|
type AddOptionalFields<T extends Record<string, any>, Fields extends Record<keyof T, DBFieldAttribute>> = { [K in keyof T as Fields[K] extends {
|
|
48
|
-
required:
|
|
49
|
-
} ?
|
|
50
|
-
required:
|
|
51
|
-
} ?
|
|
48
|
+
required: false;
|
|
49
|
+
} ? never : K]: T[K] } & { [K in keyof T as Fields[K] extends {
|
|
50
|
+
required: false;
|
|
51
|
+
} ? K : never]?: T[K] };
|
|
52
52
|
/**
|
|
53
53
|
* Infer the additional fields from the plugin options.
|
|
54
54
|
* For example, you can infer the additional fields of the org plugin's organization schema like this:
|
package/dist/db/field.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field.mjs","names":[],"sources":["../../src/db/field.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type {\n\tDBFieldAttribute,\n\tDBFieldAttributeConfig,\n\tDBFieldType,\n} from \"@better-auth/core/db\";\n\nexport const createFieldAttribute = <\n\tT extends DBFieldType,\n\tC extends DBFieldAttributeConfig,\n>(\n\ttype: T,\n\tconfig?: C | undefined,\n) => {\n\treturn {\n\t\ttype,\n\t\t...config,\n\t} satisfies DBFieldAttribute<T>;\n};\n\nexport type InferValueType<T extends DBFieldType> = T extends \"string\"\n\t? string\n\t: T extends \"number\"\n\t\t? number\n\t\t: T extends \"boolean\"\n\t\t\t? boolean\n\t\t\t: T extends \"date\"\n\t\t\t\t? Date\n\t\t\t\t: T extends \"json\"\n\t\t\t\t\t? Record<string, any>\n\t\t\t\t\t: T extends `${infer U}[]`\n\t\t\t\t\t\t? U extends \"string\"\n\t\t\t\t\t\t\t? string[]\n\t\t\t\t\t\t\t: number[]\n\t\t\t\t\t\t: T extends Array<any>\n\t\t\t\t\t\t\t? T[number]\n\t\t\t\t\t\t\t: never;\n\nexport type InferFieldsOutput<Field> =\n\tField extends Record<infer Key, DBFieldAttribute>\n\t\t? {\n\t\t\t\t[key in Key as Field[key][\"returned\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"required\"] extends false\n\t\t\t\t\t\t? Field[key][\"defaultValue\"] extends\n\t\t\t\t\t\t\t\t| boolean\n\t\t\t\t\t\t\t\t| string\n\t\t\t\t\t\t\t\t| number\n\t\t\t\t\t\t\t\t| Date\n\t\t\t\t\t\t\t? key\n\t\t\t\t\t\t\t: never\n\t\t\t\t\t\t: key]: InferFieldOutput<Field[key]>;\n\t\t\t} & {\n\t\t\t\t[key in Key as Field[key][\"returned\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"required\"] extends false\n\t\t\t\t\t\t? Field[key][\"defaultValue\"] extends\n\t\t\t\t\t\t\t\t| boolean\n\t\t\t\t\t\t\t\t| string\n\t\t\t\t\t\t\t\t| number\n\t\t\t\t\t\t\t\t| Date\n\t\t\t\t\t\t\t? never\n\t\t\t\t\t\t\t: key\n\t\t\t\t\t\t: never]?: InferFieldOutput<Field[key]> | null;\n\t\t\t}\n\t\t: {};\n\nexport type InferFieldsInput<Field> =\n\tField extends Record<infer Key, DBFieldAttribute>\n\t\t? {\n\t\t\t\t[key in Key as Field[key][\"required\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"defaultValue\"] extends string | number | boolean | Date\n\t\t\t\t\t\t? never\n\t\t\t\t\t\t: Field[key][\"input\"] extends false\n\t\t\t\t\t\t\t? never\n\t\t\t\t\t\t\t: key]: InferFieldInput<Field[key]>;\n\t\t\t} & {\n\t\t\t\t[key in Key as Field[key][\"input\"] extends false ? never : key]?:\n\t\t\t\t\t| InferFieldInput<Field[key]>\n\t\t\t\t\t| undefined\n\t\t\t\t\t| null;\n\t\t\t}\n\t\t: {};\n\n/**\n * For client will add \"?\" on optional fields\n */\nexport type InferFieldsInputClient<Field> =\n\tField extends Record<infer Key, DBFieldAttribute>\n\t\t? {\n\t\t\t\t[key in Key as Field[key][\"required\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"defaultValue\"] extends string | number | boolean | Date\n\t\t\t\t\t\t? never\n\t\t\t\t\t\t: Field[key][\"input\"] extends false\n\t\t\t\t\t\t\t? never\n\t\t\t\t\t\t\t: key]: InferFieldInput<Field[key]>;\n\t\t\t} & {\n\t\t\t\t[key in Key as Field[key][\"input\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"required\"] extends false\n\t\t\t\t\t\t? key\n\t\t\t\t\t\t: Field[key][\"defaultValue\"] extends\n\t\t\t\t\t\t\t\t\t| string\n\t\t\t\t\t\t\t\t\t| number\n\t\t\t\t\t\t\t\t\t| boolean\n\t\t\t\t\t\t\t\t\t| Date\n\t\t\t\t\t\t\t? key\n\t\t\t\t\t\t\t: never]?: InferFieldInput<Field[key]> | undefined | null;\n\t\t\t}\n\t\t: {};\n\ntype InferFieldOutput<T extends DBFieldAttribute> = T[\"returned\"] extends false\n\t? never\n\t: T[\"required\"] extends false\n\t\t? InferValueType<T[\"type\"]> | undefined | null\n\t\t: InferValueType<T[\"type\"]>;\n\n/**\n * Converts a Record<string, DBFieldAttribute> to an object type\n * with keys and value types inferred from DBFieldAttribute[\"type\"].\n */\nexport type FieldAttributeToObject<\n\tFields extends Record<string, DBFieldAttribute>,\n> = AddOptionalFields<\n\t{\n\t\t[K in keyof Fields]: InferValueType<Fields[K][\"type\"]>;\n\t},\n\tFields\n>;\n\ntype AddOptionalFields<\n\tT extends Record<string, any>,\n\tFields extends Record<keyof T, DBFieldAttribute>,\n> = {\n\t// Required fields: required
|
|
1
|
+
{"version":3,"file":"field.mjs","names":[],"sources":["../../src/db/field.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type {\n\tDBFieldAttribute,\n\tDBFieldAttributeConfig,\n\tDBFieldType,\n} from \"@better-auth/core/db\";\n\nexport const createFieldAttribute = <\n\tT extends DBFieldType,\n\tC extends DBFieldAttributeConfig,\n>(\n\ttype: T,\n\tconfig?: C | undefined,\n) => {\n\treturn {\n\t\ttype,\n\t\t...config,\n\t} satisfies DBFieldAttribute<T>;\n};\n\nexport type InferValueType<T extends DBFieldType> = T extends \"string\"\n\t? string\n\t: T extends \"number\"\n\t\t? number\n\t\t: T extends \"boolean\"\n\t\t\t? boolean\n\t\t\t: T extends \"date\"\n\t\t\t\t? Date\n\t\t\t\t: T extends \"json\"\n\t\t\t\t\t? Record<string, any>\n\t\t\t\t\t: T extends `${infer U}[]`\n\t\t\t\t\t\t? U extends \"string\"\n\t\t\t\t\t\t\t? string[]\n\t\t\t\t\t\t\t: number[]\n\t\t\t\t\t\t: T extends Array<any>\n\t\t\t\t\t\t\t? T[number]\n\t\t\t\t\t\t\t: never;\n\nexport type InferFieldsOutput<Field> =\n\tField extends Record<infer Key, DBFieldAttribute>\n\t\t? {\n\t\t\t\t[key in Key as Field[key][\"returned\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"required\"] extends false\n\t\t\t\t\t\t? Field[key][\"defaultValue\"] extends\n\t\t\t\t\t\t\t\t| boolean\n\t\t\t\t\t\t\t\t| string\n\t\t\t\t\t\t\t\t| number\n\t\t\t\t\t\t\t\t| Date\n\t\t\t\t\t\t\t? key\n\t\t\t\t\t\t\t: never\n\t\t\t\t\t\t: key]: InferFieldOutput<Field[key]>;\n\t\t\t} & {\n\t\t\t\t[key in Key as Field[key][\"returned\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"required\"] extends false\n\t\t\t\t\t\t? Field[key][\"defaultValue\"] extends\n\t\t\t\t\t\t\t\t| boolean\n\t\t\t\t\t\t\t\t| string\n\t\t\t\t\t\t\t\t| number\n\t\t\t\t\t\t\t\t| Date\n\t\t\t\t\t\t\t? never\n\t\t\t\t\t\t\t: key\n\t\t\t\t\t\t: never]?: InferFieldOutput<Field[key]> | null;\n\t\t\t}\n\t\t: {};\n\nexport type InferFieldsInput<Field> =\n\tField extends Record<infer Key, DBFieldAttribute>\n\t\t? {\n\t\t\t\t[key in Key as Field[key][\"required\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"defaultValue\"] extends string | number | boolean | Date\n\t\t\t\t\t\t? never\n\t\t\t\t\t\t: Field[key][\"input\"] extends false\n\t\t\t\t\t\t\t? never\n\t\t\t\t\t\t\t: key]: InferFieldInput<Field[key]>;\n\t\t\t} & {\n\t\t\t\t[key in Key as Field[key][\"input\"] extends false ? never : key]?:\n\t\t\t\t\t| InferFieldInput<Field[key]>\n\t\t\t\t\t| undefined\n\t\t\t\t\t| null;\n\t\t\t}\n\t\t: {};\n\n/**\n * For client will add \"?\" on optional fields\n */\nexport type InferFieldsInputClient<Field> =\n\tField extends Record<infer Key, DBFieldAttribute>\n\t\t? {\n\t\t\t\t[key in Key as Field[key][\"required\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"defaultValue\"] extends string | number | boolean | Date\n\t\t\t\t\t\t? never\n\t\t\t\t\t\t: Field[key][\"input\"] extends false\n\t\t\t\t\t\t\t? never\n\t\t\t\t\t\t\t: key]: InferFieldInput<Field[key]>;\n\t\t\t} & {\n\t\t\t\t[key in Key as Field[key][\"input\"] extends false\n\t\t\t\t\t? never\n\t\t\t\t\t: Field[key][\"required\"] extends false\n\t\t\t\t\t\t? key\n\t\t\t\t\t\t: Field[key][\"defaultValue\"] extends\n\t\t\t\t\t\t\t\t\t| string\n\t\t\t\t\t\t\t\t\t| number\n\t\t\t\t\t\t\t\t\t| boolean\n\t\t\t\t\t\t\t\t\t| Date\n\t\t\t\t\t\t\t? key\n\t\t\t\t\t\t\t: never]?: InferFieldInput<Field[key]> | undefined | null;\n\t\t\t}\n\t\t: {};\n\ntype InferFieldOutput<T extends DBFieldAttribute> = T[\"returned\"] extends false\n\t? never\n\t: T[\"required\"] extends false\n\t\t? InferValueType<T[\"type\"]> | undefined | null\n\t\t: InferValueType<T[\"type\"]>;\n\n/**\n * Converts a Record<string, DBFieldAttribute> to an object type\n * with keys and value types inferred from DBFieldAttribute[\"type\"].\n */\nexport type FieldAttributeToObject<\n\tFields extends Record<string, DBFieldAttribute>,\n> = AddOptionalFields<\n\t{\n\t\t[K in keyof Fields]: InferValueType<Fields[K][\"type\"]>;\n\t},\n\tFields\n>;\n\ntype AddOptionalFields<\n\tT extends Record<string, any>,\n\tFields extends Record<keyof T, DBFieldAttribute>,\n> = {\n\t// Required fields: required !== false\n\t[K in keyof T as Fields[K] extends { required: false } ? never : K]: T[K];\n} & {\n\t// Optional fields: required === false\n\t[K in keyof T as Fields[K] extends { required: false } ? K : never]?: T[K];\n};\n\n/**\n * Infer the additional fields from the plugin options.\n * For example, you can infer the additional fields of the org plugin's organization schema like this:\n * ```ts\n * type AdditionalFields = InferAdditionalFieldsFromPluginOptions<\"organization\", OrganizationOptions>\n * ```\n *\n * @param isClientSide - When `true` (default), filters out `input: false` fields (clients can't send these).\n * When `false`, includes all fields (for internal/server-side use).\n */\nexport type InferAdditionalFieldsFromPluginOptions<\n\tSchemaName extends string,\n\tOptions extends {\n\t\tschema?:\n\t\t\t| {\n\t\t\t\t\t[key in SchemaName]?: {\n\t\t\t\t\t\tadditionalFields?: Record<string, DBFieldAttribute>;\n\t\t\t\t\t};\n\t\t\t }\n\t\t\t| undefined;\n\t},\n\tisClientSide extends boolean = true,\n> = Options[\"schema\"] extends {\n\t[key in SchemaName]?: {\n\t\tadditionalFields: infer Field extends Record<string, DBFieldAttribute>;\n\t};\n}\n\t? isClientSide extends true\n\t\t? FieldAttributeToObject<RemoveFieldsWithInputFalse<Field>>\n\t\t: FieldAttributeToObject<Field>\n\t: {};\n\ntype RemoveFieldsWithInputFalse<T extends Record<string, DBFieldAttribute>> = {\n\t[K in keyof T as T[K][\"input\"] extends false ? never : K]: T[K];\n};\n\nexport type RemoveFieldsWithReturnedFalse<\n\tT extends Record<string, DBFieldAttribute>,\n> = {\n\t[K in keyof T as T[K][\"returned\"] extends false ? never : K]: T[K];\n};\n\ntype InferFieldInput<T extends DBFieldAttribute> = InferValueType<T[\"type\"]>;\n\nexport type PluginFieldAttribute = Omit<\n\tDBFieldAttribute,\n\t\"transform\" | \"defaultValue\" | \"hashValue\"\n>;\n\nexport type InferFieldsFromPlugins<\n\tOptions extends BetterAuthOptions,\n\tKey extends string,\n\tFormat extends \"output\" | \"input\",\n> = Options[\"plugins\"] extends []\n\t? {}\n\t: Options[\"plugins\"] extends Array<infer T>\n\t\t? T extends {\n\t\t\t\tschema: {\n\t\t\t\t\t[key in Key]: {\n\t\t\t\t\t\tfields: infer Field;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}\n\t\t\t? Format extends \"output\"\n\t\t\t\t? InferFieldsOutput<Field>\n\t\t\t\t: InferFieldsInput<Field>\n\t\t\t: {}\n\t\t: {};\n\nexport type InferFieldsFromOptions<\n\tOptions extends BetterAuthOptions,\n\tKey extends \"session\" | \"user\",\n\tFormat extends \"output\" | \"input\",\n> = Options[Key] extends {\n\tadditionalFields: infer Field;\n}\n\t? Format extends \"output\"\n\t\t? InferFieldsOutput<Field>\n\t\t: InferFieldsInput<Field>\n\t: {};\n"],"mappings":";AAOA,MAAa,wBAIZ,MACA,WACI;AACJ,QAAO;EACN;EACA,GAAG;EACH"}
|