@better-auth/core 1.7.0-beta.7 → 1.7.0-beta.9

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.
Files changed (140) hide show
  1. package/dist/api/index.d.mts +3 -3
  2. package/dist/context/global.mjs +1 -1
  3. package/dist/db/adapter/factory.mjs +1 -1
  4. package/dist/db/get-tables.mjs +3 -3
  5. package/dist/db/schema/account.d.mts +1 -1
  6. package/dist/db/schema/account.mjs +1 -1
  7. package/dist/error/codes.d.mts +0 -5
  8. package/dist/error/codes.mjs +0 -5
  9. package/dist/instrumentation/tracer.mjs +1 -1
  10. package/dist/oauth2/create-authorization-url.d.mts +1 -4
  11. package/dist/oauth2/create-authorization-url.mjs +1 -4
  12. package/dist/oauth2/index.d.mts +3 -4
  13. package/dist/oauth2/index.mjs +2 -3
  14. package/dist/oauth2/oauth-provider.d.mts +12 -50
  15. package/dist/oauth2/refresh-access-token.mjs +2 -1
  16. package/dist/oauth2/utils.d.mts +6 -1
  17. package/dist/oauth2/utils.mjs +24 -2
  18. package/dist/oauth2/verify-id-token.d.mts +6 -5
  19. package/dist/oauth2/verify-id-token.mjs +2 -2
  20. package/dist/social-providers/apple.d.mts +1 -5
  21. package/dist/social-providers/apple.mjs +5 -5
  22. package/dist/social-providers/atlassian.d.mts +1 -5
  23. package/dist/social-providers/atlassian.mjs +4 -4
  24. package/dist/social-providers/cognito.d.mts +1 -5
  25. package/dist/social-providers/cognito.mjs +11 -18
  26. package/dist/social-providers/discord.d.mts +1 -5
  27. package/dist/social-providers/discord.mjs +6 -7
  28. package/dist/social-providers/dropbox.d.mts +1 -5
  29. package/dist/social-providers/dropbox.mjs +5 -5
  30. package/dist/social-providers/facebook.d.mts +1 -5
  31. package/dist/social-providers/facebook.mjs +5 -5
  32. package/dist/social-providers/figma.d.mts +1 -5
  33. package/dist/social-providers/figma.mjs +5 -5
  34. package/dist/social-providers/github.d.mts +1 -5
  35. package/dist/social-providers/github.mjs +4 -4
  36. package/dist/social-providers/gitlab.d.mts +1 -5
  37. package/dist/social-providers/gitlab.mjs +6 -6
  38. package/dist/social-providers/google.d.mts +8 -10
  39. package/dist/social-providers/google.mjs +12 -13
  40. package/dist/social-providers/huggingface.d.mts +1 -5
  41. package/dist/social-providers/huggingface.mjs +8 -8
  42. package/dist/social-providers/index.d.mts +35 -177
  43. package/dist/social-providers/kakao.d.mts +1 -5
  44. package/dist/social-providers/kakao.mjs +8 -8
  45. package/dist/social-providers/kick.d.mts +1 -5
  46. package/dist/social-providers/kick.mjs +4 -4
  47. package/dist/social-providers/line.d.mts +1 -5
  48. package/dist/social-providers/line.mjs +10 -10
  49. package/dist/social-providers/linear.d.mts +1 -5
  50. package/dist/social-providers/linear.mjs +4 -4
  51. package/dist/social-providers/linkedin.d.mts +1 -5
  52. package/dist/social-providers/linkedin.mjs +10 -10
  53. package/dist/social-providers/microsoft-entra-id.d.mts +1 -5
  54. package/dist/social-providers/microsoft-entra-id.mjs +10 -11
  55. package/dist/social-providers/naver.d.mts +1 -5
  56. package/dist/social-providers/naver.mjs +4 -4
  57. package/dist/social-providers/notion.d.mts +1 -5
  58. package/dist/social-providers/notion.mjs +4 -4
  59. package/dist/social-providers/paybin.d.mts +1 -5
  60. package/dist/social-providers/paybin.mjs +10 -10
  61. package/dist/social-providers/paypal.d.mts +1 -5
  62. package/dist/social-providers/paypal.mjs +2 -8
  63. package/dist/social-providers/polar.d.mts +1 -5
  64. package/dist/social-providers/polar.mjs +8 -8
  65. package/dist/social-providers/railway.d.mts +1 -5
  66. package/dist/social-providers/railway.mjs +9 -9
  67. package/dist/social-providers/reddit.d.mts +1 -5
  68. package/dist/social-providers/reddit.mjs +5 -5
  69. package/dist/social-providers/roblox.d.mts +1 -5
  70. package/dist/social-providers/roblox.mjs +5 -5
  71. package/dist/social-providers/salesforce.d.mts +1 -5
  72. package/dist/social-providers/salesforce.mjs +8 -8
  73. package/dist/social-providers/slack.d.mts +1 -5
  74. package/dist/social-providers/slack.mjs +9 -9
  75. package/dist/social-providers/spotify.d.mts +1 -5
  76. package/dist/social-providers/spotify.mjs +5 -5
  77. package/dist/social-providers/tiktok.d.mts +1 -5
  78. package/dist/social-providers/tiktok.mjs +5 -9
  79. package/dist/social-providers/twitch.d.mts +1 -5
  80. package/dist/social-providers/twitch.mjs +4 -4
  81. package/dist/social-providers/twitter.d.mts +1 -5
  82. package/dist/social-providers/twitter.mjs +9 -9
  83. package/dist/social-providers/vercel.d.mts +1 -5
  84. package/dist/social-providers/vercel.mjs +7 -4
  85. package/dist/social-providers/vk.d.mts +1 -5
  86. package/dist/social-providers/vk.mjs +5 -5
  87. package/dist/social-providers/wechat.d.mts +1 -5
  88. package/dist/social-providers/wechat.mjs +5 -9
  89. package/dist/social-providers/zoom.d.mts +1 -6
  90. package/dist/social-providers/zoom.mjs +9 -15
  91. package/dist/types/context.d.mts +6 -2
  92. package/package.json +1 -1
  93. package/src/db/get-tables.ts +3 -8
  94. package/src/db/schema/account.ts +5 -14
  95. package/src/error/codes.ts +0 -5
  96. package/src/oauth2/create-authorization-url.ts +1 -1
  97. package/src/oauth2/index.ts +2 -12
  98. package/src/oauth2/oauth-provider.ts +11 -56
  99. package/src/oauth2/refresh-access-token.ts +3 -2
  100. package/src/oauth2/utils.ts +39 -1
  101. package/src/oauth2/verify-id-token.ts +7 -5
  102. package/src/social-providers/apple.ts +8 -13
  103. package/src/social-providers/atlassian.ts +8 -12
  104. package/src/social-providers/cognito.ts +11 -18
  105. package/src/social-providers/discord.ts +8 -19
  106. package/src/social-providers/dropbox.ts +7 -13
  107. package/src/social-providers/facebook.ts +9 -13
  108. package/src/social-providers/figma.ts +9 -13
  109. package/src/social-providers/github.ts +8 -12
  110. package/src/social-providers/gitlab.ts +8 -14
  111. package/src/social-providers/google.ts +23 -29
  112. package/src/social-providers/huggingface.ts +8 -12
  113. package/src/social-providers/kakao.ts +8 -16
  114. package/src/social-providers/kick.ts +7 -12
  115. package/src/social-providers/line.ts +10 -14
  116. package/src/social-providers/linear.ts +6 -12
  117. package/src/social-providers/linkedin.ts +10 -14
  118. package/src/social-providers/microsoft-entra-id.ts +8 -18
  119. package/src/social-providers/naver.ts +6 -12
  120. package/src/social-providers/notion.ts +6 -12
  121. package/src/social-providers/paybin.ts +11 -14
  122. package/src/social-providers/paypal.ts +8 -6
  123. package/src/social-providers/polar.ts +8 -12
  124. package/src/social-providers/railway.ts +9 -13
  125. package/src/social-providers/reddit.ts +7 -18
  126. package/src/social-providers/roblox.ts +7 -18
  127. package/src/social-providers/salesforce.ts +8 -12
  128. package/src/social-providers/slack.ts +9 -18
  129. package/src/social-providers/spotify.ts +7 -13
  130. package/src/social-providers/tiktok.ts +7 -13
  131. package/src/social-providers/twitch.ts +8 -12
  132. package/src/social-providers/twitter.ts +8 -17
  133. package/src/social-providers/vercel.ts +10 -16
  134. package/src/social-providers/vk.ts +7 -13
  135. package/src/social-providers/wechat.ts +8 -20
  136. package/src/social-providers/zoom.ts +6 -19
  137. package/src/types/context.ts +8 -2
  138. package/dist/oauth2/scopes.d.mts +0 -76
  139. package/dist/oauth2/scopes.mjs +0 -96
  140. package/src/oauth2/scopes.ts +0 -118
@@ -1,9 +1,8 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
2
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
3
  import {
4
4
  createAuthorizationURL,
5
5
  refreshAccessToken,
6
- resolveRequestedScopes,
7
6
  validateAuthorizationCode,
8
7
  } from "../oauth2";
9
8
 
@@ -26,15 +25,12 @@ export interface DropboxOptions extends ProviderOptions<DropboxProfile> {
26
25
  accessType?: ("offline" | "online" | "legacy") | undefined;
27
26
  }
28
27
 
29
- const DROPBOX_DEFAULT_SCOPES = ["account_info.read"];
30
-
31
28
  export const dropbox = (options: DropboxOptions) => {
32
29
  const tokenEndpoint = "https://api.dropboxapi.com/oauth2/token";
33
30
 
34
31
  return {
35
32
  id: "dropbox",
36
33
  name: "Dropbox",
37
- callbackPath: "/callback/dropbox",
38
34
  createAuthorizationURL: async ({
39
35
  state,
40
36
  scopes,
@@ -42,16 +38,14 @@ export const dropbox = (options: DropboxOptions) => {
42
38
  redirectURI,
43
39
  additionalParams,
44
40
  }) => {
45
- const requestedScopes = resolveRequestedScopes(
46
- options,
47
- DROPBOX_DEFAULT_SCOPES,
48
- scopes,
49
- );
50
- return createAuthorizationURL({
41
+ const _scopes = options.disableDefaultScope ? [] : ["account_info.read"];
42
+ if (options.scope) _scopes.push(...options.scope);
43
+ if (scopes) _scopes.push(...scopes);
44
+ return await createAuthorizationURL({
51
45
  id: "dropbox",
52
46
  options,
53
47
  authorizationEndpoint: "https://www.dropbox.com/oauth2/authorize",
54
- scopes: requestedScopes,
48
+ scopes: _scopes,
55
49
  state,
56
50
  redirectURI,
57
51
  codeVerifier,
@@ -116,5 +110,5 @@ export const dropbox = (options: DropboxOptions) => {
116
110
  };
117
111
  },
118
112
  options,
119
- } satisfies UpstreamProvider<DropboxProfile>;
113
+ } satisfies OAuthProvider<DropboxProfile>;
120
114
  };
@@ -2,12 +2,11 @@ import { betterFetch } from "@better-fetch/fetch";
2
2
  import { createRemoteJWKSet, decodeJwt } from "jose";
3
3
  import { logger } from "../env";
4
4
  import { BetterAuthError } from "../error";
5
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
5
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
6
6
  import {
7
7
  createAuthorizationURL,
8
8
  getPrimaryClientId,
9
9
  refreshAccessToken,
10
- resolveRequestedScopes,
11
10
  validateAuthorizationCode,
12
11
  } from "../oauth2";
13
12
  export interface FacebookProfile {
@@ -92,13 +91,10 @@ export interface FacebookOptions extends ProviderOptions<FacebookProfile> {
92
91
  configId?: string | undefined;
93
92
  }
94
93
 
95
- const FACEBOOK_DEFAULT_SCOPES = ["email", "public_profile"];
96
-
97
94
  export const facebook = (options: FacebookOptions) => {
98
95
  return {
99
96
  id: "facebook",
100
97
  name: "Facebook",
101
- callbackPath: "/callback/facebook",
102
98
  async createAuthorizationURL({
103
99
  state,
104
100
  scopes,
@@ -112,16 +108,16 @@ export const facebook = (options: FacebookOptions) => {
112
108
  );
113
109
  throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
114
110
  }
115
- const requestedScopes = resolveRequestedScopes(
116
- options,
117
- FACEBOOK_DEFAULT_SCOPES,
118
- scopes,
119
- );
120
- return createAuthorizationURL({
111
+ const _scopes = options.disableDefaultScope
112
+ ? []
113
+ : ["email", "public_profile"];
114
+ if (options.scope) _scopes.push(...options.scope);
115
+ if (scopes) _scopes.push(...scopes);
116
+ return await createAuthorizationURL({
121
117
  id: "facebook",
122
118
  options,
123
119
  authorizationEndpoint: "https://www.facebook.com/v24.0/dialog/oauth",
124
- scopes: requestedScopes,
120
+ scopes: _scopes,
125
121
  state,
126
122
  redirectURI,
127
123
  loginHint,
@@ -262,5 +258,5 @@ export const facebook = (options: FacebookOptions) => {
262
258
  };
263
259
  },
264
260
  options,
265
- } satisfies UpstreamProvider<FacebookProfile>;
261
+ } satisfies OAuthProvider<FacebookProfile>;
266
262
  };
@@ -1,11 +1,10 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
2
  import { logger } from "../env";
3
3
  import { BetterAuthError } from "../error";
4
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
4
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
5
5
  import {
6
6
  createAuthorizationURL,
7
7
  refreshAccessToken,
8
- resolveRequestedScopes,
9
8
  validateAuthorizationCode,
10
9
  } from "../oauth2";
11
10
 
@@ -20,14 +19,11 @@ export interface FigmaOptions extends ProviderOptions<FigmaProfile> {
20
19
  clientId: string;
21
20
  }
22
21
 
23
- const FIGMA_DEFAULT_SCOPES = ["current_user:read"];
24
-
25
22
  export const figma = (options: FigmaOptions) => {
26
23
  const tokenEndpoint = "https://api.figma.com/v1/oauth/token";
27
24
  return {
28
25
  id: "figma",
29
26
  name: "Figma",
30
- callbackPath: "/callback/figma",
31
27
  async createAuthorizationURL({
32
28
  state,
33
29
  scopes,
@@ -45,22 +41,22 @@ export const figma = (options: FigmaOptions) => {
45
41
  throw new BetterAuthError("codeVerifier is required for Figma");
46
42
  }
47
43
 
48
- const requestedScopes = resolveRequestedScopes(
49
- options,
50
- FIGMA_DEFAULT_SCOPES,
51
- scopes,
52
- );
44
+ const _scopes = options.disableDefaultScope ? [] : ["current_user:read"];
45
+ if (options.scope) _scopes.push(...options.scope);
46
+ if (scopes) _scopes.push(...scopes);
53
47
 
54
- return createAuthorizationURL({
48
+ const url = await createAuthorizationURL({
55
49
  id: "figma",
56
50
  options,
57
51
  authorizationEndpoint: "https://www.figma.com/oauth",
58
- scopes: requestedScopes,
52
+ scopes: _scopes,
59
53
  state,
60
54
  codeVerifier,
61
55
  redirectURI,
62
56
  additionalParams,
63
57
  });
58
+
59
+ return url;
64
60
  },
65
61
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
66
62
  return validateAuthorizationCode({
@@ -125,5 +121,5 @@ export const figma = (options: FigmaOptions) => {
125
121
  }
126
122
  },
127
123
  options,
128
- } satisfies UpstreamProvider<FigmaProfile>;
124
+ } satisfies OAuthProvider<FigmaProfile>;
129
125
  };
@@ -1,11 +1,10 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
2
  import { logger } from "../env";
3
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
3
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
4
4
  import {
5
5
  createAuthorizationURL,
6
6
  getOAuth2Tokens,
7
7
  refreshAccessToken,
8
- resolveRequestedScopes,
9
8
  } from "../oauth2";
10
9
  import { authorizationCodeRequest } from "../oauth2/validate-authorization-code";
11
10
 
@@ -59,14 +58,11 @@ export interface GithubProfile {
59
58
  export interface GithubOptions extends ProviderOptions<GithubProfile> {
60
59
  clientId: string;
61
60
  }
62
- const GITHUB_DEFAULT_SCOPES = ["read:user", "user:email"];
63
-
64
61
  export const github = (options: GithubOptions) => {
65
62
  const tokenEndpoint = "https://github.com/login/oauth/access_token";
66
63
  return {
67
64
  id: "github",
68
65
  name: "GitHub",
69
- callbackPath: "/callback/github",
70
66
  createAuthorizationURL({
71
67
  state,
72
68
  scopes,
@@ -75,16 +71,16 @@ export const github = (options: GithubOptions) => {
75
71
  redirectURI,
76
72
  additionalParams,
77
73
  }) {
78
- const requestedScopes = resolveRequestedScopes(
79
- options,
80
- GITHUB_DEFAULT_SCOPES,
81
- scopes,
82
- );
74
+ const _scopes = options.disableDefaultScope
75
+ ? []
76
+ : ["read:user", "user:email"];
77
+ if (options.scope) _scopes.push(...options.scope);
78
+ if (scopes) _scopes.push(...scopes);
83
79
  return createAuthorizationURL({
84
80
  id: "github",
85
81
  options,
86
82
  authorizationEndpoint: "https://github.com/login/oauth/authorize",
87
- scopes: requestedScopes,
83
+ scopes: _scopes,
88
84
  state,
89
85
  codeVerifier,
90
86
  redirectURI,
@@ -186,5 +182,5 @@ export const github = (options: GithubOptions) => {
186
182
  };
187
183
  },
188
184
  options,
189
- } satisfies UpstreamProvider<GithubProfile>;
185
+ } satisfies OAuthProvider<GithubProfile>;
190
186
  };
@@ -1,9 +1,8 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
2
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
3
  import {
4
4
  createAuthorizationURL,
5
5
  refreshAccessToken,
6
- resolveRequestedScopes,
7
6
  validateAuthorizationCode,
8
7
  } from "../oauth2";
9
8
 
@@ -74,8 +73,6 @@ const issuerToEndpoints = (issuer?: string | undefined) => {
74
73
  };
75
74
  };
76
75
 
77
- const GITLAB_DEFAULT_SCOPES = ["read_user"];
78
-
79
76
  export const gitlab = (options: GitlabOptions) => {
80
77
  const { authorizationEndpoint, tokenEndpoint, userinfoEndpoint } =
81
78
  issuerToEndpoints(options.issuer);
@@ -84,8 +81,7 @@ export const gitlab = (options: GitlabOptions) => {
84
81
  return {
85
82
  id: issuerId,
86
83
  name: issuerName,
87
- callbackPath: "/callback/gitlab",
88
- createAuthorizationURL: ({
84
+ createAuthorizationURL: async ({
89
85
  state,
90
86
  scopes,
91
87
  codeVerifier,
@@ -93,16 +89,14 @@ export const gitlab = (options: GitlabOptions) => {
93
89
  redirectURI,
94
90
  additionalParams,
95
91
  }) => {
96
- const requestedScopes = resolveRequestedScopes(
97
- options,
98
- GITLAB_DEFAULT_SCOPES,
99
- scopes,
100
- );
101
- return createAuthorizationURL({
92
+ const _scopes = options.disableDefaultScope ? [] : ["read_user"];
93
+ if (options.scope) _scopes.push(...options.scope);
94
+ if (scopes) _scopes.push(...scopes);
95
+ return await createAuthorizationURL({
102
96
  id: issuerId,
103
97
  options,
104
98
  authorizationEndpoint,
105
- scopes: requestedScopes,
99
+ scopes: _scopes,
106
100
  state,
107
101
  redirectURI,
108
102
  codeVerifier,
@@ -159,5 +153,5 @@ export const gitlab = (options: GitlabOptions) => {
159
153
  };
160
154
  },
161
155
  options,
162
- } satisfies UpstreamProvider<GitlabProfile>;
156
+ } satisfies OAuthProvider<GitlabProfile>;
163
157
  };
@@ -2,12 +2,11 @@ import { betterFetch } from "@better-fetch/fetch";
2
2
  import { decodeJwt, importJWK } from "jose";
3
3
  import { logger } from "../env";
4
4
  import { APIError, BetterAuthError } from "../error";
5
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
5
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
6
6
  import {
7
7
  createAuthorizationURL,
8
8
  getPrimaryClientId,
9
9
  refreshAccessToken,
10
- resolveRequestedScopes,
11
10
  validateAuthorizationCode,
12
11
  } from "../oauth2";
13
12
 
@@ -58,24 +57,22 @@ export interface GoogleOptions extends ProviderOptions<GoogleProfile> {
58
57
  */
59
58
  hd?: string | undefined;
60
59
  /**
61
- * Enable incremental authorization via Google's `include_granted_scopes`
62
- * parameter. When enabled, Google reports the user's full granted scope set
63
- * in the token response.
60
+ * Whether to send `include_granted_scopes=true` to Google's authorization
61
+ * endpoint, which lets new access tokens cover scopes from prior grants
62
+ * in addition to the ones requested for this flow. Set to `false` when
63
+ * each OAuth flow should request only its own scopes.
64
64
  *
65
- * @default true
65
+ * Defaults to `true`.
66
+ *
67
+ * @see https://developers.google.com/identity/protocols/oauth2/web-server#incrementalAuth
66
68
  */
67
69
  includeGrantedScopes?: boolean | undefined;
68
70
  }
69
71
 
70
- const GOOGLE_DEFAULT_SCOPES = ["email", "profile", "openid"];
71
-
72
72
  export const google = (options: GoogleOptions) => {
73
73
  return {
74
74
  id: "google",
75
75
  name: "Google",
76
- callbackPath: "/callback/google",
77
- grantAuthority:
78
- options.includeGrantedScopes !== false ? "full-grant" : "projection",
79
76
  async createAuthorizationURL({
80
77
  state,
81
78
  scopes,
@@ -94,16 +91,16 @@ export const google = (options: GoogleOptions) => {
94
91
  if (!codeVerifier) {
95
92
  throw new BetterAuthError("codeVerifier is required for Google");
96
93
  }
97
- const requestedScopes = resolveRequestedScopes(
98
- options,
99
- GOOGLE_DEFAULT_SCOPES,
100
- scopes,
101
- );
102
- return createAuthorizationURL({
94
+ const _scopes = options.disableDefaultScope
95
+ ? []
96
+ : ["email", "profile", "openid"];
97
+ if (options.scope) _scopes.push(...options.scope);
98
+ if (scopes) _scopes.push(...scopes);
99
+ const url = await createAuthorizationURL({
103
100
  id: "google",
104
101
  options,
105
102
  authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
106
- scopes: requestedScopes,
103
+ scopes: _scopes,
107
104
  state,
108
105
  codeVerifier,
109
106
  redirectURI,
@@ -112,17 +109,14 @@ export const google = (options: GoogleOptions) => {
112
109
  display: display || options.display,
113
110
  loginHint,
114
111
  hd: options.hd,
115
- additionalParams:
116
- options.includeGrantedScopes === false
117
- ? { ...(additionalParams ?? {}) }
118
- : {
119
- ...(additionalParams ?? {}),
120
- // Not caller-overridable: the emitted param must stay in
121
- // lockstep with `grantAuthority` (driven by the option), or
122
- // the callback would treat a non-authoritative grant as full.
123
- include_granted_scopes: "true",
124
- },
112
+ additionalParams: {
113
+ ...(options.includeGrantedScopes === false
114
+ ? {}
115
+ : { include_granted_scopes: "true" }),
116
+ ...(additionalParams ?? {}),
117
+ },
125
118
  });
119
+ return url;
126
120
  },
127
121
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
128
122
  return validateAuthorizationCode({
@@ -195,7 +189,7 @@ export const google = (options: GoogleOptions) => {
195
189
  };
196
190
  },
197
191
  options,
198
- } satisfies UpstreamProvider<GoogleProfile>;
192
+ } satisfies OAuthProvider<GoogleProfile>;
199
193
  };
200
194
 
201
195
  export const getGooglePublicKey = async (kid: string) => {
@@ -1,9 +1,8 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
2
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
3
  import {
4
4
  createAuthorizationURL,
5
5
  refreshAccessToken,
6
- resolveRequestedScopes,
7
6
  validateAuthorizationCode,
8
7
  } from "../oauth2";
9
8
 
@@ -43,14 +42,11 @@ export interface HuggingFaceOptions
43
42
  clientId: string;
44
43
  }
45
44
 
46
- const HUGGINGFACE_DEFAULT_SCOPES = ["openid", "profile", "email"];
47
-
48
45
  export const huggingface = (options: HuggingFaceOptions) => {
49
46
  const tokenEndpoint = "https://huggingface.co/oauth/token";
50
47
  return {
51
48
  id: "huggingface",
52
49
  name: "Hugging Face",
53
- callbackPath: "/callback/huggingface",
54
50
  createAuthorizationURL({
55
51
  state,
56
52
  scopes,
@@ -58,16 +54,16 @@ export const huggingface = (options: HuggingFaceOptions) => {
58
54
  redirectURI,
59
55
  additionalParams,
60
56
  }) {
61
- const requestedScopes = resolveRequestedScopes(
62
- options,
63
- HUGGINGFACE_DEFAULT_SCOPES,
64
- scopes,
65
- );
57
+ const _scopes = options.disableDefaultScope
58
+ ? []
59
+ : ["openid", "profile", "email"];
60
+ if (options.scope) _scopes.push(...options.scope);
61
+ if (scopes) _scopes.push(...scopes);
66
62
  return createAuthorizationURL({
67
63
  id: "huggingface",
68
64
  options,
69
65
  authorizationEndpoint: "https://huggingface.co/oauth/authorize",
70
- scopes: requestedScopes,
66
+ scopes: _scopes,
71
67
  state,
72
68
  codeVerifier,
73
69
  redirectURI,
@@ -126,5 +122,5 @@ export const huggingface = (options: HuggingFaceOptions) => {
126
122
  };
127
123
  },
128
124
  options,
129
- } satisfies UpstreamProvider<HuggingFaceProfile>;
125
+ } satisfies OAuthProvider<HuggingFaceProfile>;
130
126
  };
@@ -1,9 +1,8 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
2
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
3
  import {
4
4
  createAuthorizationURL,
5
5
  refreshAccessToken,
6
- resolveRequestedScopes,
7
6
  validateAuthorizationCode,
8
7
  } from "../oauth2";
9
8
 
@@ -102,29 +101,22 @@ export interface KakaoOptions extends ProviderOptions<KakaoProfile> {
102
101
  clientId: string;
103
102
  }
104
103
 
105
- const KAKAO_DEFAULT_SCOPES = [
106
- "account_email",
107
- "profile_image",
108
- "profile_nickname",
109
- ];
110
-
111
104
  export const kakao = (options: KakaoOptions) => {
112
105
  const tokenEndpoint = "https://kauth.kakao.com/oauth/token";
113
106
  return {
114
107
  id: "kakao",
115
108
  name: "Kakao",
116
- callbackPath: "/callback/kakao",
117
109
  createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
118
- const requestedScopes = resolveRequestedScopes(
119
- options,
120
- KAKAO_DEFAULT_SCOPES,
121
- scopes,
122
- );
110
+ const _scopes = options.disableDefaultScope
111
+ ? []
112
+ : ["account_email", "profile_image", "profile_nickname"];
113
+ if (options.scope) _scopes.push(...options.scope);
114
+ if (scopes) _scopes.push(...scopes);
123
115
  return createAuthorizationURL({
124
116
  id: "kakao",
125
117
  options,
126
118
  authorizationEndpoint: "https://kauth.kakao.com/oauth/authorize",
127
- scopes: requestedScopes,
119
+ scopes: _scopes,
128
120
  state,
129
121
  redirectURI,
130
122
  additionalParams,
@@ -184,5 +176,5 @@ export const kakao = (options: KakaoOptions) => {
184
176
  };
185
177
  },
186
178
  options,
187
- } satisfies UpstreamProvider<KakaoProfile>;
179
+ } satisfies OAuthProvider<KakaoProfile>;
188
180
  };
@@ -1,9 +1,8 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
2
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
3
  import {
4
4
  createAuthorizationURL,
5
5
  refreshAccessToken,
6
- resolveRequestedScopes,
7
6
  validateAuthorizationCode,
8
7
  } from "../oauth2";
9
8
 
@@ -30,13 +29,10 @@ export interface KickOptions extends ProviderOptions<KickProfile> {
30
29
  clientId: string;
31
30
  }
32
31
 
33
- const KICK_DEFAULT_SCOPES = ["user:read"];
34
-
35
32
  export const kick = (options: KickOptions) => {
36
33
  return {
37
34
  id: "kick",
38
35
  name: "Kick",
39
- callbackPath: "/callback/kick",
40
36
  createAuthorizationURL({
41
37
  state,
42
38
  scopes,
@@ -44,17 +40,16 @@ export const kick = (options: KickOptions) => {
44
40
  codeVerifier,
45
41
  additionalParams,
46
42
  }) {
47
- const requestedScopes = resolveRequestedScopes(
48
- options,
49
- KICK_DEFAULT_SCOPES,
50
- scopes,
51
- );
43
+ const _scopes = options.disableDefaultScope ? [] : ["user:read"];
44
+ if (options.scope) _scopes.push(...options.scope);
45
+ if (scopes) _scopes.push(...scopes);
46
+
52
47
  return createAuthorizationURL({
53
48
  id: "kick",
54
49
  redirectURI,
55
50
  options,
56
51
  authorizationEndpoint: "https://id.kick.com/oauth/authorize",
57
- scopes: requestedScopes,
52
+ scopes: _scopes,
58
53
  codeVerifier,
59
54
  state,
60
55
  additionalParams,
@@ -117,5 +112,5 @@ export const kick = (options: KickOptions) => {
117
112
  };
118
113
  },
119
114
  options,
120
- } satisfies UpstreamProvider<KickProfile>;
115
+ } satisfies OAuthProvider<KickProfile>;
121
116
  };
@@ -1,10 +1,9 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
2
  import { decodeJwt } from "jose";
3
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
3
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
4
4
  import {
5
5
  createAuthorizationURL,
6
6
  refreshAccessToken,
7
- resolveRequestedScopes,
8
7
  validateAuthorizationCode,
9
8
  } from "../oauth2";
10
9
 
@@ -33,8 +32,6 @@ export interface LineOptions
33
32
  clientId: string;
34
33
  }
35
34
 
36
- const LINE_DEFAULT_SCOPES = ["openid", "profile", "email"];
37
-
38
35
  /**
39
36
  * LINE Login v2.1
40
37
  * - Authorization endpoint: https://access.line.me/oauth2/v2.1/authorize
@@ -53,8 +50,7 @@ export const line = (options: LineOptions) => {
53
50
  return {
54
51
  id: "line",
55
52
  name: "LINE",
56
- callbackPath: "/callback/line",
57
- createAuthorizationURL({
53
+ async createAuthorizationURL({
58
54
  state,
59
55
  scopes,
60
56
  codeVerifier,
@@ -62,16 +58,16 @@ export const line = (options: LineOptions) => {
62
58
  loginHint,
63
59
  additionalParams,
64
60
  }) {
65
- const requestedScopes = resolveRequestedScopes(
66
- options,
67
- LINE_DEFAULT_SCOPES,
68
- scopes,
69
- );
70
- return createAuthorizationURL({
61
+ const _scopes = options.disableDefaultScope
62
+ ? []
63
+ : ["openid", "profile", "email"];
64
+ if (options.scope) _scopes.push(...options.scope);
65
+ if (scopes) _scopes.push(...scopes);
66
+ return await createAuthorizationURL({
71
67
  id: "line",
72
68
  options,
73
69
  authorizationEndpoint,
74
- scopes: requestedScopes,
70
+ scopes: _scopes,
75
71
  state,
76
72
  codeVerifier,
77
73
  redirectURI,
@@ -167,5 +163,5 @@ export const line = (options: LineOptions) => {
167
163
  };
168
164
  },
169
165
  options,
170
- } satisfies UpstreamProvider<LineUserInfo | LineIdTokenPayload, LineOptions>;
166
+ } satisfies OAuthProvider<LineUserInfo | LineIdTokenPayload, LineOptions>;
171
167
  };
@@ -1,9 +1,8 @@
1
1
  import { betterFetch } from "@better-fetch/fetch";
2
- import type { ProviderOptions, UpstreamProvider } from "../oauth2";
2
+ import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
3
  import {
4
4
  createAuthorizationURL,
5
5
  refreshAccessToken,
6
- resolveRequestedScopes,
7
6
  validateAuthorizationCode,
8
7
  } from "../oauth2";
9
8
 
@@ -27,14 +26,11 @@ export interface LinearOptions extends ProviderOptions<LinearUser> {
27
26
  clientId: string;
28
27
  }
29
28
 
30
- const LINEAR_DEFAULT_SCOPES = ["read"];
31
-
32
29
  export const linear = (options: LinearOptions) => {
33
30
  const tokenEndpoint = "https://api.linear.app/oauth/token";
34
31
  return {
35
32
  id: "linear",
36
33
  name: "Linear",
37
- callbackPath: "/callback/linear",
38
34
  createAuthorizationURL({
39
35
  state,
40
36
  scopes,
@@ -42,16 +38,14 @@ export const linear = (options: LinearOptions) => {
42
38
  redirectURI,
43
39
  additionalParams,
44
40
  }) {
45
- const requestedScopes = resolveRequestedScopes(
46
- options,
47
- LINEAR_DEFAULT_SCOPES,
48
- scopes,
49
- );
41
+ const _scopes = options.disableDefaultScope ? [] : ["read"];
42
+ if (options.scope) _scopes.push(...options.scope);
43
+ if (scopes) _scopes.push(...scopes);
50
44
  return createAuthorizationURL({
51
45
  id: "linear",
52
46
  options,
53
47
  authorizationEndpoint: "https://linear.app/oauth/authorize",
54
- scopes: requestedScopes,
48
+ scopes: _scopes,
55
49
  state,
56
50
  redirectURI,
57
51
  loginHint,
@@ -130,5 +124,5 @@ export const linear = (options: LinearOptions) => {
130
124
  };
131
125
  },
132
126
  options,
133
- } satisfies UpstreamProvider<LinearUser>;
127
+ } satisfies OAuthProvider<LinearUser>;
134
128
  };