@better-auth/core 1.7.0-beta.0 → 1.7.0-beta.10

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 (218) hide show
  1. package/dist/api/index.d.mts +44 -1
  2. package/dist/api/index.mjs +69 -4
  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 +91 -3
  7. package/dist/db/adapter/get-id-field.mjs +1 -1
  8. package/dist/db/adapter/index.d.mts +87 -3
  9. package/dist/db/adapter/types.d.mts +1 -1
  10. package/dist/db/get-tables.mjs +2 -1
  11. package/dist/db/type.d.mts +17 -0
  12. package/dist/env/env-impl.mjs +1 -1
  13. package/dist/error/codes.d.mts +1 -0
  14. package/dist/error/codes.mjs +1 -0
  15. package/dist/error/index.d.mts +7 -0
  16. package/dist/index.d.mts +2 -2
  17. package/dist/instrumentation/api.mjs +12 -0
  18. package/dist/instrumentation/noop.mjs +42 -0
  19. package/dist/instrumentation/pure.index.d.mts +7 -0
  20. package/dist/instrumentation/pure.index.mjs +7 -0
  21. package/dist/instrumentation/tracer.mjs +6 -3
  22. package/dist/oauth2/authorization-params.d.mts +12 -0
  23. package/dist/oauth2/authorization-params.mjs +12 -0
  24. package/dist/oauth2/basic-credentials.d.mts +30 -0
  25. package/dist/oauth2/basic-credentials.mjs +64 -0
  26. package/dist/oauth2/client-assertion.d.mts +38 -22
  27. package/dist/oauth2/client-assertion.mjs +63 -28
  28. package/dist/oauth2/client-credentials-token.d.mts +19 -40
  29. package/dist/oauth2/client-credentials-token.mjs +20 -31
  30. package/dist/oauth2/create-authorization-url.d.mts +11 -1
  31. package/dist/oauth2/create-authorization-url.mjs +27 -7
  32. package/dist/oauth2/dpop.d.mts +142 -0
  33. package/dist/oauth2/dpop.mjs +246 -0
  34. package/dist/oauth2/index.d.mts +14 -9
  35. package/dist/oauth2/index.mjs +12 -8
  36. package/dist/oauth2/oauth-provider.d.mts +150 -10
  37. package/dist/oauth2/refresh-access-token.d.mts +20 -40
  38. package/dist/oauth2/refresh-access-token.mjs +38 -36
  39. package/dist/oauth2/reject-redirects.mjs +65 -0
  40. package/dist/oauth2/token-endpoint-auth.d.mts +17 -0
  41. package/dist/oauth2/token-endpoint-auth.mjs +89 -0
  42. package/dist/oauth2/utils.d.mts +23 -1
  43. package/dist/oauth2/utils.mjs +48 -2
  44. package/dist/oauth2/validate-authorization-code.d.mts +17 -52
  45. package/dist/oauth2/validate-authorization-code.mjs +28 -34
  46. package/dist/oauth2/verify-id-token.d.mts +27 -0
  47. package/dist/oauth2/verify-id-token.mjs +62 -0
  48. package/dist/oauth2/verify.d.mts +88 -15
  49. package/dist/oauth2/verify.mjs +203 -25
  50. package/dist/social-providers/apple.d.mts +16 -4
  51. package/dist/social-providers/apple.mjs +17 -24
  52. package/dist/social-providers/atlassian.d.mts +5 -1
  53. package/dist/social-providers/atlassian.mjs +6 -3
  54. package/dist/social-providers/cognito.d.mts +27 -3
  55. package/dist/social-providers/cognito.mjs +15 -25
  56. package/dist/social-providers/discord.d.mts +7 -3
  57. package/dist/social-providers/discord.mjs +16 -3
  58. package/dist/social-providers/dropbox.d.mts +5 -1
  59. package/dist/social-providers/dropbox.mjs +5 -4
  60. package/dist/social-providers/facebook.d.mts +24 -5
  61. package/dist/social-providers/facebook.mjs +54 -20
  62. package/dist/social-providers/figma.d.mts +5 -1
  63. package/dist/social-providers/figma.mjs +4 -3
  64. package/dist/social-providers/github.d.mts +6 -2
  65. package/dist/social-providers/github.mjs +5 -4
  66. package/dist/social-providers/gitlab.d.mts +5 -1
  67. package/dist/social-providers/gitlab.mjs +3 -2
  68. package/dist/social-providers/google.d.mts +53 -5
  69. package/dist/social-providers/google.mjs +69 -25
  70. package/dist/social-providers/huggingface.d.mts +5 -1
  71. package/dist/social-providers/huggingface.mjs +3 -2
  72. package/dist/social-providers/index.d.mts +221 -45
  73. package/dist/social-providers/index.mjs +2 -2
  74. package/dist/social-providers/kakao.d.mts +5 -1
  75. package/dist/social-providers/kakao.mjs +3 -2
  76. package/dist/social-providers/kick.d.mts +5 -1
  77. package/dist/social-providers/kick.mjs +3 -2
  78. package/dist/social-providers/line.d.mts +8 -2
  79. package/dist/social-providers/line.mjs +5 -6
  80. package/dist/social-providers/linear.d.mts +5 -1
  81. package/dist/social-providers/linear.mjs +3 -2
  82. package/dist/social-providers/linkedin.d.mts +7 -3
  83. package/dist/social-providers/linkedin.mjs +4 -3
  84. package/dist/social-providers/microsoft-entra-id.d.mts +41 -7
  85. package/dist/social-providers/microsoft-entra-id.mjs +37 -28
  86. package/dist/social-providers/naver.d.mts +5 -1
  87. package/dist/social-providers/naver.mjs +3 -2
  88. package/dist/social-providers/notion.d.mts +5 -1
  89. package/dist/social-providers/notion.mjs +5 -2
  90. package/dist/social-providers/paybin.d.mts +5 -1
  91. package/dist/social-providers/paybin.mjs +4 -3
  92. package/dist/social-providers/paypal.d.mts +6 -2
  93. package/dist/social-providers/paypal.mjs +19 -14
  94. package/dist/social-providers/polar.d.mts +5 -1
  95. package/dist/social-providers/polar.mjs +3 -2
  96. package/dist/social-providers/railway.d.mts +5 -1
  97. package/dist/social-providers/railway.mjs +3 -2
  98. package/dist/social-providers/reddit.d.mts +5 -1
  99. package/dist/social-providers/reddit.mjs +7 -5
  100. package/dist/social-providers/roblox.d.mts +6 -2
  101. package/dist/social-providers/roblox.mjs +12 -2
  102. package/dist/social-providers/salesforce.d.mts +5 -1
  103. package/dist/social-providers/salesforce.mjs +4 -3
  104. package/dist/social-providers/slack.d.mts +6 -2
  105. package/dist/social-providers/slack.mjs +11 -8
  106. package/dist/social-providers/spotify.d.mts +5 -1
  107. package/dist/social-providers/spotify.mjs +3 -2
  108. package/dist/social-providers/tiktok.d.mts +5 -1
  109. package/dist/social-providers/tiktok.mjs +14 -2
  110. package/dist/social-providers/twitch.d.mts +5 -1
  111. package/dist/social-providers/twitch.mjs +3 -2
  112. package/dist/social-providers/twitter.d.mts +4 -1
  113. package/dist/social-providers/twitter.mjs +2 -1
  114. package/dist/social-providers/vercel.d.mts +5 -1
  115. package/dist/social-providers/vercel.mjs +3 -2
  116. package/dist/social-providers/vk.d.mts +5 -1
  117. package/dist/social-providers/vk.mjs +3 -2
  118. package/dist/social-providers/wechat.d.mts +5 -1
  119. package/dist/social-providers/wechat.mjs +8 -2
  120. package/dist/social-providers/zoom.d.mts +5 -1
  121. package/dist/social-providers/zoom.mjs +10 -17
  122. package/dist/types/context.d.mts +55 -6
  123. package/dist/types/index.d.mts +1 -1
  124. package/dist/types/init-options.d.mts +182 -12
  125. package/dist/types/plugin-client.d.mts +12 -2
  126. package/dist/utils/async.d.mts +22 -0
  127. package/dist/utils/async.mjs +32 -0
  128. package/dist/utils/host.d.mts +147 -0
  129. package/dist/utils/host.mjs +298 -0
  130. package/dist/utils/ip.d.mts +28 -5
  131. package/dist/utils/ip.mjs +118 -4
  132. package/dist/utils/is-api-error.d.mts +6 -0
  133. package/dist/utils/is-api-error.mjs +8 -0
  134. package/dist/utils/redirect-uri.d.mts +20 -0
  135. package/dist/utils/redirect-uri.mjs +48 -0
  136. package/dist/utils/string.d.mts +5 -1
  137. package/dist/utils/string.mjs +20 -1
  138. package/dist/utils/url.d.mts +18 -1
  139. package/dist/utils/url.mjs +34 -4
  140. package/package.json +26 -16
  141. package/src/api/index.ts +121 -5
  142. package/src/context/transaction.ts +45 -12
  143. package/src/db/adapter/factory.ts +193 -7
  144. package/src/db/adapter/get-id-field.ts +2 -2
  145. package/src/db/adapter/index.ts +85 -2
  146. package/src/db/adapter/types.ts +2 -0
  147. package/src/db/get-tables.ts +9 -1
  148. package/src/db/schema/account.ts +4 -1
  149. package/src/db/schema/user.ts +3 -0
  150. package/src/db/type.ts +17 -0
  151. package/src/env/env-impl.ts +1 -2
  152. package/src/error/codes.ts +1 -0
  153. package/src/error/index.ts +9 -0
  154. package/src/instrumentation/api.ts +17 -0
  155. package/src/instrumentation/noop.ts +74 -0
  156. package/src/instrumentation/pure.index.ts +31 -0
  157. package/src/instrumentation/tracer.ts +8 -3
  158. package/src/oauth2/authorization-params.ts +28 -0
  159. package/src/oauth2/basic-credentials.ts +87 -0
  160. package/src/oauth2/client-assertion.ts +131 -58
  161. package/src/oauth2/client-credentials-token.ts +50 -74
  162. package/src/oauth2/create-authorization-url.ts +33 -7
  163. package/src/oauth2/dpop.ts +568 -0
  164. package/src/oauth2/index.ts +81 -11
  165. package/src/oauth2/oauth-provider.ts +159 -11
  166. package/src/oauth2/refresh-access-token.ts +82 -83
  167. package/src/oauth2/reject-redirects.ts +75 -0
  168. package/src/oauth2/token-endpoint-auth.ts +221 -0
  169. package/src/oauth2/utils.ts +72 -5
  170. package/src/oauth2/validate-authorization-code.ts +69 -89
  171. package/src/oauth2/verify-id-token.ts +115 -0
  172. package/src/oauth2/verify.ts +409 -78
  173. package/src/social-providers/apple.ts +30 -40
  174. package/src/social-providers/atlassian.ts +8 -1
  175. package/src/social-providers/cognito.ts +36 -39
  176. package/src/social-providers/discord.ts +22 -18
  177. package/src/social-providers/dropbox.ts +7 -5
  178. package/src/social-providers/facebook.ts +108 -52
  179. package/src/social-providers/figma.ts +8 -1
  180. package/src/social-providers/github.ts +5 -3
  181. package/src/social-providers/gitlab.ts +2 -0
  182. package/src/social-providers/google.ts +141 -39
  183. package/src/social-providers/huggingface.ts +8 -1
  184. package/src/social-providers/kakao.ts +2 -1
  185. package/src/social-providers/kick.ts +8 -1
  186. package/src/social-providers/line.ts +25 -27
  187. package/src/social-providers/linear.ts +8 -1
  188. package/src/social-providers/linkedin.ts +5 -3
  189. package/src/social-providers/microsoft-entra-id.ts +100 -55
  190. package/src/social-providers/naver.ts +2 -1
  191. package/src/social-providers/notion.ts +8 -1
  192. package/src/social-providers/paybin.ts +2 -0
  193. package/src/social-providers/paypal.ts +28 -17
  194. package/src/social-providers/polar.ts +8 -1
  195. package/src/social-providers/railway.ts +8 -1
  196. package/src/social-providers/reddit.ts +9 -4
  197. package/src/social-providers/roblox.ts +16 -11
  198. package/src/social-providers/salesforce.ts +8 -1
  199. package/src/social-providers/slack.ts +15 -9
  200. package/src/social-providers/spotify.ts +8 -1
  201. package/src/social-providers/tiktok.ts +22 -9
  202. package/src/social-providers/twitch.ts +2 -1
  203. package/src/social-providers/twitter.ts +1 -0
  204. package/src/social-providers/vercel.ts +8 -1
  205. package/src/social-providers/vk.ts +8 -1
  206. package/src/social-providers/wechat.ts +17 -2
  207. package/src/social-providers/zoom.ts +15 -19
  208. package/src/types/context.ts +57 -5
  209. package/src/types/index.ts +7 -0
  210. package/src/types/init-options.ts +204 -14
  211. package/src/types/plugin-client.ts +16 -2
  212. package/src/utils/async.ts +53 -0
  213. package/src/utils/host.ts +425 -0
  214. package/src/utils/ip.ts +197 -13
  215. package/src/utils/is-api-error.ts +10 -0
  216. package/src/utils/redirect-uri.ts +54 -0
  217. package/src/utils/string.ts +37 -0
  218. package/src/utils/url.ts +38 -4
@@ -1,6 +1,7 @@
1
1
  import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
2
  //#region src/social-providers/paypal.d.ts
3
3
  interface PayPalProfile {
4
+ sub?: string | undefined;
4
5
  user_id: string;
5
6
  name: string;
6
7
  given_name: string;
@@ -54,7 +55,8 @@ declare const paypal: (options: PayPalOptions) => {
54
55
  createAuthorizationURL({
55
56
  state,
56
57
  codeVerifier,
57
- redirectURI
58
+ redirectURI,
59
+ additionalParams
58
60
  }: {
59
61
  state: string;
60
62
  codeVerifier: string;
@@ -62,6 +64,8 @@ declare const paypal: (options: PayPalOptions) => {
62
64
  redirectURI: string;
63
65
  display?: string | undefined;
64
66
  loginHint?: string | undefined;
67
+ idTokenNonce?: string | undefined;
68
+ additionalParams?: Record<string, string> | undefined;
65
69
  }): Promise<URL>;
66
70
  validateAuthorizationCode: ({
67
71
  code,
@@ -82,8 +86,8 @@ declare const paypal: (options: PayPalOptions) => {
82
86
  refreshToken: any;
83
87
  accessTokenExpiresAt: Date | undefined;
84
88
  }>);
85
- verifyIdToken(token: string, nonce: string | undefined): Promise<boolean>;
86
89
  getUserInfo(token: OAuth2Tokens & {
90
+ expectedIdTokenNonce?: string | undefined;
87
91
  user?: {
88
92
  name?: {
89
93
  firstName?: string;
@@ -1,8 +1,8 @@
1
- import { logger } from "../env/logger.mjs";
2
1
  import { BetterAuthError } from "../error/index.mjs";
2
+ import { logger } from "../env/logger.mjs";
3
3
  import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
4
- import { decodeJwt } from "jose";
5
4
  import { base64 } from "@better-auth/utils/base64";
5
+ import { decodeJwt } from "jose";
6
6
  import { betterFetch } from "@better-fetch/fetch";
7
7
  //#region src/social-providers/paypal.ts
8
8
  const paypal = (options) => {
@@ -13,7 +13,7 @@ const paypal = (options) => {
13
13
  return {
14
14
  id: "paypal",
15
15
  name: "PayPal",
16
- async createAuthorizationURL({ state, codeVerifier, redirectURI }) {
16
+ async 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");
@@ -26,7 +26,8 @@ const paypal = (options) => {
26
26
  state,
27
27
  codeVerifier,
28
28
  redirectURI,
29
- prompt: options.prompt
29
+ prompt: options.prompt,
30
+ additionalParams
30
31
  });
31
32
  },
32
33
  validateAuthorizationCode: async ({ code, redirectURI }) => {
@@ -90,16 +91,6 @@ const paypal = (options) => {
90
91
  throw new BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
91
92
  }
92
93
  },
93
- async verifyIdToken(token, nonce) {
94
- if (options.disableIdTokenSignIn) return false;
95
- if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
96
- try {
97
- return !!decodeJwt(token).sub;
98
- } catch (error) {
99
- logger.error("Failed to verify PayPal ID token:", error);
100
- return false;
101
- }
102
- },
103
94
  async getUserInfo(token) {
104
95
  if (options.getUserInfo) return options.getUserInfo(token);
105
96
  if (!token.accessToken) {
@@ -116,6 +107,20 @@ const paypal = (options) => {
116
107
  return null;
117
108
  }
118
109
  const userInfo = response.data;
110
+ if (token.idToken) {
111
+ let idTokenSubject;
112
+ try {
113
+ idTokenSubject = decodeJwt(token.idToken).sub;
114
+ } catch (error) {
115
+ logger.error("Failed to decode PayPal ID token:", error);
116
+ return null;
117
+ }
118
+ const userInfoSubject = userInfo.sub ?? userInfo.user_id;
119
+ if (!idTokenSubject || userInfoSubject !== idTokenSubject) {
120
+ logger.error("PayPal user info subject does not match ID token subject");
121
+ return null;
122
+ }
123
+ }
119
124
  const userMap = await options.mapProfileToUser?.(userInfo);
120
125
  return {
121
126
  user: {
@@ -29,7 +29,8 @@ declare const polar: (options: PolarOptions) => {
29
29
  state,
30
30
  scopes,
31
31
  codeVerifier,
32
- redirectURI
32
+ redirectURI,
33
+ additionalParams
33
34
  }: {
34
35
  state: string;
35
36
  codeVerifier: string;
@@ -37,6 +38,8 @@ declare const polar: (options: PolarOptions) => {
37
38
  redirectURI: string;
38
39
  display?: string | undefined;
39
40
  loginHint?: string | undefined;
41
+ idTokenNonce?: string | undefined;
42
+ additionalParams?: Record<string, string> | undefined;
40
43
  }): Promise<URL>;
41
44
  validateAuthorizationCode: ({
42
45
  code,
@@ -50,6 +53,7 @@ declare const polar: (options: PolarOptions) => {
50
53
  }) => Promise<OAuth2Tokens>;
51
54
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
52
55
  getUserInfo(token: OAuth2Tokens & {
56
+ expectedIdTokenNonce?: string | undefined;
53
57
  user?: {
54
58
  name?: {
55
59
  firstName?: string;
@@ -8,7 +8,7 @@ const polar = (options) => {
8
8
  return {
9
9
  id: "polar",
10
10
  name: "Polar",
11
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
11
+ createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
12
12
  const _scopes = options.disableDefaultScope ? [] : [
13
13
  "openid",
14
14
  "profile",
@@ -24,7 +24,8 @@ const polar = (options) => {
24
24
  state,
25
25
  codeVerifier,
26
26
  redirectURI,
27
- prompt: options.prompt
27
+ prompt: options.prompt,
28
+ additionalParams
28
29
  });
29
30
  },
30
31
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
@@ -20,7 +20,8 @@ declare const railway: (options: RailwayOptions) => {
20
20
  state,
21
21
  scopes,
22
22
  codeVerifier,
23
- redirectURI
23
+ redirectURI,
24
+ additionalParams
24
25
  }: {
25
26
  state: string;
26
27
  codeVerifier: string;
@@ -28,6 +29,8 @@ declare const railway: (options: RailwayOptions) => {
28
29
  redirectURI: string;
29
30
  display?: string | undefined;
30
31
  loginHint?: string | undefined;
32
+ idTokenNonce?: string | undefined;
33
+ additionalParams?: Record<string, string> | undefined;
31
34
  }): Promise<URL>;
32
35
  validateAuthorizationCode: ({
33
36
  code,
@@ -41,6 +44,7 @@ declare const railway: (options: RailwayOptions) => {
41
44
  }) => Promise<OAuth2Tokens>;
42
45
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
43
46
  getUserInfo(token: OAuth2Tokens & {
47
+ expectedIdTokenNonce?: string | undefined;
44
48
  user?: {
45
49
  name?: {
46
50
  firstName?: string;
@@ -10,7 +10,7 @@ const railway = (options) => {
10
10
  return {
11
11
  id: "railway",
12
12
  name: "Railway",
13
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
13
+ createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
14
14
  const _scopes = options.disableDefaultScope ? [] : [
15
15
  "openid",
16
16
  "email",
@@ -25,7 +25,8 @@ const railway = (options) => {
25
25
  scopes: _scopes,
26
26
  state,
27
27
  codeVerifier,
28
- redirectURI
28
+ redirectURI,
29
+ additionalParams
29
30
  });
30
31
  },
31
32
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
@@ -18,7 +18,8 @@ declare const reddit: (options: RedditOptions) => {
18
18
  createAuthorizationURL({
19
19
  state,
20
20
  scopes,
21
- redirectURI
21
+ redirectURI,
22
+ additionalParams
22
23
  }: {
23
24
  state: string;
24
25
  codeVerifier: string;
@@ -26,6 +27,8 @@ declare const reddit: (options: RedditOptions) => {
26
27
  redirectURI: string;
27
28
  display?: string | undefined;
28
29
  loginHint?: string | undefined;
30
+ idTokenNonce?: string | undefined;
31
+ additionalParams?: Record<string, string> | undefined;
29
32
  }): Promise<URL>;
30
33
  validateAuthorizationCode: ({
31
34
  code,
@@ -38,6 +41,7 @@ declare const reddit: (options: RedditOptions) => {
38
41
  }) => Promise<OAuth2Tokens>;
39
42
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
40
43
  getUserInfo(token: OAuth2Tokens & {
44
+ expectedIdTokenNonce?: string | undefined;
41
45
  user?: {
42
46
  name?: {
43
47
  firstName?: string;
@@ -8,7 +8,7 @@ const reddit = (options) => {
8
8
  return {
9
9
  id: "reddit",
10
10
  name: "Reddit",
11
- createAuthorizationURL({ state, scopes, redirectURI }) {
11
+ createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
12
12
  const _scopes = options.disableDefaultScope ? [] : ["identity"];
13
13
  if (options.scope) _scopes.push(...options.scope);
14
14
  if (scopes) _scopes.push(...scopes);
@@ -19,7 +19,8 @@ const reddit = (options) => {
19
19
  scopes: _scopes,
20
20
  state,
21
21
  redirectURI,
22
- duration: options.duration
22
+ duration: options.duration,
23
+ additionalParams
23
24
  });
24
25
  },
25
26
  validateAuthorizationCode: async ({ code, redirectURI }) => {
@@ -61,14 +62,15 @@ const reddit = (options) => {
61
62
  } });
62
63
  if (error) return null;
63
64
  const userMap = await options.mapProfileToUser?.(profile);
65
+ const email = userMap?.email || `${profile.id}@reddit.invalid`;
64
66
  return {
65
67
  user: {
66
68
  id: profile.id,
67
69
  name: profile.name,
68
- email: profile.oauth_client_id,
69
- emailVerified: profile.has_verified_email,
70
70
  image: profile.icon_img?.split("?")[0],
71
- ...userMap
71
+ ...userMap,
72
+ email,
73
+ emailVerified: userMap?.emailVerified ?? false
72
74
  },
73
75
  data: profile
74
76
  };
@@ -26,7 +26,8 @@ declare const roblox: (options: RobloxOptions) => {
26
26
  createAuthorizationURL({
27
27
  state,
28
28
  scopes,
29
- redirectURI
29
+ redirectURI,
30
+ additionalParams
30
31
  }: {
31
32
  state: string;
32
33
  codeVerifier: string;
@@ -34,7 +35,9 @@ declare const roblox: (options: RobloxOptions) => {
34
35
  redirectURI: string;
35
36
  display?: string | undefined;
36
37
  loginHint?: string | undefined;
37
- }): URL;
38
+ idTokenNonce?: string | undefined;
39
+ additionalParams?: Record<string, string> | undefined;
40
+ }): Promise<URL>;
38
41
  validateAuthorizationCode: ({
39
42
  code,
40
43
  redirectURI
@@ -46,6 +49,7 @@ declare const roblox: (options: RobloxOptions) => {
46
49
  }) => Promise<OAuth2Tokens>;
47
50
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
48
51
  getUserInfo(token: OAuth2Tokens & {
52
+ expectedIdTokenNonce?: string | undefined;
49
53
  user?: {
50
54
  name?: {
51
55
  firstName?: string;
@@ -1,3 +1,4 @@
1
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
1
2
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
2
3
  import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
3
4
  import { betterFetch } from "@better-fetch/fetch";
@@ -7,11 +8,20 @@ const roblox = (options) => {
7
8
  return {
8
9
  id: "roblox",
9
10
  name: "Roblox",
10
- createAuthorizationURL({ state, scopes, redirectURI }) {
11
+ createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
11
12
  const _scopes = options.disableDefaultScope ? [] : ["openid", "profile"];
12
13
  if (options.scope) _scopes.push(...options.scope);
13
14
  if (scopes) _scopes.push(...scopes);
14
- return new URL(`https://apis.roblox.com/oauth/v1/authorize?scope=${_scopes.join("+")}&response_type=code&client_id=${options.clientId}&redirect_uri=${encodeURIComponent(options.redirectURI || redirectURI)}&state=${state}&prompt=${options.prompt || "select_account consent"}`);
15
+ return createAuthorizationURL({
16
+ id: "roblox",
17
+ options,
18
+ authorizationEndpoint: "https://apis.roblox.com/oauth/v1/authorize",
19
+ scopes: _scopes,
20
+ state,
21
+ redirectURI,
22
+ prompt: options.prompt || "select_account consent",
23
+ additionalParams
24
+ });
15
25
  },
16
26
  validateAuthorizationCode: async ({ code, redirectURI }) => {
17
27
  return validateAuthorizationCode({
@@ -34,7 +34,8 @@ declare const salesforce: (options: SalesforceOptions) => {
34
34
  state,
35
35
  scopes,
36
36
  codeVerifier,
37
- redirectURI
37
+ redirectURI,
38
+ additionalParams
38
39
  }: {
39
40
  state: string;
40
41
  codeVerifier: string;
@@ -42,6 +43,8 @@ declare const salesforce: (options: SalesforceOptions) => {
42
43
  redirectURI: string;
43
44
  display?: string | undefined;
44
45
  loginHint?: string | undefined;
46
+ idTokenNonce?: string | undefined;
47
+ additionalParams?: Record<string, string> | undefined;
45
48
  }): Promise<URL>;
46
49
  validateAuthorizationCode: ({
47
50
  code,
@@ -55,6 +58,7 @@ declare const salesforce: (options: SalesforceOptions) => {
55
58
  }) => Promise<OAuth2Tokens>;
56
59
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
57
60
  getUserInfo(token: OAuth2Tokens & {
61
+ expectedIdTokenNonce?: string | undefined;
58
62
  user?: {
59
63
  name?: {
60
64
  firstName?: string;
@@ -1,5 +1,5 @@
1
- import { logger } from "../env/logger.mjs";
2
1
  import { BetterAuthError } from "../error/index.mjs";
2
+ import { logger } from "../env/logger.mjs";
3
3
  import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
4
4
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
5
5
  import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
@@ -13,7 +13,7 @@ const salesforce = (options) => {
13
13
  return {
14
14
  id: "salesforce",
15
15
  name: "Salesforce",
16
- async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
16
+ async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
17
17
  if (!options.clientId || !options.clientSecret) {
18
18
  logger.error("Client Id and Client Secret are required for Salesforce. Make sure to provide them in the options.");
19
19
  throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
@@ -33,7 +33,8 @@ const salesforce = (options) => {
33
33
  scopes: _scopes,
34
34
  state,
35
35
  codeVerifier,
36
- redirectURI: options.redirectURI || redirectURI
36
+ redirectURI: options.redirectURI || redirectURI,
37
+ additionalParams
37
38
  });
38
39
  },
39
40
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
@@ -39,7 +39,8 @@ declare const slack: (options: SlackOptions) => {
39
39
  createAuthorizationURL({
40
40
  state,
41
41
  scopes,
42
- redirectURI
42
+ redirectURI,
43
+ additionalParams
43
44
  }: {
44
45
  state: string;
45
46
  codeVerifier: string;
@@ -47,7 +48,9 @@ declare const slack: (options: SlackOptions) => {
47
48
  redirectURI: string;
48
49
  display?: string | undefined;
49
50
  loginHint?: string | undefined;
50
- }): URL;
51
+ idTokenNonce?: string | undefined;
52
+ additionalParams?: Record<string, string> | undefined;
53
+ }): Promise<URL>;
51
54
  validateAuthorizationCode: ({
52
55
  code,
53
56
  redirectURI
@@ -59,6 +62,7 @@ declare const slack: (options: SlackOptions) => {
59
62
  }) => Promise<OAuth2Tokens>;
60
63
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
61
64
  getUserInfo(token: OAuth2Tokens & {
65
+ expectedIdTokenNonce?: string | undefined;
62
66
  user?: {
63
67
  name?: {
64
68
  firstName?: string;
@@ -1,3 +1,4 @@
1
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
1
2
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
2
3
  import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
3
4
  import { betterFetch } from "@better-fetch/fetch";
@@ -7,7 +8,7 @@ const slack = (options) => {
7
8
  return {
8
9
  id: "slack",
9
10
  name: "Slack",
10
- createAuthorizationURL({ state, scopes, redirectURI }) {
11
+ createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
11
12
  const _scopes = options.disableDefaultScope ? [] : [
12
13
  "openid",
13
14
  "profile",
@@ -15,13 +16,15 @@ const slack = (options) => {
15
16
  ];
16
17
  if (scopes) _scopes.push(...scopes);
17
18
  if (options.scope) _scopes.push(...options.scope);
18
- const url = new URL("https://slack.com/openid/connect/authorize");
19
- url.searchParams.set("scope", _scopes.join(" "));
20
- url.searchParams.set("response_type", "code");
21
- url.searchParams.set("client_id", options.clientId);
22
- url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
23
- url.searchParams.set("state", state);
24
- return url;
19
+ return createAuthorizationURL({
20
+ id: "slack",
21
+ options,
22
+ authorizationEndpoint: "https://slack.com/openid/connect/authorize",
23
+ scopes: _scopes,
24
+ state,
25
+ redirectURI,
26
+ additionalParams
27
+ });
25
28
  },
26
29
  validateAuthorizationCode: async ({ code, redirectURI }) => {
27
30
  return validateAuthorizationCode({
@@ -18,7 +18,8 @@ declare const spotify: (options: SpotifyOptions) => {
18
18
  state,
19
19
  scopes,
20
20
  codeVerifier,
21
- redirectURI
21
+ redirectURI,
22
+ additionalParams
22
23
  }: {
23
24
  state: string;
24
25
  codeVerifier: string;
@@ -26,6 +27,8 @@ declare const spotify: (options: SpotifyOptions) => {
26
27
  redirectURI: string;
27
28
  display?: string | undefined;
28
29
  loginHint?: string | undefined;
30
+ idTokenNonce?: string | undefined;
31
+ additionalParams?: Record<string, string> | undefined;
29
32
  }): Promise<URL>;
30
33
  validateAuthorizationCode: ({
31
34
  code,
@@ -39,6 +42,7 @@ declare const spotify: (options: SpotifyOptions) => {
39
42
  }) => Promise<OAuth2Tokens>;
40
43
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
41
44
  getUserInfo(token: OAuth2Tokens & {
45
+ expectedIdTokenNonce?: string | undefined;
42
46
  user?: {
43
47
  name?: {
44
48
  firstName?: string;
@@ -8,7 +8,7 @@ const spotify = (options) => {
8
8
  return {
9
9
  id: "spotify",
10
10
  name: "Spotify",
11
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
11
+ createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
12
12
  const _scopes = options.disableDefaultScope ? [] : ["user-read-email"];
13
13
  if (options.scope) _scopes.push(...options.scope);
14
14
  if (scopes) _scopes.push(...scopes);
@@ -19,7 +19,8 @@ const spotify = (options) => {
19
19
  scopes: _scopes,
20
20
  state,
21
21
  codeVerifier,
22
- redirectURI
22
+ redirectURI,
23
+ additionalParams
23
24
  });
24
25
  },
25
26
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
@@ -124,7 +124,8 @@ declare const tiktok: (options: TiktokOptions) => {
124
124
  createAuthorizationURL({
125
125
  state,
126
126
  scopes,
127
- redirectURI
127
+ redirectURI,
128
+ additionalParams
128
129
  }: {
129
130
  state: string;
130
131
  codeVerifier: string;
@@ -132,6 +133,8 @@ declare const tiktok: (options: TiktokOptions) => {
132
133
  redirectURI: string;
133
134
  display?: string | undefined;
134
135
  loginHint?: string | undefined;
136
+ idTokenNonce?: string | undefined;
137
+ additionalParams?: Record<string, string> | undefined;
135
138
  }): URL;
136
139
  validateAuthorizationCode: ({
137
140
  code,
@@ -144,6 +147,7 @@ declare const tiktok: (options: TiktokOptions) => {
144
147
  }) => Promise<OAuth2Tokens>;
145
148
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
146
149
  getUserInfo(token: OAuth2Tokens & {
150
+ expectedIdTokenNonce?: string | undefined;
147
151
  user?: {
148
152
  name?: {
149
153
  firstName?: string;
@@ -1,3 +1,4 @@
1
+ import { RESERVED_AUTHORIZATION_PARAMS_SET } from "../oauth2/create-authorization-url.mjs";
1
2
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
2
3
  import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
3
4
  import { betterFetch } from "@better-fetch/fetch";
@@ -7,11 +8,22 @@ const tiktok = (options) => {
7
8
  return {
8
9
  id: "tiktok",
9
10
  name: "TikTok",
10
- createAuthorizationURL({ state, scopes, redirectURI }) {
11
+ createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
11
12
  const _scopes = options.disableDefaultScope ? [] : ["user.info.profile"];
12
13
  if (options.scope) _scopes.push(...options.scope);
13
14
  if (scopes) _scopes.push(...scopes);
14
- return new URL(`https://www.tiktok.com/v2/auth/authorize?scope=${_scopes.join(",")}&response_type=code&client_key=${options.clientKey}&redirect_uri=${encodeURIComponent(options.redirectURI || redirectURI)}&state=${state}`);
15
+ const url = new URL("https://www.tiktok.com/v2/auth/authorize");
16
+ url.searchParams.set("scope", _scopes.join(","));
17
+ url.searchParams.set("response_type", "code");
18
+ url.searchParams.set("client_key", options.clientKey);
19
+ url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
20
+ url.searchParams.set("state", state);
21
+ if (additionalParams) for (const [key, value] of Object.entries(additionalParams)) {
22
+ if (RESERVED_AUTHORIZATION_PARAMS_SET.has(key)) continue;
23
+ if (key === "client_key") continue;
24
+ url.searchParams.set(key, value);
25
+ }
26
+ return url;
15
27
  },
16
28
  validateAuthorizationCode: async ({ code, redirectURI }) => {
17
29
  return validateAuthorizationCode({
@@ -35,7 +35,8 @@ declare const twitch: (options: TwitchOptions) => {
35
35
  createAuthorizationURL({
36
36
  state,
37
37
  scopes,
38
- redirectURI
38
+ redirectURI,
39
+ additionalParams
39
40
  }: {
40
41
  state: string;
41
42
  codeVerifier: string;
@@ -43,6 +44,8 @@ declare const twitch: (options: TwitchOptions) => {
43
44
  redirectURI: string;
44
45
  display?: string | undefined;
45
46
  loginHint?: string | undefined;
47
+ idTokenNonce?: string | undefined;
48
+ additionalParams?: Record<string, string> | undefined;
46
49
  }): Promise<URL>;
47
50
  validateAuthorizationCode: ({
48
51
  code,
@@ -55,6 +58,7 @@ declare const twitch: (options: TwitchOptions) => {
55
58
  }) => Promise<OAuth2Tokens>;
56
59
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
57
60
  getUserInfo(token: OAuth2Tokens & {
61
+ expectedIdTokenNonce?: string | undefined;
58
62
  user?: {
59
63
  name?: {
60
64
  firstName?: string;
@@ -9,7 +9,7 @@ const twitch = (options) => {
9
9
  return {
10
10
  id: "twitch",
11
11
  name: "Twitch",
12
- createAuthorizationURL({ state, scopes, redirectURI }) {
12
+ createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
13
13
  const _scopes = options.disableDefaultScope ? [] : ["user:read:email", "openid"];
14
14
  if (options.scope) _scopes.push(...options.scope);
15
15
  if (scopes) _scopes.push(...scopes);
@@ -25,7 +25,8 @@ const twitch = (options) => {
25
25
  "email_verified",
26
26
  "preferred_username",
27
27
  "picture"
28
- ]
28
+ ],
29
+ additionalParams
29
30
  });
30
31
  },
31
32
  validateAuthorizationCode: async ({ code, redirectURI }) => {
@@ -89,6 +89,8 @@ declare const twitter: (options: TwitterOption) => {
89
89
  redirectURI: string;
90
90
  display?: string | undefined;
91
91
  loginHint?: string | undefined;
92
+ idTokenNonce?: string | undefined;
93
+ additionalParams?: Record<string, string> | undefined;
92
94
  }): Promise<URL>;
93
95
  validateAuthorizationCode: ({
94
96
  code,
@@ -102,8 +104,9 @@ declare const twitter: (options: TwitterOption) => {
102
104
  }) => Promise<OAuth2Tokens>;
103
105
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
104
106
  getUserInfo(token: OAuth2Tokens & {
107
+ expectedIdTokenNonce?: string | undefined;
105
108
  user?: {
106
- name? /** The start position (zero-based) of the recognized user's profile website. All start indices are inclusive. */: {
109
+ name?: {
107
110
  firstName?: string;
108
111
  lastName?: string;
109
112
  };
@@ -24,7 +24,8 @@ const twitter = (options) => {
24
24
  scopes: _scopes,
25
25
  state: data.state,
26
26
  codeVerifier: data.codeVerifier,
27
- redirectURI: data.redirectURI
27
+ redirectURI: data.redirectURI,
28
+ additionalParams: data.additionalParams
28
29
  });
29
30
  },
30
31
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
@@ -18,7 +18,8 @@ declare const vercel: (options: VercelOptions) => {
18
18
  state,
19
19
  scopes,
20
20
  codeVerifier,
21
- redirectURI
21
+ redirectURI,
22
+ additionalParams
22
23
  }: {
23
24
  state: string;
24
25
  codeVerifier: string;
@@ -26,6 +27,8 @@ declare const vercel: (options: VercelOptions) => {
26
27
  redirectURI: string;
27
28
  display?: string | undefined;
28
29
  loginHint?: string | undefined;
30
+ idTokenNonce?: string | undefined;
31
+ additionalParams?: Record<string, string> | undefined;
29
32
  }): Promise<URL>;
30
33
  validateAuthorizationCode: ({
31
34
  code,
@@ -38,6 +41,7 @@ declare const vercel: (options: VercelOptions) => {
38
41
  deviceId?: string | undefined;
39
42
  }) => Promise<OAuth2Tokens>;
40
43
  getUserInfo(token: OAuth2Tokens & {
44
+ expectedIdTokenNonce?: string | undefined;
41
45
  user?: {
42
46
  name?: {
43
47
  firstName?: string;
@@ -7,7 +7,7 @@ const vercel = (options) => {
7
7
  return {
8
8
  id: "vercel",
9
9
  name: "Vercel",
10
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
10
+ createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
11
11
  if (!codeVerifier) throw new BetterAuthError("codeVerifier is required for Vercel");
12
12
  let _scopes = void 0;
13
13
  if (options.scope !== void 0 || scopes !== void 0) {
@@ -22,7 +22,8 @@ const vercel = (options) => {
22
22
  scopes: _scopes,
23
23
  state,
24
24
  codeVerifier,
25
- redirectURI
25
+ redirectURI,
26
+ additionalParams
26
27
  });
27
28
  },
28
29
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {