@better-auth/core 1.5.0-beta.8 → 1.5.0
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/README.md +17 -0
- package/dist/api/index.d.mts +144 -41
- package/dist/api/index.mjs +2 -1
- package/dist/api/index.mjs.map +1 -0
- package/dist/async_hooks/index.d.mts +2 -1
- package/dist/async_hooks/index.mjs +2 -1
- package/dist/async_hooks/index.mjs.map +1 -0
- package/dist/async_hooks/pure.index.d.mts +2 -1
- package/dist/async_hooks/pure.index.mjs +2 -1
- package/dist/async_hooks/pure.index.mjs.map +1 -0
- package/dist/context/endpoint-context.d.mts +2 -1
- package/dist/context/endpoint-context.mjs +4 -3
- package/dist/context/endpoint-context.mjs.map +1 -0
- package/dist/context/global.d.mts +2 -2
- package/dist/context/global.mjs +3 -2
- package/dist/context/global.mjs.map +1 -0
- package/dist/context/index.d.mts +2 -2
- package/dist/context/index.mjs +2 -2
- package/dist/context/request-state.d.mts +2 -1
- package/dist/context/request-state.mjs +4 -3
- package/dist/context/request-state.mjs.map +1 -0
- package/dist/context/transaction.d.mts +12 -3
- package/dist/context/transaction.mjs +55 -11
- package/dist/context/transaction.mjs.map +1 -0
- package/dist/db/adapter/factory.d.mts +6 -13
- package/dist/db/adapter/factory.mjs +44 -57
- package/dist/db/adapter/factory.mjs.map +1 -0
- package/dist/db/adapter/get-default-field-name.d.mts +2 -1
- package/dist/db/adapter/get-default-field-name.mjs +3 -2
- package/dist/db/adapter/get-default-field-name.mjs.map +1 -0
- package/dist/db/adapter/get-default-model-name.d.mts +2 -1
- package/dist/db/adapter/get-default-model-name.mjs +5 -4
- package/dist/db/adapter/get-default-model-name.mjs.map +1 -0
- package/dist/db/adapter/get-field-attributes.d.mts +3 -2
- package/dist/db/adapter/get-field-attributes.mjs +2 -1
- package/dist/db/adapter/get-field-attributes.mjs.map +1 -0
- package/dist/db/adapter/get-field-name.d.mts +2 -1
- package/dist/db/adapter/get-field-name.mjs +2 -1
- package/dist/db/adapter/get-field-name.mjs.map +1 -0
- package/dist/db/adapter/get-id-field.d.mts +3 -2
- package/dist/db/adapter/get-id-field.mjs +3 -2
- package/dist/db/adapter/get-id-field.mjs.map +1 -0
- package/dist/db/adapter/get-model-name.d.mts +2 -1
- package/dist/db/adapter/get-model-name.mjs +2 -1
- package/dist/db/adapter/get-model-name.mjs.map +1 -0
- package/dist/db/adapter/index.d.mts +10 -4
- package/dist/db/adapter/index.mjs +19 -2
- package/dist/db/adapter/index.mjs.map +1 -0
- package/dist/db/adapter/types.d.mts +3 -34
- package/dist/db/adapter/utils.d.mts +2 -1
- package/dist/db/adapter/utils.mjs +2 -1
- package/dist/db/adapter/utils.mjs.map +1 -0
- package/dist/db/get-tables.d.mts +2 -1
- package/dist/db/get-tables.mjs +46 -39
- package/dist/db/get-tables.mjs.map +1 -0
- package/dist/db/index.d.mts +7 -7
- package/dist/db/plugin.d.mts +2 -1
- package/dist/db/schema/account.d.mts +8 -4
- package/dist/db/schema/account.mjs +2 -1
- package/dist/db/schema/account.mjs.map +1 -0
- package/dist/db/schema/rate-limit.d.mts +8 -2
- package/dist/db/schema/rate-limit.mjs +2 -1
- package/dist/db/schema/rate-limit.mjs.map +1 -0
- package/dist/db/schema/session.d.mts +8 -4
- package/dist/db/schema/session.mjs +2 -1
- package/dist/db/schema/session.mjs.map +1 -0
- package/dist/db/schema/shared.d.mts +2 -1
- package/dist/db/schema/shared.mjs +2 -1
- package/dist/db/schema/shared.mjs.map +1 -0
- package/dist/db/schema/user.d.mts +8 -4
- package/dist/db/schema/user.mjs +2 -1
- package/dist/db/schema/user.mjs.map +1 -0
- package/dist/db/schema/verification.d.mts +8 -4
- package/dist/db/schema/verification.mjs +2 -1
- package/dist/db/schema/verification.mjs.map +1 -0
- package/dist/db/type.d.mts +28 -2
- package/dist/env/color-depth.d.mts +2 -1
- package/dist/env/color-depth.mjs +2 -1
- package/dist/env/color-depth.mjs.map +1 -0
- package/dist/env/env-impl.d.mts +3 -2
- package/dist/env/env-impl.mjs +9 -8
- package/dist/env/env-impl.mjs.map +1 -0
- package/dist/env/logger.d.mts +2 -1
- package/dist/env/logger.mjs +3 -2
- package/dist/env/logger.mjs.map +1 -0
- package/dist/error/codes.d.mts +64 -181
- package/dist/error/codes.mjs +6 -2
- package/dist/error/codes.mjs.map +1 -0
- package/dist/error/index.d.mts +2 -1
- package/dist/error/index.mjs +2 -1
- package/dist/error/index.mjs.map +1 -0
- package/dist/index.d.mts +5 -4
- package/dist/oauth2/client-credentials-token.d.mts +25 -3
- package/dist/oauth2/client-credentials-token.mjs +15 -2
- package/dist/oauth2/client-credentials-token.mjs.map +1 -0
- package/dist/oauth2/create-authorization-url.d.mts +5 -2
- package/dist/oauth2/create-authorization-url.mjs +3 -1
- package/dist/oauth2/create-authorization-url.mjs.map +1 -0
- package/dist/oauth2/index.d.mts +4 -4
- package/dist/oauth2/index.mjs +4 -4
- package/dist/oauth2/oauth-provider.d.mts +3 -2
- package/dist/oauth2/refresh-access-token.d.mts +24 -4
- package/dist/oauth2/refresh-access-token.mjs +20 -2
- package/dist/oauth2/refresh-access-token.mjs.map +1 -0
- package/dist/oauth2/utils.d.mts +2 -1
- package/dist/oauth2/utils.mjs +2 -1
- package/dist/oauth2/utils.mjs.map +1 -0
- package/dist/oauth2/validate-authorization-code.d.mts +37 -4
- package/dist/oauth2/validate-authorization-code.mjs +25 -13
- package/dist/oauth2/validate-authorization-code.mjs.map +1 -0
- package/dist/oauth2/verify.d.mts +7 -13
- package/dist/oauth2/verify.mjs +2 -1
- package/dist/oauth2/verify.mjs.map +1 -0
- package/dist/social-providers/apple.d.mts +2 -1
- package/dist/social-providers/apple.mjs +22 -21
- package/dist/social-providers/apple.mjs.map +1 -0
- package/dist/social-providers/atlassian.d.mts +2 -1
- package/dist/social-providers/atlassian.mjs +2 -1
- package/dist/social-providers/atlassian.mjs.map +1 -0
- package/dist/social-providers/cognito.d.mts +2 -1
- package/dist/social-providers/cognito.mjs +4 -3
- package/dist/social-providers/cognito.mjs.map +1 -0
- package/dist/social-providers/discord.d.mts +2 -1
- package/dist/social-providers/discord.mjs +2 -1
- package/dist/social-providers/discord.mjs.map +1 -0
- package/dist/social-providers/dropbox.d.mts +2 -1
- package/dist/social-providers/dropbox.mjs +3 -2
- package/dist/social-providers/dropbox.mjs.map +1 -0
- package/dist/social-providers/facebook.d.mts +2 -1
- package/dist/social-providers/facebook.mjs +13 -12
- package/dist/social-providers/facebook.mjs.map +1 -0
- package/dist/social-providers/figma.d.mts +2 -1
- package/dist/social-providers/figma.mjs +2 -1
- package/dist/social-providers/figma.mjs.map +1 -0
- package/dist/social-providers/github.d.mts +3 -2
- package/dist/social-providers/github.mjs +23 -6
- package/dist/social-providers/github.mjs.map +1 -0
- package/dist/social-providers/gitlab.d.mts +2 -1
- package/dist/social-providers/gitlab.mjs +3 -2
- package/dist/social-providers/gitlab.mjs.map +1 -0
- package/dist/social-providers/google.d.mts +2 -1
- package/dist/social-providers/google.mjs +18 -13
- package/dist/social-providers/google.mjs.map +1 -0
- package/dist/social-providers/huggingface.d.mts +2 -1
- package/dist/social-providers/huggingface.mjs +3 -2
- package/dist/social-providers/huggingface.mjs.map +1 -0
- package/dist/social-providers/index.d.mts +61 -8
- package/dist/social-providers/index.mjs +5 -2
- package/dist/social-providers/index.mjs.map +1 -0
- package/dist/social-providers/kakao.d.mts +3 -2
- package/dist/social-providers/kakao.mjs +3 -2
- package/dist/social-providers/kakao.mjs.map +1 -0
- package/dist/social-providers/kick.d.mts +2 -1
- package/dist/social-providers/kick.mjs +2 -1
- package/dist/social-providers/kick.mjs.map +1 -0
- package/dist/social-providers/line.d.mts +2 -1
- package/dist/social-providers/line.mjs +3 -2
- package/dist/social-providers/line.mjs.map +1 -0
- package/dist/social-providers/linear.d.mts +2 -1
- package/dist/social-providers/linear.mjs +2 -1
- package/dist/social-providers/linear.mjs.map +1 -0
- package/dist/social-providers/linkedin.d.mts +2 -1
- package/dist/social-providers/linkedin.mjs +2 -1
- package/dist/social-providers/linkedin.mjs.map +1 -0
- package/dist/social-providers/microsoft-entra-id.d.mts +4 -1
- package/dist/social-providers/microsoft-entra-id.mjs +36 -2
- package/dist/social-providers/microsoft-entra-id.mjs.map +1 -0
- package/dist/social-providers/naver.d.mts +11 -20
- package/dist/social-providers/naver.mjs +3 -2
- package/dist/social-providers/naver.mjs.map +1 -0
- package/dist/social-providers/notion.d.mts +2 -1
- package/dist/social-providers/notion.mjs +3 -2
- package/dist/social-providers/notion.mjs.map +1 -0
- package/dist/social-providers/paybin.d.mts +2 -1
- package/dist/social-providers/paybin.mjs +3 -2
- package/dist/social-providers/paybin.mjs.map +1 -0
- package/dist/social-providers/paypal.d.mts +2 -1
- package/dist/social-providers/paypal.mjs +2 -1
- package/dist/social-providers/paypal.mjs.map +1 -0
- package/dist/social-providers/polar.d.mts +2 -1
- package/dist/social-providers/polar.mjs +3 -2
- package/dist/social-providers/polar.mjs.map +1 -0
- package/dist/social-providers/railway.d.mts +68 -0
- package/dist/social-providers/railway.mjs +78 -0
- package/dist/social-providers/railway.mjs.map +1 -0
- package/dist/social-providers/reddit.d.mts +2 -1
- package/dist/social-providers/reddit.mjs +2 -1
- package/dist/social-providers/reddit.mjs.map +1 -0
- package/dist/social-providers/roblox.d.mts +2 -1
- package/dist/social-providers/roblox.mjs +2 -1
- package/dist/social-providers/roblox.mjs.map +1 -0
- package/dist/social-providers/salesforce.d.mts +2 -1
- package/dist/social-providers/salesforce.mjs +2 -1
- package/dist/social-providers/salesforce.mjs.map +1 -0
- package/dist/social-providers/slack.d.mts +2 -1
- package/dist/social-providers/slack.mjs +2 -1
- package/dist/social-providers/slack.mjs.map +1 -0
- package/dist/social-providers/spotify.d.mts +2 -1
- package/dist/social-providers/spotify.mjs +2 -1
- package/dist/social-providers/spotify.mjs.map +1 -0
- package/dist/social-providers/tiktok.d.mts +3 -3
- package/dist/social-providers/tiktok.mjs +3 -2
- package/dist/social-providers/tiktok.mjs.map +1 -0
- package/dist/social-providers/twitch.d.mts +2 -1
- package/dist/social-providers/twitch.mjs +2 -1
- package/dist/social-providers/twitch.mjs.map +1 -0
- package/dist/social-providers/twitter.d.mts +14 -25
- package/dist/social-providers/twitter.mjs +2 -1
- package/dist/social-providers/twitter.mjs.map +1 -0
- package/dist/social-providers/vercel.d.mts +2 -1
- package/dist/social-providers/vercel.mjs +3 -2
- package/dist/social-providers/vercel.mjs.map +1 -0
- package/dist/social-providers/vk.d.mts +2 -1
- package/dist/social-providers/vk.mjs +2 -1
- package/dist/social-providers/vk.mjs.map +1 -0
- package/dist/social-providers/zoom.d.mts +3 -10
- package/dist/social-providers/zoom.mjs +2 -1
- package/dist/social-providers/zoom.mjs.map +1 -0
- package/dist/types/context.d.mts +54 -21
- package/dist/types/cookie.d.mts +2 -1
- package/dist/types/helper.d.mts +4 -1
- package/dist/types/index.d.mts +4 -3
- package/dist/types/init-options.d.mts +235 -144
- package/dist/types/plugin-client.d.mts +4 -1
- package/dist/types/plugin.d.mts +12 -11
- package/dist/types/secret.d.mts +12 -0
- package/dist/utils/db.d.mts +12 -0
- package/dist/utils/db.mjs +17 -0
- package/dist/utils/db.mjs.map +1 -0
- package/dist/utils/deprecate.d.mts +2 -2
- package/dist/utils/deprecate.mjs +2 -1
- package/dist/utils/deprecate.mjs.map +1 -0
- package/dist/utils/error-codes.d.mts +8 -6
- package/dist/utils/error-codes.mjs +3 -2
- package/dist/utils/error-codes.mjs.map +1 -0
- package/dist/utils/id.d.mts +2 -1
- package/dist/utils/id.mjs +2 -1
- package/dist/utils/id.mjs.map +1 -0
- package/dist/utils/ip.d.mts +55 -0
- package/dist/utils/ip.mjs +119 -0
- package/dist/utils/ip.mjs.map +1 -0
- package/dist/utils/json.d.mts +2 -1
- package/dist/utils/json.mjs +2 -1
- package/dist/utils/json.mjs.map +1 -0
- package/dist/utils/string.d.mts +2 -1
- package/dist/utils/string.mjs +2 -1
- package/dist/utils/string.mjs.map +1 -0
- package/dist/utils/url.d.mts +2 -1
- package/dist/utils/url.mjs +2 -1
- package/dist/utils/url.mjs.map +1 -0
- package/package.json +35 -13
- package/src/context/index.ts +1 -0
- package/src/context/transaction.ts +72 -9
- package/src/db/adapter/factory.ts +41 -73
- package/src/db/adapter/get-id-field.ts +1 -3
- package/src/db/adapter/index.ts +20 -15
- package/src/db/adapter/types.ts +2 -41
- package/src/db/get-tables.ts +48 -37
- package/src/db/index.ts +30 -5
- package/src/db/schema/account.ts +16 -3
- package/src/db/schema/rate-limit.ts +16 -1
- package/src/db/schema/session.ts +15 -3
- package/src/db/schema/user.ts +15 -3
- package/src/db/schema/verification.ts +16 -3
- package/src/db/test/get-tables.test.ts +33 -0
- package/src/db/type.ts +154 -1
- package/src/env/env-impl.ts +2 -2
- package/src/env/logger.ts +1 -1
- package/src/error/codes.ts +17 -0
- package/src/oauth2/client-credentials-token.ts +26 -2
- package/src/oauth2/create-authorization-url.ts +3 -1
- package/src/oauth2/index.ts +3 -0
- package/src/oauth2/oauth-provider.ts +1 -1
- package/src/oauth2/refresh-access-token.test.ts +90 -0
- package/src/oauth2/refresh-access-token.ts +37 -4
- package/src/oauth2/validate-authorization-code.ts +55 -29
- package/src/oauth2/validate-token.test.ts +229 -0
- package/src/social-providers/apple.ts +29 -29
- package/src/social-providers/cognito.ts +6 -5
- package/src/social-providers/dropbox.ts +1 -1
- package/src/social-providers/facebook.ts +3 -3
- package/src/social-providers/github.ts +26 -4
- package/src/social-providers/gitlab.ts +1 -1
- package/src/social-providers/google.ts +18 -14
- package/src/social-providers/huggingface.ts +1 -1
- package/src/social-providers/index.ts +9 -5
- package/src/social-providers/kakao.ts +1 -1
- package/src/social-providers/line.ts +1 -1
- package/src/social-providers/microsoft-entra-id.ts +84 -1
- package/src/social-providers/naver.ts +1 -1
- package/src/social-providers/notion.ts +1 -1
- package/src/social-providers/paybin.ts +1 -5
- package/src/social-providers/polar.ts +1 -1
- package/src/social-providers/railway.ts +100 -0
- package/src/social-providers/tiktok.ts +2 -1
- package/src/social-providers/vercel.ts +1 -1
- package/src/social-providers/zoom.ts +0 -8
- package/src/types/context.ts +79 -15
- package/src/types/helper.ts +9 -0
- package/src/types/index.ts +14 -2
- package/src/types/init-options.ts +298 -171
- package/src/types/plugin-client.ts +1 -0
- package/src/types/plugin.ts +11 -6
- package/src/types/secret.ts +8 -0
- package/src/utils/db.ts +20 -0
- package/src/utils/deprecate.test.ts +0 -1
- package/src/utils/error-codes.ts +12 -9
- package/src/utils/ip.test.ts +255 -0
- package/src/utils/ip.ts +211 -0
- package/.turbo/turbo-build.log +0 -180
- package/tsconfig.json +0 -7
- package/tsdown.config.ts +0 -32
- package/vitest.config.ts +0 -3
|
@@ -80,4 +80,37 @@ describe("getAuthTables", () => {
|
|
|
80
80
|
expect(newField.fieldName).toBe("new_field");
|
|
81
81
|
expect(newField.type).toBe("string");
|
|
82
82
|
});
|
|
83
|
+
|
|
84
|
+
it("should exclude verification table when secondaryStorage is configured", () => {
|
|
85
|
+
const tables = getAuthTables({
|
|
86
|
+
secondaryStorage: {
|
|
87
|
+
get: async () => null,
|
|
88
|
+
set: async () => {},
|
|
89
|
+
delete: async () => {},
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
expect(tables.verification).toBeUndefined();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("should include verification table when storeInDatabase is true", () => {
|
|
97
|
+
const tables = getAuthTables({
|
|
98
|
+
secondaryStorage: {
|
|
99
|
+
get: async () => null,
|
|
100
|
+
set: async () => {},
|
|
101
|
+
delete: async () => {},
|
|
102
|
+
},
|
|
103
|
+
verification: {
|
|
104
|
+
storeInDatabase: true,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
expect(tables.verification).toBeDefined();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("should include verification table when no secondaryStorage", () => {
|
|
112
|
+
const tables = getAuthTables({});
|
|
113
|
+
|
|
114
|
+
expect(tables.verification).toBeDefined();
|
|
115
|
+
});
|
|
83
116
|
});
|
package/src/db/type.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
Awaitable,
|
|
4
|
+
BetterAuthOptions,
|
|
5
|
+
LiteralString,
|
|
6
|
+
UnionToIntersection,
|
|
7
|
+
} from "../types";
|
|
3
8
|
|
|
4
9
|
export type BaseModelNames = "user" | "account" | "session" | "verification";
|
|
5
10
|
|
|
@@ -8,6 +13,154 @@ export type ModelNames<T extends string = LiteralString> =
|
|
|
8
13
|
| T
|
|
9
14
|
| "rate-limit";
|
|
10
15
|
|
|
16
|
+
export type InferDBValueType<T extends DBFieldType> = T extends "string"
|
|
17
|
+
? string
|
|
18
|
+
: T extends "number"
|
|
19
|
+
? number
|
|
20
|
+
: T extends "boolean"
|
|
21
|
+
? boolean
|
|
22
|
+
: T extends "date"
|
|
23
|
+
? Date
|
|
24
|
+
: T extends "json"
|
|
25
|
+
? Record<string, any>
|
|
26
|
+
: T extends `${infer U}[]`
|
|
27
|
+
? U extends "string"
|
|
28
|
+
? string[]
|
|
29
|
+
: number[]
|
|
30
|
+
: T extends Array<any>
|
|
31
|
+
? T[number]
|
|
32
|
+
: never;
|
|
33
|
+
|
|
34
|
+
export type InferDBFieldOutput<T extends DBFieldAttribute> =
|
|
35
|
+
T["returned"] extends false
|
|
36
|
+
? never
|
|
37
|
+
: T["required"] extends false
|
|
38
|
+
? InferDBValueType<T["type"]> | undefined | null
|
|
39
|
+
: InferDBValueType<T["type"]>;
|
|
40
|
+
|
|
41
|
+
export type InferDBFieldInput<T extends DBFieldAttribute> = InferDBValueType<
|
|
42
|
+
T["type"]
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
export type InferDBFieldsInput<Field> =
|
|
46
|
+
Field extends Record<infer Key, DBFieldAttribute>
|
|
47
|
+
? {
|
|
48
|
+
[key in Key as Field[key]["required"] extends false
|
|
49
|
+
? never
|
|
50
|
+
: Field[key]["defaultValue"] extends string | number | boolean | Date
|
|
51
|
+
? never
|
|
52
|
+
: Field[key]["input"] extends false
|
|
53
|
+
? never
|
|
54
|
+
: key]: InferDBFieldInput<Field[key]>;
|
|
55
|
+
} & {
|
|
56
|
+
[key in Key as Field[key]["input"] extends false ? never : key]?:
|
|
57
|
+
| InferDBFieldInput<Field[key]>
|
|
58
|
+
| undefined
|
|
59
|
+
| null;
|
|
60
|
+
}
|
|
61
|
+
: {};
|
|
62
|
+
|
|
63
|
+
export type InferDBFieldsOutput<
|
|
64
|
+
Fields extends Record<string, DBFieldAttribute>,
|
|
65
|
+
> =
|
|
66
|
+
Fields extends Record<infer Key, DBFieldAttribute>
|
|
67
|
+
? {
|
|
68
|
+
[key in Key as Fields[key]["returned"] extends false
|
|
69
|
+
? never
|
|
70
|
+
: Fields[key]["required"] extends false
|
|
71
|
+
? Fields[key]["defaultValue"] extends
|
|
72
|
+
| boolean
|
|
73
|
+
| string
|
|
74
|
+
| number
|
|
75
|
+
| Date
|
|
76
|
+
? key
|
|
77
|
+
: never
|
|
78
|
+
: key]: InferDBFieldOutput<Fields[key]>;
|
|
79
|
+
} & {
|
|
80
|
+
[key in Key as Fields[key]["returned"] extends false
|
|
81
|
+
? never
|
|
82
|
+
: Fields[key]["required"] extends false
|
|
83
|
+
? Fields[key]["defaultValue"] extends
|
|
84
|
+
| boolean
|
|
85
|
+
| string
|
|
86
|
+
| number
|
|
87
|
+
| Date
|
|
88
|
+
? never
|
|
89
|
+
: key
|
|
90
|
+
: never]?: InferDBFieldOutput<Fields[key]> | null;
|
|
91
|
+
}
|
|
92
|
+
: never;
|
|
93
|
+
|
|
94
|
+
export type InferDBFieldsFromOptionsInput<
|
|
95
|
+
DBOptions extends
|
|
96
|
+
| BetterAuthOptions["session"]
|
|
97
|
+
| BetterAuthOptions["user"]
|
|
98
|
+
| BetterAuthOptions["verification"]
|
|
99
|
+
| BetterAuthOptions["account"]
|
|
100
|
+
| BetterAuthOptions["rateLimit"],
|
|
101
|
+
> = DBOptions extends {
|
|
102
|
+
additionalFields: Record<string, DBFieldAttribute>;
|
|
103
|
+
}
|
|
104
|
+
? InferDBFieldsInput<DBOptions["additionalFields"]>
|
|
105
|
+
: {};
|
|
106
|
+
|
|
107
|
+
export type InferDBFieldsFromOptions<
|
|
108
|
+
DBOptions extends
|
|
109
|
+
| BetterAuthOptions["session"]
|
|
110
|
+
| BetterAuthOptions["user"]
|
|
111
|
+
| BetterAuthOptions["verification"]
|
|
112
|
+
| BetterAuthOptions["account"]
|
|
113
|
+
| BetterAuthOptions["rateLimit"],
|
|
114
|
+
> = DBOptions extends {
|
|
115
|
+
additionalFields: Record<string, DBFieldAttribute>;
|
|
116
|
+
}
|
|
117
|
+
? InferDBFieldsOutput<DBOptions["additionalFields"]>
|
|
118
|
+
: {};
|
|
119
|
+
|
|
120
|
+
export type InferDBFieldsFromPluginsInput<
|
|
121
|
+
ModelName extends string,
|
|
122
|
+
Plugins extends unknown[] | undefined,
|
|
123
|
+
> = Plugins extends []
|
|
124
|
+
? {}
|
|
125
|
+
: Plugins extends [infer P, ...infer Rest]
|
|
126
|
+
? P extends {
|
|
127
|
+
schema: {
|
|
128
|
+
[key in ModelName]: {
|
|
129
|
+
fields: infer Fields;
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
? Fields extends Record<string, DBFieldAttribute>
|
|
134
|
+
? UnionToIntersection<
|
|
135
|
+
InferDBFieldsInput<Fields> &
|
|
136
|
+
InferDBFieldsFromPluginsInput<ModelName, Rest>
|
|
137
|
+
>
|
|
138
|
+
: InferDBFieldsFromPluginsInput<ModelName, Rest>
|
|
139
|
+
: InferDBFieldsFromPluginsInput<ModelName, Rest>
|
|
140
|
+
: {};
|
|
141
|
+
|
|
142
|
+
export type InferDBFieldsFromPlugins<
|
|
143
|
+
ModelName extends string,
|
|
144
|
+
Plugins extends unknown[] | undefined,
|
|
145
|
+
> = Plugins extends []
|
|
146
|
+
? {}
|
|
147
|
+
: Plugins extends [infer P, ...infer Rest]
|
|
148
|
+
? P extends {
|
|
149
|
+
schema: {
|
|
150
|
+
[key in ModelName]: {
|
|
151
|
+
fields: infer Fields;
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
? Fields extends Record<string, DBFieldAttribute>
|
|
156
|
+
? UnionToIntersection<
|
|
157
|
+
InferDBFieldsOutput<Fields> &
|
|
158
|
+
InferDBFieldsFromPlugins<ModelName, Rest>
|
|
159
|
+
>
|
|
160
|
+
: InferDBFieldsFromPlugins<ModelName, Rest>
|
|
161
|
+
: InferDBFieldsFromPlugins<ModelName, Rest>
|
|
162
|
+
: {};
|
|
163
|
+
|
|
11
164
|
export type DBFieldType =
|
|
12
165
|
| "string"
|
|
13
166
|
| "number"
|
package/src/env/env-impl.ts
CHANGED
|
@@ -115,10 +115,10 @@ export const ENV = Object.freeze({
|
|
|
115
115
|
get PACKAGE_VERSION() {
|
|
116
116
|
return getEnvVar("PACKAGE_VERSION", "0.0.0");
|
|
117
117
|
},
|
|
118
|
-
get BETTER_AUTH_TELEMETRY_ENDPOINT() {
|
|
118
|
+
get BETTER_AUTH_TELEMETRY_ENDPOINT(): string | undefined {
|
|
119
119
|
return getEnvVar(
|
|
120
120
|
"BETTER_AUTH_TELEMETRY_ENDPOINT",
|
|
121
|
-
|
|
121
|
+
import.meta.env.BETTER_AUTH_TELEMETRY_ENDPOINT,
|
|
122
122
|
);
|
|
123
123
|
},
|
|
124
124
|
});
|
package/src/env/logger.ts
CHANGED
|
@@ -94,7 +94,7 @@ export type InternalLogger = {
|
|
|
94
94
|
|
|
95
95
|
export const createLogger = (options?: Logger | undefined): InternalLogger => {
|
|
96
96
|
const enabled = options?.disabled !== true;
|
|
97
|
-
const logLevel = options?.level ?? "
|
|
97
|
+
const logLevel = options?.level ?? "warn";
|
|
98
98
|
|
|
99
99
|
const isDisableColorsSpecified = options?.disableColors !== undefined;
|
|
100
100
|
const colorsEnabled = isDisableColorsSpecified
|
package/src/error/codes.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import { defineErrorCodes } from "../utils/error-codes";
|
|
2
2
|
|
|
3
|
+
declare module "@better-auth/core" {
|
|
4
|
+
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
5
|
+
/**
|
|
6
|
+
* This plugin does not exist, do not use it in runtime.
|
|
7
|
+
*/
|
|
8
|
+
"$internal:base": {
|
|
9
|
+
creator: () => {
|
|
10
|
+
$ERROR_CODES: typeof BASE_ERROR_CODES;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
3
16
|
export const BASE_ERROR_CODES = defineErrorCodes({
|
|
4
17
|
USER_NOT_FOUND: "User not found",
|
|
5
18
|
FAILED_TO_CREATE_USER: "Failed to create user",
|
|
@@ -49,6 +62,10 @@ export const BASE_ERROR_CODES = defineErrorCodes({
|
|
|
49
62
|
ASYNC_VALIDATION_NOT_SUPPORTED: "Async validation is not supported",
|
|
50
63
|
VALIDATION_ERROR: "Validation Error",
|
|
51
64
|
MISSING_FIELD: "Field is required",
|
|
65
|
+
METHOD_NOT_ALLOWED_DEFER_SESSION_REQUIRED:
|
|
66
|
+
"POST method requires deferSessionRefresh to be enabled in session config",
|
|
67
|
+
BODY_MUST_BE_AN_OBJECT: "Body must be an object",
|
|
68
|
+
PASSWORD_ALREADY_SET: "User already has a password set",
|
|
52
69
|
});
|
|
53
70
|
|
|
54
71
|
export type APIErrorCode = keyof typeof BASE_ERROR_CODES;
|
|
@@ -1,7 +1,31 @@
|
|
|
1
1
|
import { base64Url } from "@better-auth/utils/base64";
|
|
2
2
|
import { betterFetch } from "@better-fetch/fetch";
|
|
3
|
+
import type { AwaitableFunction } from "../types";
|
|
3
4
|
import type { OAuth2Tokens, ProviderOptions } from "./oauth-provider";
|
|
4
5
|
|
|
6
|
+
export async function clientCredentialsTokenRequest({
|
|
7
|
+
options,
|
|
8
|
+
scope,
|
|
9
|
+
authentication,
|
|
10
|
+
resource,
|
|
11
|
+
}: {
|
|
12
|
+
options: AwaitableFunction<ProviderOptions & { clientSecret: string }>;
|
|
13
|
+
scope?: string | undefined;
|
|
14
|
+
authentication?: ("basic" | "post") | undefined;
|
|
15
|
+
resource?: (string | string[]) | undefined;
|
|
16
|
+
}) {
|
|
17
|
+
options = typeof options === "function" ? await options() : options;
|
|
18
|
+
return createClientCredentialsTokenRequest({
|
|
19
|
+
options,
|
|
20
|
+
scope,
|
|
21
|
+
authentication,
|
|
22
|
+
resource,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated use async'd clientCredentialsTokenRequest instead
|
|
28
|
+
*/
|
|
5
29
|
export function createClientCredentialsTokenRequest({
|
|
6
30
|
options,
|
|
7
31
|
scope,
|
|
@@ -59,13 +83,13 @@ export async function clientCredentialsToken({
|
|
|
59
83
|
authentication,
|
|
60
84
|
resource,
|
|
61
85
|
}: {
|
|
62
|
-
options: ProviderOptions & { clientSecret: string }
|
|
86
|
+
options: AwaitableFunction<ProviderOptions & { clientSecret: string }>;
|
|
63
87
|
tokenEndpoint: string;
|
|
64
88
|
scope: string;
|
|
65
89
|
authentication?: ("basic" | "post") | undefined;
|
|
66
90
|
resource?: (string | string[]) | undefined;
|
|
67
91
|
}): Promise<OAuth2Tokens> {
|
|
68
|
-
const { body, headers } =
|
|
92
|
+
const { body, headers } = await clientCredentialsTokenRequest({
|
|
69
93
|
options,
|
|
70
94
|
scope,
|
|
71
95
|
authentication,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AwaitableFunction } from "../types";
|
|
1
2
|
import type { ProviderOptions } from "./index";
|
|
2
3
|
import { generateCodeChallenge } from "./utils";
|
|
3
4
|
|
|
@@ -22,7 +23,7 @@ export async function createAuthorizationURL({
|
|
|
22
23
|
scopeJoiner,
|
|
23
24
|
}: {
|
|
24
25
|
id: string;
|
|
25
|
-
options: ProviderOptions
|
|
26
|
+
options: AwaitableFunction<ProviderOptions>;
|
|
26
27
|
redirectURI: string;
|
|
27
28
|
authorizationEndpoint: string;
|
|
28
29
|
state: string;
|
|
@@ -40,6 +41,7 @@ export async function createAuthorizationURL({
|
|
|
40
41
|
additionalParams?: Record<string, string> | undefined;
|
|
41
42
|
scopeJoiner?: string | undefined;
|
|
42
43
|
}) {
|
|
44
|
+
options = typeof options === "function" ? await options() : options;
|
|
43
45
|
const url = new URL(options.authorizationEndpoint || authorizationEndpoint);
|
|
44
46
|
url.searchParams.set("response_type", responseType || "code");
|
|
45
47
|
const primaryClientId = Array.isArray(options.clientId)
|
package/src/oauth2/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export {
|
|
2
2
|
clientCredentialsToken,
|
|
3
|
+
clientCredentialsTokenRequest,
|
|
3
4
|
createClientCredentialsTokenRequest,
|
|
4
5
|
} from "./client-credentials-token";
|
|
5
6
|
export { createAuthorizationURL } from "./create-authorization-url";
|
|
@@ -12,9 +13,11 @@ export type {
|
|
|
12
13
|
export {
|
|
13
14
|
createRefreshAccessTokenRequest,
|
|
14
15
|
refreshAccessToken,
|
|
16
|
+
refreshAccessTokenRequest,
|
|
15
17
|
} from "./refresh-access-token";
|
|
16
18
|
export { generateCodeChallenge, getOAuth2Tokens } from "./utils";
|
|
17
19
|
export {
|
|
20
|
+
authorizationCodeRequest,
|
|
18
21
|
createAuthorizationCodeRequest,
|
|
19
22
|
validateAuthorizationCode,
|
|
20
23
|
validateToken,
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
vi.mock("@better-fetch/fetch", () => ({
|
|
4
|
+
betterFetch: vi.fn(),
|
|
5
|
+
}));
|
|
6
|
+
|
|
7
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
8
|
+
import { refreshAccessToken } from "./refresh-access-token";
|
|
9
|
+
|
|
10
|
+
const mockedBetterFetch = vi.mocked(betterFetch);
|
|
11
|
+
|
|
12
|
+
describe("refreshAccessToken", () => {
|
|
13
|
+
it("should set accessTokenExpiresAt when expires_in is returned", async () => {
|
|
14
|
+
const now = Date.now();
|
|
15
|
+
mockedBetterFetch.mockResolvedValueOnce({
|
|
16
|
+
data: {
|
|
17
|
+
access_token: "new-access-token",
|
|
18
|
+
refresh_token: "new-refresh-token",
|
|
19
|
+
expires_in: 3600,
|
|
20
|
+
token_type: "Bearer",
|
|
21
|
+
},
|
|
22
|
+
error: null,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const tokens = await refreshAccessToken({
|
|
26
|
+
refreshToken: "old-refresh-token",
|
|
27
|
+
options: { clientId: "test-client", clientSecret: "test-secret" },
|
|
28
|
+
tokenEndpoint: "https://example.com/token",
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
expect(tokens.accessToken).toBe("new-access-token");
|
|
32
|
+
expect(tokens.refreshToken).toBe("new-refresh-token");
|
|
33
|
+
expect(tokens.accessTokenExpiresAt).toBeInstanceOf(Date);
|
|
34
|
+
expect(tokens.accessTokenExpiresAt!.getTime()).toBeGreaterThanOrEqual(
|
|
35
|
+
now + 3600 * 1000 - 1000,
|
|
36
|
+
);
|
|
37
|
+
expect(tokens.refreshTokenExpiresAt).toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @see https://github.com/better-auth/better-auth/issues/7682
|
|
42
|
+
*/
|
|
43
|
+
it("should set refreshTokenExpiresAt when refresh_token_expires_in is returned", async () => {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
mockedBetterFetch.mockResolvedValueOnce({
|
|
46
|
+
data: {
|
|
47
|
+
access_token: "new-access-token",
|
|
48
|
+
refresh_token: "new-refresh-token",
|
|
49
|
+
expires_in: 3600,
|
|
50
|
+
refresh_token_expires_in: 86400,
|
|
51
|
+
token_type: "Bearer",
|
|
52
|
+
},
|
|
53
|
+
error: null,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const tokens = await refreshAccessToken({
|
|
57
|
+
refreshToken: "old-refresh-token",
|
|
58
|
+
options: { clientId: "test-client", clientSecret: "test-secret" },
|
|
59
|
+
tokenEndpoint: "https://example.com/token",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
expect(tokens.accessToken).toBe("new-access-token");
|
|
63
|
+
expect(tokens.refreshToken).toBe("new-refresh-token");
|
|
64
|
+
expect(tokens.accessTokenExpiresAt).toBeInstanceOf(Date);
|
|
65
|
+
expect(tokens.refreshTokenExpiresAt).toBeInstanceOf(Date);
|
|
66
|
+
expect(tokens.refreshTokenExpiresAt!.getTime()).toBeGreaterThanOrEqual(
|
|
67
|
+
now + 86400 * 1000 - 1000,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("should not set refreshTokenExpiresAt when refresh_token_expires_in is not returned", async () => {
|
|
72
|
+
mockedBetterFetch.mockResolvedValueOnce({
|
|
73
|
+
data: {
|
|
74
|
+
access_token: "new-access-token",
|
|
75
|
+
refresh_token: "new-refresh-token",
|
|
76
|
+
expires_in: 3600,
|
|
77
|
+
token_type: "Bearer",
|
|
78
|
+
},
|
|
79
|
+
error: null,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const tokens = await refreshAccessToken({
|
|
83
|
+
refreshToken: "old-refresh-token",
|
|
84
|
+
options: { clientId: "test-client", clientSecret: "test-secret" },
|
|
85
|
+
tokenEndpoint: "https://example.com/token",
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(tokens.refreshTokenExpiresAt).toBeUndefined();
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import { base64 } from "@better-auth/utils/base64";
|
|
2
2
|
import { betterFetch } from "@better-fetch/fetch";
|
|
3
|
+
import type { AwaitableFunction } from "../types";
|
|
3
4
|
import type { OAuth2Tokens, ProviderOptions } from "./oauth-provider";
|
|
4
5
|
|
|
6
|
+
export async function refreshAccessTokenRequest({
|
|
7
|
+
refreshToken,
|
|
8
|
+
options,
|
|
9
|
+
authentication,
|
|
10
|
+
extraParams,
|
|
11
|
+
resource,
|
|
12
|
+
}: {
|
|
13
|
+
refreshToken: string;
|
|
14
|
+
options: AwaitableFunction<Partial<ProviderOptions>>;
|
|
15
|
+
authentication?: ("basic" | "post") | undefined;
|
|
16
|
+
extraParams?: Record<string, string> | undefined;
|
|
17
|
+
resource?: (string | string[]) | undefined;
|
|
18
|
+
}) {
|
|
19
|
+
options = typeof options === "function" ? await options() : options;
|
|
20
|
+
return createRefreshAccessTokenRequest({
|
|
21
|
+
refreshToken,
|
|
22
|
+
options,
|
|
23
|
+
authentication,
|
|
24
|
+
extraParams,
|
|
25
|
+
resource,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated use async'd refreshAccessTokenRequest instead
|
|
31
|
+
*/
|
|
5
32
|
export function createRefreshAccessTokenRequest({
|
|
6
33
|
refreshToken,
|
|
7
34
|
options,
|
|
@@ -10,7 +37,7 @@ export function createRefreshAccessTokenRequest({
|
|
|
10
37
|
resource,
|
|
11
38
|
}: {
|
|
12
39
|
refreshToken: string;
|
|
13
|
-
options:
|
|
40
|
+
options: ProviderOptions;
|
|
14
41
|
authentication?: ("basic" | "post") | undefined;
|
|
15
42
|
extraParams?: Record<string, string> | undefined;
|
|
16
43
|
resource?: (string | string[]) | undefined;
|
|
@@ -80,10 +107,8 @@ export async function refreshAccessToken({
|
|
|
80
107
|
tokenEndpoint: string;
|
|
81
108
|
authentication?: ("basic" | "post") | undefined;
|
|
82
109
|
extraParams?: Record<string, string> | undefined;
|
|
83
|
-
/** @deprecated always "refresh_token" */
|
|
84
|
-
grantType?: string | undefined;
|
|
85
110
|
}): Promise<OAuth2Tokens> {
|
|
86
|
-
const { body, headers } = createRefreshAccessTokenRequest({
|
|
111
|
+
const { body, headers } = await createRefreshAccessTokenRequest({
|
|
87
112
|
refreshToken,
|
|
88
113
|
options,
|
|
89
114
|
authentication,
|
|
@@ -94,6 +119,7 @@ export async function refreshAccessToken({
|
|
|
94
119
|
access_token: string;
|
|
95
120
|
refresh_token?: string | undefined;
|
|
96
121
|
expires_in?: number | undefined;
|
|
122
|
+
refresh_token_expires_in?: number | undefined;
|
|
97
123
|
token_type?: string | undefined;
|
|
98
124
|
scope?: string | undefined;
|
|
99
125
|
id_token?: string | undefined;
|
|
@@ -120,5 +146,12 @@ export async function refreshAccessToken({
|
|
|
120
146
|
);
|
|
121
147
|
}
|
|
122
148
|
|
|
149
|
+
if (data.refresh_token_expires_in) {
|
|
150
|
+
const now = new Date();
|
|
151
|
+
tokens.refreshTokenExpiresAt = new Date(
|
|
152
|
+
now.getTime() + data.refresh_token_expires_in * 1000,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
123
156
|
return tokens;
|
|
124
157
|
}
|
|
@@ -1,9 +1,48 @@
|
|
|
1
1
|
import { base64 } from "@better-auth/utils/base64";
|
|
2
2
|
import { betterFetch } from "@better-fetch/fetch";
|
|
3
|
-
import { jwtVerify } from "jose";
|
|
3
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
4
|
+
import type { AwaitableFunction } from "../types";
|
|
4
5
|
import type { ProviderOptions } from "./index";
|
|
5
6
|
import { getOAuth2Tokens } from "./index";
|
|
6
7
|
|
|
8
|
+
export async function authorizationCodeRequest({
|
|
9
|
+
code,
|
|
10
|
+
codeVerifier,
|
|
11
|
+
redirectURI,
|
|
12
|
+
options,
|
|
13
|
+
authentication,
|
|
14
|
+
deviceId,
|
|
15
|
+
headers,
|
|
16
|
+
additionalParams = {},
|
|
17
|
+
resource,
|
|
18
|
+
}: {
|
|
19
|
+
code: string;
|
|
20
|
+
redirectURI: string;
|
|
21
|
+
options: AwaitableFunction<Partial<ProviderOptions>>;
|
|
22
|
+
codeVerifier?: string | undefined;
|
|
23
|
+
deviceId?: string | undefined;
|
|
24
|
+
authentication?: ("basic" | "post") | undefined;
|
|
25
|
+
headers?: Record<string, string> | undefined;
|
|
26
|
+
additionalParams?: Record<string, string> | undefined;
|
|
27
|
+
resource?: (string | string[]) | undefined;
|
|
28
|
+
}) {
|
|
29
|
+
options = typeof options === "function" ? await options() : options;
|
|
30
|
+
return createAuthorizationCodeRequest({
|
|
31
|
+
code,
|
|
32
|
+
codeVerifier,
|
|
33
|
+
redirectURI,
|
|
34
|
+
options,
|
|
35
|
+
authentication,
|
|
36
|
+
deviceId,
|
|
37
|
+
headers,
|
|
38
|
+
additionalParams,
|
|
39
|
+
resource,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated use async'd authorizationCodeRequest instead
|
|
45
|
+
*/
|
|
7
46
|
export function createAuthorizationCodeRequest({
|
|
8
47
|
code,
|
|
9
48
|
codeVerifier,
|
|
@@ -31,6 +70,7 @@ export function createAuthorizationCodeRequest({
|
|
|
31
70
|
accept: "application/json",
|
|
32
71
|
...headers,
|
|
33
72
|
};
|
|
73
|
+
|
|
34
74
|
body.set("grant_type", "authorization_code");
|
|
35
75
|
body.set("code", code);
|
|
36
76
|
codeVerifier && body.set("code_verifier", codeVerifier);
|
|
@@ -90,7 +130,7 @@ export async function validateAuthorizationCode({
|
|
|
90
130
|
}: {
|
|
91
131
|
code: string;
|
|
92
132
|
redirectURI: string;
|
|
93
|
-
options: Partial<ProviderOptions
|
|
133
|
+
options: AwaitableFunction<Partial<ProviderOptions>>;
|
|
94
134
|
codeVerifier?: string | undefined;
|
|
95
135
|
deviceId?: string | undefined;
|
|
96
136
|
tokenEndpoint: string;
|
|
@@ -99,7 +139,7 @@ export async function validateAuthorizationCode({
|
|
|
99
139
|
additionalParams?: Record<string, string> | undefined;
|
|
100
140
|
resource?: (string | string[]) | undefined;
|
|
101
141
|
}) {
|
|
102
|
-
const { body, headers: requestHeaders } =
|
|
142
|
+
const { body, headers: requestHeaders } = await authorizationCodeRequest({
|
|
103
143
|
code,
|
|
104
144
|
codeVerifier,
|
|
105
145
|
redirectURI,
|
|
@@ -116,7 +156,6 @@ export async function validateAuthorizationCode({
|
|
|
116
156
|
body: body,
|
|
117
157
|
headers: requestHeaders,
|
|
118
158
|
});
|
|
119
|
-
|
|
120
159
|
if (error) {
|
|
121
160
|
throw error;
|
|
122
161
|
}
|
|
@@ -124,31 +163,18 @@ export async function validateAuthorizationCode({
|
|
|
124
163
|
return tokens;
|
|
125
164
|
}
|
|
126
165
|
|
|
127
|
-
export async function validateToken(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
headers: {
|
|
140
|
-
accept: "application/json",
|
|
141
|
-
},
|
|
166
|
+
export async function validateToken(
|
|
167
|
+
token: string,
|
|
168
|
+
jwksEndpoint: string,
|
|
169
|
+
options?: {
|
|
170
|
+
audience?: string | string[];
|
|
171
|
+
issuer?: string | string[];
|
|
172
|
+
},
|
|
173
|
+
) {
|
|
174
|
+
const jwks = createRemoteJWKSet(new URL(jwksEndpoint));
|
|
175
|
+
const verified = await jwtVerify(token, jwks, {
|
|
176
|
+
audience: options?.audience,
|
|
177
|
+
issuer: options?.issuer,
|
|
142
178
|
});
|
|
143
|
-
if (error) {
|
|
144
|
-
throw error;
|
|
145
|
-
}
|
|
146
|
-
const keys = data["keys"];
|
|
147
|
-
const header = JSON.parse(atob(token.split(".")[0]!));
|
|
148
|
-
const key = keys.find((key) => key.kid === header.kid);
|
|
149
|
-
if (!key) {
|
|
150
|
-
throw new Error("Key not found");
|
|
151
|
-
}
|
|
152
|
-
const verified = await jwtVerify(token, key);
|
|
153
179
|
return verified;
|
|
154
180
|
}
|