@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,126 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/discord.d.ts
5
+ interface DiscordProfile extends Record<string, any> {
6
+ /** the user's id (i.e. the numerical snowflake) */
7
+ id: string;
8
+ /** the user's username, not unique across the platform */
9
+ username: string;
10
+ /** the user's Discord-tag */
11
+ discriminator: string;
12
+ /** the user's display name, if it is set */
13
+ global_name: string | null;
14
+ /**
15
+ * the user's avatar hash:
16
+ * https://discord.com/developers/docs/reference#image-formatting
17
+ */
18
+ avatar: string | null;
19
+ /** whether the user belongs to an OAuth2 application */
20
+ bot?: boolean | undefined;
21
+ /**
22
+ * whether the user is an Official Discord System user (part of the urgent
23
+ * message system)
24
+ */
25
+ system?: boolean | undefined;
26
+ /** whether the user has two factor enabled on their account */
27
+ mfa_enabled: boolean;
28
+ /**
29
+ * the user's banner hash:
30
+ * https://discord.com/developers/docs/reference#image-formatting
31
+ */
32
+ banner: string | null;
33
+ /** the user's banner color encoded as an integer representation of hexadecimal color code */
34
+ accent_color: number | null;
35
+ /**
36
+ * the user's chosen language option:
37
+ * https://discord.com/developers/docs/reference#locales
38
+ */
39
+ locale: string;
40
+ /** whether the email on this account has been verified */
41
+ verified: boolean;
42
+ /** the user's email */
43
+ email: string;
44
+ /**
45
+ * the flags on a user's account:
46
+ * https://discord.com/developers/docs/resources/user#user-object-user-flags
47
+ */
48
+ flags: number;
49
+ /**
50
+ * the type of Nitro subscription on a user's account:
51
+ * https://discord.com/developers/docs/resources/user#user-object-premium-types
52
+ */
53
+ premium_type: number;
54
+ /**
55
+ * the public flags on a user's account:
56
+ * https://discord.com/developers/docs/resources/user#user-object-user-flags
57
+ */
58
+ public_flags: number;
59
+ /** undocumented field; corresponds to the user's custom nickname */
60
+ display_name: string | null;
61
+ /**
62
+ * undocumented field; corresponds to the Discord feature where you can e.g.
63
+ * put your avatar inside of an ice cube
64
+ */
65
+ avatar_decoration: string | null;
66
+ /**
67
+ * undocumented field; corresponds to the premium feature where you can
68
+ * select a custom banner color
69
+ */
70
+ banner_color: string | null;
71
+ /** undocumented field; the CDN URL of their profile picture */
72
+ image_url: string;
73
+ }
74
+ interface DiscordOptions extends ProviderOptions<DiscordProfile> {
75
+ clientId: string;
76
+ prompt?: ("none" | "consent") | undefined;
77
+ permissions?: number | undefined;
78
+ }
79
+ declare const discord: (options: DiscordOptions) => {
80
+ id: "discord";
81
+ name: string;
82
+ createAuthorizationURL({
83
+ state,
84
+ scopes,
85
+ redirectURI
86
+ }: {
87
+ state: string;
88
+ codeVerifier: string;
89
+ scopes?: string[] | undefined;
90
+ redirectURI: string;
91
+ display?: string | undefined;
92
+ loginHint?: string | undefined;
93
+ }): URL;
94
+ validateAuthorizationCode: ({
95
+ code,
96
+ redirectURI
97
+ }: {
98
+ code: string;
99
+ redirectURI: string;
100
+ codeVerifier?: string | undefined;
101
+ deviceId?: string | undefined;
102
+ }) => Promise<OAuth2Tokens>;
103
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
104
+ getUserInfo(token: OAuth2Tokens & {
105
+ user?: {
106
+ name?: {
107
+ firstName?: string;
108
+ lastName?: string;
109
+ };
110
+ email?: string;
111
+ } | undefined;
112
+ }): Promise<{
113
+ user: {
114
+ id: string;
115
+ name?: string;
116
+ email?: string | null;
117
+ image?: string;
118
+ emailVerified: boolean;
119
+ [key: string]: any;
120
+ };
121
+ data: any;
122
+ } | null>;
123
+ options: DiscordOptions;
124
+ };
125
+ //#endregion
126
+ export { DiscordOptions, DiscordProfile, discord };
@@ -0,0 +1,64 @@
1
+ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
2
+ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
3
+ import "../oauth2/index.mjs";
4
+ import { betterFetch } from "@better-fetch/fetch";
5
+
6
+ //#region src/social-providers/discord.ts
7
+ const discord = (options) => {
8
+ return {
9
+ id: "discord",
10
+ name: "Discord",
11
+ createAuthorizationURL({ state, scopes, redirectURI }) {
12
+ const _scopes = options.disableDefaultScope ? [] : ["identify", "email"];
13
+ if (scopes) _scopes.push(...scopes);
14
+ if (options.scope) _scopes.push(...options.scope);
15
+ const permissionsParam = _scopes.includes("bot") && options.permissions !== void 0 ? `&permissions=${options.permissions}` : "";
16
+ return new URL(`https://discord.com/api/oauth2/authorize?scope=${_scopes.join("+")}&response_type=code&client_id=${options.clientId}&redirect_uri=${encodeURIComponent(options.redirectURI || redirectURI)}&state=${state}&prompt=${options.prompt || "none"}${permissionsParam}`);
17
+ },
18
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
19
+ return validateAuthorizationCode({
20
+ code,
21
+ redirectURI,
22
+ options,
23
+ tokenEndpoint: "https://discord.com/api/oauth2/token"
24
+ });
25
+ },
26
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
27
+ return refreshAccessToken({
28
+ refreshToken,
29
+ options: {
30
+ clientId: options.clientId,
31
+ clientKey: options.clientKey,
32
+ clientSecret: options.clientSecret
33
+ },
34
+ tokenEndpoint: "https://discord.com/api/oauth2/token"
35
+ });
36
+ },
37
+ async getUserInfo(token) {
38
+ if (options.getUserInfo) return options.getUserInfo(token);
39
+ const { data: profile, error } = await betterFetch("https://discord.com/api/users/@me", { headers: { authorization: `Bearer ${token.accessToken}` } });
40
+ if (error) return null;
41
+ if (profile.avatar === null) profile.image_url = `https://cdn.discordapp.com/embed/avatars/${profile.discriminator === "0" ? Number(BigInt(profile.id) >> BigInt(22)) % 6 : parseInt(profile.discriminator) % 5}.png`;
42
+ else {
43
+ const format = profile.avatar.startsWith("a_") ? "gif" : "png";
44
+ profile.image_url = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
45
+ }
46
+ const userMap = await options.mapProfileToUser?.(profile);
47
+ return {
48
+ user: {
49
+ id: profile.id,
50
+ name: profile.global_name || profile.username || "",
51
+ email: profile.email,
52
+ emailVerified: profile.verified,
53
+ image: profile.image_url,
54
+ ...userMap
55
+ },
56
+ data: profile
57
+ };
58
+ },
59
+ options
60
+ };
61
+ };
62
+
63
+ //#endregion
64
+ export { discord };
@@ -0,0 +1,71 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/dropbox.d.ts
5
+ interface DropboxProfile {
6
+ account_id: string;
7
+ name: {
8
+ given_name: string;
9
+ surname: string;
10
+ familiar_name: string;
11
+ display_name: string;
12
+ abbreviated_name: string;
13
+ };
14
+ email: string;
15
+ email_verified: boolean;
16
+ profile_photo_url: string;
17
+ }
18
+ interface DropboxOptions extends ProviderOptions<DropboxProfile> {
19
+ clientId: string;
20
+ accessType?: ("offline" | "online" | "legacy") | undefined;
21
+ }
22
+ declare const dropbox: (options: DropboxOptions) => {
23
+ id: "dropbox";
24
+ name: string;
25
+ createAuthorizationURL: ({
26
+ state,
27
+ scopes,
28
+ codeVerifier,
29
+ redirectURI
30
+ }: {
31
+ state: string;
32
+ codeVerifier: string;
33
+ scopes?: string[] | undefined;
34
+ redirectURI: string;
35
+ display?: string | undefined;
36
+ loginHint?: string | undefined;
37
+ }) => Promise<URL>;
38
+ validateAuthorizationCode: ({
39
+ code,
40
+ codeVerifier,
41
+ redirectURI
42
+ }: {
43
+ code: string;
44
+ redirectURI: string;
45
+ codeVerifier?: string | undefined;
46
+ deviceId?: string | undefined;
47
+ }) => Promise<OAuth2Tokens>;
48
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
49
+ getUserInfo(token: OAuth2Tokens & {
50
+ user?: {
51
+ name?: {
52
+ firstName?: string;
53
+ lastName?: string;
54
+ };
55
+ email?: string;
56
+ } | undefined;
57
+ }): Promise<{
58
+ user: {
59
+ id: string;
60
+ name?: string;
61
+ email?: string | null;
62
+ image?: string;
63
+ emailVerified: boolean;
64
+ [key: string]: any;
65
+ };
66
+ data: any;
67
+ } | null>;
68
+ options: DropboxOptions;
69
+ };
70
+ //#endregion
71
+ export { DropboxOptions, DropboxProfile, dropbox };
@@ -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/dropbox.ts
8
+ const dropbox = (options) => {
9
+ const tokenEndpoint = "https://api.dropboxapi.com/oauth2/token";
10
+ return {
11
+ id: "dropbox",
12
+ name: "Dropbox",
13
+ createAuthorizationURL: async ({ state, scopes, codeVerifier, redirectURI }) => {
14
+ const _scopes = options.disableDefaultScope ? [] : ["account_info.read"];
15
+ if (options.scope) _scopes.push(...options.scope);
16
+ if (scopes) _scopes.push(...scopes);
17
+ const additionalParams = {};
18
+ if (options.accessType) additionalParams.token_access_type = options.accessType;
19
+ return await createAuthorizationURL({
20
+ id: "dropbox",
21
+ options,
22
+ authorizationEndpoint: "https://www.dropbox.com/oauth2/authorize",
23
+ scopes: _scopes,
24
+ state,
25
+ redirectURI,
26
+ codeVerifier,
27
+ additionalParams
28
+ });
29
+ },
30
+ validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
31
+ return await validateAuthorizationCode({
32
+ code,
33
+ codeVerifier,
34
+ redirectURI,
35
+ options,
36
+ tokenEndpoint
37
+ });
38
+ },
39
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
40
+ return refreshAccessToken({
41
+ refreshToken,
42
+ options: {
43
+ clientId: options.clientId,
44
+ clientKey: options.clientKey,
45
+ clientSecret: options.clientSecret
46
+ },
47
+ tokenEndpoint: "https://api.dropbox.com/oauth2/token"
48
+ });
49
+ },
50
+ async getUserInfo(token) {
51
+ if (options.getUserInfo) return options.getUserInfo(token);
52
+ const { data: profile, error } = await betterFetch("https://api.dropboxapi.com/2/users/get_current_account", {
53
+ method: "POST",
54
+ headers: { Authorization: `Bearer ${token.accessToken}` }
55
+ });
56
+ if (error) return null;
57
+ const userMap = await options.mapProfileToUser?.(profile);
58
+ return {
59
+ user: {
60
+ id: profile.account_id,
61
+ name: profile.name?.display_name,
62
+ email: profile.email,
63
+ emailVerified: profile.email_verified || false,
64
+ image: profile.profile_photo_url,
65
+ ...userMap
66
+ },
67
+ data: profile
68
+ };
69
+ },
70
+ options
71
+ };
72
+ };
73
+
74
+ //#endregion
75
+ export { dropbox };
@@ -0,0 +1,81 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/facebook.d.ts
5
+ interface FacebookProfile {
6
+ id: string;
7
+ name: string;
8
+ email: string;
9
+ email_verified: boolean;
10
+ picture: {
11
+ data: {
12
+ height: number;
13
+ is_silhouette: boolean;
14
+ url: string;
15
+ width: number;
16
+ };
17
+ };
18
+ }
19
+ interface FacebookOptions extends ProviderOptions<FacebookProfile> {
20
+ clientId: string;
21
+ /**
22
+ * Extend list of fields to retrieve from the Facebook user profile.
23
+ *
24
+ * @default ["id", "name", "email", "picture"]
25
+ */
26
+ fields?: string[] | undefined;
27
+ /**
28
+ * The config id to use when undergoing oauth
29
+ */
30
+ configId?: string | undefined;
31
+ }
32
+ declare const facebook: (options: FacebookOptions) => {
33
+ id: "facebook";
34
+ name: string;
35
+ createAuthorizationURL({
36
+ state,
37
+ scopes,
38
+ redirectURI,
39
+ loginHint
40
+ }: {
41
+ state: string;
42
+ codeVerifier: string;
43
+ scopes?: string[] | undefined;
44
+ redirectURI: string;
45
+ display?: string | undefined;
46
+ loginHint?: string | undefined;
47
+ }): Promise<URL>;
48
+ validateAuthorizationCode: ({
49
+ code,
50
+ redirectURI
51
+ }: {
52
+ code: string;
53
+ redirectURI: string;
54
+ codeVerifier?: string | undefined;
55
+ deviceId?: string | undefined;
56
+ }) => Promise<OAuth2Tokens>;
57
+ verifyIdToken(token: string, nonce: string | undefined): Promise<boolean>;
58
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
59
+ getUserInfo(token: OAuth2Tokens & {
60
+ user?: {
61
+ name?: {
62
+ firstName?: string;
63
+ lastName?: string;
64
+ };
65
+ email?: string;
66
+ } | undefined;
67
+ }): Promise<{
68
+ user: {
69
+ id: string;
70
+ name?: string;
71
+ email?: string | null;
72
+ image?: string;
73
+ emailVerified: boolean;
74
+ [key: string]: any;
75
+ };
76
+ data: any;
77
+ } | null>;
78
+ options: FacebookOptions;
79
+ };
80
+ //#endregion
81
+ export { FacebookOptions, FacebookProfile, facebook };
@@ -0,0 +1,120 @@
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
+ import { createRemoteJWKSet, decodeJwt, jwtVerify } from "jose";
7
+
8
+ //#region src/social-providers/facebook.ts
9
+ const facebook = (options) => {
10
+ return {
11
+ id: "facebook",
12
+ name: "Facebook",
13
+ async createAuthorizationURL({ state, scopes, redirectURI, loginHint }) {
14
+ const _scopes = options.disableDefaultScope ? [] : ["email", "public_profile"];
15
+ if (options.scope) _scopes.push(...options.scope);
16
+ if (scopes) _scopes.push(...scopes);
17
+ return await createAuthorizationURL({
18
+ id: "facebook",
19
+ options,
20
+ authorizationEndpoint: "https://www.facebook.com/v21.0/dialog/oauth",
21
+ scopes: _scopes,
22
+ state,
23
+ redirectURI,
24
+ loginHint,
25
+ additionalParams: options.configId ? { config_id: options.configId } : {}
26
+ });
27
+ },
28
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
29
+ return validateAuthorizationCode({
30
+ code,
31
+ redirectURI,
32
+ options,
33
+ tokenEndpoint: "https://graph.facebook.com/oauth/access_token"
34
+ });
35
+ },
36
+ async verifyIdToken(token, nonce) {
37
+ if (options.disableIdTokenSignIn) return false;
38
+ if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
39
+ if (token.split(".").length === 3) try {
40
+ const { payload: jwtClaims } = await jwtVerify(token, createRemoteJWKSet(new URL("https://limited.facebook.com/.well-known/oauth/openid/jwks/")), {
41
+ algorithms: ["RS256"],
42
+ audience: options.clientId,
43
+ issuer: "https://www.facebook.com"
44
+ });
45
+ if (nonce && jwtClaims.nonce !== nonce) return false;
46
+ return !!jwtClaims;
47
+ } catch {
48
+ return false;
49
+ }
50
+ return true;
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: "https://graph.facebook.com/v18.0/oauth/access_token"
61
+ });
62
+ },
63
+ async getUserInfo(token) {
64
+ if (options.getUserInfo) return options.getUserInfo(token);
65
+ if (token.idToken && token.idToken.split(".").length === 3) {
66
+ const profile$1 = decodeJwt(token.idToken);
67
+ const user = {
68
+ id: profile$1.sub,
69
+ name: profile$1.name,
70
+ email: profile$1.email,
71
+ picture: { data: {
72
+ url: profile$1.picture,
73
+ height: 100,
74
+ width: 100,
75
+ is_silhouette: false
76
+ } }
77
+ };
78
+ const userMap$1 = await options.mapProfileToUser?.({
79
+ ...user,
80
+ email_verified: false
81
+ });
82
+ return {
83
+ user: {
84
+ ...user,
85
+ emailVerified: false,
86
+ ...userMap$1
87
+ },
88
+ data: profile$1
89
+ };
90
+ }
91
+ const { data: profile, error } = await betterFetch("https://graph.facebook.com/me?fields=" + [
92
+ "id",
93
+ "name",
94
+ "email",
95
+ "picture",
96
+ ...options?.fields || []
97
+ ].join(","), { auth: {
98
+ type: "Bearer",
99
+ token: token.accessToken
100
+ } });
101
+ if (error) return null;
102
+ const userMap = await options.mapProfileToUser?.(profile);
103
+ return {
104
+ user: {
105
+ id: profile.id,
106
+ name: profile.name,
107
+ email: profile.email,
108
+ image: profile.picture.data.url,
109
+ emailVerified: profile.email_verified,
110
+ ...userMap
111
+ },
112
+ data: profile
113
+ };
114
+ },
115
+ options
116
+ };
117
+ };
118
+
119
+ //#endregion
120
+ export { facebook };
@@ -0,0 +1,63 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ import "../oauth2/index.mjs";
3
+
4
+ //#region src/social-providers/figma.d.ts
5
+ interface FigmaProfile {
6
+ id: string;
7
+ email: string;
8
+ handle: string;
9
+ img_url: string;
10
+ }
11
+ interface FigmaOptions extends ProviderOptions<FigmaProfile> {
12
+ clientId: string;
13
+ }
14
+ declare const figma: (options: FigmaOptions) => {
15
+ id: "figma";
16
+ name: string;
17
+ createAuthorizationURL({
18
+ state,
19
+ scopes,
20
+ codeVerifier,
21
+ redirectURI
22
+ }: {
23
+ state: string;
24
+ codeVerifier: string;
25
+ scopes?: string[] | undefined;
26
+ redirectURI: string;
27
+ display?: string | undefined;
28
+ loginHint?: string | undefined;
29
+ }): Promise<URL>;
30
+ validateAuthorizationCode: ({
31
+ code,
32
+ codeVerifier,
33
+ redirectURI
34
+ }: {
35
+ code: string;
36
+ redirectURI: string;
37
+ codeVerifier?: string | undefined;
38
+ deviceId?: string | undefined;
39
+ }) => Promise<OAuth2Tokens>;
40
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
41
+ getUserInfo(token: OAuth2Tokens & {
42
+ user?: {
43
+ name?: {
44
+ firstName?: string;
45
+ lastName?: string;
46
+ };
47
+ email?: string;
48
+ } | undefined;
49
+ }): Promise<{
50
+ user: {
51
+ id: string;
52
+ name?: string;
53
+ email?: string | null;
54
+ image?: string;
55
+ emailVerified: boolean;
56
+ [key: string]: any;
57
+ };
58
+ data: any;
59
+ } | null>;
60
+ options: FigmaOptions;
61
+ };
62
+ //#endregion
63
+ export { FigmaOptions, FigmaProfile, figma };
@@ -0,0 +1,84 @@
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 { betterFetch } from "@better-fetch/fetch";
9
+
10
+ //#region src/social-providers/figma.ts
11
+ const figma = (options) => {
12
+ return {
13
+ id: "figma",
14
+ name: "Figma",
15
+ async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
16
+ if (!options.clientId || !options.clientSecret) {
17
+ logger.error("Client Id and Client Secret are required for Figma. Make sure to provide them in the options.");
18
+ throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
19
+ }
20
+ if (!codeVerifier) throw new BetterAuthError("codeVerifier is required for Figma");
21
+ const _scopes = options.disableDefaultScope ? [] : ["file_read"];
22
+ if (options.scope) _scopes.push(...options.scope);
23
+ if (scopes) _scopes.push(...scopes);
24
+ return await createAuthorizationURL({
25
+ id: "figma",
26
+ options,
27
+ authorizationEndpoint: "https://www.figma.com/oauth",
28
+ scopes: _scopes,
29
+ state,
30
+ codeVerifier,
31
+ redirectURI
32
+ });
33
+ },
34
+ validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
35
+ return validateAuthorizationCode({
36
+ code,
37
+ codeVerifier,
38
+ redirectURI,
39
+ options,
40
+ tokenEndpoint: "https://www.figma.com/api/oauth/token"
41
+ });
42
+ },
43
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
44
+ return refreshAccessToken({
45
+ refreshToken,
46
+ options: {
47
+ clientId: options.clientId,
48
+ clientKey: options.clientKey,
49
+ clientSecret: options.clientSecret
50
+ },
51
+ tokenEndpoint: "https://www.figma.com/api/oauth/token"
52
+ });
53
+ },
54
+ async getUserInfo(token) {
55
+ if (options.getUserInfo) return options.getUserInfo(token);
56
+ try {
57
+ const { data: profile } = await betterFetch("https://api.figma.com/v1/me", { headers: { Authorization: `Bearer ${token.accessToken}` } });
58
+ if (!profile) {
59
+ logger.error("Failed to fetch user from Figma");
60
+ return null;
61
+ }
62
+ const userMap = await options.mapProfileToUser?.(profile);
63
+ return {
64
+ user: {
65
+ id: profile.id,
66
+ name: profile.handle,
67
+ email: profile.email,
68
+ image: profile.img_url,
69
+ emailVerified: false,
70
+ ...userMap
71
+ },
72
+ data: profile
73
+ };
74
+ } catch (error) {
75
+ logger.error("Failed to fetch user info from Figma:", error);
76
+ return null;
77
+ }
78
+ },
79
+ options
80
+ };
81
+ };
82
+
83
+ //#endregion
84
+ export { figma };