@better-auth/core 1.7.0-beta.4 → 1.7.0-beta.5
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 +3 -3
- package/dist/context/global.mjs +1 -1
- package/dist/db/adapter/factory.mjs +2 -2
- package/dist/db/get-tables.mjs +3 -3
- package/dist/db/schema/account.d.mts +1 -1
- package/dist/db/schema/account.mjs +1 -1
- package/dist/env/env-impl.mjs +1 -1
- package/dist/error/codes.d.mts +5 -0
- package/dist/error/codes.mjs +5 -0
- package/dist/index.d.mts +2 -2
- package/dist/instrumentation/tracer.mjs +1 -1
- package/dist/oauth2/create-authorization-url.d.mts +4 -1
- package/dist/oauth2/create-authorization-url.mjs +5 -2
- package/dist/oauth2/index.d.mts +4 -2
- package/dist/oauth2/index.mjs +3 -1
- package/dist/oauth2/oauth-provider.d.mts +128 -9
- package/dist/oauth2/refresh-access-token.mjs +1 -1
- package/dist/oauth2/scopes.d.mts +76 -0
- package/dist/oauth2/scopes.mjs +96 -0
- package/dist/oauth2/utils.mjs +2 -1
- package/dist/oauth2/verify-id-token.d.mts +26 -0
- package/dist/oauth2/verify-id-token.mjs +62 -0
- package/dist/oauth2/verify.d.mts +14 -0
- package/dist/oauth2/verify.mjs +23 -7
- package/dist/social-providers/apple.d.mts +14 -2
- package/dist/social-providers/apple.mjs +12 -36
- package/dist/social-providers/atlassian.d.mts +5 -1
- package/dist/social-providers/atlassian.mjs +4 -4
- package/dist/social-providers/cognito.d.mts +13 -2
- package/dist/social-providers/cognito.mjs +24 -32
- package/dist/social-providers/discord.d.mts +5 -1
- package/dist/social-providers/discord.mjs +7 -6
- package/dist/social-providers/dropbox.d.mts +5 -1
- package/dist/social-providers/dropbox.mjs +5 -5
- package/dist/social-providers/facebook.d.mts +21 -2
- package/dist/social-providers/facebook.mjs +46 -22
- package/dist/social-providers/figma.d.mts +5 -1
- package/dist/social-providers/figma.mjs +5 -5
- package/dist/social-providers/github.d.mts +5 -1
- package/dist/social-providers/github.mjs +4 -4
- package/dist/social-providers/gitlab.d.mts +5 -1
- package/dist/social-providers/gitlab.mjs +6 -6
- package/dist/social-providers/google.d.mts +29 -3
- package/dist/social-providers/google.mjs +24 -30
- package/dist/social-providers/huggingface.d.mts +5 -1
- package/dist/social-providers/huggingface.mjs +8 -8
- package/dist/social-providers/index.d.mts +221 -42
- package/dist/social-providers/kakao.d.mts +5 -1
- package/dist/social-providers/kakao.mjs +8 -8
- package/dist/social-providers/kick.d.mts +5 -1
- package/dist/social-providers/kick.mjs +4 -4
- package/dist/social-providers/line.d.mts +8 -2
- package/dist/social-providers/line.mjs +12 -14
- package/dist/social-providers/linear.d.mts +5 -1
- package/dist/social-providers/linear.mjs +4 -4
- package/dist/social-providers/linkedin.d.mts +5 -1
- package/dist/social-providers/linkedin.mjs +10 -10
- package/dist/social-providers/microsoft-entra-id.d.mts +31 -6
- package/dist/social-providers/microsoft-entra-id.mjs +26 -37
- package/dist/social-providers/naver.d.mts +5 -1
- package/dist/social-providers/naver.mjs +4 -4
- package/dist/social-providers/notion.d.mts +5 -1
- package/dist/social-providers/notion.mjs +4 -4
- package/dist/social-providers/paybin.d.mts +5 -1
- package/dist/social-providers/paybin.mjs +10 -10
- package/dist/social-providers/paypal.d.mts +5 -2
- package/dist/social-providers/paypal.mjs +8 -13
- package/dist/social-providers/polar.d.mts +5 -1
- package/dist/social-providers/polar.mjs +8 -8
- package/dist/social-providers/railway.d.mts +5 -1
- package/dist/social-providers/railway.mjs +9 -9
- package/dist/social-providers/reddit.d.mts +5 -1
- package/dist/social-providers/reddit.mjs +9 -8
- package/dist/social-providers/roblox.d.mts +5 -1
- package/dist/social-providers/roblox.mjs +5 -5
- package/dist/social-providers/salesforce.d.mts +5 -1
- package/dist/social-providers/salesforce.mjs +8 -8
- package/dist/social-providers/slack.d.mts +5 -1
- package/dist/social-providers/slack.mjs +9 -9
- package/dist/social-providers/spotify.d.mts +5 -1
- package/dist/social-providers/spotify.mjs +5 -5
- package/dist/social-providers/tiktok.d.mts +5 -1
- package/dist/social-providers/tiktok.mjs +9 -5
- package/dist/social-providers/twitch.d.mts +5 -1
- package/dist/social-providers/twitch.mjs +4 -4
- package/dist/social-providers/twitter.d.mts +6 -4
- package/dist/social-providers/twitter.mjs +9 -9
- package/dist/social-providers/vercel.d.mts +5 -1
- package/dist/social-providers/vercel.mjs +4 -7
- package/dist/social-providers/vk.d.mts +5 -1
- package/dist/social-providers/vk.mjs +5 -5
- package/dist/social-providers/wechat.d.mts +5 -1
- package/dist/social-providers/wechat.mjs +9 -5
- package/dist/social-providers/zoom.d.mts +6 -1
- package/dist/social-providers/zoom.mjs +15 -9
- package/dist/types/context.d.mts +10 -8
- package/dist/types/index.d.mts +1 -1
- package/dist/types/init-options.d.mts +92 -1
- package/package.json +5 -5
- package/src/db/adapter/factory.ts +10 -2
- package/src/db/get-tables.ts +8 -3
- package/src/db/schema/account.ts +14 -2
- package/src/env/env-impl.ts +1 -2
- package/src/error/codes.ts +5 -0
- package/src/oauth2/create-authorization-url.ts +2 -2
- package/src/oauth2/index.ts +17 -1
- package/src/oauth2/oauth-provider.ts +140 -10
- package/src/oauth2/refresh-access-token.ts +2 -2
- package/src/oauth2/scopes.ts +118 -0
- package/src/oauth2/utils.ts +2 -5
- package/src/oauth2/verify-id-token.ts +111 -0
- package/src/oauth2/verify.ts +62 -11
- package/src/social-providers/apple.ts +24 -61
- package/src/social-providers/atlassian.ts +12 -8
- package/src/social-providers/cognito.ts +25 -47
- package/src/social-providers/discord.ts +19 -8
- package/src/social-providers/dropbox.ts +13 -7
- package/src/social-providers/facebook.ts +97 -51
- package/src/social-providers/figma.ts +13 -9
- package/src/social-providers/github.ts +12 -8
- package/src/social-providers/gitlab.ts +14 -8
- package/src/social-providers/google.ts +66 -47
- package/src/social-providers/huggingface.ts +12 -8
- package/src/social-providers/kakao.ts +16 -8
- package/src/social-providers/kick.ts +12 -7
- package/src/social-providers/line.ts +37 -37
- package/src/social-providers/linear.ts +12 -6
- package/src/social-providers/linkedin.ts +14 -10
- package/src/social-providers/microsoft-entra-id.ts +65 -64
- package/src/social-providers/naver.ts +12 -6
- package/src/social-providers/notion.ts +12 -6
- package/src/social-providers/paybin.ts +14 -11
- package/src/social-providers/paypal.ts +6 -25
- package/src/social-providers/polar.ts +12 -8
- package/src/social-providers/railway.ts +13 -9
- package/src/social-providers/reddit.ts +21 -10
- package/src/social-providers/roblox.ts +18 -7
- package/src/social-providers/salesforce.ts +12 -8
- package/src/social-providers/slack.ts +18 -9
- package/src/social-providers/spotify.ts +13 -7
- package/src/social-providers/tiktok.ts +13 -7
- package/src/social-providers/twitch.ts +12 -8
- package/src/social-providers/twitter.ts +17 -8
- package/src/social-providers/vercel.ts +16 -10
- package/src/social-providers/vk.ts +13 -7
- package/src/social-providers/wechat.ts +20 -8
- package/src/social-providers/zoom.ts +19 -6
- package/src/types/context.ts +8 -8
- package/src/types/index.ts +7 -0
- package/src/types/init-options.ts +119 -0
|
@@ -93,6 +93,7 @@ interface KakaoOptions extends ProviderOptions<KakaoProfile> {
|
|
|
93
93
|
declare const kakao: (options: KakaoOptions) => {
|
|
94
94
|
id: "kakao";
|
|
95
95
|
name: string;
|
|
96
|
+
callbackPath: string;
|
|
96
97
|
createAuthorizationURL({
|
|
97
98
|
state,
|
|
98
99
|
scopes,
|
|
@@ -106,7 +107,10 @@ declare const kakao: (options: KakaoOptions) => {
|
|
|
106
107
|
display?: string | undefined;
|
|
107
108
|
loginHint?: string | undefined;
|
|
108
109
|
additionalParams?: Record<string, string> | undefined;
|
|
109
|
-
}): Promise<
|
|
110
|
+
}): Promise<{
|
|
111
|
+
url: URL;
|
|
112
|
+
requestedScopes: string[];
|
|
113
|
+
}>;
|
|
110
114
|
validateAuthorizationCode: ({
|
|
111
115
|
code,
|
|
112
116
|
redirectURI
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
6
|
//#region src/social-providers/kakao.ts
|
|
7
|
+
const KAKAO_DEFAULT_SCOPES = [
|
|
8
|
+
"account_email",
|
|
9
|
+
"profile_image",
|
|
10
|
+
"profile_nickname"
|
|
11
|
+
];
|
|
6
12
|
const kakao = (options) => {
|
|
7
13
|
const tokenEndpoint = "https://kauth.kakao.com/oauth/token";
|
|
8
14
|
return {
|
|
9
15
|
id: "kakao",
|
|
10
16
|
name: "Kakao",
|
|
17
|
+
callbackPath: "/callback/kakao",
|
|
11
18
|
createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
|
|
12
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
13
|
-
"account_email",
|
|
14
|
-
"profile_image",
|
|
15
|
-
"profile_nickname"
|
|
16
|
-
];
|
|
17
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
18
|
-
if (scopes) _scopes.push(...scopes);
|
|
19
19
|
return createAuthorizationURL({
|
|
20
20
|
id: "kakao",
|
|
21
21
|
options,
|
|
22
22
|
authorizationEndpoint: "https://kauth.kakao.com/oauth/authorize",
|
|
23
|
-
scopes:
|
|
23
|
+
scopes: resolveRequestedScopes(options, KAKAO_DEFAULT_SCOPES, scopes),
|
|
24
24
|
state,
|
|
25
25
|
redirectURI,
|
|
26
26
|
additionalParams
|
|
@@ -24,6 +24,7 @@ interface KickOptions extends ProviderOptions<KickProfile> {
|
|
|
24
24
|
declare const kick: (options: KickOptions) => {
|
|
25
25
|
id: "kick";
|
|
26
26
|
name: string;
|
|
27
|
+
callbackPath: string;
|
|
27
28
|
createAuthorizationURL({
|
|
28
29
|
state,
|
|
29
30
|
scopes,
|
|
@@ -38,7 +39,10 @@ declare const kick: (options: KickOptions) => {
|
|
|
38
39
|
display?: string | undefined;
|
|
39
40
|
loginHint?: string | undefined;
|
|
40
41
|
additionalParams?: Record<string, string> | undefined;
|
|
41
|
-
}): Promise<
|
|
42
|
+
}): Promise<{
|
|
43
|
+
url: URL;
|
|
44
|
+
requestedScopes: string[];
|
|
45
|
+
}>;
|
|
42
46
|
validateAuthorizationCode({
|
|
43
47
|
code,
|
|
44
48
|
redirectURI,
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
6
|
//#region src/social-providers/kick.ts
|
|
7
|
+
const KICK_DEFAULT_SCOPES = ["user:read"];
|
|
6
8
|
const kick = (options) => {
|
|
7
9
|
return {
|
|
8
10
|
id: "kick",
|
|
9
11
|
name: "Kick",
|
|
12
|
+
callbackPath: "/callback/kick",
|
|
10
13
|
createAuthorizationURL({ state, scopes, redirectURI, codeVerifier, additionalParams }) {
|
|
11
|
-
const _scopes = options.disableDefaultScope ? [] : ["user:read"];
|
|
12
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
13
|
-
if (scopes) _scopes.push(...scopes);
|
|
14
14
|
return createAuthorizationURL({
|
|
15
15
|
id: "kick",
|
|
16
16
|
redirectURI,
|
|
17
17
|
options,
|
|
18
18
|
authorizationEndpoint: "https://id.kick.com/oauth/authorize",
|
|
19
|
-
scopes:
|
|
19
|
+
scopes: resolveRequestedScopes(options, KICK_DEFAULT_SCOPES, scopes),
|
|
20
20
|
codeVerifier,
|
|
21
21
|
state,
|
|
22
22
|
additionalParams
|
|
@@ -33,6 +33,7 @@ interface LineOptions extends ProviderOptions<LineUserInfo | LineIdTokenPayload>
|
|
|
33
33
|
declare const line: (options: LineOptions) => {
|
|
34
34
|
id: "line";
|
|
35
35
|
name: string;
|
|
36
|
+
callbackPath: string;
|
|
36
37
|
createAuthorizationURL({
|
|
37
38
|
state,
|
|
38
39
|
scopes,
|
|
@@ -48,7 +49,10 @@ declare const line: (options: LineOptions) => {
|
|
|
48
49
|
display?: string | undefined;
|
|
49
50
|
loginHint?: string | undefined;
|
|
50
51
|
additionalParams?: Record<string, string> | undefined;
|
|
51
|
-
}): Promise<
|
|
52
|
+
}): Promise<{
|
|
53
|
+
url: URL;
|
|
54
|
+
requestedScopes: string[];
|
|
55
|
+
}>;
|
|
52
56
|
validateAuthorizationCode: ({
|
|
53
57
|
code,
|
|
54
58
|
codeVerifier,
|
|
@@ -60,7 +64,9 @@ declare const line: (options: LineOptions) => {
|
|
|
60
64
|
deviceId?: string | undefined;
|
|
61
65
|
}) => Promise<OAuth2Tokens>;
|
|
62
66
|
refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
|
|
63
|
-
|
|
67
|
+
idToken: {
|
|
68
|
+
verify: (token: string, nonce: string | undefined) => Promise<boolean>;
|
|
69
|
+
};
|
|
64
70
|
getUserInfo(token: OAuth2Tokens & {
|
|
65
71
|
user?: {
|
|
66
72
|
name?: {
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { decodeJwt } from "jose";
|
|
5
6
|
import { betterFetch } from "@better-fetch/fetch";
|
|
6
7
|
//#region src/social-providers/line.ts
|
|
8
|
+
const LINE_DEFAULT_SCOPES = [
|
|
9
|
+
"openid",
|
|
10
|
+
"profile",
|
|
11
|
+
"email"
|
|
12
|
+
];
|
|
7
13
|
/**
|
|
8
14
|
* LINE Login v2.1
|
|
9
15
|
* - Authorization endpoint: https://access.line.me/oauth2/v2.1/authorize
|
|
@@ -21,19 +27,13 @@ const line = (options) => {
|
|
|
21
27
|
return {
|
|
22
28
|
id: "line",
|
|
23
29
|
name: "LINE",
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"profile",
|
|
28
|
-
"email"
|
|
29
|
-
];
|
|
30
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
31
|
-
if (scopes) _scopes.push(...scopes);
|
|
32
|
-
return await createAuthorizationURL({
|
|
30
|
+
callbackPath: "/callback/line",
|
|
31
|
+
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, loginHint, additionalParams }) {
|
|
32
|
+
return createAuthorizationURL({
|
|
33
33
|
id: "line",
|
|
34
34
|
options,
|
|
35
35
|
authorizationEndpoint,
|
|
36
|
-
scopes:
|
|
36
|
+
scopes: resolveRequestedScopes(options, LINE_DEFAULT_SCOPES, scopes),
|
|
37
37
|
state,
|
|
38
38
|
codeVerifier,
|
|
39
39
|
redirectURI,
|
|
@@ -60,9 +60,7 @@ const line = (options) => {
|
|
|
60
60
|
tokenEndpoint
|
|
61
61
|
});
|
|
62
62
|
},
|
|
63
|
-
async
|
|
64
|
-
if (options.disableIdTokenSignIn) return false;
|
|
65
|
-
if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
|
|
63
|
+
idToken: { verify: async (token, nonce) => {
|
|
66
64
|
const body = new URLSearchParams();
|
|
67
65
|
body.set("id_token", token);
|
|
68
66
|
body.set("client_id", options.clientId);
|
|
@@ -76,7 +74,7 @@ const line = (options) => {
|
|
|
76
74
|
if (data.aud !== options.clientId) return false;
|
|
77
75
|
if (data.nonce && data.nonce !== nonce) return false;
|
|
78
76
|
return true;
|
|
79
|
-
},
|
|
77
|
+
} },
|
|
80
78
|
async getUserInfo(token) {
|
|
81
79
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
82
80
|
let profile = null;
|
|
@@ -20,6 +20,7 @@ interface LinearOptions extends ProviderOptions<LinearUser> {
|
|
|
20
20
|
declare const linear: (options: LinearOptions) => {
|
|
21
21
|
id: "linear";
|
|
22
22
|
name: string;
|
|
23
|
+
callbackPath: string;
|
|
23
24
|
createAuthorizationURL({
|
|
24
25
|
state,
|
|
25
26
|
scopes,
|
|
@@ -34,7 +35,10 @@ declare const linear: (options: LinearOptions) => {
|
|
|
34
35
|
display?: string | undefined;
|
|
35
36
|
loginHint?: string | undefined;
|
|
36
37
|
additionalParams?: Record<string, string> | undefined;
|
|
37
|
-
}): Promise<
|
|
38
|
+
}): Promise<{
|
|
39
|
+
url: URL;
|
|
40
|
+
requestedScopes: string[];
|
|
41
|
+
}>;
|
|
38
42
|
validateAuthorizationCode: ({
|
|
39
43
|
code,
|
|
40
44
|
redirectURI
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
6
|
//#region src/social-providers/linear.ts
|
|
7
|
+
const LINEAR_DEFAULT_SCOPES = ["read"];
|
|
6
8
|
const linear = (options) => {
|
|
7
9
|
const tokenEndpoint = "https://api.linear.app/oauth/token";
|
|
8
10
|
return {
|
|
9
11
|
id: "linear",
|
|
10
12
|
name: "Linear",
|
|
13
|
+
callbackPath: "/callback/linear",
|
|
11
14
|
createAuthorizationURL({ state, scopes, loginHint, redirectURI, additionalParams }) {
|
|
12
|
-
const _scopes = options.disableDefaultScope ? [] : ["read"];
|
|
13
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
14
|
-
if (scopes) _scopes.push(...scopes);
|
|
15
15
|
return createAuthorizationURL({
|
|
16
16
|
id: "linear",
|
|
17
17
|
options,
|
|
18
18
|
authorizationEndpoint: "https://linear.app/oauth/authorize",
|
|
19
|
-
scopes:
|
|
19
|
+
scopes: resolveRequestedScopes(options, LINEAR_DEFAULT_SCOPES, scopes),
|
|
20
20
|
state,
|
|
21
21
|
redirectURI,
|
|
22
22
|
loginHint,
|
|
@@ -19,6 +19,7 @@ interface LinkedInOptions extends ProviderOptions<LinkedInProfile> {
|
|
|
19
19
|
declare const linkedin: (options: LinkedInOptions) => {
|
|
20
20
|
id: "linkedin";
|
|
21
21
|
name: string;
|
|
22
|
+
callbackPath: string;
|
|
22
23
|
createAuthorizationURL: ({
|
|
23
24
|
state,
|
|
24
25
|
scopes,
|
|
@@ -33,7 +34,10 @@ declare const linkedin: (options: LinkedInOptions) => {
|
|
|
33
34
|
display?: string | undefined;
|
|
34
35
|
loginHint?: string | undefined;
|
|
35
36
|
additionalParams?: Record<string, string> | undefined;
|
|
36
|
-
}) => Promise<
|
|
37
|
+
}) => Promise<{
|
|
38
|
+
url: URL;
|
|
39
|
+
requestedScopes: string[];
|
|
40
|
+
}>;
|
|
37
41
|
validateAuthorizationCode: ({
|
|
38
42
|
code,
|
|
39
43
|
redirectURI
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
6
|
//#region src/social-providers/linkedin.ts
|
|
7
|
+
const LINKEDIN_DEFAULT_SCOPES = [
|
|
8
|
+
"profile",
|
|
9
|
+
"email",
|
|
10
|
+
"openid"
|
|
11
|
+
];
|
|
6
12
|
const linkedin = (options) => {
|
|
7
13
|
const authorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
|
|
8
14
|
const tokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
|
|
9
15
|
return {
|
|
10
16
|
id: "linkedin",
|
|
11
17
|
name: "Linkedin",
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"email",
|
|
16
|
-
"openid"
|
|
17
|
-
];
|
|
18
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
19
|
-
if (scopes) _scopes.push(...scopes);
|
|
20
|
-
return await createAuthorizationURL({
|
|
18
|
+
callbackPath: "/callback/linkedin",
|
|
19
|
+
createAuthorizationURL: ({ state, scopes, redirectURI, loginHint, additionalParams }) => {
|
|
20
|
+
return createAuthorizationURL({
|
|
21
21
|
id: "linkedin",
|
|
22
22
|
options,
|
|
23
23
|
authorizationEndpoint,
|
|
24
|
-
scopes:
|
|
24
|
+
scopes: resolveRequestedScopes(options, LINKEDIN_DEFAULT_SCOPES, scopes),
|
|
25
25
|
state,
|
|
26
26
|
loginHint,
|
|
27
27
|
redirectURI,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { ClientAssertionGetter } from "../oauth2/client-assertion.mjs";
|
|
1
2
|
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
3
|
+
import * as jose from "jose";
|
|
4
|
+
|
|
2
5
|
//#region src/social-providers/microsoft-entra-id.d.ts
|
|
3
6
|
/**
|
|
4
7
|
* @see [Microsoft Identity Platform - Optional claims reference](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims-reference)
|
|
@@ -109,25 +112,34 @@ interface MicrosoftOptions extends ProviderOptions<MicrosoftEntraIDProfile> {
|
|
|
109
112
|
* The tenant ID of the Microsoft account
|
|
110
113
|
* @default "common"
|
|
111
114
|
*/
|
|
112
|
-
tenantId?: string
|
|
115
|
+
tenantId?: string;
|
|
113
116
|
/**
|
|
114
117
|
* The authentication authority URL. Use the default "https://login.microsoftonline.com" for standard Entra ID or "https://<tenant-id>.ciamlogin.com" for CIAM scenarios.
|
|
115
118
|
* @default "https://login.microsoftonline.com"
|
|
116
119
|
*/
|
|
117
|
-
authority?: string
|
|
120
|
+
authority?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Function that returns a JWT client assertion for token endpoint authentication.
|
|
123
|
+
*
|
|
124
|
+
* Use this instead of `clientSecret` when your Microsoft Entra ID app is
|
|
125
|
+
* configured for client authentication with assertions (private_key_jwt or
|
|
126
|
+
* workload identity federation).
|
|
127
|
+
*/
|
|
128
|
+
clientAssertion?: ClientAssertionGetter;
|
|
118
129
|
/**
|
|
119
130
|
* The size of the profile photo
|
|
120
131
|
* @default 48
|
|
121
132
|
*/
|
|
122
|
-
profilePhotoSize?:
|
|
133
|
+
profilePhotoSize?: 48 | 64 | 96 | 120 | 240 | 360 | 432 | 504 | 648;
|
|
123
134
|
/**
|
|
124
135
|
* Disable profile photo
|
|
125
136
|
*/
|
|
126
|
-
disableProfilePhoto?: boolean
|
|
137
|
+
disableProfilePhoto?: boolean;
|
|
127
138
|
}
|
|
128
139
|
declare const microsoft: (options: MicrosoftOptions) => {
|
|
129
140
|
id: "microsoft";
|
|
130
141
|
name: string;
|
|
142
|
+
callbackPath: string;
|
|
131
143
|
createAuthorizationURL(data: {
|
|
132
144
|
state: string;
|
|
133
145
|
codeVerifier: string;
|
|
@@ -136,7 +148,10 @@ declare const microsoft: (options: MicrosoftOptions) => {
|
|
|
136
148
|
display?: string | undefined;
|
|
137
149
|
loginHint?: string | undefined;
|
|
138
150
|
additionalParams?: Record<string, string> | undefined;
|
|
139
|
-
}): Promise<
|
|
151
|
+
}): Promise<{
|
|
152
|
+
url: URL;
|
|
153
|
+
requestedScopes: string[];
|
|
154
|
+
}>;
|
|
140
155
|
validateAuthorizationCode({
|
|
141
156
|
code,
|
|
142
157
|
codeVerifier,
|
|
@@ -147,7 +162,17 @@ declare const microsoft: (options: MicrosoftOptions) => {
|
|
|
147
162
|
codeVerifier?: string | undefined;
|
|
148
163
|
deviceId?: string | undefined;
|
|
149
164
|
}): Promise<OAuth2Tokens>;
|
|
150
|
-
|
|
165
|
+
idToken: {
|
|
166
|
+
jwks: (header: jose.JWTHeaderParameters) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
|
|
167
|
+
audience: string | string[];
|
|
168
|
+
maxTokenAge: string;
|
|
169
|
+
/**
|
|
170
|
+
* Issuer varies per tenant for multi-tenant endpoints, so only validate it for
|
|
171
|
+
* specific tenants.
|
|
172
|
+
* @see https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols#endpoints
|
|
173
|
+
*/
|
|
174
|
+
issuer: string | undefined;
|
|
175
|
+
};
|
|
151
176
|
getUserInfo(token: OAuth2Tokens & {
|
|
152
177
|
user?: {
|
|
153
178
|
name?: {
|
|
@@ -1,42 +1,48 @@
|
|
|
1
1
|
import { APIError, BetterAuthError } from "../error/index.mjs";
|
|
2
2
|
import { logger } from "../env/logger.mjs";
|
|
3
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
3
4
|
import { getPrimaryClientId } from "../oauth2/utils.mjs";
|
|
4
5
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
5
6
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
6
7
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
7
8
|
import { base64 } from "@better-auth/utils/base64";
|
|
8
|
-
import { decodeJwt,
|
|
9
|
+
import { decodeJwt, importJWK } from "jose";
|
|
9
10
|
import { betterFetch } from "@better-fetch/fetch";
|
|
10
11
|
//#region src/social-providers/microsoft-entra-id.ts
|
|
12
|
+
const MICROSOFT_ENTRA_ID_DEFAULT_SCOPES = [
|
|
13
|
+
"openid",
|
|
14
|
+
"profile",
|
|
15
|
+
"email",
|
|
16
|
+
"User.Read",
|
|
17
|
+
"offline_access"
|
|
18
|
+
];
|
|
11
19
|
const microsoft = (options) => {
|
|
12
20
|
const tenant = options.tenantId || "common";
|
|
13
21
|
const authority = options.authority || "https://login.microsoftonline.com";
|
|
14
22
|
const authorizationEndpoint = `${authority}/${tenant}/oauth2/v2.0/authorize`;
|
|
15
23
|
const tokenEndpoint = `${authority}/${tenant}/oauth2/v2.0/token`;
|
|
24
|
+
if (options.clientSecret && options.clientAssertion) throw new BetterAuthError("Microsoft Entra ID clientAssertion cannot be combined with clientSecret");
|
|
25
|
+
const tokenEndpointAuth = options.clientAssertion ? {
|
|
26
|
+
method: "private_key_jwt",
|
|
27
|
+
getClientAssertion: options.clientAssertion
|
|
28
|
+
} : void 0;
|
|
16
29
|
return {
|
|
17
30
|
id: "microsoft",
|
|
18
31
|
name: "Microsoft EntraID",
|
|
32
|
+
callbackPath: "/callback/microsoft",
|
|
19
33
|
createAuthorizationURL(data) {
|
|
20
34
|
if (!getPrimaryClientId(options.clientId)) {
|
|
21
35
|
logger.error("Client Id is required for Microsoft Entra ID. Make sure to provide it in the options.");
|
|
22
36
|
throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
|
|
23
37
|
}
|
|
24
|
-
const
|
|
25
|
-
"openid",
|
|
26
|
-
"profile",
|
|
27
|
-
"email",
|
|
28
|
-
"User.Read",
|
|
29
|
-
"offline_access"
|
|
30
|
-
];
|
|
31
|
-
if (options.scope) scopes.push(...options.scope);
|
|
32
|
-
if (data.scopes) scopes.push(...data.scopes);
|
|
38
|
+
const requestedScopes = resolveRequestedScopes(options, MICROSOFT_ENTRA_ID_DEFAULT_SCOPES, data.scopes);
|
|
33
39
|
return createAuthorizationURL({
|
|
34
40
|
id: "microsoft",
|
|
35
41
|
options,
|
|
36
42
|
authorizationEndpoint,
|
|
37
43
|
state: data.state,
|
|
38
44
|
codeVerifier: data.codeVerifier,
|
|
39
|
-
scopes,
|
|
45
|
+
scopes: requestedScopes,
|
|
40
46
|
redirectURI: data.redirectURI,
|
|
41
47
|
prompt: options.prompt,
|
|
42
48
|
loginHint: data.loginHint,
|
|
@@ -49,33 +55,15 @@ const microsoft = (options) => {
|
|
|
49
55
|
codeVerifier,
|
|
50
56
|
redirectURI,
|
|
51
57
|
options,
|
|
52
|
-
tokenEndpoint
|
|
58
|
+
tokenEndpoint,
|
|
59
|
+
tokenEndpointAuth
|
|
53
60
|
});
|
|
54
61
|
},
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (!kid || !jwtAlg) return false;
|
|
61
|
-
const publicKey = await getMicrosoftPublicKey(kid, tenant, authority);
|
|
62
|
-
const verifyOptions = {
|
|
63
|
-
algorithms: [jwtAlg],
|
|
64
|
-
audience: options.clientId,
|
|
65
|
-
maxTokenAge: "1h"
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
* Issuer varies per user's tenant for multi-tenant endpoints, so only validate for specific tenants.
|
|
69
|
-
* @see https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols#endpoints
|
|
70
|
-
*/
|
|
71
|
-
if (tenant !== "common" && tenant !== "organizations" && tenant !== "consumers") verifyOptions.issuer = `${authority}/${tenant}/v2.0`;
|
|
72
|
-
const { payload: jwtClaims } = await jwtVerify(token, publicKey, verifyOptions);
|
|
73
|
-
if (nonce && jwtClaims.nonce !== nonce) return false;
|
|
74
|
-
return true;
|
|
75
|
-
} catch (error) {
|
|
76
|
-
logger.error("Failed to verify ID token:", error);
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
62
|
+
idToken: {
|
|
63
|
+
jwks: (header) => getMicrosoftPublicKey(header.kid, tenant, authority),
|
|
64
|
+
audience: options.clientId,
|
|
65
|
+
maxTokenAge: "1h",
|
|
66
|
+
issuer: tenant !== "common" && tenant !== "organizations" && tenant !== "consumers" ? `${authority}/${tenant}/v2.0` : void 0
|
|
79
67
|
},
|
|
80
68
|
async getUserInfo(token) {
|
|
81
69
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
@@ -124,7 +112,8 @@ const microsoft = (options) => {
|
|
|
124
112
|
clientSecret: options.clientSecret
|
|
125
113
|
},
|
|
126
114
|
extraParams: { scope: scopes.join(" ") },
|
|
127
|
-
tokenEndpoint
|
|
115
|
+
tokenEndpoint,
|
|
116
|
+
tokenEndpointAuth
|
|
128
117
|
});
|
|
129
118
|
},
|
|
130
119
|
options
|
|
@@ -24,6 +24,7 @@ interface NaverOptions extends ProviderOptions<NaverProfile> {
|
|
|
24
24
|
declare const naver: (options: NaverOptions) => {
|
|
25
25
|
id: "naver";
|
|
26
26
|
name: string;
|
|
27
|
+
callbackPath: string;
|
|
27
28
|
createAuthorizationURL({
|
|
28
29
|
state,
|
|
29
30
|
scopes,
|
|
@@ -37,7 +38,10 @@ declare const naver: (options: NaverOptions) => {
|
|
|
37
38
|
display?: string | undefined;
|
|
38
39
|
loginHint?: string | undefined;
|
|
39
40
|
additionalParams?: Record<string, string> | undefined;
|
|
40
|
-
}): Promise<
|
|
41
|
+
}): Promise<{
|
|
42
|
+
url: URL;
|
|
43
|
+
requestedScopes: string[];
|
|
44
|
+
}>;
|
|
41
45
|
validateAuthorizationCode: ({
|
|
42
46
|
code,
|
|
43
47
|
redirectURI
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
6
|
//#region src/social-providers/naver.ts
|
|
7
|
+
const NAVER_DEFAULT_SCOPES = ["profile", "email"];
|
|
6
8
|
const naver = (options) => {
|
|
7
9
|
const tokenEndpoint = "https://nid.naver.com/oauth2.0/token";
|
|
8
10
|
return {
|
|
9
11
|
id: "naver",
|
|
10
12
|
name: "Naver",
|
|
13
|
+
callbackPath: "/callback/naver",
|
|
11
14
|
createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
|
|
12
|
-
const _scopes = options.disableDefaultScope ? [] : ["profile", "email"];
|
|
13
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
14
|
-
if (scopes) _scopes.push(...scopes);
|
|
15
15
|
return createAuthorizationURL({
|
|
16
16
|
id: "naver",
|
|
17
17
|
options,
|
|
18
18
|
authorizationEndpoint: "https://nid.naver.com/oauth2.0/authorize",
|
|
19
|
-
scopes:
|
|
19
|
+
scopes: resolveRequestedScopes(options, NAVER_DEFAULT_SCOPES, scopes),
|
|
20
20
|
state,
|
|
21
21
|
redirectURI,
|
|
22
22
|
additionalParams
|
|
@@ -16,6 +16,7 @@ interface NotionOptions extends ProviderOptions<NotionProfile> {
|
|
|
16
16
|
declare const notion: (options: NotionOptions) => {
|
|
17
17
|
id: "notion";
|
|
18
18
|
name: string;
|
|
19
|
+
callbackPath: string;
|
|
19
20
|
createAuthorizationURL({
|
|
20
21
|
state,
|
|
21
22
|
scopes,
|
|
@@ -30,7 +31,10 @@ declare const notion: (options: NotionOptions) => {
|
|
|
30
31
|
display?: string | undefined;
|
|
31
32
|
loginHint?: string | undefined;
|
|
32
33
|
additionalParams?: Record<string, string> | undefined;
|
|
33
|
-
}): Promise<
|
|
34
|
+
}): Promise<{
|
|
35
|
+
url: URL;
|
|
36
|
+
requestedScopes: string[];
|
|
37
|
+
}>;
|
|
34
38
|
validateAuthorizationCode: ({
|
|
35
39
|
code,
|
|
36
40
|
redirectURI
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
1
2
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
3
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
4
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
6
|
//#region src/social-providers/notion.ts
|
|
7
|
+
const NOTION_DEFAULT_SCOPES = [];
|
|
6
8
|
const notion = (options) => {
|
|
7
9
|
const tokenEndpoint = "https://api.notion.com/v1/oauth/token";
|
|
8
10
|
return {
|
|
9
11
|
id: "notion",
|
|
10
12
|
name: "Notion",
|
|
13
|
+
callbackPath: "/callback/notion",
|
|
11
14
|
createAuthorizationURL({ state, scopes, loginHint, redirectURI, additionalParams }) {
|
|
12
|
-
const _scopes = options.disableDefaultScope ? [] : [];
|
|
13
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
14
|
-
if (scopes) _scopes.push(...scopes);
|
|
15
15
|
return createAuthorizationURL({
|
|
16
16
|
id: "notion",
|
|
17
17
|
options,
|
|
18
18
|
authorizationEndpoint: "https://api.notion.com/v1/oauth/authorize",
|
|
19
|
-
scopes:
|
|
19
|
+
scopes: resolveRequestedScopes(options, NOTION_DEFAULT_SCOPES, scopes),
|
|
20
20
|
state,
|
|
21
21
|
redirectURI,
|
|
22
22
|
loginHint,
|
|
@@ -21,6 +21,7 @@ interface PaybinOptions extends ProviderOptions<PaybinProfile> {
|
|
|
21
21
|
declare const paybin: (options: PaybinOptions) => {
|
|
22
22
|
id: "paybin";
|
|
23
23
|
name: string;
|
|
24
|
+
callbackPath: string;
|
|
24
25
|
createAuthorizationURL({
|
|
25
26
|
state,
|
|
26
27
|
scopes,
|
|
@@ -36,7 +37,10 @@ declare const paybin: (options: PaybinOptions) => {
|
|
|
36
37
|
display?: string | undefined;
|
|
37
38
|
loginHint?: string | undefined;
|
|
38
39
|
additionalParams?: Record<string, string> | undefined;
|
|
39
|
-
}): Promise<
|
|
40
|
+
}): Promise<{
|
|
41
|
+
url: URL;
|
|
42
|
+
requestedScopes: string[];
|
|
43
|
+
}>;
|
|
40
44
|
validateAuthorizationCode: ({
|
|
41
45
|
code,
|
|
42
46
|
codeVerifier,
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { BetterAuthError } from "../error/index.mjs";
|
|
2
2
|
import { logger } from "../env/logger.mjs";
|
|
3
|
+
import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
|
|
3
4
|
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
4
5
|
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
5
6
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
6
7
|
import { decodeJwt } from "jose";
|
|
7
8
|
//#region src/social-providers/paybin.ts
|
|
9
|
+
const PAYBIN_DEFAULT_SCOPES = [
|
|
10
|
+
"openid",
|
|
11
|
+
"email",
|
|
12
|
+
"profile"
|
|
13
|
+
];
|
|
8
14
|
const paybin = (options) => {
|
|
9
15
|
const issuer = options.issuer || "https://idp.paybin.io";
|
|
10
16
|
const authorizationEndpoint = `${issuer}/oauth2/authorize`;
|
|
@@ -12,24 +18,18 @@ const paybin = (options) => {
|
|
|
12
18
|
return {
|
|
13
19
|
id: "paybin",
|
|
14
20
|
name: "Paybin",
|
|
15
|
-
|
|
21
|
+
callbackPath: "/callback/paybin",
|
|
22
|
+
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, loginHint, additionalParams }) {
|
|
16
23
|
if (!options.clientId || !options.clientSecret) {
|
|
17
24
|
logger.error("Client Id and Client Secret is required for Paybin. Make sure to provide them in the options.");
|
|
18
25
|
throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
|
|
19
26
|
}
|
|
20
27
|
if (!codeVerifier) throw new BetterAuthError("codeVerifier is required for Paybin");
|
|
21
|
-
|
|
22
|
-
"openid",
|
|
23
|
-
"email",
|
|
24
|
-
"profile"
|
|
25
|
-
];
|
|
26
|
-
if (options.scope) _scopes.push(...options.scope);
|
|
27
|
-
if (scopes) _scopes.push(...scopes);
|
|
28
|
-
return await createAuthorizationURL({
|
|
28
|
+
return createAuthorizationURL({
|
|
29
29
|
id: "paybin",
|
|
30
30
|
options,
|
|
31
31
|
authorizationEndpoint,
|
|
32
|
-
scopes:
|
|
32
|
+
scopes: resolveRequestedScopes(options, PAYBIN_DEFAULT_SCOPES, scopes),
|
|
33
33
|
state,
|
|
34
34
|
codeVerifier,
|
|
35
35
|
redirectURI,
|