@better-auth/core 1.7.0-beta.4 → 1.7.0-beta.6

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 (170) hide show
  1. package/dist/api/index.d.mts +47 -4
  2. package/dist/api/index.mjs +40 -1
  3. package/dist/context/global.mjs +1 -1
  4. package/dist/context/transaction.d.mts +7 -4
  5. package/dist/context/transaction.mjs +6 -3
  6. package/dist/db/adapter/factory.mjs +57 -31
  7. package/dist/db/adapter/index.d.mts +54 -10
  8. package/dist/db/adapter/types.d.mts +1 -1
  9. package/dist/db/get-tables.mjs +3 -3
  10. package/dist/db/schema/account.d.mts +1 -1
  11. package/dist/db/schema/account.mjs +1 -1
  12. package/dist/db/type.d.mts +12 -7
  13. package/dist/env/env-impl.mjs +1 -1
  14. package/dist/error/codes.d.mts +5 -0
  15. package/dist/error/codes.mjs +5 -0
  16. package/dist/index.d.mts +2 -2
  17. package/dist/instrumentation/tracer.mjs +1 -1
  18. package/dist/oauth2/create-authorization-url.d.mts +4 -1
  19. package/dist/oauth2/create-authorization-url.mjs +5 -2
  20. package/dist/oauth2/dpop.d.mts +142 -0
  21. package/dist/oauth2/dpop.mjs +246 -0
  22. package/dist/oauth2/index.d.mts +6 -3
  23. package/dist/oauth2/index.mjs +5 -2
  24. package/dist/oauth2/oauth-provider.d.mts +128 -9
  25. package/dist/oauth2/refresh-access-token.mjs +1 -1
  26. package/dist/oauth2/scopes.d.mts +76 -0
  27. package/dist/oauth2/scopes.mjs +96 -0
  28. package/dist/oauth2/utils.mjs +2 -1
  29. package/dist/oauth2/verify-id-token.d.mts +26 -0
  30. package/dist/oauth2/verify-id-token.mjs +62 -0
  31. package/dist/oauth2/verify.d.mts +88 -15
  32. package/dist/oauth2/verify.mjs +187 -19
  33. package/dist/social-providers/apple.d.mts +14 -2
  34. package/dist/social-providers/apple.mjs +12 -36
  35. package/dist/social-providers/atlassian.d.mts +5 -1
  36. package/dist/social-providers/atlassian.mjs +4 -4
  37. package/dist/social-providers/cognito.d.mts +13 -2
  38. package/dist/social-providers/cognito.mjs +24 -32
  39. package/dist/social-providers/discord.d.mts +5 -1
  40. package/dist/social-providers/discord.mjs +7 -6
  41. package/dist/social-providers/dropbox.d.mts +5 -1
  42. package/dist/social-providers/dropbox.mjs +5 -5
  43. package/dist/social-providers/facebook.d.mts +21 -2
  44. package/dist/social-providers/facebook.mjs +46 -22
  45. package/dist/social-providers/figma.d.mts +5 -1
  46. package/dist/social-providers/figma.mjs +5 -5
  47. package/dist/social-providers/github.d.mts +5 -1
  48. package/dist/social-providers/github.mjs +4 -4
  49. package/dist/social-providers/gitlab.d.mts +5 -1
  50. package/dist/social-providers/gitlab.mjs +6 -6
  51. package/dist/social-providers/google.d.mts +29 -3
  52. package/dist/social-providers/google.mjs +24 -30
  53. package/dist/social-providers/huggingface.d.mts +5 -1
  54. package/dist/social-providers/huggingface.mjs +8 -8
  55. package/dist/social-providers/index.d.mts +222 -42
  56. package/dist/social-providers/kakao.d.mts +5 -1
  57. package/dist/social-providers/kakao.mjs +8 -8
  58. package/dist/social-providers/kick.d.mts +5 -1
  59. package/dist/social-providers/kick.mjs +4 -4
  60. package/dist/social-providers/line.d.mts +8 -2
  61. package/dist/social-providers/line.mjs +12 -14
  62. package/dist/social-providers/linear.d.mts +5 -1
  63. package/dist/social-providers/linear.mjs +4 -4
  64. package/dist/social-providers/linkedin.d.mts +5 -1
  65. package/dist/social-providers/linkedin.mjs +10 -10
  66. package/dist/social-providers/microsoft-entra-id.d.mts +41 -6
  67. package/dist/social-providers/microsoft-entra-id.mjs +40 -36
  68. package/dist/social-providers/naver.d.mts +5 -1
  69. package/dist/social-providers/naver.mjs +4 -4
  70. package/dist/social-providers/notion.d.mts +5 -1
  71. package/dist/social-providers/notion.mjs +4 -4
  72. package/dist/social-providers/paybin.d.mts +5 -1
  73. package/dist/social-providers/paybin.mjs +10 -10
  74. package/dist/social-providers/paypal.d.mts +5 -2
  75. package/dist/social-providers/paypal.mjs +8 -13
  76. package/dist/social-providers/polar.d.mts +5 -1
  77. package/dist/social-providers/polar.mjs +8 -8
  78. package/dist/social-providers/railway.d.mts +5 -1
  79. package/dist/social-providers/railway.mjs +9 -9
  80. package/dist/social-providers/reddit.d.mts +5 -1
  81. package/dist/social-providers/reddit.mjs +9 -8
  82. package/dist/social-providers/roblox.d.mts +5 -1
  83. package/dist/social-providers/roblox.mjs +5 -5
  84. package/dist/social-providers/salesforce.d.mts +5 -1
  85. package/dist/social-providers/salesforce.mjs +8 -8
  86. package/dist/social-providers/slack.d.mts +5 -1
  87. package/dist/social-providers/slack.mjs +9 -9
  88. package/dist/social-providers/spotify.d.mts +5 -1
  89. package/dist/social-providers/spotify.mjs +5 -5
  90. package/dist/social-providers/tiktok.d.mts +5 -1
  91. package/dist/social-providers/tiktok.mjs +9 -5
  92. package/dist/social-providers/twitch.d.mts +5 -1
  93. package/dist/social-providers/twitch.mjs +4 -4
  94. package/dist/social-providers/twitter.d.mts +6 -4
  95. package/dist/social-providers/twitter.mjs +9 -9
  96. package/dist/social-providers/vercel.d.mts +5 -1
  97. package/dist/social-providers/vercel.mjs +4 -7
  98. package/dist/social-providers/vk.d.mts +5 -1
  99. package/dist/social-providers/vk.mjs +5 -5
  100. package/dist/social-providers/wechat.d.mts +5 -1
  101. package/dist/social-providers/wechat.mjs +10 -6
  102. package/dist/social-providers/zoom.d.mts +6 -1
  103. package/dist/social-providers/zoom.mjs +15 -9
  104. package/dist/types/context.d.mts +27 -8
  105. package/dist/types/index.d.mts +1 -1
  106. package/dist/types/init-options.d.mts +137 -6
  107. package/dist/types/plugin-client.d.mts +12 -2
  108. package/dist/utils/host.mjs +4 -0
  109. package/dist/utils/url.mjs +4 -3
  110. package/package.json +7 -7
  111. package/src/api/index.ts +82 -0
  112. package/src/context/transaction.ts +45 -12
  113. package/src/db/adapter/factory.ts +127 -64
  114. package/src/db/adapter/index.ts +54 -9
  115. package/src/db/adapter/types.ts +1 -0
  116. package/src/db/get-tables.ts +8 -3
  117. package/src/db/schema/account.ts +14 -2
  118. package/src/db/type.ts +12 -7
  119. package/src/env/env-impl.ts +1 -2
  120. package/src/error/codes.ts +5 -0
  121. package/src/oauth2/create-authorization-url.ts +2 -2
  122. package/src/oauth2/dpop.ts +568 -0
  123. package/src/oauth2/index.ts +61 -2
  124. package/src/oauth2/oauth-provider.ts +140 -10
  125. package/src/oauth2/refresh-access-token.ts +2 -2
  126. package/src/oauth2/scopes.ts +118 -0
  127. package/src/oauth2/utils.ts +2 -5
  128. package/src/oauth2/verify-id-token.ts +111 -0
  129. package/src/oauth2/verify.ts +372 -58
  130. package/src/social-providers/apple.ts +24 -61
  131. package/src/social-providers/atlassian.ts +12 -8
  132. package/src/social-providers/cognito.ts +25 -47
  133. package/src/social-providers/discord.ts +19 -8
  134. package/src/social-providers/dropbox.ts +13 -7
  135. package/src/social-providers/facebook.ts +97 -51
  136. package/src/social-providers/figma.ts +13 -9
  137. package/src/social-providers/github.ts +12 -8
  138. package/src/social-providers/gitlab.ts +14 -8
  139. package/src/social-providers/google.ts +66 -47
  140. package/src/social-providers/huggingface.ts +12 -8
  141. package/src/social-providers/kakao.ts +16 -8
  142. package/src/social-providers/kick.ts +12 -7
  143. package/src/social-providers/line.ts +37 -37
  144. package/src/social-providers/linear.ts +12 -6
  145. package/src/social-providers/linkedin.ts +14 -10
  146. package/src/social-providers/microsoft-entra-id.ts +103 -59
  147. package/src/social-providers/naver.ts +12 -6
  148. package/src/social-providers/notion.ts +12 -6
  149. package/src/social-providers/paybin.ts +14 -11
  150. package/src/social-providers/paypal.ts +6 -25
  151. package/src/social-providers/polar.ts +12 -8
  152. package/src/social-providers/railway.ts +13 -9
  153. package/src/social-providers/reddit.ts +25 -10
  154. package/src/social-providers/roblox.ts +18 -7
  155. package/src/social-providers/salesforce.ts +12 -8
  156. package/src/social-providers/slack.ts +18 -9
  157. package/src/social-providers/spotify.ts +13 -7
  158. package/src/social-providers/tiktok.ts +13 -7
  159. package/src/social-providers/twitch.ts +12 -8
  160. package/src/social-providers/twitter.ts +17 -8
  161. package/src/social-providers/vercel.ts +16 -10
  162. package/src/social-providers/vk.ts +13 -7
  163. package/src/social-providers/wechat.ts +28 -9
  164. package/src/social-providers/zoom.ts +19 -6
  165. package/src/types/context.ts +26 -8
  166. package/src/types/index.ts +7 -0
  167. package/src/types/init-options.ts +159 -8
  168. package/src/types/plugin-client.ts +16 -2
  169. package/src/utils/host.ts +15 -0
  170. package/src/utils/url.ts +10 -4
@@ -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
- async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, loginHint, additionalParams }) {
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
- const _scopes = options.disableDefaultScope ? [] : [
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: _scopes,
32
+ scopes: resolveRequestedScopes(options, PAYBIN_DEFAULT_SCOPES, scopes),
33
33
  state,
34
34
  codeVerifier,
35
35
  redirectURI,
@@ -51,6 +51,7 @@ interface PayPalOptions extends ProviderOptions<PayPalProfile> {
51
51
  declare const paypal: (options: PayPalOptions) => {
52
52
  id: "paypal";
53
53
  name: string;
54
+ callbackPath: string;
54
55
  createAuthorizationURL({
55
56
  state,
56
57
  codeVerifier,
@@ -64,7 +65,10 @@ declare const paypal: (options: PayPalOptions) => {
64
65
  display?: string | undefined;
65
66
  loginHint?: string | undefined;
66
67
  additionalParams?: Record<string, string> | undefined;
67
- }): Promise<URL>;
68
+ }): Promise<{
69
+ url: URL;
70
+ requestedScopes: string[];
71
+ }>;
68
72
  validateAuthorizationCode: ({
69
73
  code,
70
74
  redirectURI
@@ -84,7 +88,6 @@ declare const paypal: (options: PayPalOptions) => {
84
88
  refreshToken: any;
85
89
  accessTokenExpiresAt: Date | undefined;
86
90
  }>);
87
- verifyIdToken(token: string, nonce: string | undefined): Promise<boolean>;
88
91
  getUserInfo(token: OAuth2Tokens & {
89
92
  user?: {
90
93
  name?: {
@@ -2,7 +2,6 @@ import { BetterAuthError } from "../error/index.mjs";
2
2
  import { logger } from "../env/logger.mjs";
3
3
  import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
4
4
  import { base64 } from "@better-auth/utils/base64";
5
- import { decodeJwt } from "jose";
6
5
  import { betterFetch } from "@better-fetch/fetch";
7
6
  //#region src/social-providers/paypal.ts
8
7
  const paypal = (options) => {
@@ -13,12 +12,18 @@ const paypal = (options) => {
13
12
  return {
14
13
  id: "paypal",
15
14
  name: "PayPal",
16
- async createAuthorizationURL({ state, codeVerifier, redirectURI, additionalParams }) {
15
+ callbackPath: "/callback/paypal",
16
+ createAuthorizationURL({ state, codeVerifier, redirectURI, additionalParams }) {
17
17
  if (!options.clientId || !options.clientSecret) {
18
18
  logger.error("Client Id and Client Secret is required for PayPal. Make sure to provide them in the options.");
19
19
  throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
20
20
  }
21
- return await createAuthorizationURL({
21
+ /**
22
+ * Log in with PayPal doesn't use traditional OAuth2 scopes
23
+ * Instead, permissions are configured in the PayPal Developer Dashboard
24
+ * We don't pass any scopes to avoid "invalid scope" errors
25
+ **/
26
+ return createAuthorizationURL({
22
27
  id: "paypal",
23
28
  options,
24
29
  authorizationEndpoint,
@@ -91,16 +96,6 @@ const paypal = (options) => {
91
96
  throw new BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
92
97
  }
93
98
  },
94
- async verifyIdToken(token, nonce) {
95
- if (options.disableIdTokenSignIn) return false;
96
- if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
97
- try {
98
- return !!decodeJwt(token).sub;
99
- } catch (error) {
100
- logger.error("Failed to verify PayPal ID token:", error);
101
- return false;
102
- }
103
- },
104
99
  async getUserInfo(token) {
105
100
  if (options.getUserInfo) return options.getUserInfo(token);
106
101
  if (!token.accessToken) {
@@ -25,6 +25,7 @@ interface PolarOptions extends ProviderOptions<PolarProfile> {}
25
25
  declare const polar: (options: PolarOptions) => {
26
26
  id: "polar";
27
27
  name: string;
28
+ callbackPath: string;
28
29
  createAuthorizationURL({
29
30
  state,
30
31
  scopes,
@@ -39,7 +40,10 @@ declare const polar: (options: PolarOptions) => {
39
40
  display?: string | undefined;
40
41
  loginHint?: string | undefined;
41
42
  additionalParams?: Record<string, string> | undefined;
42
- }): Promise<URL>;
43
+ }): Promise<{
44
+ url: URL;
45
+ requestedScopes: string[];
46
+ }>;
43
47
  validateAuthorizationCode: ({
44
48
  code,
45
49
  codeVerifier,
@@ -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/polar.ts
7
+ const POLAR_DEFAULT_SCOPES = [
8
+ "openid",
9
+ "profile",
10
+ "email"
11
+ ];
6
12
  const polar = (options) => {
7
13
  const tokenEndpoint = "https://api.polar.sh/v1/oauth2/token";
8
14
  return {
9
15
  id: "polar",
10
16
  name: "Polar",
17
+ callbackPath: "/callback/polar",
11
18
  createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
12
- const _scopes = options.disableDefaultScope ? [] : [
13
- "openid",
14
- "profile",
15
- "email"
16
- ];
17
- if (options.scope) _scopes.push(...options.scope);
18
- if (scopes) _scopes.push(...scopes);
19
19
  return createAuthorizationURL({
20
20
  id: "polar",
21
21
  options,
22
22
  authorizationEndpoint: "https://polar.sh/oauth2/authorize",
23
- scopes: _scopes,
23
+ scopes: resolveRequestedScopes(options, POLAR_DEFAULT_SCOPES, scopes),
24
24
  state,
25
25
  codeVerifier,
26
26
  redirectURI,
@@ -16,6 +16,7 @@ interface RailwayOptions extends ProviderOptions<RailwayProfile> {
16
16
  declare const railway: (options: RailwayOptions) => {
17
17
  id: "railway";
18
18
  name: string;
19
+ callbackPath: string;
19
20
  createAuthorizationURL({
20
21
  state,
21
22
  scopes,
@@ -30,7 +31,10 @@ declare const railway: (options: RailwayOptions) => {
30
31
  display?: string | undefined;
31
32
  loginHint?: string | undefined;
32
33
  additionalParams?: Record<string, string> | undefined;
33
- }): Promise<URL>;
34
+ }): Promise<{
35
+ url: URL;
36
+ requestedScopes: string[];
37
+ }>;
34
38
  validateAuthorizationCode: ({
35
39
  code,
36
40
  codeVerifier,
@@ -1,3 +1,4 @@
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";
@@ -6,23 +7,22 @@ import { betterFetch } from "@better-fetch/fetch";
6
7
  const authorizationEndpoint = "https://backboard.railway.com/oauth/auth";
7
8
  const tokenEndpoint = "https://backboard.railway.com/oauth/token";
8
9
  const userinfoEndpoint = "https://backboard.railway.com/oauth/me";
10
+ const RAILWAY_DEFAULT_SCOPES = [
11
+ "openid",
12
+ "email",
13
+ "profile"
14
+ ];
9
15
  const railway = (options) => {
10
16
  return {
11
17
  id: "railway",
12
18
  name: "Railway",
13
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
14
- const _scopes = options.disableDefaultScope ? [] : [
15
- "openid",
16
- "email",
17
- "profile"
18
- ];
19
- if (options.scope) _scopes.push(...options.scope);
20
- if (scopes) _scopes.push(...scopes);
19
+ callbackPath: "/callback/railway",
20
+ async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
21
21
  return createAuthorizationURL({
22
22
  id: "railway",
23
23
  options,
24
24
  authorizationEndpoint,
25
- scopes: _scopes,
25
+ scopes: resolveRequestedScopes(options, RAILWAY_DEFAULT_SCOPES, scopes),
26
26
  state,
27
27
  codeVerifier,
28
28
  redirectURI,
@@ -15,6 +15,7 @@ interface RedditOptions extends ProviderOptions<RedditProfile> {
15
15
  declare const reddit: (options: RedditOptions) => {
16
16
  id: "reddit";
17
17
  name: string;
18
+ callbackPath: string;
18
19
  createAuthorizationURL({
19
20
  state,
20
21
  scopes,
@@ -28,7 +29,10 @@ declare const reddit: (options: RedditOptions) => {
28
29
  display?: string | undefined;
29
30
  loginHint?: string | undefined;
30
31
  additionalParams?: Record<string, string> | undefined;
31
- }): Promise<URL>;
32
+ }): Promise<{
33
+ url: URL;
34
+ requestedScopes: string[];
35
+ }>;
32
36
  validateAuthorizationCode: ({
33
37
  code,
34
38
  redirectURI
@@ -1,22 +1,22 @@
1
+ import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
1
2
  import { getOAuth2Tokens } from "../oauth2/utils.mjs";
2
3
  import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
3
4
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
4
5
  import { base64 } from "@better-auth/utils/base64";
5
6
  import { betterFetch } from "@better-fetch/fetch";
6
7
  //#region src/social-providers/reddit.ts
8
+ const REDDIT_DEFAULT_SCOPES = ["identity"];
7
9
  const reddit = (options) => {
8
10
  return {
9
11
  id: "reddit",
10
12
  name: "Reddit",
11
- createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
12
- const _scopes = options.disableDefaultScope ? [] : ["identity"];
13
- if (options.scope) _scopes.push(...options.scope);
14
- if (scopes) _scopes.push(...scopes);
13
+ callbackPath: "/callback/reddit",
14
+ async createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
15
15
  return createAuthorizationURL({
16
16
  id: "reddit",
17
17
  options,
18
18
  authorizationEndpoint: "https://www.reddit.com/api/v1/authorize",
19
- scopes: _scopes,
19
+ scopes: resolveRequestedScopes(options, REDDIT_DEFAULT_SCOPES, scopes),
20
20
  state,
21
21
  redirectURI,
22
22
  duration: options.duration,
@@ -62,14 +62,15 @@ const reddit = (options) => {
62
62
  } });
63
63
  if (error) return null;
64
64
  const userMap = await options.mapProfileToUser?.(profile);
65
+ const email = userMap?.email || `${profile.id}@reddit.invalid`;
65
66
  return {
66
67
  user: {
67
68
  id: profile.id,
68
69
  name: profile.name,
69
- email: profile.oauth_client_id,
70
- emailVerified: profile.has_verified_email,
71
70
  image: profile.icon_img?.split("?")[0],
72
- ...userMap
71
+ ...userMap,
72
+ email,
73
+ emailVerified: userMap?.emailVerified ?? false
73
74
  },
74
75
  data: profile
75
76
  };
@@ -23,6 +23,7 @@ interface RobloxOptions extends ProviderOptions<RobloxProfile> {
23
23
  declare const roblox: (options: RobloxOptions) => {
24
24
  id: "roblox";
25
25
  name: string;
26
+ callbackPath: string;
26
27
  createAuthorizationURL({
27
28
  state,
28
29
  scopes,
@@ -36,7 +37,10 @@ declare const roblox: (options: RobloxOptions) => {
36
37
  display?: string | undefined;
37
38
  loginHint?: string | undefined;
38
39
  additionalParams?: Record<string, string> | undefined;
39
- }): Promise<URL>;
40
+ }): Promise<{
41
+ url: URL;
42
+ requestedScopes: string[];
43
+ }>;
40
44
  validateAuthorizationCode: ({
41
45
  code,
42
46
  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/roblox.ts
7
+ const ROBLOX_DEFAULT_SCOPES = ["openid", "profile"];
6
8
  const roblox = (options) => {
7
9
  const tokenEndpoint = "https://apis.roblox.com/oauth/v1/token";
8
10
  return {
9
11
  id: "roblox",
10
12
  name: "Roblox",
11
- createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
12
- const _scopes = options.disableDefaultScope ? [] : ["openid", "profile"];
13
- if (options.scope) _scopes.push(...options.scope);
14
- if (scopes) _scopes.push(...scopes);
13
+ callbackPath: "/callback/roblox",
14
+ async createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
15
15
  return createAuthorizationURL({
16
16
  id: "roblox",
17
17
  options,
18
18
  authorizationEndpoint: "https://apis.roblox.com/oauth/v1/authorize",
19
- scopes: _scopes,
19
+ scopes: resolveRequestedScopes(options, ROBLOX_DEFAULT_SCOPES, scopes),
20
20
  state,
21
21
  redirectURI,
22
22
  prompt: options.prompt || "select_account consent",
@@ -30,6 +30,7 @@ interface SalesforceOptions extends ProviderOptions<SalesforceProfile> {
30
30
  declare const salesforce: (options: SalesforceOptions) => {
31
31
  id: "salesforce";
32
32
  name: string;
33
+ callbackPath: string;
33
34
  createAuthorizationURL({
34
35
  state,
35
36
  scopes,
@@ -44,7 +45,10 @@ declare const salesforce: (options: SalesforceOptions) => {
44
45
  display?: string | undefined;
45
46
  loginHint?: string | undefined;
46
47
  additionalParams?: Record<string, string> | undefined;
47
- }): Promise<URL>;
48
+ }): Promise<{
49
+ url: URL;
50
+ requestedScopes: string[];
51
+ }>;
48
52
  validateAuthorizationCode: ({
49
53
  code,
50
54
  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 { betterFetch } from "@better-fetch/fetch";
7
8
  //#region src/social-providers/salesforce.ts
9
+ const SALESFORCE_DEFAULT_SCOPES = [
10
+ "openid",
11
+ "email",
12
+ "profile"
13
+ ];
8
14
  const salesforce = (options) => {
9
15
  const isSandbox = (options.environment ?? "production") === "sandbox";
10
16
  const authorizationEndpoint = options.loginUrl ? `https://${options.loginUrl}/services/oauth2/authorize` : isSandbox ? "https://test.salesforce.com/services/oauth2/authorize" : "https://login.salesforce.com/services/oauth2/authorize";
@@ -13,24 +19,18 @@ const salesforce = (options) => {
13
19
  return {
14
20
  id: "salesforce",
15
21
  name: "Salesforce",
22
+ callbackPath: "/callback/salesforce",
16
23
  async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
17
24
  if (!options.clientId || !options.clientSecret) {
18
25
  logger.error("Client Id and Client Secret are required for Salesforce. Make sure to provide them in the options.");
19
26
  throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
20
27
  }
21
28
  if (!codeVerifier) throw new BetterAuthError("codeVerifier is required for Salesforce");
22
- const _scopes = options.disableDefaultScope ? [] : [
23
- "openid",
24
- "email",
25
- "profile"
26
- ];
27
- if (options.scope) _scopes.push(...options.scope);
28
- if (scopes) _scopes.push(...scopes);
29
29
  return createAuthorizationURL({
30
30
  id: "salesforce",
31
31
  options,
32
32
  authorizationEndpoint,
33
- scopes: _scopes,
33
+ scopes: resolveRequestedScopes(options, SALESFORCE_DEFAULT_SCOPES, scopes),
34
34
  state,
35
35
  codeVerifier,
36
36
  redirectURI: options.redirectURI || redirectURI,
@@ -36,6 +36,7 @@ interface SlackOptions extends ProviderOptions<SlackProfile> {
36
36
  declare const slack: (options: SlackOptions) => {
37
37
  id: "slack";
38
38
  name: string;
39
+ callbackPath: string;
39
40
  createAuthorizationURL({
40
41
  state,
41
42
  scopes,
@@ -49,7 +50,10 @@ declare const slack: (options: SlackOptions) => {
49
50
  display?: string | undefined;
50
51
  loginHint?: string | undefined;
51
52
  additionalParams?: Record<string, string> | undefined;
52
- }): Promise<URL>;
53
+ }): Promise<{
54
+ url: URL;
55
+ requestedScopes: string[];
56
+ }>;
53
57
  validateAuthorizationCode: ({
54
58
  code,
55
59
  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/slack.ts
7
+ const SLACK_DEFAULT_SCOPES = [
8
+ "openid",
9
+ "profile",
10
+ "email"
11
+ ];
6
12
  const slack = (options) => {
7
13
  const tokenEndpoint = "https://slack.com/api/openid.connect.token";
8
14
  return {
9
15
  id: "slack",
10
16
  name: "Slack",
11
- createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
12
- const _scopes = options.disableDefaultScope ? [] : [
13
- "openid",
14
- "profile",
15
- "email"
16
- ];
17
- if (scopes) _scopes.push(...scopes);
18
- if (options.scope) _scopes.push(...options.scope);
17
+ callbackPath: "/callback/slack",
18
+ async createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
19
19
  return createAuthorizationURL({
20
20
  id: "slack",
21
21
  options,
22
22
  authorizationEndpoint: "https://slack.com/openid/connect/authorize",
23
- scopes: _scopes,
23
+ scopes: resolveRequestedScopes(options, SLACK_DEFAULT_SCOPES, scopes),
24
24
  state,
25
25
  redirectURI,
26
26
  additionalParams
@@ -14,6 +14,7 @@ interface SpotifyOptions extends ProviderOptions<SpotifyProfile> {
14
14
  declare const spotify: (options: SpotifyOptions) => {
15
15
  id: "spotify";
16
16
  name: string;
17
+ callbackPath: string;
17
18
  createAuthorizationURL({
18
19
  state,
19
20
  scopes,
@@ -28,7 +29,10 @@ declare const spotify: (options: SpotifyOptions) => {
28
29
  display?: string | undefined;
29
30
  loginHint?: string | undefined;
30
31
  additionalParams?: Record<string, string> | undefined;
31
- }): Promise<URL>;
32
+ }): Promise<{
33
+ url: URL;
34
+ requestedScopes: string[];
35
+ }>;
32
36
  validateAuthorizationCode: ({
33
37
  code,
34
38
  codeVerifier,
@@ -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/spotify.ts
7
+ const SPOTIFY_DEFAULT_SCOPES = ["user-read-email"];
6
8
  const spotify = (options) => {
7
9
  const tokenEndpoint = "https://accounts.spotify.com/api/token";
8
10
  return {
9
11
  id: "spotify",
10
12
  name: "Spotify",
11
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
12
- const _scopes = options.disableDefaultScope ? [] : ["user-read-email"];
13
- if (options.scope) _scopes.push(...options.scope);
14
- if (scopes) _scopes.push(...scopes);
13
+ callbackPath: "/callback/spotify",
14
+ async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
15
15
  return createAuthorizationURL({
16
16
  id: "spotify",
17
17
  options,
18
18
  authorizationEndpoint: "https://accounts.spotify.com/authorize",
19
- scopes: _scopes,
19
+ scopes: resolveRequestedScopes(options, SPOTIFY_DEFAULT_SCOPES, scopes),
20
20
  state,
21
21
  codeVerifier,
22
22
  redirectURI,
@@ -121,6 +121,7 @@ interface TiktokOptions extends ProviderOptions {
121
121
  declare const tiktok: (options: TiktokOptions) => {
122
122
  id: "tiktok";
123
123
  name: string;
124
+ callbackPath: string;
124
125
  createAuthorizationURL({
125
126
  state,
126
127
  scopes,
@@ -134,7 +135,10 @@ declare const tiktok: (options: TiktokOptions) => {
134
135
  display?: string | undefined;
135
136
  loginHint?: string | undefined;
136
137
  additionalParams?: Record<string, string> | undefined;
137
- }): URL;
138
+ }): {
139
+ url: URL;
140
+ requestedScopes: string[];
141
+ };
138
142
  validateAuthorizationCode: ({
139
143
  code,
140
144
  redirectURI
@@ -1,19 +1,20 @@
1
+ import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
1
2
  import { RESERVED_AUTHORIZATION_PARAMS_SET } 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/tiktok.ts
7
+ const TIKTOK_DEFAULT_SCOPES = ["user.info.profile"];
6
8
  const tiktok = (options) => {
7
9
  const tokenEndpoint = "https://open.tiktokapis.com/v2/oauth/token/";
8
10
  return {
9
11
  id: "tiktok",
10
12
  name: "TikTok",
13
+ callbackPath: "/callback/tiktok",
11
14
  createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
12
- const _scopes = options.disableDefaultScope ? [] : ["user.info.profile"];
13
- if (options.scope) _scopes.push(...options.scope);
14
- if (scopes) _scopes.push(...scopes);
15
+ const requestedScopes = resolveRequestedScopes(options, TIKTOK_DEFAULT_SCOPES, scopes);
15
16
  const url = new URL("https://www.tiktok.com/v2/auth/authorize");
16
- url.searchParams.set("scope", _scopes.join(","));
17
+ url.searchParams.set("scope", requestedScopes.join(","));
17
18
  url.searchParams.set("response_type", "code");
18
19
  url.searchParams.set("client_key", options.clientKey);
19
20
  url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
@@ -23,7 +24,10 @@ const tiktok = (options) => {
23
24
  if (key === "client_key") continue;
24
25
  url.searchParams.set(key, value);
25
26
  }
26
- return url;
27
+ return {
28
+ url,
29
+ requestedScopes
30
+ };
27
31
  },
28
32
  validateAuthorizationCode: async ({ code, redirectURI }) => {
29
33
  return validateAuthorizationCode({
@@ -32,6 +32,7 @@ interface TwitchOptions extends ProviderOptions<TwitchProfile> {
32
32
  declare const twitch: (options: TwitchOptions) => {
33
33
  id: "twitch";
34
34
  name: string;
35
+ callbackPath: string;
35
36
  createAuthorizationURL({
36
37
  state,
37
38
  scopes,
@@ -45,7 +46,10 @@ declare const twitch: (options: TwitchOptions) => {
45
46
  display?: string | undefined;
46
47
  loginHint?: string | undefined;
47
48
  additionalParams?: Record<string, string> | undefined;
48
- }): Promise<URL>;
49
+ }): Promise<{
50
+ url: URL;
51
+ requestedScopes: string[];
52
+ }>;
49
53
  validateAuthorizationCode: ({
50
54
  code,
51
55
  redirectURI
@@ -1,24 +1,24 @@
1
1
  import { logger } from "../env/logger.mjs";
2
+ import { resolveRequestedScopes } from "../oauth2/scopes.mjs";
2
3
  import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
3
4
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
4
5
  import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
5
6
  import { decodeJwt } from "jose";
6
7
  //#region src/social-providers/twitch.ts
8
+ const TWITCH_DEFAULT_SCOPES = ["user:read:email", "openid"];
7
9
  const twitch = (options) => {
8
10
  const tokenEndpoint = "https://id.twitch.tv/oauth2/token";
9
11
  return {
10
12
  id: "twitch",
11
13
  name: "Twitch",
14
+ callbackPath: "/callback/twitch",
12
15
  createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
13
- const _scopes = options.disableDefaultScope ? [] : ["user:read:email", "openid"];
14
- if (options.scope) _scopes.push(...options.scope);
15
- if (scopes) _scopes.push(...scopes);
16
16
  return createAuthorizationURL({
17
17
  id: "twitch",
18
18
  redirectURI,
19
19
  options,
20
20
  authorizationEndpoint: "https://id.twitch.tv/oauth2/authorize",
21
- scopes: _scopes,
21
+ scopes: resolveRequestedScopes(options, TWITCH_DEFAULT_SCOPES, scopes),
22
22
  state,
23
23
  claims: options.claims || [
24
24
  "email",
@@ -82,6 +82,7 @@ interface TwitterOption extends ProviderOptions<TwitterProfile> {
82
82
  declare const twitter: (options: TwitterOption) => {
83
83
  id: "twitter";
84
84
  name: string;
85
+ callbackPath: string;
85
86
  createAuthorizationURL(data: {
86
87
  state: string;
87
88
  codeVerifier: string;
@@ -90,7 +91,10 @@ declare const twitter: (options: TwitterOption) => {
90
91
  display?: string | undefined;
91
92
  loginHint?: string | undefined;
92
93
  additionalParams?: Record<string, string> | undefined;
93
- }): Promise<URL>;
94
+ }): Promise<{
95
+ url: URL;
96
+ requestedScopes: string[];
97
+ }>;
94
98
  validateAuthorizationCode: ({
95
99
  code,
96
100
  codeVerifier,
@@ -106,9 +110,7 @@ declare const twitter: (options: TwitterOption) => {
106
110
  user?: {
107
111
  name?: {
108
112
  firstName?: string;
109
- lastName
110
-
111
- /** The fully resolved URL. */? /** The fully resolved URL. */: string;
113
+ lastName?: string;
112
114
  };
113
115
  email?: string;
114
116
  } | undefined;