@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,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 NaverProfile {
10
- /** API response result code */
11
- resultcode: string;
12
- /** API response message */
13
- message: string;
14
- response: {
15
- /** Unique Naver user identifier */
16
- id: string;
17
- /** User nickname */
18
- nickname: string;
19
- /** User real name */
20
- name: string;
21
- /** User email address */
22
- email: string;
23
- /** Gender (F: female, M: male, U: unknown) */
24
- gender: string;
25
- /** Age range */
26
- age: string;
27
- /** Birthday (MM-DD format) */
28
- birthday: string;
29
- /** Birth year */
30
- birthyear: string;
31
- /** Profile image URL */
32
- profile_image: string;
33
- /** Mobile phone number */
34
- mobile: string;
35
- };
36
- }
37
-
38
- export interface NaverOptions extends ProviderOptions<NaverProfile> {
39
- clientId: string;
40
- }
41
-
42
- export const naver = (options: NaverOptions) => {
43
- return {
44
- id: "naver",
45
- name: "Naver",
46
- createAuthorizationURL({ state, scopes, redirectURI }) {
47
- const _scopes = options.disableDefaultScope ? [] : ["profile", "email"];
48
- if (options.scope) _scopes.push(...options.scope);
49
- if (scopes) _scopes.push(...scopes);
50
- return createAuthorizationURL({
51
- id: "naver",
52
- options,
53
- authorizationEndpoint: "https://nid.naver.com/oauth2.0/authorize",
54
- scopes: _scopes,
55
- state,
56
- redirectURI,
57
- });
58
- },
59
- validateAuthorizationCode: async ({ code, redirectURI }) => {
60
- return validateAuthorizationCode({
61
- code,
62
- redirectURI,
63
- options,
64
- tokenEndpoint: "https://nid.naver.com/oauth2.0/token",
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://nid.naver.com/oauth2.0/token",
78
- });
79
- },
80
- async getUserInfo(token) {
81
- if (options.getUserInfo) {
82
- return options.getUserInfo(token);
83
- }
84
- const { data: profile, error } = await betterFetch<NaverProfile>(
85
- "https://openapi.naver.com/v1/nid/me",
86
- {
87
- headers: {
88
- Authorization: `Bearer ${token.accessToken}`,
89
- },
90
- },
91
- );
92
- if (error || !profile || profile.resultcode !== "00") {
93
- return null;
94
- }
95
- const userMap = await options.mapProfileToUser?.(profile);
96
- const res = profile.response || {};
97
- const user = {
98
- id: res.id,
99
- name: res.name || res.nickname,
100
- email: res.email,
101
- image: res.profile_image,
102
- emailVerified: false,
103
- ...userMap,
104
- };
105
- return {
106
- user,
107
- data: profile,
108
- };
109
- },
110
- options,
111
- } satisfies OAuthProvider<NaverProfile>;
112
- };
@@ -1,108 +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 NotionProfile {
10
- object: "user";
11
- id: string;
12
- type: "person" | "bot";
13
- name?: string | undefined;
14
- avatar_url?: string | undefined;
15
- person?:
16
- | {
17
- email?: string;
18
- }
19
- | undefined;
20
- }
21
-
22
- export interface NotionOptions extends ProviderOptions<NotionProfile> {
23
- clientId: string;
24
- }
25
-
26
- export const notion = (options: NotionOptions) => {
27
- const tokenEndpoint = "https://api.notion.com/v1/oauth/token";
28
- return {
29
- id: "notion",
30
- name: "Notion",
31
- createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
32
- const _scopes: string[] = options.disableDefaultScope ? [] : [];
33
- if (options.scope) _scopes.push(...options.scope);
34
- if (scopes) _scopes.push(...scopes);
35
- return createAuthorizationURL({
36
- id: "notion",
37
- options,
38
- authorizationEndpoint: "https://api.notion.com/v1/oauth/authorize",
39
- scopes: _scopes,
40
- state,
41
- redirectURI,
42
- loginHint,
43
- additionalParams: {
44
- owner: "user",
45
- },
46
- });
47
- },
48
- validateAuthorizationCode: async ({ code, redirectURI }) => {
49
- return validateAuthorizationCode({
50
- code,
51
- redirectURI,
52
- options,
53
- tokenEndpoint,
54
- authentication: "basic",
55
- });
56
- },
57
- refreshAccessToken: options.refreshAccessToken
58
- ? options.refreshAccessToken
59
- : async (refreshToken) => {
60
- return refreshAccessToken({
61
- refreshToken,
62
- options: {
63
- clientId: options.clientId,
64
- clientKey: options.clientKey,
65
- clientSecret: options.clientSecret,
66
- },
67
- tokenEndpoint,
68
- });
69
- },
70
- async getUserInfo(token) {
71
- if (options.getUserInfo) {
72
- return options.getUserInfo(token);
73
- }
74
- const { data: profile, error } = await betterFetch<{
75
- bot: {
76
- owner: {
77
- user: NotionProfile;
78
- };
79
- };
80
- }>("https://api.notion.com/v1/users/me", {
81
- headers: {
82
- Authorization: `Bearer ${token.accessToken}`,
83
- "Notion-Version": "2022-06-28",
84
- },
85
- });
86
- if (error || !profile) {
87
- return null;
88
- }
89
- const userProfile = profile.bot?.owner?.user;
90
- if (!userProfile) {
91
- return null;
92
- }
93
- const userMap = await options.mapProfileToUser?.(userProfile);
94
- return {
95
- user: {
96
- id: userProfile.id,
97
- name: userProfile.name || "Notion User",
98
- email: userProfile.person?.email || null,
99
- image: userProfile.avatar_url,
100
- emailVerified: !!userProfile.person?.email,
101
- ...userMap,
102
- },
103
- data: userProfile,
104
- };
105
- },
106
- options,
107
- } satisfies OAuthProvider<NotionProfile>;
108
- };
@@ -1,122 +0,0 @@
1
- import { decodeJwt } from "jose";
2
- import { logger } from "../env";
3
- import { PayvoAuthError } from "../error";
4
- import type { OAuthProvider, ProviderOptions } from "../oauth2";
5
- import {
6
- createAuthorizationURL,
7
- refreshAccessToken,
8
- validateAuthorizationCode,
9
- } from "../oauth2";
10
-
11
- export interface PaybinProfile {
12
- sub: string;
13
- email: string;
14
- email_verified?: boolean | undefined;
15
- name?: string | undefined;
16
- preferred_username?: string | undefined;
17
- picture?: string | undefined;
18
- given_name?: string | undefined;
19
- family_name?: string | undefined;
20
- }
21
-
22
- export interface PaybinOptions extends ProviderOptions<PaybinProfile> {
23
- clientId: string;
24
- /**
25
- * The issuer URL of your Paybin OAuth server
26
- * @default "https://idp.paybin.io"
27
- */
28
- issuer?: string | undefined;
29
- }
30
-
31
- export const paybin = (options: PaybinOptions) => {
32
- const issuer = options.issuer || "https://idp.paybin.io";
33
- const authorizationEndpoint = `${issuer}/oauth2/authorize`;
34
- const tokenEndpoint = `${issuer}/oauth2/token`;
35
-
36
- return {
37
- id: "paybin",
38
- name: "Paybin",
39
- async createAuthorizationURL({
40
- state,
41
- scopes,
42
- codeVerifier,
43
- redirectURI,
44
- loginHint,
45
- }) {
46
- if (!options.clientId || !options.clientSecret) {
47
- logger.error(
48
- "Client Id and Client Secret is required for Paybin. Make sure to provide them in the options."
49
- );
50
- throw new PayvoAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
51
- }
52
- if (!codeVerifier) {
53
- throw new PayvoAuthError("codeVerifier is required for Paybin");
54
- }
55
- const _scopes = options.disableDefaultScope
56
- ? []
57
- : ["openid", "email", "profile"];
58
- if (options.scope) _scopes.push(...options.scope);
59
- if (scopes) _scopes.push(...scopes);
60
- const url = await createAuthorizationURL({
61
- id: "paybin",
62
- options,
63
- authorizationEndpoint,
64
- scopes: _scopes,
65
- state,
66
- codeVerifier,
67
- redirectURI,
68
- prompt: options.prompt,
69
- loginHint,
70
- });
71
- return url;
72
- },
73
- validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
74
- return validateAuthorizationCode({
75
- code,
76
- codeVerifier,
77
- redirectURI,
78
- options,
79
- tokenEndpoint,
80
- });
81
- },
82
- refreshAccessToken: options.refreshAccessToken
83
- ? options.refreshAccessToken
84
- : async (refreshToken) => {
85
- return refreshAccessToken({
86
- refreshToken,
87
- options: {
88
- clientId: options.clientId,
89
- clientKey: options.clientKey,
90
- clientSecret: options.clientSecret,
91
- },
92
- tokenEndpoint,
93
- });
94
- },
95
- async getUserInfo(token) {
96
- if (options.getUserInfo) {
97
- return options.getUserInfo(token);
98
- }
99
- if (!token.idToken) {
100
- return null;
101
- }
102
- const user = decodeJwt(token.idToken) as PaybinProfile;
103
- const userMap = await options.mapProfileToUser?.(user);
104
- return {
105
- user: {
106
- id: user.sub,
107
- name:
108
- user.name ||
109
- user.preferred_username ||
110
- (user.email ? user.email.split("@")[0] : "User") ||
111
- "User",
112
- email: user.email,
113
- image: user.picture,
114
- emailVerified: user.email_verified || false,
115
- ...userMap,
116
- },
117
- data: user,
118
- };
119
- },
120
- options,
121
- } satisfies OAuthProvider<PaybinProfile>;
122
- };
@@ -1,263 +0,0 @@
1
- import { base64 } from "@gatwech/utils/base64";
2
- import { betterFetch } from "@better-fetch/fetch";
3
- import { decodeJwt } from "jose";
4
- import { logger } from "../env";
5
- import { PayvoAuthError } from "../error";
6
- import type { OAuthProvider, ProviderOptions } from "../oauth2";
7
- import { createAuthorizationURL } from "../oauth2";
8
-
9
- export interface PayPalProfile {
10
- user_id: string;
11
- name: string;
12
- given_name: string;
13
- family_name: string;
14
- middle_name?: string | undefined;
15
- picture?: string | undefined;
16
- email: string;
17
- email_verified: boolean;
18
- gender?: string | undefined;
19
- birthdate?: string | undefined;
20
- zoneinfo?: string | undefined;
21
- locale?: string | undefined;
22
- phone_number?: string | undefined;
23
- address?:
24
- | {
25
- street_address?: string;
26
- locality?: string;
27
- region?: string;
28
- postal_code?: string;
29
- country?: string;
30
- }
31
- | undefined;
32
- verified_account?: boolean | undefined;
33
- account_type?: string | undefined;
34
- age_range?: string | undefined;
35
- payer_id?: string | undefined;
36
- }
37
-
38
- export interface PayPalTokenResponse {
39
- scope?: string | undefined;
40
- access_token: string;
41
- refresh_token?: string | undefined;
42
- token_type: "Bearer";
43
- id_token?: string | undefined;
44
- expires_in: number;
45
- nonce?: string | undefined;
46
- }
47
-
48
- export interface PayPalOptions extends ProviderOptions<PayPalProfile> {
49
- clientId: string;
50
- /**
51
- * PayPal environment - 'sandbox' for testing, 'live' for production
52
- * @default 'sandbox'
53
- */
54
- environment?: ("sandbox" | "live") | undefined;
55
- /**
56
- * Whether to request shipping address information
57
- * @default false
58
- */
59
- requestShippingAddress?: boolean | undefined;
60
- }
61
-
62
- export const paypal = (options: PayPalOptions) => {
63
- const environment = options.environment || "sandbox";
64
- const isSandbox = environment === "sandbox";
65
-
66
- const authorizationEndpoint = isSandbox
67
- ? "https://www.sandbox.paypal.com/signin/authorize"
68
- : "https://www.paypal.com/signin/authorize";
69
-
70
- const tokenEndpoint = isSandbox
71
- ? "https://api-m.sandbox.paypal.com/v1/oauth2/token"
72
- : "https://api-m.paypal.com/v1/oauth2/token";
73
-
74
- const userInfoEndpoint = isSandbox
75
- ? "https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo"
76
- : "https://api-m.paypal.com/v1/identity/oauth2/userinfo";
77
-
78
- return {
79
- id: "paypal",
80
- name: "PayPal",
81
- async createAuthorizationURL({ state, codeVerifier, redirectURI }) {
82
- if (!options.clientId || !options.clientSecret) {
83
- logger.error(
84
- "Client Id and Client Secret is required for PayPal. Make sure to provide them in the options."
85
- );
86
- throw new PayvoAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
87
- }
88
-
89
- /**
90
- * Log in with PayPal doesn't use traditional OAuth2 scopes
91
- * Instead, permissions are configured in the PayPal Developer Dashboard
92
- * We don't pass any scopes to avoid "invalid scope" errors
93
- **/
94
-
95
- const _scopes: string[] = [];
96
-
97
- const url = await createAuthorizationURL({
98
- id: "paypal",
99
- options,
100
- authorizationEndpoint,
101
- scopes: _scopes,
102
- state,
103
- codeVerifier,
104
- redirectURI,
105
- prompt: options.prompt,
106
- });
107
- return url;
108
- },
109
-
110
- validateAuthorizationCode: async ({ code, redirectURI }) => {
111
- /**
112
- * PayPal requires Basic Auth for token exchange
113
- **/
114
-
115
- const credentials = base64.encode(
116
- `${options.clientId}:${options.clientSecret}`
117
- );
118
-
119
- try {
120
- const response = await betterFetch(tokenEndpoint, {
121
- method: "POST",
122
- headers: {
123
- Authorization: `Basic ${credentials}`,
124
- Accept: "application/json",
125
- "Accept-Language": "en_US",
126
- "Content-Type": "application/x-www-form-urlencoded",
127
- },
128
- body: new URLSearchParams({
129
- grant_type: "authorization_code",
130
- code: code,
131
- redirect_uri: redirectURI,
132
- }).toString(),
133
- });
134
-
135
- if (!response.data) {
136
- throw new PayvoAuthError("FAILED_TO_GET_ACCESS_TOKEN");
137
- }
138
-
139
- const data = response.data as PayPalTokenResponse;
140
-
141
- const result = {
142
- accessToken: data.access_token,
143
- refreshToken: data.refresh_token,
144
- accessTokenExpiresAt: data.expires_in
145
- ? new Date(Date.now() + data.expires_in * 1000)
146
- : undefined,
147
- idToken: data.id_token,
148
- };
149
-
150
- return result;
151
- } catch (error) {
152
- logger.error("PayPal token exchange failed:", error);
153
- throw new PayvoAuthError("FAILED_TO_GET_ACCESS_TOKEN");
154
- }
155
- },
156
-
157
- refreshAccessToken: options.refreshAccessToken
158
- ? options.refreshAccessToken
159
- : async (refreshToken) => {
160
- const credentials = base64.encode(
161
- `${options.clientId}:${options.clientSecret}`
162
- );
163
-
164
- try {
165
- const response = await betterFetch(tokenEndpoint, {
166
- method: "POST",
167
- headers: {
168
- Authorization: `Basic ${credentials}`,
169
- Accept: "application/json",
170
- "Accept-Language": "en_US",
171
- "Content-Type": "application/x-www-form-urlencoded",
172
- },
173
- body: new URLSearchParams({
174
- grant_type: "refresh_token",
175
- refresh_token: refreshToken,
176
- }).toString(),
177
- });
178
-
179
- if (!response.data) {
180
- throw new PayvoAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
181
- }
182
-
183
- const data = response.data as any;
184
- return {
185
- accessToken: data.access_token,
186
- refreshToken: data.refresh_token,
187
- accessTokenExpiresAt: data.expires_in
188
- ? new Date(Date.now() + data.expires_in * 1000)
189
- : undefined,
190
- };
191
- } catch (error) {
192
- logger.error("PayPal token refresh failed:", error);
193
- throw new PayvoAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
194
- }
195
- },
196
-
197
- async verifyIdToken(token, nonce) {
198
- if (options.disableIdTokenSignIn) {
199
- return false;
200
- }
201
- if (options.verifyIdToken) {
202
- return options.verifyIdToken(token, nonce);
203
- }
204
- try {
205
- const payload = decodeJwt(token);
206
- return !!payload.sub;
207
- } catch (error) {
208
- logger.error("Failed to verify PayPal ID token:", error);
209
- return false;
210
- }
211
- },
212
-
213
- async getUserInfo(token) {
214
- if (options.getUserInfo) {
215
- return options.getUserInfo(token);
216
- }
217
-
218
- if (!token.accessToken) {
219
- logger.error("Access token is required to fetch PayPal user info");
220
- return null;
221
- }
222
-
223
- try {
224
- const response = await betterFetch<PayPalProfile>(
225
- `${userInfoEndpoint}?schema=paypalv1.1`,
226
- {
227
- headers: {
228
- Authorization: `Bearer ${token.accessToken}`,
229
- Accept: "application/json",
230
- },
231
- }
232
- );
233
-
234
- if (!response.data) {
235
- logger.error("Failed to fetch user info from PayPal");
236
- return null;
237
- }
238
-
239
- const userInfo = response.data;
240
- const userMap = await options.mapProfileToUser?.(userInfo);
241
-
242
- const result = {
243
- user: {
244
- id: userInfo.user_id,
245
- name: userInfo.name,
246
- email: userInfo.email,
247
- image: userInfo.picture,
248
- emailVerified: userInfo.email_verified,
249
- ...userMap,
250
- },
251
- data: userInfo,
252
- };
253
-
254
- return result;
255
- } catch (error) {
256
- logger.error("Failed to fetch user info from PayPal:", error);
257
- return null;
258
- }
259
- },
260
-
261
- options,
262
- } satisfies OAuthProvider<PayPalProfile>;
263
- };
@@ -1,107 +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 PolarProfile {
10
- id: string;
11
- email: string;
12
- username: string;
13
- avatar_url: string;
14
- github_username?: string | undefined;
15
- account_id?: string | undefined;
16
- public_name?: string | undefined;
17
- profile_settings?:
18
- | {
19
- profile_settings_enabled?: boolean;
20
- profile_settings_public_name?: string;
21
- profile_settings_public_avatar?: string;
22
- profile_settings_public_bio?: string;
23
- profile_settings_public_location?: string;
24
- profile_settings_public_website?: string;
25
- profile_settings_public_twitter?: string;
26
- profile_settings_public_github?: string;
27
- profile_settings_public_email?: string;
28
- }
29
- | undefined;
30
- }
31
-
32
- export interface PolarOptions extends ProviderOptions<PolarProfile> {}
33
-
34
- export const polar = (options: PolarOptions) => {
35
- return {
36
- id: "polar",
37
- name: "Polar",
38
- createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
39
- const _scopes = options.disableDefaultScope
40
- ? []
41
- : ["openid", "profile", "email"];
42
- if (options.scope) _scopes.push(...options.scope);
43
- if (scopes) _scopes.push(...scopes);
44
- return createAuthorizationURL({
45
- id: "polar",
46
- options,
47
- authorizationEndpoint: "https://polar.sh/oauth2/authorize",
48
- scopes: _scopes,
49
- state,
50
- codeVerifier,
51
- redirectURI,
52
- prompt: options.prompt,
53
- });
54
- },
55
- validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
56
- return validateAuthorizationCode({
57
- code,
58
- codeVerifier,
59
- redirectURI,
60
- options,
61
- tokenEndpoint: "https://api.polar.sh/v1/oauth2/token",
62
- });
63
- },
64
- refreshAccessToken: options.refreshAccessToken
65
- ? options.refreshAccessToken
66
- : async (refreshToken) => {
67
- return refreshAccessToken({
68
- refreshToken,
69
- options: {
70
- clientId: options.clientId,
71
- clientKey: options.clientKey,
72
- clientSecret: options.clientSecret,
73
- },
74
- tokenEndpoint: "https://api.polar.sh/v1/oauth2/token",
75
- });
76
- },
77
- async getUserInfo(token) {
78
- if (options.getUserInfo) {
79
- return options.getUserInfo(token);
80
- }
81
- const { data: profile, error } = await betterFetch<PolarProfile>(
82
- "https://api.polar.sh/v1/oauth2/userinfo",
83
- {
84
- headers: {
85
- Authorization: `Bearer ${token.accessToken}`,
86
- },
87
- },
88
- );
89
- if (error) {
90
- return null;
91
- }
92
- const userMap = await options.mapProfileToUser?.(profile);
93
- return {
94
- user: {
95
- id: profile.id,
96
- name: profile.public_name || profile.username,
97
- email: profile.email,
98
- image: profile.avatar_url,
99
- emailVerified: true,
100
- ...userMap,
101
- },
102
- data: profile,
103
- };
104
- },
105
- options,
106
- } satisfies OAuthProvider<PolarProfile>;
107
- };