@gatwech/core 0.0.11 → 1.0.0-beta.19

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 (134) hide show
  1. package/dist/api/index.d.mts +2 -2
  2. package/dist/context/index.d.mts +2 -2
  3. package/dist/db/adapter/index.d.mts +2 -2
  4. package/dist/db/index.d.mts +2 -2
  5. package/dist/env/index.d.mts +1 -1
  6. package/dist/env/index.mjs +1 -1
  7. package/dist/{env-JMSMESs1.mjs → env-ubiqEEZm.mjs} +10 -9
  8. package/dist/error/index.mjs +2 -2
  9. package/dist/{error-41YsFQ8b.mjs → error-DKIIiFmH.mjs} +1 -1
  10. package/dist/{index-DLP-K0uY.d.mts → index-CNtOUpmF.d.mts} +4 -3
  11. package/dist/index-Df0KhQRf.d.mts +3002 -0
  12. package/dist/index.d.mts +3 -3
  13. package/dist/oauth2/index.d.mts +2 -2
  14. package/dist/social-providers/index.d.mts +3 -3
  15. package/dist/social-providers/index.mjs +73 -2414
  16. package/dist/src/api/index.d.ts +119 -0
  17. package/dist/src/async_hooks/index.d.ts +6 -0
  18. package/dist/src/context/endpoint-context.d.ts +14 -0
  19. package/dist/src/context/index.d.ts +3 -0
  20. package/dist/src/context/request-state.d.ts +13 -0
  21. package/dist/src/context/transaction.d.ts +11 -0
  22. package/dist/src/db/adapter/index.d.ts +401 -0
  23. package/{src/db/index.ts → dist/src/db/index.d.ts} +2 -18
  24. package/dist/src/db/plugin.d.ts +10 -0
  25. package/dist/src/db/schema/account.d.ts +22 -0
  26. package/dist/src/db/schema/rate-limit.d.ts +10 -0
  27. package/dist/src/db/schema/session.d.ts +17 -0
  28. package/dist/src/db/schema/shared.d.ts +6 -0
  29. package/dist/src/db/schema/user.d.ts +16 -0
  30. package/{src/db/schema/verification.ts → dist/src/db/schema/verification.d.ts} +8 -8
  31. package/dist/src/db/type.d.ts +159 -0
  32. package/dist/src/env/color-depth.d.ts +1 -0
  33. package/dist/src/env/env-impl.d.ts +29 -0
  34. package/dist/src/env/index.d.ts +3 -0
  35. package/dist/src/env/logger.d.ts +52 -0
  36. package/dist/src/error/codes.d.ts +27 -0
  37. package/dist/src/error/index.d.ts +4 -0
  38. package/dist/src/oauth2/client-credentials-token.d.ts +21 -0
  39. package/dist/src/oauth2/create-authorization-url.d.ts +21 -0
  40. package/dist/src/oauth2/index.d.ts +6 -0
  41. package/dist/src/oauth2/oauth-provider.d.ts +178 -0
  42. package/dist/src/oauth2/refresh-access-token.d.ts +20 -0
  43. package/dist/src/oauth2/utils.d.ts +3 -0
  44. package/dist/src/oauth2/validate-authorization-code.d.ts +28 -0
  45. package/dist/src/social-providers/github.d.ts +89 -0
  46. package/dist/src/social-providers/google.d.ts +82 -0
  47. package/dist/src/social-providers/index.d.ts +93 -0
  48. package/dist/src/types/context.d.ts +177 -0
  49. package/dist/src/types/cookie.d.ts +15 -0
  50. package/dist/src/types/helper.d.ts +9 -0
  51. package/dist/src/types/index.d.ts +7 -0
  52. package/dist/src/types/init-options.d.ts +1140 -0
  53. package/dist/src/types/plugin-client.d.ts +88 -0
  54. package/dist/src/types/plugin.d.ts +120 -0
  55. package/dist/src/utils/error-codes.d.ts +9 -0
  56. package/dist/utils/index.mjs +1 -1
  57. package/package.json +11 -5
  58. package/.turbo/turbo-build.log +0 -42
  59. package/dist/index-DjrJweYn.d.mts +0 -7312
  60. package/src/api/index.ts +0 -57
  61. package/src/async_hooks/index.ts +0 -35
  62. package/src/context/endpoint-context.ts +0 -48
  63. package/src/context/index.ts +0 -21
  64. package/src/context/request-state.test.ts +0 -346
  65. package/src/context/request-state.ts +0 -75
  66. package/src/context/transaction.ts +0 -72
  67. package/src/db/adapter/index.ts +0 -466
  68. package/src/db/plugin.ts +0 -11
  69. package/src/db/schema/account.ts +0 -34
  70. package/src/db/schema/rate-limit.ts +0 -21
  71. package/src/db/schema/session.ts +0 -17
  72. package/src/db/schema/shared.ts +0 -7
  73. package/src/db/schema/user.ts +0 -16
  74. package/src/db/type.ts +0 -180
  75. package/src/env/color-depth.ts +0 -172
  76. package/src/env/env-impl.ts +0 -124
  77. package/src/env/index.ts +0 -23
  78. package/src/env/logger.test.ts +0 -33
  79. package/src/env/logger.ts +0 -145
  80. package/src/error/codes.ts +0 -31
  81. package/src/error/index.ts +0 -11
  82. package/src/oauth2/client-credentials-token.ts +0 -102
  83. package/src/oauth2/create-authorization-url.ts +0 -85
  84. package/src/oauth2/index.ts +0 -21
  85. package/src/oauth2/oauth-provider.ts +0 -211
  86. package/src/oauth2/refresh-access-token.ts +0 -124
  87. package/src/oauth2/utils.ts +0 -36
  88. package/src/oauth2/validate-authorization-code.ts +0 -154
  89. package/src/social-providers/apple.ts +0 -213
  90. package/src/social-providers/atlassian.ts +0 -132
  91. package/src/social-providers/cognito.ts +0 -269
  92. package/src/social-providers/discord.ts +0 -169
  93. package/src/social-providers/dropbox.ts +0 -112
  94. package/src/social-providers/facebook.ts +0 -204
  95. package/src/social-providers/figma.ts +0 -115
  96. package/src/social-providers/github.ts +0 -154
  97. package/src/social-providers/gitlab.ts +0 -152
  98. package/src/social-providers/google.ts +0 -171
  99. package/src/social-providers/huggingface.ts +0 -118
  100. package/src/social-providers/index.ts +0 -124
  101. package/src/social-providers/kakao.ts +0 -178
  102. package/src/social-providers/kick.ts +0 -92
  103. package/src/social-providers/line.ts +0 -169
  104. package/src/social-providers/linear.ts +0 -120
  105. package/src/social-providers/linkedin.ts +0 -110
  106. package/src/social-providers/microsoft-entra-id.ts +0 -245
  107. package/src/social-providers/naver.ts +0 -112
  108. package/src/social-providers/notion.ts +0 -108
  109. package/src/social-providers/paybin.ts +0 -122
  110. package/src/social-providers/paypal.ts +0 -263
  111. package/src/social-providers/polar.ts +0 -107
  112. package/src/social-providers/reddit.ts +0 -122
  113. package/src/social-providers/roblox.ts +0 -110
  114. package/src/social-providers/salesforce.ts +0 -159
  115. package/src/social-providers/slack.ts +0 -111
  116. package/src/social-providers/spotify.ts +0 -93
  117. package/src/social-providers/tiktok.ts +0 -210
  118. package/src/social-providers/twitch.ts +0 -111
  119. package/src/social-providers/twitter.ts +0 -198
  120. package/src/social-providers/vk.ts +0 -126
  121. package/src/social-providers/zoom.ts +0 -217
  122. package/src/types/context.ts +0 -269
  123. package/src/types/cookie.ts +0 -7
  124. package/src/types/helper.ts +0 -6
  125. package/src/types/index.ts +0 -21
  126. package/src/types/init-options.ts +0 -1346
  127. package/src/types/plugin-client.ts +0 -100
  128. package/src/types/plugin.ts +0 -158
  129. package/src/utils/error-codes.ts +0 -51
  130. package/tsconfig.json +0 -7
  131. package/tsdown.config.ts +0 -20
  132. /package/{src/index.ts → dist/src/index.d.ts} +0 -0
  133. /package/{src/utils/index.ts → dist/src/utils/index.d.ts} +0 -0
  134. /package/dist/{utils-BFQCAfNW.mjs → utils-CTOwq_Nj.mjs} +0 -0
@@ -1,269 +0,0 @@
1
- import { betterFetch } from "@better-fetch/fetch";
2
- import { APIError } from "better-call";
3
- import { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from "jose";
4
- import { logger } from "../env";
5
- import { PayvoAuthError } from "../error";
6
- import type { OAuthProvider, ProviderOptions } from "../oauth2";
7
- import {
8
- createAuthorizationURL,
9
- refreshAccessToken,
10
- validateAuthorizationCode,
11
- } from "../oauth2";
12
-
13
- export interface CognitoProfile {
14
- sub: string;
15
- email: string;
16
- email_verified: boolean;
17
- name: string;
18
- given_name?: string | undefined;
19
- family_name?: string | undefined;
20
- picture?: string | undefined;
21
- username?: string | undefined;
22
- locale?: string | undefined;
23
- phone_number?: string | undefined;
24
- phone_number_verified?: boolean | undefined;
25
- aud: string;
26
- iss: string;
27
- exp: number;
28
- iat: number;
29
- // Custom attributes from Cognito can be added here
30
- [key: string]: any;
31
- }
32
-
33
- export interface CognitoOptions extends ProviderOptions<CognitoProfile> {
34
- clientId: string;
35
- /**
36
- * The Cognito domain (e.g., "your-app.auth.us-east-1.amazoncognito.com")
37
- */
38
- domain: string;
39
- /**
40
- * AWS region where User Pool is hosted (e.g., "us-east-1")
41
- */
42
- region: string;
43
- userPoolId: string;
44
- requireClientSecret?: boolean | undefined;
45
- }
46
-
47
- export const cognito = (options: CognitoOptions) => {
48
- if (!options.domain || !options.region || !options.userPoolId) {
49
- logger.error(
50
- "Domain, region and userPoolId are required for Amazon Cognito. Make sure to provide them in the options."
51
- );
52
- throw new PayvoAuthError("DOMAIN_AND_REGION_REQUIRED");
53
- }
54
-
55
- const cleanDomain = options.domain.replace(/^https?:\/\//, "");
56
- const authorizationEndpoint = `https://${cleanDomain}/oauth2/authorize`;
57
- const tokenEndpoint = `https://${cleanDomain}/oauth2/token`;
58
- const userInfoEndpoint = `https://${cleanDomain}/oauth2/userinfo`;
59
-
60
- return {
61
- id: "cognito",
62
- name: "Cognito",
63
- async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
64
- if (!options.clientId) {
65
- logger.error(
66
- "ClientId is required for Amazon Cognito. Make sure to provide them in the options."
67
- );
68
- throw new PayvoAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
69
- }
70
-
71
- if (options.requireClientSecret && !options.clientSecret) {
72
- logger.error(
73
- "Client Secret is required when requireClientSecret is true. Make sure to provide it in the options."
74
- );
75
- throw new PayvoAuthError("CLIENT_SECRET_REQUIRED");
76
- }
77
- const _scopes = options.disableDefaultScope
78
- ? []
79
- : ["openid", "profile", "email"];
80
- if (options.scope) _scopes.push(...options.scope);
81
- if (scopes) _scopes.push(...scopes);
82
-
83
- const url = await createAuthorizationURL({
84
- id: "cognito",
85
- options: {
86
- ...options,
87
- },
88
- authorizationEndpoint,
89
- scopes: _scopes,
90
- state,
91
- codeVerifier,
92
- redirectURI,
93
- prompt: options.prompt,
94
- });
95
- return url;
96
- },
97
-
98
- validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
99
- return validateAuthorizationCode({
100
- code,
101
- codeVerifier,
102
- redirectURI,
103
- options,
104
- tokenEndpoint,
105
- });
106
- },
107
-
108
- refreshAccessToken: options.refreshAccessToken
109
- ? options.refreshAccessToken
110
- : async (refreshToken) => {
111
- return refreshAccessToken({
112
- refreshToken,
113
- options: {
114
- clientId: options.clientId,
115
- clientKey: options.clientKey,
116
- clientSecret: options.clientSecret,
117
- },
118
- tokenEndpoint,
119
- });
120
- },
121
-
122
- async verifyIdToken(token, nonce) {
123
- if (options.disableIdTokenSignIn) {
124
- return false;
125
- }
126
- if (options.verifyIdToken) {
127
- return options.verifyIdToken(token, nonce);
128
- }
129
-
130
- try {
131
- const decodedHeader = decodeProtectedHeader(token);
132
- const { kid, alg: jwtAlg } = decodedHeader;
133
- if (!kid || !jwtAlg) return false;
134
-
135
- const publicKey = await getCognitoPublicKey(
136
- kid,
137
- options.region,
138
- options.userPoolId
139
- );
140
- const expectedIssuer = `https://cognito-idp.${options.region}.amazonaws.com/${options.userPoolId}`;
141
-
142
- const { payload: jwtClaims } = await jwtVerify(token, publicKey, {
143
- algorithms: [jwtAlg],
144
- issuer: expectedIssuer,
145
- audience: options.clientId,
146
- maxTokenAge: "1h",
147
- });
148
-
149
- if (nonce && jwtClaims.nonce !== nonce) {
150
- return false;
151
- }
152
- return true;
153
- } catch (error) {
154
- logger.error("Failed to verify ID token:", error);
155
- return false;
156
- }
157
- },
158
-
159
- async getUserInfo(token) {
160
- if (options.getUserInfo) {
161
- return options.getUserInfo(token);
162
- }
163
-
164
- if (token.idToken) {
165
- try {
166
- const profile = decodeJwt<CognitoProfile>(token.idToken);
167
- if (!profile) {
168
- return null;
169
- }
170
- const name =
171
- profile.name ||
172
- profile.given_name ||
173
- profile.username ||
174
- profile.email;
175
- const enrichedProfile = {
176
- ...profile,
177
- name,
178
- };
179
- const userMap = await options.mapProfileToUser?.(enrichedProfile);
180
-
181
- return {
182
- user: {
183
- id: profile.sub,
184
- name: enrichedProfile.name,
185
- email: profile.email,
186
- image: profile.picture,
187
- emailVerified: profile.email_verified,
188
- ...userMap,
189
- },
190
- data: enrichedProfile,
191
- };
192
- } catch (error) {
193
- logger.error("Failed to decode ID token:", error);
194
- }
195
- }
196
-
197
- if (token.accessToken) {
198
- try {
199
- const { data: userInfo } = await betterFetch<CognitoProfile>(
200
- userInfoEndpoint,
201
- {
202
- headers: {
203
- Authorization: `Bearer ${token.accessToken}`,
204
- },
205
- }
206
- );
207
-
208
- if (userInfo) {
209
- const userMap = await options.mapProfileToUser?.(userInfo);
210
- return {
211
- user: {
212
- id: userInfo.sub,
213
- name: userInfo.name || userInfo.given_name || userInfo.username,
214
- email: userInfo.email,
215
- image: userInfo.picture,
216
- emailVerified: userInfo.email_verified,
217
- ...userMap,
218
- },
219
- data: userInfo,
220
- };
221
- }
222
- } catch (error) {
223
- logger.error("Failed to fetch user info from Cognito:", error);
224
- }
225
- }
226
-
227
- return null;
228
- },
229
-
230
- options,
231
- } satisfies OAuthProvider<CognitoProfile>;
232
- };
233
-
234
- export const getCognitoPublicKey = async (
235
- kid: string,
236
- region: string,
237
- userPoolId: string
238
- ) => {
239
- const COGNITO_JWKS_URI = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`;
240
-
241
- try {
242
- const { data } = await betterFetch<{
243
- keys: Array<{
244
- kid: string;
245
- alg: string;
246
- kty: string;
247
- use: string;
248
- n: string;
249
- e: string;
250
- }>;
251
- }>(COGNITO_JWKS_URI);
252
-
253
- if (!data?.keys) {
254
- throw new APIError("BAD_REQUEST", {
255
- message: "Keys not found",
256
- });
257
- }
258
-
259
- const jwk = data.keys.find((key) => key.kid === kid);
260
- if (!jwk) {
261
- throw new Error(`JWK with kid ${kid} not found`);
262
- }
263
-
264
- return await importJWK(jwk, jwk.alg);
265
- } catch (error) {
266
- logger.error("Failed to fetch Cognito public key:", error);
267
- throw error;
268
- }
269
- };
@@ -1,169 +0,0 @@
1
- import { betterFetch } from "@better-fetch/fetch";
2
- import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
- import { refreshAccessToken, validateAuthorizationCode } from "../oauth2";
4
- export interface DiscordProfile extends Record<string, any> {
5
- /** the user's id (i.e. the numerical snowflake) */
6
- id: string;
7
- /** the user's username, not unique across the platform */
8
- username: string;
9
- /** the user's Discord-tag */
10
- discriminator: string;
11
- /** the user's display name, if it is set */
12
- global_name: string | null;
13
- /**
14
- * the user's avatar hash:
15
- * https://discord.com/developers/docs/reference#image-formatting
16
- */
17
- avatar: string | null;
18
- /** whether the user belongs to an OAuth2 application */
19
- bot?: boolean | undefined;
20
- /**
21
- * whether the user is an Official Discord System user (part of the urgent
22
- * message system)
23
- */
24
- system?: boolean | undefined;
25
- /** whether the user has two factor enabled on their account */
26
- mfa_enabled: boolean;
27
- /**
28
- * the user's banner hash:
29
- * https://discord.com/developers/docs/reference#image-formatting
30
- */
31
- banner: string | null;
32
-
33
- /** the user's banner color encoded as an integer representation of hexadecimal color code */
34
- accent_color: number | null;
35
-
36
- /**
37
- * the user's chosen language option:
38
- * https://discord.com/developers/docs/reference#locales
39
- */
40
- locale: string;
41
- /** whether the email on this account has been verified */
42
- verified: boolean;
43
- /** the user's email */
44
- email: string;
45
- /**
46
- * the flags on a user's account:
47
- * https://discord.com/developers/docs/resources/user#user-object-user-flags
48
- */
49
- flags: number;
50
- /**
51
- * the type of Nitro subscription on a user's account:
52
- * https://discord.com/developers/docs/resources/user#user-object-premium-types
53
- */
54
- premium_type: number;
55
- /**
56
- * the public flags on a user's account:
57
- * https://discord.com/developers/docs/resources/user#user-object-user-flags
58
- */
59
- public_flags: number;
60
- /** undocumented field; corresponds to the user's custom nickname */
61
- display_name: string | null;
62
- /**
63
- * undocumented field; corresponds to the Discord feature where you can e.g.
64
- * put your avatar inside of an ice cube
65
- */
66
- avatar_decoration: string | null;
67
- /**
68
- * undocumented field; corresponds to the premium feature where you can
69
- * select a custom banner color
70
- */
71
- banner_color: string | null;
72
- /** undocumented field; the CDN URL of their profile picture */
73
- image_url: string;
74
- }
75
-
76
- export interface DiscordOptions extends ProviderOptions<DiscordProfile> {
77
- clientId: string;
78
- prompt?: ("none" | "consent") | undefined;
79
- permissions?: number | undefined;
80
- }
81
-
82
- export const discord = (options: DiscordOptions) => {
83
- return {
84
- id: "discord",
85
- name: "Discord",
86
- createAuthorizationURL({ state, scopes, redirectURI }) {
87
- const _scopes = options.disableDefaultScope ? [] : ["identify", "email"];
88
- if (scopes) _scopes.push(...scopes);
89
- if (options.scope) _scopes.push(...options.scope);
90
- const hasBotScope = _scopes.includes("bot");
91
- const permissionsParam =
92
- hasBotScope && options.permissions !== undefined
93
- ? `&permissions=${options.permissions}`
94
- : "";
95
- return new URL(
96
- `https://discord.com/api/oauth2/authorize?scope=${_scopes.join(
97
- "+",
98
- )}&response_type=code&client_id=${
99
- options.clientId
100
- }&redirect_uri=${encodeURIComponent(
101
- options.redirectURI || redirectURI,
102
- )}&state=${state}&prompt=${
103
- options.prompt || "none"
104
- }${permissionsParam}`,
105
- );
106
- },
107
- validateAuthorizationCode: async ({ code, redirectURI }) => {
108
- return validateAuthorizationCode({
109
- code,
110
- redirectURI,
111
- options,
112
- tokenEndpoint: "https://discord.com/api/oauth2/token",
113
- });
114
- },
115
- refreshAccessToken: options.refreshAccessToken
116
- ? options.refreshAccessToken
117
- : async (refreshToken) => {
118
- return refreshAccessToken({
119
- refreshToken,
120
- options: {
121
- clientId: options.clientId,
122
- clientKey: options.clientKey,
123
- clientSecret: options.clientSecret,
124
- },
125
- tokenEndpoint: "https://discord.com/api/oauth2/token",
126
- });
127
- },
128
- async getUserInfo(token) {
129
- if (options.getUserInfo) {
130
- return options.getUserInfo(token);
131
- }
132
- const { data: profile, error } = await betterFetch<DiscordProfile>(
133
- "https://discord.com/api/users/@me",
134
- {
135
- headers: {
136
- authorization: `Bearer ${token.accessToken}`,
137
- },
138
- },
139
- );
140
-
141
- if (error) {
142
- return null;
143
- }
144
- if (profile.avatar === null) {
145
- const defaultAvatarNumber =
146
- profile.discriminator === "0"
147
- ? Number(BigInt(profile.id) >> BigInt(22)) % 6
148
- : parseInt(profile.discriminator) % 5;
149
- profile.image_url = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarNumber}.png`;
150
- } else {
151
- const format = profile.avatar.startsWith("a_") ? "gif" : "png";
152
- profile.image_url = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;
153
- }
154
- const userMap = await options.mapProfileToUser?.(profile);
155
- return {
156
- user: {
157
- id: profile.id,
158
- name: profile.global_name || profile.username || "",
159
- email: profile.email,
160
- emailVerified: profile.verified,
161
- image: profile.image_url,
162
- ...userMap,
163
- },
164
- data: profile,
165
- };
166
- },
167
- options,
168
- } satisfies OAuthProvider<DiscordProfile>;
169
- };
@@ -1,112 +0,0 @@
1
- import { betterFetch } from "@better-fetch/fetch";
2
- import type { OAuthProvider, ProviderOptions } from "../oauth2";
3
- import {
4
- createAuthorizationURL,
5
- refreshAccessToken,
6
- validateAuthorizationCode,
7
- } from "../oauth2";
8
-
9
- export interface DropboxProfile {
10
- account_id: string;
11
- name: {
12
- given_name: string;
13
- surname: string;
14
- familiar_name: string;
15
- display_name: string;
16
- abbreviated_name: string;
17
- };
18
- email: string;
19
- email_verified: boolean;
20
- profile_photo_url: string;
21
- }
22
-
23
- export interface DropboxOptions extends ProviderOptions<DropboxProfile> {
24
- clientId: string;
25
- accessType?: ("offline" | "online" | "legacy") | undefined;
26
- }
27
-
28
- export const dropbox = (options: DropboxOptions) => {
29
- const tokenEndpoint = "https://api.dropboxapi.com/oauth2/token";
30
-
31
- return {
32
- id: "dropbox",
33
- name: "Dropbox",
34
- createAuthorizationURL: async ({
35
- state,
36
- scopes,
37
- codeVerifier,
38
- redirectURI,
39
- }) => {
40
- const _scopes = options.disableDefaultScope ? [] : ["account_info.read"];
41
- if (options.scope) _scopes.push(...options.scope);
42
- if (scopes) _scopes.push(...scopes);
43
- const additionalParams: Record<string, string> = {};
44
- if (options.accessType) {
45
- additionalParams.token_access_type = options.accessType;
46
- }
47
- return await createAuthorizationURL({
48
- id: "dropbox",
49
- options,
50
- authorizationEndpoint: "https://www.dropbox.com/oauth2/authorize",
51
- scopes: _scopes,
52
- state,
53
- redirectURI,
54
- codeVerifier,
55
- additionalParams,
56
- });
57
- },
58
- validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
59
- return await validateAuthorizationCode({
60
- code,
61
- codeVerifier,
62
- redirectURI,
63
- options,
64
- tokenEndpoint,
65
- });
66
- },
67
- refreshAccessToken: options.refreshAccessToken
68
- ? options.refreshAccessToken
69
- : async (refreshToken) => {
70
- return refreshAccessToken({
71
- refreshToken,
72
- options: {
73
- clientId: options.clientId,
74
- clientKey: options.clientKey,
75
- clientSecret: options.clientSecret,
76
- },
77
- tokenEndpoint: "https://api.dropbox.com/oauth2/token",
78
- });
79
- },
80
- async getUserInfo(token) {
81
- if (options.getUserInfo) {
82
- return options.getUserInfo(token);
83
- }
84
- const { data: profile, error } = await betterFetch<DropboxProfile>(
85
- "https://api.dropboxapi.com/2/users/get_current_account",
86
- {
87
- method: "POST",
88
- headers: {
89
- Authorization: `Bearer ${token.accessToken}`,
90
- },
91
- },
92
- );
93
-
94
- if (error) {
95
- return null;
96
- }
97
- const userMap = await options.mapProfileToUser?.(profile);
98
- return {
99
- user: {
100
- id: profile.account_id,
101
- name: profile.name?.display_name,
102
- email: profile.email,
103
- emailVerified: profile.email_verified || false,
104
- image: profile.profile_photo_url,
105
- ...userMap,
106
- },
107
- data: profile,
108
- };
109
- },
110
- options,
111
- } satisfies OAuthProvider<DropboxProfile>;
112
- };