@better-auth/core 1.6.22 → 1.6.24
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/api/index.d.mts +28 -28
- package/dist/async_hooks/index.d.mts +0 -1
- package/dist/async_hooks/pure.index.d.mts +0 -1
- package/dist/context/endpoint-context.d.mts +1 -1
- package/dist/context/global.d.mts +0 -1
- package/dist/context/global.mjs +1 -1
- package/dist/context/request-state.d.mts +0 -1
- package/dist/context/request-state.mjs +8 -5
- package/dist/context/transaction.d.mts +1 -1
- package/dist/db/adapter/factory.d.mts +3 -5
- package/dist/db/adapter/factory.mjs +1 -1
- package/dist/db/adapter/get-default-field-name.d.mts +2 -9
- package/dist/db/adapter/get-default-model-name.d.mts +1 -5
- package/dist/db/adapter/get-default-model-name.mjs +6 -5
- package/dist/db/adapter/get-field-attributes.d.mts +4 -11
- package/dist/db/adapter/get-field-name.d.mts +2 -9
- package/dist/db/adapter/get-id-field.d.mts +4 -12
- package/dist/db/adapter/get-model-name.d.mts +1 -5
- package/dist/db/adapter/index.d.mts +7 -32
- package/dist/db/adapter/types.d.mts +5 -17
- package/dist/db/adapter/utils.d.mts +0 -1
- package/dist/db/get-tables.d.mts +1 -0
- package/dist/db/get-tables.mjs +2 -2
- package/dist/db/plugin.d.mts +1 -2
- package/dist/db/schema/account.d.mts +1 -1
- package/dist/db/schema/account.mjs +12 -0
- package/dist/db/schema/rate-limit.d.mts +1 -1
- package/dist/db/schema/rate-limit.mjs +9 -0
- package/dist/db/schema/session.d.mts +1 -1
- package/dist/db/schema/shared.d.mts +0 -1
- package/dist/db/schema/user.d.mts +1 -1
- package/dist/db/schema/verification.d.mts +1 -1
- package/dist/db/type.d.mts +5 -8
- package/dist/env/logger.d.mts +25 -25
- package/dist/error/codes.d.mts +0 -1
- package/dist/error/index.d.mts +0 -1
- package/dist/index.d.mts +1 -1
- package/dist/instrumentation/attributes.d.mts +0 -1
- package/dist/instrumentation/pure.index.d.mts +0 -1
- package/dist/instrumentation/tracer.mjs +1 -1
- package/dist/oauth2/client-credentials-token.d.mts +4 -20
- package/dist/oauth2/client-credentials-token.mjs +1 -4
- package/dist/oauth2/create-authorization-url.d.mts +3 -20
- package/dist/oauth2/oauth-provider.d.mts +9 -3
- package/dist/oauth2/refresh-access-token.d.mts +4 -22
- package/dist/oauth2/refresh-access-token.mjs +2 -8
- package/dist/oauth2/reject-redirects.mjs +1 -1
- package/dist/oauth2/utils.d.mts +0 -1
- package/dist/oauth2/utils.mjs +1 -2
- package/dist/oauth2/validate-authorization-code.d.mts +6 -37
- package/dist/oauth2/verify.d.mts +12 -10
- package/dist/oauth2/verify.mjs +2 -2
- package/dist/social-providers/apple.d.mts +7 -28
- package/dist/social-providers/apple.mjs +2 -2
- package/dist/social-providers/atlassian.d.mts +3 -11
- package/dist/social-providers/cognito.d.mts +6 -12
- package/dist/social-providers/cognito.mjs +2 -2
- package/dist/social-providers/discord.d.mts +3 -9
- package/dist/social-providers/dropbox.d.mts +3 -11
- package/dist/social-providers/facebook.d.mts +6 -11
- package/dist/social-providers/facebook.mjs +2 -2
- package/dist/social-providers/figma.d.mts +3 -11
- package/dist/social-providers/github.d.mts +3 -12
- package/dist/social-providers/gitlab.d.mts +3 -12
- package/dist/social-providers/google.d.mts +7 -20
- package/dist/social-providers/google.mjs +2 -2
- package/dist/social-providers/huggingface.d.mts +3 -11
- package/dist/social-providers/index.d.mts +78 -362
- package/dist/social-providers/kakao.d.mts +3 -9
- package/dist/social-providers/kick.d.mts +3 -11
- package/dist/social-providers/line.d.mts +6 -13
- package/dist/social-providers/line.mjs +2 -2
- package/dist/social-providers/linear.d.mts +3 -10
- package/dist/social-providers/linkedin.d.mts +3 -10
- package/dist/social-providers/microsoft-entra-id.d.mts +5 -6
- package/dist/social-providers/microsoft-entra-id.mjs +4 -3
- package/dist/social-providers/naver.d.mts +22 -18
- package/dist/social-providers/notion.d.mts +3 -10
- package/dist/social-providers/paybin.d.mts +3 -12
- package/dist/social-providers/paypal.d.mts +6 -10
- package/dist/social-providers/paypal.mjs +2 -2
- package/dist/social-providers/polar.d.mts +3 -11
- package/dist/social-providers/railway.d.mts +3 -11
- package/dist/social-providers/reddit.d.mts +3 -9
- package/dist/social-providers/roblox.d.mts +3 -9
- package/dist/social-providers/salesforce.d.mts +3 -11
- package/dist/social-providers/slack.d.mts +3 -9
- package/dist/social-providers/spotify.d.mts +3 -11
- package/dist/social-providers/tiktok.d.mts +5 -10
- package/dist/social-providers/twitch.d.mts +3 -9
- package/dist/social-providers/twitter.d.mts +26 -17
- package/dist/social-providers/vercel.d.mts +3 -11
- package/dist/social-providers/vk.d.mts +3 -12
- package/dist/social-providers/vk.mjs +4 -5
- package/dist/social-providers/wechat.d.mts +3 -8
- package/dist/social-providers/zoom.d.mts +5 -14
- package/dist/types/context.d.mts +2 -1
- package/dist/types/cookie.d.mts +0 -1
- package/dist/types/helper.d.mts +1 -1
- package/dist/types/index.d.mts +1 -1
- package/dist/types/init-options.d.mts +10 -7
- package/dist/types/plugin-client.d.mts +1 -3
- package/dist/types/plugin.d.mts +2 -2
- package/dist/utils/async.d.mts +0 -1
- package/dist/utils/db.d.mts +1 -0
- package/dist/utils/deprecate.d.mts +0 -1
- package/dist/utils/error-codes.d.mts +2 -2
- package/dist/utils/host.d.mts +27 -1
- package/dist/utils/host.mjs +1 -1
- package/dist/utils/ip.d.mts +1 -0
- package/dist/utils/ip.mjs +1 -1
- package/dist/utils/is-api-error.d.mts +0 -1
- package/dist/utils/redirect-uri.d.mts +0 -1
- package/package.json +2 -2
- package/src/context/request-state.ts +26 -6
- package/src/db/adapter/get-default-model-name.ts +23 -14
- package/src/db/get-tables.ts +17 -2
- package/src/oauth2/oauth-provider.ts +20 -4
- package/src/social-providers/apple.ts +7 -2
- package/src/social-providers/cognito.ts +7 -2
- package/src/social-providers/facebook.ts +7 -2
- package/src/social-providers/google.ts +7 -2
- package/src/social-providers/line.ts +7 -2
- package/src/social-providers/microsoft-entra-id.ts +7 -2
- package/src/social-providers/paypal.ts +7 -2
|
@@ -20,26 +20,35 @@ export const initGetDefaultModelName = ({
|
|
|
20
20
|
* 3. Using this function helps us get the actual model name based on the user's defined custom modelName.
|
|
21
21
|
*/
|
|
22
22
|
const getDefaultModelName = (model: string) => {
|
|
23
|
+
// Resolve a model string (either a schema key or a user-defined
|
|
24
|
+
// `modelName`) back to its canonical schema key.
|
|
25
|
+
//
|
|
26
|
+
// An exact schema-key match must win over a `modelName` match.
|
|
27
|
+
// Better-auth internals (and `references.model`, see get-tables.ts)
|
|
28
|
+
// always pass canonical schema keys, so when a user remaps a
|
|
29
|
+
// built-in table onto another table's schema key (e.g.
|
|
30
|
+
// `user.modelName = "account"`), preferring the modelName alias
|
|
31
|
+
// would silently reroute every internal "account" query to the
|
|
32
|
+
// user table. The modelName lookup is only a fallback for
|
|
33
|
+
// externally supplied physical table names.
|
|
34
|
+
// @see https://github.com/better-auth/better-auth/issues/8111
|
|
35
|
+
// @see https://github.com/better-auth/better-auth/issues/10136
|
|
36
|
+
const resolve = (candidate: string): string | undefined => {
|
|
37
|
+
if (schema[candidate]) return candidate;
|
|
38
|
+
return Object.entries(schema).find(
|
|
39
|
+
([_, f]) => f.modelName === candidate,
|
|
40
|
+
)?.[0];
|
|
41
|
+
};
|
|
42
|
+
|
|
23
43
|
// It's possible this `model` could had applied `usePlural`.
|
|
24
44
|
// Thus we'll try the search but without the trailing `s`.
|
|
25
45
|
if (usePlural && model.charAt(model.length - 1) === "s") {
|
|
26
46
|
const pluralessModel = model.slice(0, -1);
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
m = Object.entries(schema).find(
|
|
30
|
-
([_, f]) => f.modelName === pluralessModel,
|
|
31
|
-
)?.[0];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (m) {
|
|
35
|
-
return m;
|
|
36
|
-
}
|
|
47
|
+
const m = resolve(pluralessModel);
|
|
48
|
+
if (m) return m;
|
|
37
49
|
}
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
if (!m) {
|
|
41
|
-
m = Object.entries(schema).find(([_, f]) => f.modelName === model)?.[0];
|
|
42
|
-
}
|
|
51
|
+
const m = resolve(model);
|
|
43
52
|
|
|
44
53
|
if (!m) {
|
|
45
54
|
throw new BetterAuthError(`Model "${model}" not found in schema`);
|
package/src/db/get-tables.ts
CHANGED
|
@@ -142,7 +142,18 @@ export const getAuthTables = (
|
|
|
142
142
|
type: "string",
|
|
143
143
|
fieldName: options.session?.fields?.userId || "userId",
|
|
144
144
|
references: {
|
|
145
|
-
|
|
145
|
+
// Use the canonical user schema key here rather than
|
|
146
|
+
// `options.user.modelName`. Downstream consumers (e.g.
|
|
147
|
+
// `getSchema`, `getMigrations`, and the runtime adapter
|
|
148
|
+
// resolvers) treat `references.model` as a schema key
|
|
149
|
+
// and look it up via `tables[references.model]` /
|
|
150
|
+
// `getDefaultModelName`. Writing the modelName alias
|
|
151
|
+
// here would collide when a user picks a modelName that
|
|
152
|
+
// matches another schema key (for example
|
|
153
|
+
// `user.modelName = "account"`), causing the FK to
|
|
154
|
+
// resolve to the wrong table.
|
|
155
|
+
// @see https://github.com/better-auth/better-auth/issues/8111
|
|
156
|
+
model: "user",
|
|
146
157
|
field: "id",
|
|
147
158
|
onDelete: "cascade",
|
|
148
159
|
},
|
|
@@ -225,7 +236,11 @@ export const getAuthTables = (
|
|
|
225
236
|
userId: {
|
|
226
237
|
type: "string",
|
|
227
238
|
references: {
|
|
228
|
-
|
|
239
|
+
// See note on `session.userId.references.model` above:
|
|
240
|
+
// always use the canonical user schema key so the FK
|
|
241
|
+
// target survives `user.modelName` aliasing.
|
|
242
|
+
// @see https://github.com/better-auth/better-auth/issues/8111
|
|
243
|
+
model: "user",
|
|
229
244
|
field: "id",
|
|
230
245
|
onDelete: "cascade",
|
|
231
246
|
},
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Awaitable,
|
|
3
|
+
GenericEndpointContext,
|
|
4
|
+
LiteralString,
|
|
5
|
+
} from "../types";
|
|
2
6
|
|
|
3
7
|
export interface OAuth2Tokens {
|
|
4
8
|
tokenType?: string | undefined;
|
|
@@ -74,10 +78,15 @@ export interface OAuthProvider<
|
|
|
74
78
|
* Verify the id token
|
|
75
79
|
* @param token - The id token
|
|
76
80
|
* @param nonce - The nonce
|
|
81
|
+
* @param ctx - Request endpoint context (headers via `ctx.headers`)
|
|
77
82
|
* @returns True if the id token is valid, false otherwise
|
|
78
83
|
*/
|
|
79
84
|
verifyIdToken?:
|
|
80
|
-
| ((
|
|
85
|
+
| ((
|
|
86
|
+
token: string,
|
|
87
|
+
nonce?: string,
|
|
88
|
+
ctx?: GenericEndpointContext,
|
|
89
|
+
) => Promise<boolean>)
|
|
81
90
|
| undefined;
|
|
82
91
|
/**
|
|
83
92
|
* Disable implicit sign up for new users. When set to true for the provider,
|
|
@@ -137,10 +146,17 @@ export type ProviderOptions<Profile extends Record<string, any> = any> = {
|
|
|
137
146
|
*/
|
|
138
147
|
disableIdTokenSignIn?: boolean | undefined;
|
|
139
148
|
/**
|
|
140
|
-
*
|
|
149
|
+
* Custom function to verify the id token.
|
|
150
|
+
* @param token - The id token
|
|
151
|
+
* @param nonce - The nonce
|
|
152
|
+
* @param ctx - Request endpoint context (headers via `ctx.headers`)
|
|
141
153
|
*/
|
|
142
154
|
verifyIdToken?:
|
|
143
|
-
| ((
|
|
155
|
+
| ((
|
|
156
|
+
token: string,
|
|
157
|
+
nonce?: string,
|
|
158
|
+
ctx?: GenericEndpointContext,
|
|
159
|
+
) => Promise<boolean>)
|
|
144
160
|
| undefined;
|
|
145
161
|
/**
|
|
146
162
|
* Custom function to get user info from the provider
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
refreshAccessToken,
|
|
11
11
|
validateAuthorizationCode,
|
|
12
12
|
} from "../oauth2";
|
|
13
|
+
import type { GenericEndpointContext } from "../types";
|
|
13
14
|
export interface AppleProfile {
|
|
14
15
|
/**
|
|
15
16
|
* The subject registered claim identifies the principal that’s the subject
|
|
@@ -131,12 +132,16 @@ export const apple = (options: AppleOptions) => {
|
|
|
131
132
|
tokenEndpoint,
|
|
132
133
|
});
|
|
133
134
|
},
|
|
134
|
-
async verifyIdToken(
|
|
135
|
+
async verifyIdToken(
|
|
136
|
+
token: string,
|
|
137
|
+
nonce?: string,
|
|
138
|
+
ctx?: GenericEndpointContext,
|
|
139
|
+
) {
|
|
135
140
|
if (options.disableIdTokenSignIn) {
|
|
136
141
|
return false;
|
|
137
142
|
}
|
|
138
143
|
if (options.verifyIdToken) {
|
|
139
|
-
return options.verifyIdToken(token, nonce);
|
|
144
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
140
145
|
}
|
|
141
146
|
try {
|
|
142
147
|
const decodedHeader = decodeProtectedHeader(token);
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
refreshAccessToken,
|
|
10
10
|
validateAuthorizationCode,
|
|
11
11
|
} from "../oauth2";
|
|
12
|
+
import type { GenericEndpointContext } from "../types";
|
|
12
13
|
|
|
13
14
|
export interface CognitoProfile {
|
|
14
15
|
sub: string;
|
|
@@ -130,12 +131,16 @@ export const cognito = (options: CognitoOptions) => {
|
|
|
130
131
|
});
|
|
131
132
|
},
|
|
132
133
|
|
|
133
|
-
async verifyIdToken(
|
|
134
|
+
async verifyIdToken(
|
|
135
|
+
token: string,
|
|
136
|
+
nonce?: string,
|
|
137
|
+
ctx?: GenericEndpointContext,
|
|
138
|
+
) {
|
|
134
139
|
if (options.disableIdTokenSignIn) {
|
|
135
140
|
return false;
|
|
136
141
|
}
|
|
137
142
|
if (options.verifyIdToken) {
|
|
138
|
-
return options.verifyIdToken(token, nonce);
|
|
143
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
139
144
|
}
|
|
140
145
|
|
|
141
146
|
try {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
refreshAccessToken,
|
|
10
10
|
validateAuthorizationCode,
|
|
11
11
|
} from "../oauth2";
|
|
12
|
+
import type { GenericEndpointContext } from "../types";
|
|
12
13
|
export interface FacebookProfile {
|
|
13
14
|
id: string;
|
|
14
15
|
name: string;
|
|
@@ -130,13 +131,17 @@ export const facebook = (options: FacebookOptions) => {
|
|
|
130
131
|
tokenEndpoint: "https://graph.facebook.com/v24.0/oauth/access_token",
|
|
131
132
|
});
|
|
132
133
|
},
|
|
133
|
-
async verifyIdToken(
|
|
134
|
+
async verifyIdToken(
|
|
135
|
+
token: string,
|
|
136
|
+
nonce?: string,
|
|
137
|
+
ctx?: GenericEndpointContext,
|
|
138
|
+
) {
|
|
134
139
|
if (options.disableIdTokenSignIn) {
|
|
135
140
|
return false;
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
if (options.verifyIdToken) {
|
|
139
|
-
return options.verifyIdToken(token, nonce);
|
|
144
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
140
145
|
}
|
|
141
146
|
|
|
142
147
|
/* limited login */
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
refreshAccessToken,
|
|
11
11
|
validateAuthorizationCode,
|
|
12
12
|
} from "../oauth2";
|
|
13
|
+
import type { GenericEndpointContext } from "../types";
|
|
13
14
|
|
|
14
15
|
export interface GoogleProfile {
|
|
15
16
|
aud: string;
|
|
@@ -181,12 +182,16 @@ export const google = (options: GoogleOptions) => {
|
|
|
181
182
|
tokenEndpoint: "https://oauth2.googleapis.com/token",
|
|
182
183
|
});
|
|
183
184
|
},
|
|
184
|
-
async verifyIdToken(
|
|
185
|
+
async verifyIdToken(
|
|
186
|
+
token: string,
|
|
187
|
+
nonce?: string,
|
|
188
|
+
ctx?: GenericEndpointContext,
|
|
189
|
+
) {
|
|
185
190
|
if (options.disableIdTokenSignIn) {
|
|
186
191
|
return false;
|
|
187
192
|
}
|
|
188
193
|
if (options.verifyIdToken) {
|
|
189
|
-
return options.verifyIdToken(token, nonce);
|
|
194
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
const jwtClaims = await verifyGoogleIdToken({
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
refreshAccessToken,
|
|
7
7
|
validateAuthorizationCode,
|
|
8
8
|
} from "../oauth2";
|
|
9
|
+
import type { GenericEndpointContext } from "../types";
|
|
9
10
|
|
|
10
11
|
export interface LineIdTokenPayload {
|
|
11
12
|
iss: string;
|
|
@@ -94,12 +95,16 @@ export const line = (options: LineOptions) => {
|
|
|
94
95
|
tokenEndpoint,
|
|
95
96
|
});
|
|
96
97
|
},
|
|
97
|
-
async verifyIdToken(
|
|
98
|
+
async verifyIdToken(
|
|
99
|
+
token: string,
|
|
100
|
+
nonce?: string,
|
|
101
|
+
ctx?: GenericEndpointContext,
|
|
102
|
+
) {
|
|
98
103
|
if (options.disableIdTokenSignIn) {
|
|
99
104
|
return false;
|
|
100
105
|
}
|
|
101
106
|
if (options.verifyIdToken) {
|
|
102
|
-
return options.verifyIdToken(token, nonce);
|
|
107
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
103
108
|
}
|
|
104
109
|
const body = new URLSearchParams();
|
|
105
110
|
body.set("id_token", token);
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
refreshAccessToken,
|
|
11
11
|
validateAuthorizationCode,
|
|
12
12
|
} from "../oauth2";
|
|
13
|
+
import type { GenericEndpointContext } from "../types";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Microsoft's fixed tenant id for personal (consumer) Microsoft accounts. Every
|
|
@@ -200,12 +201,16 @@ export const microsoft = (options: MicrosoftOptions) => {
|
|
|
200
201
|
tokenEndpoint,
|
|
201
202
|
});
|
|
202
203
|
},
|
|
203
|
-
async verifyIdToken(
|
|
204
|
+
async verifyIdToken(
|
|
205
|
+
token: string,
|
|
206
|
+
nonce?: string,
|
|
207
|
+
ctx?: GenericEndpointContext,
|
|
208
|
+
) {
|
|
204
209
|
if (options.disableIdTokenSignIn) {
|
|
205
210
|
return false;
|
|
206
211
|
}
|
|
207
212
|
if (options.verifyIdToken) {
|
|
208
|
-
return options.verifyIdToken(token, nonce);
|
|
213
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
209
214
|
}
|
|
210
215
|
|
|
211
216
|
try {
|
|
@@ -5,6 +5,7 @@ import { logger } from "../env";
|
|
|
5
5
|
import { APIError, BetterAuthError } from "../error";
|
|
6
6
|
import type { OAuthProvider, ProviderOptions } from "../oauth2";
|
|
7
7
|
import { createAuthorizationURL } from "../oauth2";
|
|
8
|
+
import type { GenericEndpointContext } from "../types";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* ID token signing algorithms advertised by PayPal's OpenID configuration.
|
|
@@ -217,12 +218,16 @@ export const paypal = (options: PayPalOptions) => {
|
|
|
217
218
|
}
|
|
218
219
|
},
|
|
219
220
|
|
|
220
|
-
async verifyIdToken(
|
|
221
|
+
async verifyIdToken(
|
|
222
|
+
token: string,
|
|
223
|
+
nonce?: string,
|
|
224
|
+
ctx?: GenericEndpointContext,
|
|
225
|
+
) {
|
|
221
226
|
if (options.disableIdTokenSignIn) {
|
|
222
227
|
return false;
|
|
223
228
|
}
|
|
224
229
|
if (options.verifyIdToken) {
|
|
225
|
-
return options.verifyIdToken(token, nonce);
|
|
230
|
+
return options.verifyIdToken(token, nonce, ctx);
|
|
226
231
|
}
|
|
227
232
|
|
|
228
233
|
// Cryptographically verify the ID token. Decoding alone is not enough:
|