@better-auth/core 1.4.12-beta.2 → 1.4.13

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 (185) hide show
  1. package/.turbo/turbo-build.log +172 -35
  2. package/dist/api/index.d.mts +178 -1
  3. package/dist/api/index.mjs +2 -1
  4. package/dist/context/endpoint-context.d.mts +19 -0
  5. package/dist/context/endpoint-context.mjs +31 -0
  6. package/dist/context/global.d.mts +7 -0
  7. package/dist/context/global.mjs +37 -0
  8. package/dist/context/index.d.mts +5 -53
  9. package/dist/context/index.mjs +5 -2
  10. package/dist/context/request-state.d.mts +27 -0
  11. package/dist/context/request-state.mjs +49 -0
  12. package/dist/context/transaction.d.mts +16 -0
  13. package/dist/context/transaction.mjs +52 -0
  14. package/dist/db/adapter/factory.d.mts +27 -0
  15. package/dist/db/adapter/factory.mjs +738 -0
  16. package/dist/db/adapter/get-default-field-name.d.mts +18 -0
  17. package/dist/db/adapter/get-default-field-name.mjs +38 -0
  18. package/dist/db/adapter/get-default-model-name.d.mts +12 -0
  19. package/dist/db/adapter/get-default-model-name.mjs +32 -0
  20. package/dist/db/adapter/get-field-attributes.d.mts +29 -0
  21. package/dist/db/adapter/get-field-attributes.mjs +39 -0
  22. package/dist/db/adapter/get-field-name.d.mts +18 -0
  23. package/dist/db/adapter/get-field-name.mjs +33 -0
  24. package/dist/db/adapter/get-id-field.d.mts +39 -0
  25. package/dist/db/adapter/get-id-field.mjs +68 -0
  26. package/dist/db/adapter/get-model-name.d.mts +12 -0
  27. package/dist/db/adapter/get-model-name.mjs +23 -0
  28. package/dist/db/adapter/index.d.mts +513 -1
  29. package/dist/db/adapter/index.mjs +8 -970
  30. package/dist/db/adapter/types.d.mts +139 -0
  31. package/dist/db/adapter/utils.d.mts +7 -0
  32. package/dist/db/adapter/utils.mjs +38 -0
  33. package/dist/db/get-tables.d.mts +8 -0
  34. package/dist/{get-tables-CMc_Emww.mjs → db/get-tables.mjs} +1 -1
  35. package/dist/db/index.d.mts +10 -2
  36. package/dist/db/index.mjs +7 -60
  37. package/dist/db/plugin.d.mts +12 -0
  38. package/dist/db/schema/account.d.mts +26 -0
  39. package/dist/db/schema/account.mjs +19 -0
  40. package/dist/db/schema/rate-limit.d.mts +14 -0
  41. package/dist/db/schema/rate-limit.mjs +11 -0
  42. package/dist/db/schema/session.d.mts +21 -0
  43. package/dist/db/schema/session.mjs +14 -0
  44. package/dist/db/schema/shared.d.mts +10 -0
  45. package/dist/db/schema/shared.mjs +11 -0
  46. package/dist/db/schema/user.d.mts +20 -0
  47. package/dist/db/schema/user.mjs +13 -0
  48. package/dist/db/schema/verification.d.mts +19 -0
  49. package/dist/db/schema/verification.mjs +12 -0
  50. package/dist/db/type.d.mts +143 -0
  51. package/dist/env/color-depth.d.mts +4 -0
  52. package/dist/env/color-depth.mjs +88 -0
  53. package/dist/env/env-impl.d.mts +32 -0
  54. package/dist/env/env-impl.mjs +82 -0
  55. package/dist/env/index.d.mts +4 -2
  56. package/dist/env/index.mjs +3 -1
  57. package/dist/{index-BRBu0-5h.d.mts → env/logger.d.mts} +1 -35
  58. package/dist/env/logger.mjs +81 -0
  59. package/dist/error/codes.d.mts +48 -0
  60. package/dist/{error-DP1xOn7P.mjs → error/codes.mjs} +3 -14
  61. package/dist/error/index.d.mts +5 -48
  62. package/dist/error/index.mjs +12 -3
  63. package/dist/index.d.mts +8 -2
  64. package/dist/oauth2/client-credentials-token.d.mts +36 -0
  65. package/dist/oauth2/client-credentials-token.mjs +54 -0
  66. package/dist/oauth2/create-authorization-url.d.mts +45 -0
  67. package/dist/oauth2/create-authorization-url.mjs +42 -0
  68. package/dist/oauth2/index.d.mts +8 -2
  69. package/dist/oauth2/index.mjs +6 -2
  70. package/dist/oauth2/oauth-provider.d.mts +194 -0
  71. package/dist/oauth2/refresh-access-token.d.mts +36 -0
  72. package/dist/oauth2/refresh-access-token.mjs +58 -0
  73. package/dist/oauth2/utils.d.mts +7 -0
  74. package/dist/oauth2/utils.mjs +27 -0
  75. package/dist/oauth2/validate-authorization-code.d.mts +55 -0
  76. package/dist/oauth2/validate-authorization-code.mjs +71 -0
  77. package/dist/oauth2/verify.d.mts +49 -0
  78. package/dist/oauth2/verify.mjs +95 -0
  79. package/dist/social-providers/apple.d.mts +119 -0
  80. package/dist/social-providers/apple.mjs +102 -0
  81. package/dist/social-providers/atlassian.d.mts +72 -0
  82. package/dist/social-providers/atlassian.mjs +83 -0
  83. package/dist/social-providers/cognito.d.mts +87 -0
  84. package/dist/social-providers/cognito.mjs +166 -0
  85. package/dist/social-providers/discord.d.mts +126 -0
  86. package/dist/social-providers/discord.mjs +64 -0
  87. package/dist/social-providers/dropbox.d.mts +71 -0
  88. package/dist/social-providers/dropbox.mjs +75 -0
  89. package/dist/social-providers/facebook.d.mts +81 -0
  90. package/dist/social-providers/facebook.mjs +120 -0
  91. package/dist/social-providers/figma.d.mts +63 -0
  92. package/dist/social-providers/figma.mjs +84 -0
  93. package/dist/social-providers/github.d.mts +104 -0
  94. package/dist/social-providers/github.mjs +80 -0
  95. package/dist/social-providers/gitlab.d.mts +125 -0
  96. package/dist/social-providers/gitlab.mjs +82 -0
  97. package/dist/social-providers/google.d.mts +99 -0
  98. package/dist/social-providers/google.mjs +109 -0
  99. package/dist/social-providers/huggingface.d.mts +85 -0
  100. package/dist/social-providers/huggingface.mjs +75 -0
  101. package/dist/social-providers/index.d.mts +1723 -1
  102. package/dist/social-providers/index.mjs +33 -2570
  103. package/dist/social-providers/kakao.d.mts +163 -0
  104. package/dist/social-providers/kakao.mjs +72 -0
  105. package/dist/social-providers/kick.d.mts +75 -0
  106. package/dist/social-providers/kick.mjs +71 -0
  107. package/dist/social-providers/line.d.mts +107 -0
  108. package/dist/social-providers/line.mjs +113 -0
  109. package/dist/social-providers/linear.d.mts +70 -0
  110. package/dist/social-providers/linear.mjs +88 -0
  111. package/dist/social-providers/linkedin.d.mts +69 -0
  112. package/dist/social-providers/linkedin.mjs +76 -0
  113. package/dist/social-providers/microsoft-entra-id.d.mts +174 -0
  114. package/dist/social-providers/microsoft-entra-id.mjs +106 -0
  115. package/dist/social-providers/naver.d.mts +104 -0
  116. package/dist/social-providers/naver.mjs +67 -0
  117. package/dist/social-providers/notion.d.mts +66 -0
  118. package/dist/social-providers/notion.mjs +75 -0
  119. package/dist/social-providers/paybin.d.mts +73 -0
  120. package/dist/social-providers/paybin.mjs +85 -0
  121. package/dist/social-providers/paypal.d.mts +131 -0
  122. package/dist/social-providers/paypal.mjs +144 -0
  123. package/dist/social-providers/polar.d.mts +76 -0
  124. package/dist/social-providers/polar.mjs +73 -0
  125. package/dist/social-providers/reddit.d.mts +64 -0
  126. package/dist/social-providers/reddit.mjs +83 -0
  127. package/dist/social-providers/roblox.d.mts +72 -0
  128. package/dist/social-providers/roblox.mjs +59 -0
  129. package/dist/social-providers/salesforce.d.mts +81 -0
  130. package/dist/social-providers/salesforce.mjs +91 -0
  131. package/dist/social-providers/slack.d.mts +85 -0
  132. package/dist/social-providers/slack.mjs +68 -0
  133. package/dist/social-providers/spotify.d.mts +65 -0
  134. package/dist/social-providers/spotify.mjs +71 -0
  135. package/dist/social-providers/tiktok.d.mts +171 -0
  136. package/dist/social-providers/tiktok.mjs +62 -0
  137. package/dist/social-providers/twitch.d.mts +81 -0
  138. package/dist/social-providers/twitch.mjs +78 -0
  139. package/dist/social-providers/twitter.d.mts +140 -0
  140. package/dist/social-providers/twitter.mjs +87 -0
  141. package/dist/social-providers/vercel.d.mts +64 -0
  142. package/dist/social-providers/vercel.mjs +61 -0
  143. package/dist/social-providers/vk.d.mts +72 -0
  144. package/dist/social-providers/vk.mjs +83 -0
  145. package/dist/social-providers/zoom.d.mts +173 -0
  146. package/dist/social-providers/zoom.mjs +72 -0
  147. package/dist/types/context.d.mts +215 -0
  148. package/dist/types/cookie.d.mts +15 -0
  149. package/dist/types/helper.d.mts +8 -0
  150. package/dist/types/index.d.mts +8 -0
  151. package/dist/types/init-options.d.mts +1266 -0
  152. package/dist/types/plugin-client.d.mts +103 -0
  153. package/dist/types/plugin.d.mts +121 -0
  154. package/dist/utils/deprecate.d.mts +10 -0
  155. package/dist/utils/deprecate.mjs +17 -0
  156. package/dist/utils/error-codes.d.mts +9 -0
  157. package/dist/utils/error-codes.mjs +7 -0
  158. package/dist/utils/id.d.mts +4 -0
  159. package/dist/utils/id.mjs +9 -0
  160. package/dist/utils/index.d.mts +5 -26
  161. package/dist/utils/index.mjs +5 -2
  162. package/dist/utils/json.d.mts +4 -0
  163. package/dist/utils/json.mjs +25 -0
  164. package/dist/utils/string.d.mts +4 -0
  165. package/dist/utils/string.mjs +7 -0
  166. package/package.json +1 -1
  167. package/src/context/endpoint-context.ts +7 -15
  168. package/src/context/global.ts +57 -0
  169. package/src/context/index.ts +1 -0
  170. package/src/context/request-state.ts +7 -12
  171. package/src/context/transaction.ts +7 -16
  172. package/src/db/adapter/factory.ts +13 -13
  173. package/src/db/adapter/get-default-model-name.ts +1 -1
  174. package/src/db/adapter/get-id-field.ts +2 -2
  175. package/src/error/index.ts +2 -3
  176. package/src/social-providers/gitlab.ts +1 -1
  177. package/src/types/context.ts +137 -131
  178. package/src/types/cookie.ts +6 -4
  179. package/src/types/index.ts +2 -1
  180. package/tsdown.config.ts +9 -0
  181. package/dist/context-BGZ8V6DD.mjs +0 -126
  182. package/dist/env-DbssmzoK.mjs +0 -245
  183. package/dist/index-zgYuzZ7O.d.mts +0 -8020
  184. package/dist/oauth2-COJkghlT.mjs +0 -326
  185. package/dist/utils-U2L7n92V.mjs +0 -59
@@ -0,0 +1,66 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/notion.d.ts
5
+ interface NotionProfile {
6
+ object: "user";
7
+ id: string;
8
+ type: "person" | "bot";
9
+ name?: string | undefined;
10
+ avatar_url?: string | undefined;
11
+ person?: {
12
+ email?: string;
13
+ } | undefined;
14
+ }
15
+ interface NotionOptions extends ProviderOptions<NotionProfile> {
16
+ clientId: string;
17
+ }
18
+ declare const notion: (options: NotionOptions) => {
19
+ id: "notion";
20
+ name: string;
21
+ createAuthorizationURL({
22
+ state,
23
+ scopes,
24
+ loginHint,
25
+ redirectURI
26
+ }: {
27
+ state: string;
28
+ codeVerifier: string;
29
+ scopes?: string[] | undefined;
30
+ redirectURI: string;
31
+ display?: string | undefined;
32
+ loginHint?: string | undefined;
33
+ }): Promise<URL>;
34
+ validateAuthorizationCode: ({
35
+ code,
36
+ redirectURI
37
+ }: {
38
+ code: string;
39
+ redirectURI: string;
40
+ codeVerifier?: string | undefined;
41
+ deviceId?: string | undefined;
42
+ }) => Promise<OAuth2Tokens>;
43
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
44
+ getUserInfo(token: OAuth2Tokens & {
45
+ user?: {
46
+ name?: {
47
+ firstName?: string;
48
+ lastName?: string;
49
+ };
50
+ email?: string;
51
+ } | undefined;
52
+ }): Promise<{
53
+ user: {
54
+ id: string;
55
+ name?: string;
56
+ email?: string | null;
57
+ image?: string;
58
+ emailVerified: boolean;
59
+ [key: string]: any;
60
+ };
61
+ data: any;
62
+ } | null>;
63
+ options: NotionOptions;
64
+ };
65
+ //#endregion
66
+ export { NotionOptions, NotionProfile, notion };
@@ -0,0 +1,75 @@
1
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
2
+ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
3
+ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
4
+ import "../oauth2/index.mjs";
5
+ import { betterFetch } from "@better-fetch/fetch";
6
+
7
+ //#region src/social-providers/notion.ts
8
+ const notion = (options) => {
9
+ const tokenEndpoint = "https://api.notion.com/v1/oauth/token";
10
+ return {
11
+ id: "notion",
12
+ name: "Notion",
13
+ createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
14
+ const _scopes = options.disableDefaultScope ? [] : [];
15
+ if (options.scope) _scopes.push(...options.scope);
16
+ if (scopes) _scopes.push(...scopes);
17
+ return createAuthorizationURL({
18
+ id: "notion",
19
+ options,
20
+ authorizationEndpoint: "https://api.notion.com/v1/oauth/authorize",
21
+ scopes: _scopes,
22
+ state,
23
+ redirectURI,
24
+ loginHint,
25
+ additionalParams: { owner: "user" }
26
+ });
27
+ },
28
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
29
+ return validateAuthorizationCode({
30
+ code,
31
+ redirectURI,
32
+ options,
33
+ tokenEndpoint,
34
+ authentication: "basic"
35
+ });
36
+ },
37
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
38
+ return refreshAccessToken({
39
+ refreshToken,
40
+ options: {
41
+ clientId: options.clientId,
42
+ clientKey: options.clientKey,
43
+ clientSecret: options.clientSecret
44
+ },
45
+ tokenEndpoint
46
+ });
47
+ },
48
+ async getUserInfo(token) {
49
+ if (options.getUserInfo) return options.getUserInfo(token);
50
+ const { data: profile, error } = await betterFetch("https://api.notion.com/v1/users/me", { headers: {
51
+ Authorization: `Bearer ${token.accessToken}`,
52
+ "Notion-Version": "2022-06-28"
53
+ } });
54
+ if (error || !profile) return null;
55
+ const userProfile = profile.bot?.owner?.user;
56
+ if (!userProfile) return null;
57
+ const userMap = await options.mapProfileToUser?.(userProfile);
58
+ return {
59
+ user: {
60
+ id: userProfile.id,
61
+ name: userProfile.name || "Notion User",
62
+ email: userProfile.person?.email || null,
63
+ image: userProfile.avatar_url,
64
+ emailVerified: false,
65
+ ...userMap
66
+ },
67
+ data: userProfile
68
+ };
69
+ },
70
+ options
71
+ };
72
+ };
73
+
74
+ //#endregion
75
+ export { notion };
@@ -0,0 +1,73 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/paybin.d.ts
5
+ interface PaybinProfile {
6
+ sub: string;
7
+ email: string;
8
+ email_verified?: boolean | undefined;
9
+ name?: string | undefined;
10
+ preferred_username?: string | undefined;
11
+ picture?: string | undefined;
12
+ given_name?: string | undefined;
13
+ family_name?: string | undefined;
14
+ }
15
+ interface PaybinOptions extends ProviderOptions<PaybinProfile> {
16
+ clientId: string;
17
+ /**
18
+ * The issuer URL of your Paybin OAuth server
19
+ * @default "https://idp.paybin.io"
20
+ */
21
+ issuer?: string | undefined;
22
+ }
23
+ declare const paybin: (options: PaybinOptions) => {
24
+ id: "paybin";
25
+ name: string;
26
+ createAuthorizationURL({
27
+ state,
28
+ scopes,
29
+ codeVerifier,
30
+ redirectURI,
31
+ loginHint
32
+ }: {
33
+ state: string;
34
+ codeVerifier: string;
35
+ scopes?: string[] | undefined;
36
+ redirectURI: string;
37
+ display?: string | undefined;
38
+ loginHint?: string | undefined;
39
+ }): Promise<URL>;
40
+ validateAuthorizationCode: ({
41
+ code,
42
+ codeVerifier,
43
+ redirectURI
44
+ }: {
45
+ code: string;
46
+ redirectURI: string;
47
+ codeVerifier?: string | undefined;
48
+ deviceId?: string | undefined;
49
+ }) => Promise<OAuth2Tokens>;
50
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
51
+ getUserInfo(token: OAuth2Tokens & {
52
+ user?: {
53
+ name?: {
54
+ firstName?: string;
55
+ lastName?: string;
56
+ };
57
+ email?: string;
58
+ } | undefined;
59
+ }): Promise<{
60
+ user: {
61
+ id: string;
62
+ name?: string;
63
+ email?: string | null;
64
+ image?: string;
65
+ emailVerified: boolean;
66
+ [key: string]: any;
67
+ };
68
+ data: any;
69
+ } | null>;
70
+ options: PaybinOptions;
71
+ };
72
+ //#endregion
73
+ export { PaybinOptions, PaybinProfile, paybin };
@@ -0,0 +1,85 @@
1
+ import { logger } from "../env/logger.mjs";
2
+ import "../env/index.mjs";
3
+ import { BetterAuthError } from "../error/index.mjs";
4
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
5
+ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
6
+ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
7
+ import "../oauth2/index.mjs";
8
+ import { decodeJwt } from "jose";
9
+
10
+ //#region src/social-providers/paybin.ts
11
+ const paybin = (options) => {
12
+ const issuer = options.issuer || "https://idp.paybin.io";
13
+ const authorizationEndpoint = `${issuer}/oauth2/authorize`;
14
+ const tokenEndpoint = `${issuer}/oauth2/token`;
15
+ return {
16
+ id: "paybin",
17
+ name: "Paybin",
18
+ async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, loginHint }) {
19
+ if (!options.clientId || !options.clientSecret) {
20
+ logger.error("Client Id and Client Secret is required for Paybin. Make sure to provide them in the options.");
21
+ throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
22
+ }
23
+ if (!codeVerifier) throw new BetterAuthError("codeVerifier is required for Paybin");
24
+ const _scopes = options.disableDefaultScope ? [] : [
25
+ "openid",
26
+ "email",
27
+ "profile"
28
+ ];
29
+ if (options.scope) _scopes.push(...options.scope);
30
+ if (scopes) _scopes.push(...scopes);
31
+ return await createAuthorizationURL({
32
+ id: "paybin",
33
+ options,
34
+ authorizationEndpoint,
35
+ scopes: _scopes,
36
+ state,
37
+ codeVerifier,
38
+ redirectURI,
39
+ prompt: options.prompt,
40
+ loginHint
41
+ });
42
+ },
43
+ validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
44
+ return validateAuthorizationCode({
45
+ code,
46
+ codeVerifier,
47
+ redirectURI,
48
+ options,
49
+ tokenEndpoint
50
+ });
51
+ },
52
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
53
+ return refreshAccessToken({
54
+ refreshToken,
55
+ options: {
56
+ clientId: options.clientId,
57
+ clientKey: options.clientKey,
58
+ clientSecret: options.clientSecret
59
+ },
60
+ tokenEndpoint
61
+ });
62
+ },
63
+ async getUserInfo(token) {
64
+ if (options.getUserInfo) return options.getUserInfo(token);
65
+ if (!token.idToken) return null;
66
+ const user = decodeJwt(token.idToken);
67
+ const userMap = await options.mapProfileToUser?.(user);
68
+ return {
69
+ user: {
70
+ id: user.sub,
71
+ name: user.name || user.preferred_username || (user.email ? user.email.split("@")[0] : "User") || "User",
72
+ email: user.email,
73
+ image: user.picture,
74
+ emailVerified: user.email_verified || false,
75
+ ...userMap
76
+ },
77
+ data: user
78
+ };
79
+ },
80
+ options
81
+ };
82
+ };
83
+
84
+ //#endregion
85
+ export { paybin };
@@ -0,0 +1,131 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/paypal.d.ts
5
+ interface PayPalProfile {
6
+ user_id: string;
7
+ name: string;
8
+ given_name: string;
9
+ family_name: string;
10
+ middle_name?: string | undefined;
11
+ picture?: string | undefined;
12
+ email: string;
13
+ email_verified: boolean;
14
+ gender?: string | undefined;
15
+ birthdate?: string | undefined;
16
+ zoneinfo?: string | undefined;
17
+ locale?: string | undefined;
18
+ phone_number?: string | undefined;
19
+ address?: {
20
+ street_address?: string;
21
+ locality?: string;
22
+ region?: string;
23
+ postal_code?: string;
24
+ country?: string;
25
+ } | undefined;
26
+ verified_account?: boolean | undefined;
27
+ account_type?: string | undefined;
28
+ age_range?: string | undefined;
29
+ payer_id?: string | undefined;
30
+ }
31
+ interface PayPalTokenResponse {
32
+ scope?: string | undefined;
33
+ access_token: string;
34
+ refresh_token?: string | undefined;
35
+ token_type: "Bearer";
36
+ id_token?: string | undefined;
37
+ expires_in: number;
38
+ nonce?: string | undefined;
39
+ }
40
+ interface PayPalOptions extends ProviderOptions<PayPalProfile> {
41
+ clientId: string;
42
+ /**
43
+ * PayPal environment - 'sandbox' for testing, 'live' for production
44
+ * @default 'sandbox'
45
+ */
46
+ environment?: ("sandbox" | "live") | undefined;
47
+ /**
48
+ * Whether to request shipping address information
49
+ * @default false
50
+ */
51
+ requestShippingAddress?: boolean | undefined;
52
+ }
53
+ declare const paypal: (options: PayPalOptions) => {
54
+ id: "paypal";
55
+ name: string;
56
+ createAuthorizationURL({
57
+ state,
58
+ codeVerifier,
59
+ redirectURI
60
+ }: {
61
+ state: string;
62
+ codeVerifier: string;
63
+ scopes?: string[] | undefined;
64
+ redirectURI: string;
65
+ display?: string | undefined;
66
+ loginHint?: string | undefined;
67
+ }): Promise<URL>;
68
+ validateAuthorizationCode: ({
69
+ code,
70
+ redirectURI
71
+ }: {
72
+ code: string;
73
+ redirectURI: string;
74
+ codeVerifier?: string | undefined;
75
+ deviceId?: string | undefined;
76
+ }) => Promise<{
77
+ accessToken: string;
78
+ refreshToken: string | undefined;
79
+ accessTokenExpiresAt: Date | undefined;
80
+ idToken: string | undefined;
81
+ }>;
82
+ refreshAccessToken: ((refreshToken: string) => Promise<OAuth2Tokens>) | ((refreshToken: string) => Promise<{
83
+ accessToken: any;
84
+ refreshToken: any;
85
+ accessTokenExpiresAt: Date | undefined;
86
+ }>);
87
+ verifyIdToken(token: string, nonce: string | undefined): Promise<boolean>;
88
+ getUserInfo(token: OAuth2Tokens & {
89
+ user?: {
90
+ name?: {
91
+ firstName?: string;
92
+ lastName?: string;
93
+ };
94
+ email?: string;
95
+ } | undefined;
96
+ }): Promise<{
97
+ user: {
98
+ id: string;
99
+ name?: string;
100
+ email?: string | null;
101
+ image?: string;
102
+ emailVerified: boolean;
103
+ [key: string]: any;
104
+ };
105
+ data: any;
106
+ } | {
107
+ user: {
108
+ id: string;
109
+ name: string;
110
+ email: string;
111
+ image: string | undefined;
112
+ emailVerified: boolean;
113
+ } | {
114
+ id: string;
115
+ name: string;
116
+ email: string | null;
117
+ image: string;
118
+ emailVerified: boolean;
119
+ } | {
120
+ id: string;
121
+ name: string;
122
+ email: string | null;
123
+ image: string;
124
+ emailVerified: boolean;
125
+ };
126
+ data: PayPalProfile;
127
+ } | null>;
128
+ options: PayPalOptions;
129
+ };
130
+ //#endregion
131
+ export { PayPalOptions, PayPalProfile, PayPalTokenResponse, paypal };
@@ -0,0 +1,144 @@
1
+ import { logger } from "../env/logger.mjs";
2
+ import "../env/index.mjs";
3
+ import { BetterAuthError } from "../error/index.mjs";
4
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
5
+ import "../oauth2/index.mjs";
6
+ import { base64 } from "@better-auth/utils/base64";
7
+ import { betterFetch } from "@better-fetch/fetch";
8
+ import { decodeJwt } from "jose";
9
+
10
+ //#region src/social-providers/paypal.ts
11
+ const paypal = (options) => {
12
+ const isSandbox = (options.environment || "sandbox") === "sandbox";
13
+ const authorizationEndpoint = isSandbox ? "https://www.sandbox.paypal.com/signin/authorize" : "https://www.paypal.com/signin/authorize";
14
+ const tokenEndpoint = isSandbox ? "https://api-m.sandbox.paypal.com/v1/oauth2/token" : "https://api-m.paypal.com/v1/oauth2/token";
15
+ const userInfoEndpoint = isSandbox ? "https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo" : "https://api-m.paypal.com/v1/identity/oauth2/userinfo";
16
+ return {
17
+ id: "paypal",
18
+ name: "PayPal",
19
+ async createAuthorizationURL({ state, codeVerifier, redirectURI }) {
20
+ if (!options.clientId || !options.clientSecret) {
21
+ logger.error("Client Id and Client Secret is required for PayPal. Make sure to provide them in the options.");
22
+ throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
23
+ }
24
+ return await createAuthorizationURL({
25
+ id: "paypal",
26
+ options,
27
+ authorizationEndpoint,
28
+ scopes: [],
29
+ state,
30
+ codeVerifier,
31
+ redirectURI,
32
+ prompt: options.prompt
33
+ });
34
+ },
35
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
36
+ /**
37
+ * PayPal requires Basic Auth for token exchange
38
+ **/
39
+ const credentials = base64.encode(`${options.clientId}:${options.clientSecret}`);
40
+ try {
41
+ const response = await betterFetch(tokenEndpoint, {
42
+ method: "POST",
43
+ headers: {
44
+ Authorization: `Basic ${credentials}`,
45
+ Accept: "application/json",
46
+ "Accept-Language": "en_US",
47
+ "Content-Type": "application/x-www-form-urlencoded"
48
+ },
49
+ body: new URLSearchParams({
50
+ grant_type: "authorization_code",
51
+ code,
52
+ redirect_uri: redirectURI
53
+ }).toString()
54
+ });
55
+ if (!response.data) throw new BetterAuthError("FAILED_TO_GET_ACCESS_TOKEN");
56
+ const data = response.data;
57
+ return {
58
+ accessToken: data.access_token,
59
+ refreshToken: data.refresh_token,
60
+ accessTokenExpiresAt: data.expires_in ? new Date(Date.now() + data.expires_in * 1e3) : void 0,
61
+ idToken: data.id_token
62
+ };
63
+ } catch (error) {
64
+ logger.error("PayPal token exchange failed:", error);
65
+ throw new BetterAuthError("FAILED_TO_GET_ACCESS_TOKEN");
66
+ }
67
+ },
68
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
69
+ const credentials = base64.encode(`${options.clientId}:${options.clientSecret}`);
70
+ try {
71
+ const response = await betterFetch(tokenEndpoint, {
72
+ method: "POST",
73
+ headers: {
74
+ Authorization: `Basic ${credentials}`,
75
+ Accept: "application/json",
76
+ "Accept-Language": "en_US",
77
+ "Content-Type": "application/x-www-form-urlencoded"
78
+ },
79
+ body: new URLSearchParams({
80
+ grant_type: "refresh_token",
81
+ refresh_token: refreshToken
82
+ }).toString()
83
+ });
84
+ if (!response.data) throw new BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
85
+ const data = response.data;
86
+ return {
87
+ accessToken: data.access_token,
88
+ refreshToken: data.refresh_token,
89
+ accessTokenExpiresAt: data.expires_in ? new Date(Date.now() + data.expires_in * 1e3) : void 0
90
+ };
91
+ } catch (error) {
92
+ logger.error("PayPal token refresh failed:", error);
93
+ throw new BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
94
+ }
95
+ },
96
+ async verifyIdToken(token, nonce) {
97
+ if (options.disableIdTokenSignIn) return false;
98
+ if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
99
+ try {
100
+ return !!decodeJwt(token).sub;
101
+ } catch (error) {
102
+ logger.error("Failed to verify PayPal ID token:", error);
103
+ return false;
104
+ }
105
+ },
106
+ async getUserInfo(token) {
107
+ if (options.getUserInfo) return options.getUserInfo(token);
108
+ if (!token.accessToken) {
109
+ logger.error("Access token is required to fetch PayPal user info");
110
+ return null;
111
+ }
112
+ try {
113
+ const response = await betterFetch(`${userInfoEndpoint}?schema=paypalv1.1`, { headers: {
114
+ Authorization: `Bearer ${token.accessToken}`,
115
+ Accept: "application/json"
116
+ } });
117
+ if (!response.data) {
118
+ logger.error("Failed to fetch user info from PayPal");
119
+ return null;
120
+ }
121
+ const userInfo = response.data;
122
+ const userMap = await options.mapProfileToUser?.(userInfo);
123
+ return {
124
+ user: {
125
+ id: userInfo.user_id,
126
+ name: userInfo.name,
127
+ email: userInfo.email,
128
+ image: userInfo.picture,
129
+ emailVerified: userInfo.email_verified,
130
+ ...userMap
131
+ },
132
+ data: userInfo
133
+ };
134
+ } catch (error) {
135
+ logger.error("Failed to fetch user info from PayPal:", error);
136
+ return null;
137
+ }
138
+ },
139
+ options
140
+ };
141
+ };
142
+
143
+ //#endregion
144
+ export { paypal };
@@ -0,0 +1,76 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/polar.d.ts
5
+ interface PolarProfile {
6
+ id: string;
7
+ email: string;
8
+ username: string;
9
+ avatar_url: string;
10
+ github_username?: string | undefined;
11
+ account_id?: string | undefined;
12
+ public_name?: string | undefined;
13
+ email_verified?: boolean | undefined;
14
+ profile_settings?: {
15
+ profile_settings_enabled?: boolean;
16
+ profile_settings_public_name?: string;
17
+ profile_settings_public_avatar?: string;
18
+ profile_settings_public_bio?: string;
19
+ profile_settings_public_location?: string;
20
+ profile_settings_public_website?: string;
21
+ profile_settings_public_twitter?: string;
22
+ profile_settings_public_github?: string;
23
+ profile_settings_public_email?: string;
24
+ } | undefined;
25
+ }
26
+ interface PolarOptions extends ProviderOptions<PolarProfile> {}
27
+ declare const polar: (options: PolarOptions) => {
28
+ id: "polar";
29
+ name: string;
30
+ createAuthorizationURL({
31
+ state,
32
+ scopes,
33
+ codeVerifier,
34
+ redirectURI
35
+ }: {
36
+ state: string;
37
+ codeVerifier: string;
38
+ scopes?: string[] | undefined;
39
+ redirectURI: string;
40
+ display?: string | undefined;
41
+ loginHint?: string | undefined;
42
+ }): Promise<URL>;
43
+ validateAuthorizationCode: ({
44
+ code,
45
+ codeVerifier,
46
+ redirectURI
47
+ }: {
48
+ code: string;
49
+ redirectURI: string;
50
+ codeVerifier?: string | undefined;
51
+ deviceId?: string | undefined;
52
+ }) => Promise<OAuth2Tokens>;
53
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
54
+ getUserInfo(token: OAuth2Tokens & {
55
+ user?: {
56
+ name?: {
57
+ firstName?: string;
58
+ lastName?: string;
59
+ };
60
+ email?: string;
61
+ } | undefined;
62
+ }): Promise<{
63
+ user: {
64
+ id: string;
65
+ name?: string;
66
+ email?: string | null;
67
+ image?: string;
68
+ emailVerified: boolean;
69
+ [key: string]: any;
70
+ };
71
+ data: any;
72
+ } | null>;
73
+ options: PolarOptions;
74
+ };
75
+ //#endregion
76
+ export { PolarOptions, PolarProfile, polar };