@better-auth/core 1.5.5 → 1.5.7-beta.1
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.
- package/dist/api/index.d.mts +41 -14
- package/dist/api/index.mjs +1 -2
- package/dist/api/index.mjs.map +1 -1
- package/dist/async_hooks/index.mjs +1 -1
- package/dist/async_hooks/pure.index.mjs +1 -1
- package/dist/async_hooks/pure.index.mjs.map +1 -1
- package/dist/context/endpoint-context.d.mts +1 -2
- package/dist/context/endpoint-context.mjs +1 -2
- package/dist/context/endpoint-context.mjs.map +1 -1
- package/dist/context/global.mjs +2 -2
- package/dist/context/global.mjs.map +1 -1
- package/dist/context/index.mjs +1 -2
- package/dist/context/request-state.mjs +1 -2
- package/dist/context/request-state.mjs.map +1 -1
- package/dist/context/transaction.mjs +1 -2
- package/dist/context/transaction.mjs.map +1 -1
- package/dist/db/adapter/factory.d.mts +0 -2
- package/dist/db/adapter/factory.mjs +54 -22
- package/dist/db/adapter/factory.mjs.map +1 -1
- package/dist/db/adapter/get-default-field-name.mjs +1 -2
- package/dist/db/adapter/get-default-field-name.mjs.map +1 -1
- package/dist/db/adapter/get-default-model-name.mjs +1 -2
- package/dist/db/adapter/get-default-model-name.mjs.map +1 -1
- package/dist/db/adapter/get-field-attributes.d.mts +0 -3
- package/dist/db/adapter/get-field-attributes.mjs +1 -2
- package/dist/db/adapter/get-field-attributes.mjs.map +1 -1
- package/dist/db/adapter/get-field-name.mjs +1 -2
- package/dist/db/adapter/get-field-name.mjs.map +1 -1
- package/dist/db/adapter/get-id-field.d.mts +0 -3
- package/dist/db/adapter/get-id-field.mjs +3 -4
- package/dist/db/adapter/get-id-field.mjs.map +1 -1
- package/dist/db/adapter/get-model-name.mjs +1 -2
- package/dist/db/adapter/get-model-name.mjs.map +1 -1
- package/dist/db/adapter/index.d.mts +0 -2
- package/dist/db/adapter/index.mjs +1 -2
- package/dist/db/adapter/index.mjs.map +1 -1
- package/dist/db/adapter/types.d.mts +0 -2
- package/dist/db/adapter/utils.mjs +1 -1
- package/dist/db/adapter/utils.mjs.map +1 -1
- package/dist/db/get-tables.d.mts +0 -2
- package/dist/db/get-tables.mjs +1 -1
- package/dist/db/index.mjs +1 -2
- package/dist/db/schema/account.d.mts +0 -1
- package/dist/db/schema/account.mjs +1 -2
- package/dist/db/schema/account.mjs.map +1 -1
- package/dist/db/schema/rate-limit.d.mts +0 -1
- package/dist/db/schema/rate-limit.mjs +1 -2
- package/dist/db/schema/rate-limit.mjs.map +1 -1
- package/dist/db/schema/session.d.mts +0 -1
- package/dist/db/schema/session.mjs +1 -2
- package/dist/db/schema/session.mjs.map +1 -1
- package/dist/db/schema/shared.mjs +1 -2
- package/dist/db/schema/shared.mjs.map +1 -1
- package/dist/db/schema/user.d.mts +0 -1
- package/dist/db/schema/user.mjs +1 -2
- package/dist/db/schema/user.mjs.map +1 -1
- package/dist/db/schema/verification.d.mts +0 -1
- package/dist/db/schema/verification.mjs +1 -2
- package/dist/db/schema/verification.mjs.map +1 -1
- package/dist/db/type.d.mts +0 -1
- package/dist/env/color-depth.mjs +1 -2
- package/dist/env/color-depth.mjs.map +1 -1
- package/dist/env/env-impl.mjs +1 -1
- package/dist/env/env-impl.mjs.map +1 -1
- package/dist/env/index.mjs +1 -2
- package/dist/env/logger.mjs +1 -2
- package/dist/env/logger.mjs.map +1 -1
- package/dist/error/codes.mjs +1 -2
- package/dist/error/codes.mjs.map +1 -1
- package/dist/error/index.mjs +1 -2
- package/dist/error/index.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/instrumentation/attributes.d.mts +12 -0
- package/dist/instrumentation/attributes.mjs +12 -0
- package/dist/instrumentation/attributes.mjs.map +1 -0
- package/dist/instrumentation/index.d.mts +3 -0
- package/dist/instrumentation/index.mjs +3 -0
- package/dist/instrumentation/tracer.d.mts +14 -0
- package/dist/instrumentation/tracer.mjs +36 -0
- package/dist/instrumentation/tracer.mjs.map +1 -0
- package/dist/oauth2/client-credentials-token.d.mts +0 -1
- package/dist/oauth2/client-credentials-token.mjs +1 -2
- package/dist/oauth2/client-credentials-token.mjs.map +1 -1
- package/dist/oauth2/create-authorization-url.d.mts +0 -3
- package/dist/oauth2/create-authorization-url.mjs +1 -2
- package/dist/oauth2/create-authorization-url.mjs.map +1 -1
- package/dist/oauth2/index.mjs +1 -2
- package/dist/oauth2/oauth-provider.d.mts +0 -2
- package/dist/oauth2/refresh-access-token.d.mts +0 -1
- package/dist/oauth2/refresh-access-token.mjs +1 -2
- package/dist/oauth2/refresh-access-token.mjs.map +1 -1
- package/dist/oauth2/utils.mjs +1 -2
- package/dist/oauth2/utils.mjs.map +1 -1
- package/dist/oauth2/validate-authorization-code.d.mts +0 -2
- package/dist/oauth2/validate-authorization-code.mjs +1 -2
- package/dist/oauth2/validate-authorization-code.mjs.map +1 -1
- package/dist/oauth2/verify.mjs +1 -2
- package/dist/oauth2/verify.mjs.map +1 -1
- package/dist/social-providers/apple.d.mts +0 -2
- package/dist/social-providers/apple.mjs +2 -3
- package/dist/social-providers/apple.mjs.map +1 -1
- package/dist/social-providers/atlassian.d.mts +0 -2
- package/dist/social-providers/atlassian.mjs +4 -4
- package/dist/social-providers/atlassian.mjs.map +1 -1
- package/dist/social-providers/cognito.d.mts +0 -2
- package/dist/social-providers/cognito.mjs +1 -2
- package/dist/social-providers/cognito.mjs.map +1 -1
- package/dist/social-providers/discord.d.mts +0 -2
- package/dist/social-providers/discord.mjs +4 -4
- package/dist/social-providers/discord.mjs.map +1 -1
- package/dist/social-providers/dropbox.d.mts +0 -2
- package/dist/social-providers/dropbox.mjs +1 -2
- package/dist/social-providers/dropbox.mjs.map +1 -1
- package/dist/social-providers/facebook.d.mts +0 -2
- package/dist/social-providers/facebook.mjs +1 -2
- package/dist/social-providers/facebook.mjs.map +1 -1
- package/dist/social-providers/figma.d.mts +0 -2
- package/dist/social-providers/figma.mjs +4 -4
- package/dist/social-providers/figma.mjs.map +1 -1
- package/dist/social-providers/github.d.mts +0 -2
- package/dist/social-providers/github.mjs +2 -3
- package/dist/social-providers/github.mjs.map +1 -1
- package/dist/social-providers/gitlab.d.mts +0 -2
- package/dist/social-providers/gitlab.mjs +1 -2
- package/dist/social-providers/gitlab.mjs.map +1 -1
- package/dist/social-providers/google.d.mts +0 -2
- package/dist/social-providers/google.mjs +1 -2
- package/dist/social-providers/google.mjs.map +1 -1
- package/dist/social-providers/huggingface.d.mts +0 -2
- package/dist/social-providers/huggingface.mjs +4 -4
- package/dist/social-providers/huggingface.mjs.map +1 -1
- package/dist/social-providers/index.d.mts +61 -3
- package/dist/social-providers/index.mjs +5 -4
- package/dist/social-providers/index.mjs.map +1 -1
- package/dist/social-providers/kakao.d.mts +0 -2
- package/dist/social-providers/kakao.mjs +4 -4
- package/dist/social-providers/kakao.mjs.map +1 -1
- package/dist/social-providers/kick.d.mts +0 -2
- package/dist/social-providers/kick.mjs +1 -2
- package/dist/social-providers/kick.mjs.map +1 -1
- package/dist/social-providers/line.d.mts +0 -2
- package/dist/social-providers/line.mjs +1 -2
- package/dist/social-providers/line.mjs.map +1 -1
- package/dist/social-providers/linear.d.mts +0 -2
- package/dist/social-providers/linear.mjs +1 -2
- package/dist/social-providers/linear.mjs.map +1 -1
- package/dist/social-providers/linkedin.d.mts +0 -2
- package/dist/social-providers/linkedin.mjs +1 -2
- package/dist/social-providers/linkedin.mjs.map +1 -1
- package/dist/social-providers/microsoft-entra-id.d.mts +0 -2
- package/dist/social-providers/microsoft-entra-id.mjs +1 -2
- package/dist/social-providers/microsoft-entra-id.mjs.map +1 -1
- package/dist/social-providers/naver.d.mts +0 -2
- package/dist/social-providers/naver.mjs +4 -4
- package/dist/social-providers/naver.mjs.map +1 -1
- package/dist/social-providers/notion.d.mts +0 -2
- package/dist/social-providers/notion.mjs +1 -2
- package/dist/social-providers/notion.mjs.map +1 -1
- package/dist/social-providers/paybin.d.mts +0 -2
- package/dist/social-providers/paybin.mjs +1 -2
- package/dist/social-providers/paybin.mjs.map +1 -1
- package/dist/social-providers/paypal.d.mts +0 -2
- package/dist/social-providers/paypal.mjs +1 -2
- package/dist/social-providers/paypal.mjs.map +1 -1
- package/dist/social-providers/polar.d.mts +0 -2
- package/dist/social-providers/polar.mjs +4 -4
- package/dist/social-providers/polar.mjs.map +1 -1
- package/dist/social-providers/railway.d.mts +0 -2
- package/dist/social-providers/railway.mjs +1 -2
- package/dist/social-providers/railway.mjs.map +1 -1
- package/dist/social-providers/reddit.d.mts +0 -2
- package/dist/social-providers/reddit.mjs +1 -2
- package/dist/social-providers/reddit.mjs.map +1 -1
- package/dist/social-providers/roblox.d.mts +0 -2
- package/dist/social-providers/roblox.mjs +4 -4
- package/dist/social-providers/roblox.mjs.map +1 -1
- package/dist/social-providers/salesforce.d.mts +0 -2
- package/dist/social-providers/salesforce.mjs +1 -2
- package/dist/social-providers/salesforce.mjs.map +1 -1
- package/dist/social-providers/slack.d.mts +0 -2
- package/dist/social-providers/slack.mjs +4 -4
- package/dist/social-providers/slack.mjs.map +1 -1
- package/dist/social-providers/spotify.d.mts +0 -2
- package/dist/social-providers/spotify.mjs +4 -4
- package/dist/social-providers/spotify.mjs.map +1 -1
- package/dist/social-providers/tiktok.d.mts +0 -2
- package/dist/social-providers/tiktok.mjs +4 -4
- package/dist/social-providers/tiktok.mjs.map +1 -1
- package/dist/social-providers/twitch.d.mts +0 -2
- package/dist/social-providers/twitch.mjs +4 -4
- package/dist/social-providers/twitch.mjs.map +1 -1
- package/dist/social-providers/twitter.d.mts +0 -2
- package/dist/social-providers/twitter.mjs +4 -4
- package/dist/social-providers/twitter.mjs.map +1 -1
- package/dist/social-providers/vercel.d.mts +0 -2
- package/dist/social-providers/vercel.mjs +1 -2
- package/dist/social-providers/vercel.mjs.map +1 -1
- package/dist/social-providers/vk.d.mts +0 -2
- package/dist/social-providers/vk.mjs +4 -4
- package/dist/social-providers/vk.mjs.map +1 -1
- package/dist/social-providers/wechat.d.mts +114 -0
- package/dist/social-providers/wechat.mjs +83 -0
- package/dist/social-providers/wechat.mjs.map +1 -0
- package/dist/social-providers/zoom.d.mts +0 -2
- package/dist/social-providers/zoom.mjs +1 -2
- package/dist/social-providers/zoom.mjs.map +1 -1
- package/dist/types/context.d.mts +1 -5
- package/dist/types/init-options.d.mts +0 -1
- package/dist/types/plugin.d.mts +4 -2
- package/dist/utils/db.d.mts +0 -2
- package/dist/utils/db.mjs +1 -1
- package/dist/utils/deprecate.mjs +1 -1
- package/dist/utils/error-codes.mjs +1 -1
- package/dist/utils/fetch-metadata.mjs +1 -1
- package/dist/utils/id.mjs +1 -2
- package/dist/utils/id.mjs.map +1 -1
- package/dist/utils/ip.mjs +1 -2
- package/dist/utils/ip.mjs.map +1 -1
- package/dist/utils/json.mjs +1 -2
- package/dist/utils/json.mjs.map +1 -1
- package/dist/utils/string.mjs +1 -1
- package/dist/utils/url.mjs +1 -1
- package/package.json +18 -5
- package/src/api/index.ts +151 -41
- package/src/context/endpoint-context.ts +2 -1
- package/src/db/adapter/factory.ts +119 -47
- package/src/db/adapter/get-id-field.test.ts +222 -0
- package/src/db/adapter/get-id-field.ts +15 -4
- package/src/instrumentation/attributes.ts +22 -0
- package/src/instrumentation/index.ts +2 -0
- package/src/instrumentation/instrumentation.test.ts +139 -0
- package/src/instrumentation/tracer.ts +62 -0
- package/src/social-providers/apple.ts +1 -1
- package/src/social-providers/atlassian.ts +3 -2
- package/src/social-providers/discord.ts +3 -2
- package/src/social-providers/figma.ts +3 -2
- package/src/social-providers/github.ts +1 -1
- package/src/social-providers/huggingface.ts +3 -2
- package/src/social-providers/index.ts +3 -0
- package/src/social-providers/kakao.ts +3 -2
- package/src/social-providers/naver.ts +3 -2
- package/src/social-providers/polar.ts +3 -2
- package/src/social-providers/roblox.ts +3 -2
- package/src/social-providers/slack.ts +3 -2
- package/src/social-providers/spotify.ts +3 -2
- package/src/social-providers/tiktok.ts +3 -2
- package/src/social-providers/twitch.ts +3 -2
- package/src/social-providers/twitter.ts +3 -2
- package/src/social-providers/vk.ts +3 -2
- package/src/social-providers/wechat.ts +213 -0
- package/src/types/context.ts +1 -3
- package/src/types/plugin.ts +14 -1
|
@@ -3,7 +3,6 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
3
3
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
4
|
import "../oauth2/index.mjs";
|
|
5
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
6
|
-
|
|
7
6
|
//#region src/social-providers/notion.ts
|
|
8
7
|
const notion = (options) => {
|
|
9
8
|
const tokenEndpoint = "https://api.notion.com/v1/oauth/token";
|
|
@@ -70,7 +69,7 @@ const notion = (options) => {
|
|
|
70
69
|
options
|
|
71
70
|
};
|
|
72
71
|
};
|
|
73
|
-
|
|
74
72
|
//#endregion
|
|
75
73
|
export { notion };
|
|
74
|
+
|
|
76
75
|
//# sourceMappingURL=notion.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notion.mjs","names":[],"sources":["../../src/social-providers/notion.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface NotionProfile {\n\tobject: \"user\";\n\tid: string;\n\ttype: \"person\" | \"bot\";\n\tname?: string | undefined;\n\tavatar_url?: string | undefined;\n\tperson?:\n\t\t| {\n\t\t\t\temail?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface NotionOptions extends ProviderOptions<NotionProfile> {\n\tclientId: string;\n}\n\nexport const notion = (options: NotionOptions) => {\n\tconst tokenEndpoint = \"https://api.notion.com/v1/oauth/token\";\n\treturn {\n\t\tid: \"notion\",\n\t\tname: \"Notion\",\n\t\tcreateAuthorizationURL({ state, scopes, loginHint, redirectURI }) {\n\t\t\tconst _scopes: string[] = options.disableDefaultScope ? [] : [];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"notion\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://api.notion.com/v1/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tloginHint,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\towner: \"user\",\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t\tauthentication: \"basic\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<{\n\t\t\t\tbot: {\n\t\t\t\t\towner: {\n\t\t\t\t\t\tuser: NotionProfile;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}>(\"https://api.notion.com/v1/users/me\", {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\"Notion-Version\": \"2022-06-28\",\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (error || !profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userProfile = profile.bot?.owner?.user;\n\t\t\tif (!userProfile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(userProfile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: userProfile.id,\n\t\t\t\t\tname: userProfile.name || \"\",\n\t\t\t\t\temail: userProfile.person?.email || null,\n\t\t\t\t\timage: userProfile.avatar_url,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: userProfile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<NotionProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"notion.mjs","names":[],"sources":["../../src/social-providers/notion.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface NotionProfile {\n\tobject: \"user\";\n\tid: string;\n\ttype: \"person\" | \"bot\";\n\tname?: string | undefined;\n\tavatar_url?: string | undefined;\n\tperson?:\n\t\t| {\n\t\t\t\temail?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface NotionOptions extends ProviderOptions<NotionProfile> {\n\tclientId: string;\n}\n\nexport const notion = (options: NotionOptions) => {\n\tconst tokenEndpoint = \"https://api.notion.com/v1/oauth/token\";\n\treturn {\n\t\tid: \"notion\",\n\t\tname: \"Notion\",\n\t\tcreateAuthorizationURL({ state, scopes, loginHint, redirectURI }) {\n\t\t\tconst _scopes: string[] = options.disableDefaultScope ? [] : [];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"notion\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://api.notion.com/v1/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tloginHint,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\towner: \"user\",\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t\tauthentication: \"basic\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<{\n\t\t\t\tbot: {\n\t\t\t\t\towner: {\n\t\t\t\t\t\tuser: NotionProfile;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}>(\"https://api.notion.com/v1/users/me\", {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\"Notion-Version\": \"2022-06-28\",\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (error || !profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userProfile = profile.bot?.owner?.user;\n\t\t\tif (!userProfile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(userProfile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: userProfile.id,\n\t\t\t\t\tname: userProfile.name || \"\",\n\t\t\t\t\temail: userProfile.person?.email || null,\n\t\t\t\t\timage: userProfile.avatar_url,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: userProfile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<NotionProfile>;\n};\n"],"mappings":";;;;;;AAyBA,MAAa,UAAU,YAA2B;CACjD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,WAAW,eAAe;GACjE,MAAM,UAAoB,QAAQ,sBAAsB,EAAE,GAAG,EAAE;AAC/D,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,kBAAkB,EACjB,OAAO,QACP;IACD,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,gBAAgB;IAChB,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YAMpC,sCAAsC,EACxC,SAAS;IACR,eAAe,UAAU,MAAM;IAC/B,kBAAkB;IAClB,EACD,CAAC;AACF,OAAI,SAAS,CAAC,QACb,QAAO;GAER,MAAM,cAAc,QAAQ,KAAK,OAAO;AACxC,OAAI,CAAC,YACJ,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,YAAY;AAC7D,UAAO;IACN,MAAM;KACL,IAAI,YAAY;KAChB,MAAM,YAAY,QAAQ;KAC1B,OAAO,YAAY,QAAQ,SAAS;KACpC,OAAO,YAAY;KACnB,eAAe;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -6,7 +6,6 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
6
6
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
7
7
|
import "../oauth2/index.mjs";
|
|
8
8
|
import { decodeJwt } from "jose";
|
|
9
|
-
|
|
10
9
|
//#region src/social-providers/paybin.ts
|
|
11
10
|
const paybin = (options) => {
|
|
12
11
|
const issuer = options.issuer || "https://idp.paybin.io";
|
|
@@ -80,7 +79,7 @@ const paybin = (options) => {
|
|
|
80
79
|
options
|
|
81
80
|
};
|
|
82
81
|
};
|
|
83
|
-
|
|
84
82
|
//#endregion
|
|
85
83
|
export { paybin };
|
|
84
|
+
|
|
86
85
|
//# sourceMappingURL=paybin.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paybin.mjs","names":[],"sources":["../../src/social-providers/paybin.ts"],"sourcesContent":["import { decodeJwt } from \"jose\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface PaybinProfile {\n\tsub: string;\n\temail: string;\n\temail_verified?: boolean | undefined;\n\tname?: string | undefined;\n\tpreferred_username?: string | undefined;\n\tpicture?: string | undefined;\n\tgiven_name?: string | undefined;\n\tfamily_name?: string | undefined;\n}\n\nexport interface PaybinOptions extends ProviderOptions<PaybinProfile> {\n\tclientId: string;\n\t/**\n\t * The issuer URL of your Paybin OAuth server\n\t * @default \"https://idp.paybin.io\"\n\t */\n\tissuer?: string | undefined;\n}\n\nexport const paybin = (options: PaybinOptions) => {\n\tconst issuer = options.issuer || \"https://idp.paybin.io\";\n\tconst authorizationEndpoint = `${issuer}/oauth2/authorize`;\n\tconst tokenEndpoint = `${issuer}/oauth2/token`;\n\n\treturn {\n\t\tid: \"paybin\",\n\t\tname: \"Paybin\",\n\t\tasync createAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t\tloginHint,\n\t\t}) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret is required for Paybin. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Paybin\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"paybin\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t\tloginHint,\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tif (!token.idToken) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst user = decodeJwt(token.idToken) as PaybinProfile;\n\t\t\tconst userMap = await options.mapProfileToUser?.(user);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: user.sub,\n\t\t\t\t\tname: user.name || user.preferred_username || \"\",\n\t\t\t\t\temail: user.email,\n\t\t\t\t\timage: user.picture,\n\t\t\t\t\temailVerified: user.email_verified || false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: user,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<PaybinProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"paybin.mjs","names":[],"sources":["../../src/social-providers/paybin.ts"],"sourcesContent":["import { decodeJwt } from \"jose\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface PaybinProfile {\n\tsub: string;\n\temail: string;\n\temail_verified?: boolean | undefined;\n\tname?: string | undefined;\n\tpreferred_username?: string | undefined;\n\tpicture?: string | undefined;\n\tgiven_name?: string | undefined;\n\tfamily_name?: string | undefined;\n}\n\nexport interface PaybinOptions extends ProviderOptions<PaybinProfile> {\n\tclientId: string;\n\t/**\n\t * The issuer URL of your Paybin OAuth server\n\t * @default \"https://idp.paybin.io\"\n\t */\n\tissuer?: string | undefined;\n}\n\nexport const paybin = (options: PaybinOptions) => {\n\tconst issuer = options.issuer || \"https://idp.paybin.io\";\n\tconst authorizationEndpoint = `${issuer}/oauth2/authorize`;\n\tconst tokenEndpoint = `${issuer}/oauth2/token`;\n\n\treturn {\n\t\tid: \"paybin\",\n\t\tname: \"Paybin\",\n\t\tasync createAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t\tloginHint,\n\t\t}) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret is required for Paybin. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Paybin\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"paybin\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t\tloginHint,\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tif (!token.idToken) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst user = decodeJwt(token.idToken) as PaybinProfile;\n\t\t\tconst userMap = await options.mapProfileToUser?.(user);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: user.sub,\n\t\t\t\t\tname: user.name || user.preferred_username || \"\",\n\t\t\t\t\temail: user.email,\n\t\t\t\t\timage: user.picture,\n\t\t\t\t\temailVerified: user.email_verified || false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: user,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<PaybinProfile>;\n};\n"],"mappings":";;;;;;;;;AA8BA,MAAa,UAAU,YAA2B;CACjD,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,wBAAwB,GAAG,OAAO;CACxC,MAAM,gBAAgB,GAAG,OAAO;AAEhC,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAC5B,OACA,QACA,cACA,aACA,aACE;AACF,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MACN,gGACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,sCAAsC;GAEjE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAS;IAAU;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAYnC,UAXY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA,QAAQ,QAAQ;IAChB;IACA,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAElC,OAAI,CAAC,MAAM,QACV,QAAO;GAER,MAAM,OAAO,UAAU,MAAM,QAAQ;GACrC,MAAM,UAAU,MAAM,QAAQ,mBAAmB,KAAK;AACtD,UAAO;IACN,MAAM;KACL,IAAI,KAAK;KACT,MAAM,KAAK,QAAQ,KAAK,sBAAsB;KAC9C,OAAO,KAAK;KACZ,OAAO,KAAK;KACZ,eAAe,KAAK,kBAAkB;KACtC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -6,7 +6,6 @@ import "../oauth2/index.mjs";
|
|
|
6
6
|
import { base64 } from "@better-auth/utils/base64";
|
|
7
7
|
import { betterFetch } from "@better-fetch/fetch";
|
|
8
8
|
import { decodeJwt } from "jose";
|
|
9
|
-
|
|
10
9
|
//#region src/social-providers/paypal.ts
|
|
11
10
|
const paypal = (options) => {
|
|
12
11
|
const isSandbox = (options.environment || "sandbox") === "sandbox";
|
|
@@ -139,7 +138,7 @@ const paypal = (options) => {
|
|
|
139
138
|
options
|
|
140
139
|
};
|
|
141
140
|
};
|
|
142
|
-
|
|
143
141
|
//#endregion
|
|
144
142
|
export { paypal };
|
|
143
|
+
|
|
145
144
|
//# sourceMappingURL=paypal.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paypal.mjs","names":[],"sources":["../../src/social-providers/paypal.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt } from \"jose\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { createAuthorizationURL } from \"../oauth2\";\n\nexport interface PayPalProfile {\n\tuser_id: string;\n\tname: string;\n\tgiven_name: string;\n\tfamily_name: string;\n\tmiddle_name?: string | undefined;\n\tpicture?: string | undefined;\n\temail: string;\n\temail_verified: boolean;\n\tgender?: string | undefined;\n\tbirthdate?: string | undefined;\n\tzoneinfo?: string | undefined;\n\tlocale?: string | undefined;\n\tphone_number?: string | undefined;\n\taddress?:\n\t\t| {\n\t\t\t\tstreet_address?: string;\n\t\t\t\tlocality?: string;\n\t\t\t\tregion?: string;\n\t\t\t\tpostal_code?: string;\n\t\t\t\tcountry?: string;\n\t\t }\n\t\t| undefined;\n\tverified_account?: boolean | undefined;\n\taccount_type?: string | undefined;\n\tage_range?: string | undefined;\n\tpayer_id?: string | undefined;\n}\n\nexport interface PayPalTokenResponse {\n\tscope?: string | undefined;\n\taccess_token: string;\n\trefresh_token?: string | undefined;\n\ttoken_type: \"Bearer\";\n\tid_token?: string | undefined;\n\texpires_in: number;\n\tnonce?: string | undefined;\n}\n\nexport interface PayPalOptions extends ProviderOptions<PayPalProfile> {\n\tclientId: string;\n\t/**\n\t * PayPal environment - 'sandbox' for testing, 'live' for production\n\t * @default 'sandbox'\n\t */\n\tenvironment?: (\"sandbox\" | \"live\") | undefined;\n\t/**\n\t * Whether to request shipping address information\n\t * @default false\n\t */\n\trequestShippingAddress?: boolean | undefined;\n}\n\nexport const paypal = (options: PayPalOptions) => {\n\tconst environment = options.environment || \"sandbox\";\n\tconst isSandbox = environment === \"sandbox\";\n\n\tconst authorizationEndpoint = isSandbox\n\t\t? \"https://www.sandbox.paypal.com/signin/authorize\"\n\t\t: \"https://www.paypal.com/signin/authorize\";\n\n\tconst tokenEndpoint = isSandbox\n\t\t? \"https://api-m.sandbox.paypal.com/v1/oauth2/token\"\n\t\t: \"https://api-m.paypal.com/v1/oauth2/token\";\n\n\tconst userInfoEndpoint = isSandbox\n\t\t? \"https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo\"\n\t\t: \"https://api-m.paypal.com/v1/identity/oauth2/userinfo\";\n\n\treturn {\n\t\tid: \"paypal\",\n\t\tname: \"PayPal\",\n\t\tasync createAuthorizationURL({ state, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret is required for PayPal. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Log in with PayPal doesn't use traditional OAuth2 scopes\n\t\t\t * Instead, permissions are configured in the PayPal Developer Dashboard\n\t\t\t * We don't pass any scopes to avoid \"invalid scope\" errors\n\t\t\t **/\n\n\t\t\tconst _scopes: string[] = [];\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"paypal\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\t/**\n\t\t\t * PayPal requires Basic Auth for token exchange\n\t\t\t **/\n\n\t\t\tconst credentials = base64.encode(\n\t\t\t\t`${options.clientId}:${options.clientSecret}`,\n\t\t\t);\n\n\t\t\ttry {\n\t\t\t\tconst response = await betterFetch(tokenEndpoint, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Basic ${credentials}`,\n\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t\"Accept-Language\": \"en_US\",\n\t\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\t\t\tcode: code,\n\t\t\t\t\t\tredirect_uri: redirectURI,\n\t\t\t\t\t}).toString(),\n\t\t\t\t});\n\n\t\t\t\tif (!response.data) {\n\t\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_GET_ACCESS_TOKEN\");\n\t\t\t\t}\n\n\t\t\t\tconst data = response.data as PayPalTokenResponse;\n\n\t\t\t\tconst result = {\n\t\t\t\t\taccessToken: data.access_token,\n\t\t\t\t\trefreshToken: data.refresh_token,\n\t\t\t\t\taccessTokenExpiresAt: data.expires_in\n\t\t\t\t\t\t? new Date(Date.now() + data.expires_in * 1000)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tidToken: data.id_token,\n\t\t\t\t};\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"PayPal token exchange failed:\", error);\n\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_GET_ACCESS_TOKEN\");\n\t\t\t}\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\tconst credentials = base64.encode(\n\t\t\t\t\t\t`${options.clientId}:${options.clientSecret}`,\n\t\t\t\t\t);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst response = await betterFetch(tokenEndpoint, {\n\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\tAuthorization: `Basic ${credentials}`,\n\t\t\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t\t\t\"Accept-Language\": \"en_US\",\n\t\t\t\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t\t\t\t}).toString(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!response.data) {\n\t\t\t\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_REFRESH_ACCESS_TOKEN\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst data = response.data as any;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\taccessToken: data.access_token,\n\t\t\t\t\t\t\trefreshToken: data.refresh_token,\n\t\t\t\t\t\t\taccessTokenExpiresAt: data.expires_in\n\t\t\t\t\t\t\t\t? new Date(Date.now() + data.expires_in * 1000)\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tlogger.error(\"PayPal token refresh failed:\", error);\n\t\t\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_REFRESH_ACCESS_TOKEN\");\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst payload = decodeJwt(token);\n\t\t\t\treturn !!payload.sub;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to verify PayPal ID token:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\tif (!token.accessToken) {\n\t\t\t\tlogger.error(\"Access token is required to fetch PayPal user info\");\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst response = await betterFetch<PayPalProfile>(\n\t\t\t\t\t`${userInfoEndpoint}?schema=paypalv1.1`,\n\t\t\t\t\t{\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!response.data) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user info from PayPal\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userInfo = response.data;\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(userInfo);\n\n\t\t\t\tconst result = {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: userInfo.user_id,\n\t\t\t\t\t\tname: userInfo.name,\n\t\t\t\t\t\temail: userInfo.email,\n\t\t\t\t\t\timage: userInfo.picture,\n\t\t\t\t\t\temailVerified: userInfo.email_verified,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: userInfo,\n\t\t\t\t};\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from PayPal:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\toptions,\n\t} satisfies OAuthProvider<PayPalProfile>;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"paypal.mjs","names":[],"sources":["../../src/social-providers/paypal.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt } from \"jose\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { createAuthorizationURL } from \"../oauth2\";\n\nexport interface PayPalProfile {\n\tuser_id: string;\n\tname: string;\n\tgiven_name: string;\n\tfamily_name: string;\n\tmiddle_name?: string | undefined;\n\tpicture?: string | undefined;\n\temail: string;\n\temail_verified: boolean;\n\tgender?: string | undefined;\n\tbirthdate?: string | undefined;\n\tzoneinfo?: string | undefined;\n\tlocale?: string | undefined;\n\tphone_number?: string | undefined;\n\taddress?:\n\t\t| {\n\t\t\t\tstreet_address?: string;\n\t\t\t\tlocality?: string;\n\t\t\t\tregion?: string;\n\t\t\t\tpostal_code?: string;\n\t\t\t\tcountry?: string;\n\t\t }\n\t\t| undefined;\n\tverified_account?: boolean | undefined;\n\taccount_type?: string | undefined;\n\tage_range?: string | undefined;\n\tpayer_id?: string | undefined;\n}\n\nexport interface PayPalTokenResponse {\n\tscope?: string | undefined;\n\taccess_token: string;\n\trefresh_token?: string | undefined;\n\ttoken_type: \"Bearer\";\n\tid_token?: string | undefined;\n\texpires_in: number;\n\tnonce?: string | undefined;\n}\n\nexport interface PayPalOptions extends ProviderOptions<PayPalProfile> {\n\tclientId: string;\n\t/**\n\t * PayPal environment - 'sandbox' for testing, 'live' for production\n\t * @default 'sandbox'\n\t */\n\tenvironment?: (\"sandbox\" | \"live\") | undefined;\n\t/**\n\t * Whether to request shipping address information\n\t * @default false\n\t */\n\trequestShippingAddress?: boolean | undefined;\n}\n\nexport const paypal = (options: PayPalOptions) => {\n\tconst environment = options.environment || \"sandbox\";\n\tconst isSandbox = environment === \"sandbox\";\n\n\tconst authorizationEndpoint = isSandbox\n\t\t? \"https://www.sandbox.paypal.com/signin/authorize\"\n\t\t: \"https://www.paypal.com/signin/authorize\";\n\n\tconst tokenEndpoint = isSandbox\n\t\t? \"https://api-m.sandbox.paypal.com/v1/oauth2/token\"\n\t\t: \"https://api-m.paypal.com/v1/oauth2/token\";\n\n\tconst userInfoEndpoint = isSandbox\n\t\t? \"https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo\"\n\t\t: \"https://api-m.paypal.com/v1/identity/oauth2/userinfo\";\n\n\treturn {\n\t\tid: \"paypal\",\n\t\tname: \"PayPal\",\n\t\tasync createAuthorizationURL({ state, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret is required for PayPal. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Log in with PayPal doesn't use traditional OAuth2 scopes\n\t\t\t * Instead, permissions are configured in the PayPal Developer Dashboard\n\t\t\t * We don't pass any scopes to avoid \"invalid scope\" errors\n\t\t\t **/\n\n\t\t\tconst _scopes: string[] = [];\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"paypal\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\t/**\n\t\t\t * PayPal requires Basic Auth for token exchange\n\t\t\t **/\n\n\t\t\tconst credentials = base64.encode(\n\t\t\t\t`${options.clientId}:${options.clientSecret}`,\n\t\t\t);\n\n\t\t\ttry {\n\t\t\t\tconst response = await betterFetch(tokenEndpoint, {\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Basic ${credentials}`,\n\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t\"Accept-Language\": \"en_US\",\n\t\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t},\n\t\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\t\t\tcode: code,\n\t\t\t\t\t\tredirect_uri: redirectURI,\n\t\t\t\t\t}).toString(),\n\t\t\t\t});\n\n\t\t\t\tif (!response.data) {\n\t\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_GET_ACCESS_TOKEN\");\n\t\t\t\t}\n\n\t\t\t\tconst data = response.data as PayPalTokenResponse;\n\n\t\t\t\tconst result = {\n\t\t\t\t\taccessToken: data.access_token,\n\t\t\t\t\trefreshToken: data.refresh_token,\n\t\t\t\t\taccessTokenExpiresAt: data.expires_in\n\t\t\t\t\t\t? new Date(Date.now() + data.expires_in * 1000)\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tidToken: data.id_token,\n\t\t\t\t};\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"PayPal token exchange failed:\", error);\n\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_GET_ACCESS_TOKEN\");\n\t\t\t}\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\tconst credentials = base64.encode(\n\t\t\t\t\t\t`${options.clientId}:${options.clientSecret}`,\n\t\t\t\t\t);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst response = await betterFetch(tokenEndpoint, {\n\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\tAuthorization: `Basic ${credentials}`,\n\t\t\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t\t\t\"Accept-Language\": \"en_US\",\n\t\t\t\t\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\t\t\t\t\trefresh_token: refreshToken,\n\t\t\t\t\t\t\t}).toString(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!response.data) {\n\t\t\t\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_REFRESH_ACCESS_TOKEN\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst data = response.data as any;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\taccessToken: data.access_token,\n\t\t\t\t\t\t\trefreshToken: data.refresh_token,\n\t\t\t\t\t\t\taccessTokenExpiresAt: data.expires_in\n\t\t\t\t\t\t\t\t? new Date(Date.now() + data.expires_in * 1000)\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tlogger.error(\"PayPal token refresh failed:\", error);\n\t\t\t\t\t\tthrow new BetterAuthError(\"FAILED_TO_REFRESH_ACCESS_TOKEN\");\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst payload = decodeJwt(token);\n\t\t\t\treturn !!payload.sub;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to verify PayPal ID token:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\tif (!token.accessToken) {\n\t\t\t\tlogger.error(\"Access token is required to fetch PayPal user info\");\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst response = await betterFetch<PayPalProfile>(\n\t\t\t\t\t`${userInfoEndpoint}?schema=paypalv1.1`,\n\t\t\t\t\t{\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!response.data) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user info from PayPal\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userInfo = response.data;\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(userInfo);\n\n\t\t\t\tconst result = {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: userInfo.user_id,\n\t\t\t\t\t\tname: userInfo.name,\n\t\t\t\t\t\temail: userInfo.email,\n\t\t\t\t\t\timage: userInfo.picture,\n\t\t\t\t\t\temailVerified: userInfo.email_verified,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: userInfo,\n\t\t\t\t};\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from PayPal:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\toptions,\n\t} satisfies OAuthProvider<PayPalProfile>;\n};\n"],"mappings":"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"}
|
|
@@ -3,9 +3,9 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
3
3
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
4
|
import "../oauth2/index.mjs";
|
|
5
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
6
|
-
|
|
7
6
|
//#region src/social-providers/polar.ts
|
|
8
7
|
const polar = (options) => {
|
|
8
|
+
const tokenEndpoint = "https://api.polar.sh/v1/oauth2/token";
|
|
9
9
|
return {
|
|
10
10
|
id: "polar",
|
|
11
11
|
name: "Polar",
|
|
@@ -34,7 +34,7 @@ const polar = (options) => {
|
|
|
34
34
|
codeVerifier,
|
|
35
35
|
redirectURI,
|
|
36
36
|
options,
|
|
37
|
-
tokenEndpoint
|
|
37
|
+
tokenEndpoint
|
|
38
38
|
});
|
|
39
39
|
},
|
|
40
40
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -45,7 +45,7 @@ const polar = (options) => {
|
|
|
45
45
|
clientKey: options.clientKey,
|
|
46
46
|
clientSecret: options.clientSecret
|
|
47
47
|
},
|
|
48
|
-
tokenEndpoint
|
|
48
|
+
tokenEndpoint
|
|
49
49
|
});
|
|
50
50
|
},
|
|
51
51
|
async getUserInfo(token) {
|
|
@@ -68,7 +68,7 @@ const polar = (options) => {
|
|
|
68
68
|
options
|
|
69
69
|
};
|
|
70
70
|
};
|
|
71
|
-
|
|
72
71
|
//#endregion
|
|
73
72
|
export { polar };
|
|
73
|
+
|
|
74
74
|
//# sourceMappingURL=polar.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polar.mjs","names":[],"sources":["../../src/social-providers/polar.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface PolarProfile {\n\tid: string;\n\temail: string;\n\tusername: string;\n\tavatar_url: string;\n\tgithub_username?: string | undefined;\n\taccount_id?: string | undefined;\n\tpublic_name?: string | undefined;\n\temail_verified?: boolean | undefined;\n\tprofile_settings?:\n\t\t| {\n\t\t\t\tprofile_settings_enabled?: boolean;\n\t\t\t\tprofile_settings_public_name?: string;\n\t\t\t\tprofile_settings_public_avatar?: string;\n\t\t\t\tprofile_settings_public_bio?: string;\n\t\t\t\tprofile_settings_public_location?: string;\n\t\t\t\tprofile_settings_public_website?: string;\n\t\t\t\tprofile_settings_public_twitter?: string;\n\t\t\t\tprofile_settings_public_github?: string;\n\t\t\t\tprofile_settings_public_email?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface PolarOptions extends ProviderOptions<PolarProfile> {}\n\nexport const polar = (options: PolarOptions) => {\n\treturn {\n\t\tid: \"polar\",\n\t\tname: \"Polar\",\n\t\tcreateAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"polar\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://polar.sh/oauth2/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint
|
|
1
|
+
{"version":3,"file":"polar.mjs","names":[],"sources":["../../src/social-providers/polar.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface PolarProfile {\n\tid: string;\n\temail: string;\n\tusername: string;\n\tavatar_url: string;\n\tgithub_username?: string | undefined;\n\taccount_id?: string | undefined;\n\tpublic_name?: string | undefined;\n\temail_verified?: boolean | undefined;\n\tprofile_settings?:\n\t\t| {\n\t\t\t\tprofile_settings_enabled?: boolean;\n\t\t\t\tprofile_settings_public_name?: string;\n\t\t\t\tprofile_settings_public_avatar?: string;\n\t\t\t\tprofile_settings_public_bio?: string;\n\t\t\t\tprofile_settings_public_location?: string;\n\t\t\t\tprofile_settings_public_website?: string;\n\t\t\t\tprofile_settings_public_twitter?: string;\n\t\t\t\tprofile_settings_public_github?: string;\n\t\t\t\tprofile_settings_public_email?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface PolarOptions extends ProviderOptions<PolarProfile> {}\n\nexport const polar = (options: PolarOptions) => {\n\tconst tokenEndpoint = \"https://api.polar.sh/v1/oauth2/token\";\n\treturn {\n\t\tid: \"polar\",\n\t\tname: \"Polar\",\n\t\tcreateAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"polar\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://polar.sh/oauth2/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<PolarProfile>(\n\t\t\t\t\"https://api.polar.sh/v1/oauth2/userinfo\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// Polar may provide email_verified claim, but it's not guaranteed.\n\t\t\t// We check for it first, then default to false for security consistency.\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.id,\n\t\t\t\t\tname: profile.public_name || profile.username || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.avatar_url,\n\t\t\t\t\temailVerified: profile.email_verified ?? false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<PolarProfile>;\n};\n"],"mappings":";;;;;;AAkCA,MAAa,SAAS,YAA0B;CAC/C,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;GACpE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAW;IAAQ;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,QAAQ,QAAQ;IAChB,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,2CACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAGzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,eAAe,QAAQ,YAAY;KACjD,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -3,7 +3,6 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
3
3
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
4
|
import "../oauth2/index.mjs";
|
|
5
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
6
|
-
|
|
7
6
|
//#region src/social-providers/railway.ts
|
|
8
7
|
const authorizationEndpoint = "https://backboard.railway.com/oauth/auth";
|
|
9
8
|
const tokenEndpoint = "https://backboard.railway.com/oauth/token";
|
|
@@ -72,7 +71,7 @@ const railway = (options) => {
|
|
|
72
71
|
options
|
|
73
72
|
};
|
|
74
73
|
};
|
|
75
|
-
|
|
76
74
|
//#endregion
|
|
77
75
|
export { railway };
|
|
76
|
+
|
|
78
77
|
//# sourceMappingURL=railway.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"railway.mjs","names":[],"sources":["../../src/social-providers/railway.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nconst authorizationEndpoint = \"https://backboard.railway.com/oauth/auth\";\nconst tokenEndpoint = \"https://backboard.railway.com/oauth/token\";\nconst userinfoEndpoint = \"https://backboard.railway.com/oauth/me\";\n\nexport interface RailwayProfile {\n\t/** The user's unique ID (OAuth `sub` claim). */\n\tsub: string;\n\t/** The user's email address. */\n\temail: string;\n\t/** The user's display name. */\n\tname: string;\n\t/** URL of the user's profile picture. */\n\tpicture: string;\n}\n\nexport interface RailwayOptions extends ProviderOptions<RailwayProfile> {\n\tclientId: string;\n}\n\nexport const railway = (options: RailwayOptions) => {\n\treturn {\n\t\tid: \"railway\",\n\t\tname: \"Railway\",\n\t\tcreateAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"railway\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t\tauthentication: \"basic\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t\tauthentication: \"basic\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<RailwayProfile>(\n\t\t\t\tuserinfoEndpoint,\n\t\t\t\t{ headers: { authorization: `Bearer ${token.accessToken}` } },\n\t\t\t);\n\t\t\tif (error || !profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// Railway does not provide an email_verified claim.\n\t\t\t// We default to false for security consistency.\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.picture,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<RailwayProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"railway.mjs","names":[],"sources":["../../src/social-providers/railway.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nconst authorizationEndpoint = \"https://backboard.railway.com/oauth/auth\";\nconst tokenEndpoint = \"https://backboard.railway.com/oauth/token\";\nconst userinfoEndpoint = \"https://backboard.railway.com/oauth/me\";\n\nexport interface RailwayProfile {\n\t/** The user's unique ID (OAuth `sub` claim). */\n\tsub: string;\n\t/** The user's email address. */\n\temail: string;\n\t/** The user's display name. */\n\tname: string;\n\t/** URL of the user's profile picture. */\n\tpicture: string;\n}\n\nexport interface RailwayOptions extends ProviderOptions<RailwayProfile> {\n\tclientId: string;\n}\n\nexport const railway = (options: RailwayOptions) => {\n\treturn {\n\t\tid: \"railway\",\n\t\tname: \"Railway\",\n\t\tcreateAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"railway\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t\tauthentication: \"basic\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t\tauthentication: \"basic\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<RailwayProfile>(\n\t\t\t\tuserinfoEndpoint,\n\t\t\t\t{ headers: { authorization: `Bearer ${token.accessToken}` } },\n\t\t\t);\n\t\t\tif (error || !profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// Railway does not provide an email_verified claim.\n\t\t\t// We default to false for security consistency.\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.picture,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<RailwayProfile>;\n};\n"],"mappings":";;;;;;AAQA,MAAM,wBAAwB;AAC9B,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AAiBzB,MAAa,WAAW,YAA4B;AACnD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;GACpE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAS;IAAU;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,gBAAgB;IAChB,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,gBAAgB;IAChB,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,kBACA,EAAE,SAAS,EAAE,eAAe,UAAU,MAAM,eAAe,EAAE,CAC7D;AACD,OAAI,SAAS,CAAC,QACb,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAGzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf,eAAe;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -4,7 +4,6 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
4
4
|
import "../oauth2/index.mjs";
|
|
5
5
|
import { base64 } from "@better-auth/utils/base64";
|
|
6
6
|
import { betterFetch } from "@better-fetch/fetch";
|
|
7
|
-
|
|
8
7
|
//#region src/social-providers/reddit.ts
|
|
9
8
|
const reddit = (options) => {
|
|
10
9
|
return {
|
|
@@ -78,7 +77,7 @@ const reddit = (options) => {
|
|
|
78
77
|
options
|
|
79
78
|
};
|
|
80
79
|
};
|
|
81
|
-
|
|
82
80
|
//#endregion
|
|
83
81
|
export { reddit };
|
|
82
|
+
|
|
84
83
|
//# sourceMappingURL=reddit.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reddit.mjs","names":[],"sources":["../../src/social-providers/reddit.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tgetOAuth2Tokens,\n\trefreshAccessToken,\n} from \"../oauth2\";\n\nexport interface RedditProfile {\n\tid: string;\n\tname: string;\n\ticon_img: string | null;\n\thas_verified_email: boolean;\n\toauth_client_id: string;\n\tverified: boolean;\n}\n\nexport interface RedditOptions extends ProviderOptions<RedditProfile> {\n\tclientId: string;\n\tduration?: string | undefined;\n}\n\nexport const reddit = (options: RedditOptions) => {\n\treturn {\n\t\tid: \"reddit\",\n\t\tname: \"Reddit\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"identity\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"reddit\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.reddit.com/api/v1/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tduration: options.duration,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\tconst body = new URLSearchParams({\n\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\tcode,\n\t\t\t\tredirect_uri: options.redirectURI || redirectURI,\n\t\t\t});\n\t\t\tconst headers = {\n\t\t\t\t\"content-type\": \"application/x-www-form-urlencoded\",\n\t\t\t\taccept: \"text/plain\",\n\t\t\t\t\"user-agent\": \"better-auth\",\n\t\t\t\tAuthorization: `Basic ${base64.encode(\n\t\t\t\t\t`${options.clientId}:${options.clientSecret}`,\n\t\t\t\t)}`,\n\t\t\t};\n\n\t\t\tconst { data, error } = await betterFetch<object>(\n\t\t\t\t\"https://www.reddit.com/api/v1/access_token\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders,\n\t\t\t\t\tbody: body.toString(),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\treturn getOAuth2Tokens(data);\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tauthentication: \"basic\",\n\t\t\t\t\t\ttokenEndpoint: \"https://www.reddit.com/api/v1/access_token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\tconst { data: profile, error } = await betterFetch<RedditProfile>(\n\t\t\t\t\"https://oauth.reddit.com/api/v1/me\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t\"User-Agent\": \"better-auth\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.oauth_client_id,\n\t\t\t\t\temailVerified: profile.has_verified_email,\n\t\t\t\t\timage: profile.icon_img?.split(\"?\")[0]!,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<RedditProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"reddit.mjs","names":[],"sources":["../../src/social-providers/reddit.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tgetOAuth2Tokens,\n\trefreshAccessToken,\n} from \"../oauth2\";\n\nexport interface RedditProfile {\n\tid: string;\n\tname: string;\n\ticon_img: string | null;\n\thas_verified_email: boolean;\n\toauth_client_id: string;\n\tverified: boolean;\n}\n\nexport interface RedditOptions extends ProviderOptions<RedditProfile> {\n\tclientId: string;\n\tduration?: string | undefined;\n}\n\nexport const reddit = (options: RedditOptions) => {\n\treturn {\n\t\tid: \"reddit\",\n\t\tname: \"Reddit\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"identity\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"reddit\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.reddit.com/api/v1/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tduration: options.duration,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\tconst body = new URLSearchParams({\n\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\tcode,\n\t\t\t\tredirect_uri: options.redirectURI || redirectURI,\n\t\t\t});\n\t\t\tconst headers = {\n\t\t\t\t\"content-type\": \"application/x-www-form-urlencoded\",\n\t\t\t\taccept: \"text/plain\",\n\t\t\t\t\"user-agent\": \"better-auth\",\n\t\t\t\tAuthorization: `Basic ${base64.encode(\n\t\t\t\t\t`${options.clientId}:${options.clientSecret}`,\n\t\t\t\t)}`,\n\t\t\t};\n\n\t\t\tconst { data, error } = await betterFetch<object>(\n\t\t\t\t\"https://www.reddit.com/api/v1/access_token\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders,\n\t\t\t\t\tbody: body.toString(),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\treturn getOAuth2Tokens(data);\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tauthentication: \"basic\",\n\t\t\t\t\t\ttokenEndpoint: \"https://www.reddit.com/api/v1/access_token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\tconst { data: profile, error } = await betterFetch<RedditProfile>(\n\t\t\t\t\"https://oauth.reddit.com/api/v1/me\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t\"User-Agent\": \"better-auth\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.oauth_client_id,\n\t\t\t\t\temailVerified: profile.has_verified_email,\n\t\t\t\t\timage: profile.icon_img?.split(\"?\")[0]!,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<RedditProfile>;\n};\n"],"mappings":";;;;;;;AAuBA,MAAa,UAAU,YAA2B;AACjD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GACtD,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,WAAW;AAC/D,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA,UAAU,QAAQ;IAClB,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;GAC3D,MAAM,OAAO,IAAI,gBAAgB;IAChC,YAAY;IACZ;IACA,cAAc,QAAQ,eAAe;IACrC,CAAC;GAUF,MAAM,EAAE,MAAM,UAAU,MAAM,YAC7B,8CACA;IACC,QAAQ;IACR,SAbc;KACf,gBAAgB;KAChB,QAAQ;KACR,cAAc;KACd,eAAe,SAAS,OAAO,OAC9B,GAAG,QAAQ,SAAS,GAAG,QAAQ,eAC/B;KACD;IAOC,MAAM,KAAK,UAAU;IACrB,CACD;AAED,OAAI,MACH,OAAM;AAGP,UAAO,gBAAgB,KAAK;;EAG7B,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,gBAAgB;IAChB,eAAe;IACf,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAGlC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,sCACA,EACC,SAAS;IACR,eAAe,UAAU,MAAM;IAC/B,cAAc;IACd,EACD,CACD;AAED,OAAI,MACH,QAAO;GAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAEzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,eAAe,QAAQ;KACvB,OAAO,QAAQ,UAAU,MAAM,IAAI,CAAC;KACpC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -2,9 +2,9 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
2
2
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
3
3
|
import "../oauth2/index.mjs";
|
|
4
4
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
|
-
|
|
6
5
|
//#region src/social-providers/roblox.ts
|
|
7
6
|
const roblox = (options) => {
|
|
7
|
+
const tokenEndpoint = "https://apis.roblox.com/oauth/v1/token";
|
|
8
8
|
return {
|
|
9
9
|
id: "roblox",
|
|
10
10
|
name: "Roblox",
|
|
@@ -19,7 +19,7 @@ const roblox = (options) => {
|
|
|
19
19
|
code,
|
|
20
20
|
redirectURI: options.redirectURI || redirectURI,
|
|
21
21
|
options,
|
|
22
|
-
tokenEndpoint
|
|
22
|
+
tokenEndpoint,
|
|
23
23
|
authentication: "post"
|
|
24
24
|
});
|
|
25
25
|
},
|
|
@@ -31,7 +31,7 @@ const roblox = (options) => {
|
|
|
31
31
|
clientKey: options.clientKey,
|
|
32
32
|
clientSecret: options.clientSecret
|
|
33
33
|
},
|
|
34
|
-
tokenEndpoint
|
|
34
|
+
tokenEndpoint
|
|
35
35
|
});
|
|
36
36
|
},
|
|
37
37
|
async getUserInfo(token) {
|
|
@@ -54,7 +54,7 @@ const roblox = (options) => {
|
|
|
54
54
|
options
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
|
-
|
|
58
57
|
//#endregion
|
|
59
58
|
export { roblox };
|
|
59
|
+
|
|
60
60
|
//# sourceMappingURL=roblox.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roblox.mjs","names":[],"sources":["../../src/social-providers/roblox.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { refreshAccessToken, validateAuthorizationCode } from \"../oauth2\";\n\nexport interface RobloxProfile extends Record<string, any> {\n\t/** the user's id */\n\tsub: string;\n\t/** the user's username */\n\tpreferred_username: string;\n\t/** the user's display name, will return the same value as the preferred_username if not set */\n\tnickname: string;\n\t/** the user's display name, again, will return the same value as the preferred_username if not set */\n\tname: string;\n\t/** the account creation date as a unix timestamp in seconds */\n\tcreated_at: number;\n\t/** the user's profile URL */\n\tprofile: string;\n\t/** the user's avatar URL */\n\tpicture: string;\n}\n\nexport interface RobloxOptions extends ProviderOptions<RobloxProfile> {\n\tclientId: string;\n\tprompt?:\n\t\t| (\n\t\t\t\t| \"none\"\n\t\t\t\t| \"consent\"\n\t\t\t\t| \"login\"\n\t\t\t\t| \"select_account\"\n\t\t\t\t| \"select_account consent\"\n\t\t )\n\t\t| undefined;\n}\n\nexport const roblox = (options: RobloxOptions) => {\n\treturn {\n\t\tid: \"roblox\",\n\t\tname: \"Roblox\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"openid\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn new URL(\n\t\t\t\t`https://apis.roblox.com/oauth/v1/authorize?scope=${_scopes.join(\n\t\t\t\t\t\"+\",\n\t\t\t\t)}&response_type=code&client_id=${\n\t\t\t\t\toptions.clientId\n\t\t\t\t}&redirect_uri=${encodeURIComponent(\n\t\t\t\t\toptions.redirectURI || redirectURI,\n\t\t\t\t)}&state=${state}&prompt=${options.prompt || \"select_account consent\"}`,\n\t\t\t);\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI: options.redirectURI || redirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint
|
|
1
|
+
{"version":3,"file":"roblox.mjs","names":[],"sources":["../../src/social-providers/roblox.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { refreshAccessToken, validateAuthorizationCode } from \"../oauth2\";\n\nexport interface RobloxProfile extends Record<string, any> {\n\t/** the user's id */\n\tsub: string;\n\t/** the user's username */\n\tpreferred_username: string;\n\t/** the user's display name, will return the same value as the preferred_username if not set */\n\tnickname: string;\n\t/** the user's display name, again, will return the same value as the preferred_username if not set */\n\tname: string;\n\t/** the account creation date as a unix timestamp in seconds */\n\tcreated_at: number;\n\t/** the user's profile URL */\n\tprofile: string;\n\t/** the user's avatar URL */\n\tpicture: string;\n}\n\nexport interface RobloxOptions extends ProviderOptions<RobloxProfile> {\n\tclientId: string;\n\tprompt?:\n\t\t| (\n\t\t\t\t| \"none\"\n\t\t\t\t| \"consent\"\n\t\t\t\t| \"login\"\n\t\t\t\t| \"select_account\"\n\t\t\t\t| \"select_account consent\"\n\t\t )\n\t\t| undefined;\n}\n\nexport const roblox = (options: RobloxOptions) => {\n\tconst tokenEndpoint = \"https://apis.roblox.com/oauth/v1/token\";\n\treturn {\n\t\tid: \"roblox\",\n\t\tname: \"Roblox\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"openid\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn new URL(\n\t\t\t\t`https://apis.roblox.com/oauth/v1/authorize?scope=${_scopes.join(\n\t\t\t\t\t\"+\",\n\t\t\t\t)}&response_type=code&client_id=${\n\t\t\t\t\toptions.clientId\n\t\t\t\t}&redirect_uri=${encodeURIComponent(\n\t\t\t\t\toptions.redirectURI || redirectURI,\n\t\t\t\t)}&state=${state}&prompt=${options.prompt || \"select_account consent\"}`,\n\t\t\t);\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI: options.redirectURI || redirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t\tauthentication: \"post\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<RobloxProfile>(\n\t\t\t\t\"https://apis.roblox.com/oauth/v1/userinfo\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tauthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// Roblox does not provide email or email_verified claim.\n\t\t\t// We default to false for security consistency.\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.nickname || profile.preferred_username || \"\",\n\t\t\t\t\timage: profile.picture,\n\t\t\t\t\temail: profile.preferred_username || null, // Roblox does not provide email\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: {\n\t\t\t\t\t...profile,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<RobloxProfile>;\n};\n"],"mappings":";;;;;AAkCA,MAAa,UAAU,YAA2B;CACjD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GACtD,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,UAAU,UAAU;AACxE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,IAAI,IACV,oDAAoD,QAAQ,KAC3D,IACA,CAAC,gCACD,QAAQ,SACR,gBAAgB,mBAChB,QAAQ,eAAe,YACvB,CAAC,SAAS,MAAM,UAAU,QAAQ,UAAU,2BAC7C;;EAEF,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA,aAAa,QAAQ,eAAe;IACpC;IACA;IACA,gBAAgB;IAChB,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,6CACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AAED,OAAI,MACH,QAAO;GAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAGzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,YAAY,QAAQ,sBAAsB;KACxD,OAAO,QAAQ;KACf,OAAO,QAAQ,sBAAsB;KACrC,eAAe;KACf,GAAG;KACH;IACD,MAAM,EACL,GAAG,SACH;IACD;;EAEF;EACA"}
|
|
@@ -6,7 +6,6 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
6
6
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
7
7
|
import "../oauth2/index.mjs";
|
|
8
8
|
import { betterFetch } from "@better-fetch/fetch";
|
|
9
|
-
|
|
10
9
|
//#region src/social-providers/salesforce.ts
|
|
11
10
|
const salesforce = (options) => {
|
|
12
11
|
const isSandbox = (options.environment ?? "production") === "sandbox";
|
|
@@ -86,7 +85,7 @@ const salesforce = (options) => {
|
|
|
86
85
|
options
|
|
87
86
|
};
|
|
88
87
|
};
|
|
89
|
-
|
|
90
88
|
//#endregion
|
|
91
89
|
export { salesforce };
|
|
90
|
+
|
|
92
91
|
//# sourceMappingURL=salesforce.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"salesforce.mjs","names":[],"sources":["../../src/social-providers/salesforce.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface SalesforceProfile {\n\tsub: string;\n\tuser_id: string;\n\torganization_id: string;\n\tpreferred_username?: string | undefined;\n\temail: string;\n\temail_verified?: boolean | undefined;\n\tname: string;\n\tgiven_name?: string | undefined;\n\tfamily_name?: string | undefined;\n\tzoneinfo?: string | undefined;\n\tphotos?:\n\t\t| {\n\t\t\t\tpicture?: string;\n\t\t\t\tthumbnail?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface SalesforceOptions extends ProviderOptions<SalesforceProfile> {\n\tclientId: string;\n\tenvironment?: (\"sandbox\" | \"production\") | undefined;\n\tloginUrl?: string | undefined;\n\t/**\n\t * Override the redirect URI if auto-detection fails.\n\t * Should match the Callback URL configured in your Salesforce Connected App.\n\t * @example \"http://localhost:3000/api/auth/callback/salesforce\"\n\t */\n\tredirectURI?: string | undefined;\n}\n\nexport const salesforce = (options: SalesforceOptions) => {\n\tconst environment = options.environment ?? \"production\";\n\tconst isSandbox = environment === \"sandbox\";\n\tconst authorizationEndpoint = options.loginUrl\n\t\t? `https://${options.loginUrl}/services/oauth2/authorize`\n\t\t: isSandbox\n\t\t\t? \"https://test.salesforce.com/services/oauth2/authorize\"\n\t\t\t: \"https://login.salesforce.com/services/oauth2/authorize\";\n\n\tconst tokenEndpoint = options.loginUrl\n\t\t? `https://${options.loginUrl}/services/oauth2/token`\n\t\t: isSandbox\n\t\t\t? \"https://test.salesforce.com/services/oauth2/token\"\n\t\t\t: \"https://login.salesforce.com/services/oauth2/token\";\n\n\tconst userInfoEndpoint = options.loginUrl\n\t\t? `https://${options.loginUrl}/services/oauth2/userinfo`\n\t\t: isSandbox\n\t\t\t? \"https://test.salesforce.com/services/oauth2/userinfo\"\n\t\t\t: \"https://login.salesforce.com/services/oauth2/userinfo\";\n\n\treturn {\n\t\tid: \"salesforce\",\n\t\tname: \"Salesforce\",\n\n\t\tasync createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret are required for Salesforce. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Salesforce\");\n\t\t\t}\n\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"salesforce\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI: options.redirectURI || redirectURI,\n\t\t\t});\n\t\t},\n\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI: options.redirectURI || redirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { data: user } = await betterFetch<SalesforceProfile>(\n\t\t\t\t\tuserInfoEndpoint,\n\t\t\t\t\t{\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!user) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user info from Salesforce\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(user);\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: user.user_id,\n\t\t\t\t\t\tname: user.name,\n\t\t\t\t\t\temail: user.email,\n\t\t\t\t\t\timage: user.photos?.picture || user.photos?.thumbnail,\n\t\t\t\t\t\temailVerified: user.email_verified ?? false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: user,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from Salesforce:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\toptions,\n\t} satisfies OAuthProvider<SalesforceProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"salesforce.mjs","names":[],"sources":["../../src/social-providers/salesforce.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface SalesforceProfile {\n\tsub: string;\n\tuser_id: string;\n\torganization_id: string;\n\tpreferred_username?: string | undefined;\n\temail: string;\n\temail_verified?: boolean | undefined;\n\tname: string;\n\tgiven_name?: string | undefined;\n\tfamily_name?: string | undefined;\n\tzoneinfo?: string | undefined;\n\tphotos?:\n\t\t| {\n\t\t\t\tpicture?: string;\n\t\t\t\tthumbnail?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface SalesforceOptions extends ProviderOptions<SalesforceProfile> {\n\tclientId: string;\n\tenvironment?: (\"sandbox\" | \"production\") | undefined;\n\tloginUrl?: string | undefined;\n\t/**\n\t * Override the redirect URI if auto-detection fails.\n\t * Should match the Callback URL configured in your Salesforce Connected App.\n\t * @example \"http://localhost:3000/api/auth/callback/salesforce\"\n\t */\n\tredirectURI?: string | undefined;\n}\n\nexport const salesforce = (options: SalesforceOptions) => {\n\tconst environment = options.environment ?? \"production\";\n\tconst isSandbox = environment === \"sandbox\";\n\tconst authorizationEndpoint = options.loginUrl\n\t\t? `https://${options.loginUrl}/services/oauth2/authorize`\n\t\t: isSandbox\n\t\t\t? \"https://test.salesforce.com/services/oauth2/authorize\"\n\t\t\t: \"https://login.salesforce.com/services/oauth2/authorize\";\n\n\tconst tokenEndpoint = options.loginUrl\n\t\t? `https://${options.loginUrl}/services/oauth2/token`\n\t\t: isSandbox\n\t\t\t? \"https://test.salesforce.com/services/oauth2/token\"\n\t\t\t: \"https://login.salesforce.com/services/oauth2/token\";\n\n\tconst userInfoEndpoint = options.loginUrl\n\t\t? `https://${options.loginUrl}/services/oauth2/userinfo`\n\t\t: isSandbox\n\t\t\t? \"https://test.salesforce.com/services/oauth2/userinfo\"\n\t\t\t: \"https://login.salesforce.com/services/oauth2/userinfo\";\n\n\treturn {\n\t\tid: \"salesforce\",\n\t\tname: \"Salesforce\",\n\n\t\tasync createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret are required for Salesforce. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Salesforce\");\n\t\t\t}\n\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"salesforce\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI: options.redirectURI || redirectURI,\n\t\t\t});\n\t\t},\n\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI: options.redirectURI || redirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { data: user } = await betterFetch<SalesforceProfile>(\n\t\t\t\t\tuserInfoEndpoint,\n\t\t\t\t\t{\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!user) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user info from Salesforce\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(user);\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: user.user_id,\n\t\t\t\t\t\tname: user.name,\n\t\t\t\t\t\temail: user.email,\n\t\t\t\t\t\timage: user.photos?.picture || user.photos?.thumbnail,\n\t\t\t\t\t\temailVerified: user.email_verified ?? false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: user,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from Salesforce:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\n\t\toptions,\n\t} satisfies OAuthProvider<SalesforceProfile>;\n};\n"],"mappings":";;;;;;;;;AAyCA,MAAa,cAAc,YAA+B;CAEzD,MAAM,aADc,QAAQ,eAAe,kBACT;CAClC,MAAM,wBAAwB,QAAQ,WACnC,WAAW,QAAQ,SAAS,8BAC5B,YACC,0DACA;CAEJ,MAAM,gBAAgB,QAAQ,WAC3B,WAAW,QAAQ,SAAS,0BAC5B,YACC,sDACA;CAEJ,MAAM,mBAAmB,QAAQ,WAC9B,WAAW,QAAQ,SAAS,6BAC5B,YACC,yDACA;AAEJ,QAAO;EACN,IAAI;EACJ,MAAM;EAEN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;AAC1E,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MACN,qGACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,0CAA0C;GAGrE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAS;IAAU;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAEnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA,aAAa,QAAQ,eAAe;IACpC,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA,aAAa,QAAQ,eAAe;IACpC;IACA;IACA,CAAC;;EAGH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAGL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAGlC,OAAI;IACH,MAAM,EAAE,MAAM,SAAS,MAAM,YAC5B,kBACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AAED,QAAI,CAAC,MAAM;AACV,YAAO,MAAM,4CAA4C;AACzD,YAAO;;IAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,KAAK;AAEtD,WAAO;KACN,MAAM;MACL,IAAI,KAAK;MACT,MAAM,KAAK;MACX,OAAO,KAAK;MACZ,OAAO,KAAK,QAAQ,WAAW,KAAK,QAAQ;MAC5C,eAAe,KAAK,kBAAkB;MACtC,GAAG;MACH;KACD,MAAM;KACN;YACO,OAAO;AACf,WAAO,MAAM,8CAA8C,MAAM;AACjE,WAAO;;;EAIT;EACA"}
|
|
@@ -2,9 +2,9 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
2
2
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
3
3
|
import "../oauth2/index.mjs";
|
|
4
4
|
import { betterFetch } from "@better-fetch/fetch";
|
|
5
|
-
|
|
6
5
|
//#region src/social-providers/slack.ts
|
|
7
6
|
const slack = (options) => {
|
|
7
|
+
const tokenEndpoint = "https://slack.com/api/openid.connect.token";
|
|
8
8
|
return {
|
|
9
9
|
id: "slack",
|
|
10
10
|
name: "Slack",
|
|
@@ -29,7 +29,7 @@ const slack = (options) => {
|
|
|
29
29
|
code,
|
|
30
30
|
redirectURI,
|
|
31
31
|
options,
|
|
32
|
-
tokenEndpoint
|
|
32
|
+
tokenEndpoint
|
|
33
33
|
});
|
|
34
34
|
},
|
|
35
35
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -40,7 +40,7 @@ const slack = (options) => {
|
|
|
40
40
|
clientKey: options.clientKey,
|
|
41
41
|
clientSecret: options.clientSecret
|
|
42
42
|
},
|
|
43
|
-
tokenEndpoint
|
|
43
|
+
tokenEndpoint
|
|
44
44
|
});
|
|
45
45
|
},
|
|
46
46
|
async getUserInfo(token) {
|
|
@@ -63,7 +63,7 @@ const slack = (options) => {
|
|
|
63
63
|
options
|
|
64
64
|
};
|
|
65
65
|
};
|
|
66
|
-
|
|
67
66
|
//#endregion
|
|
68
67
|
export { slack };
|
|
68
|
+
|
|
69
69
|
//# sourceMappingURL=slack.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.mjs","names":[],"sources":["../../src/social-providers/slack.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { refreshAccessToken, validateAuthorizationCode } from \"../oauth2\";\n\nexport interface SlackProfile extends Record<string, any> {\n\tok: boolean;\n\tsub: string;\n\t\"https://slack.com/user_id\": string;\n\t\"https://slack.com/team_id\": string;\n\temail: string;\n\temail_verified: boolean;\n\tdate_email_verified: number;\n\tname: string;\n\tpicture: string;\n\tgiven_name: string;\n\tfamily_name: string;\n\tlocale: string;\n\t\"https://slack.com/team_name\": string;\n\t\"https://slack.com/team_domain\": string;\n\t\"https://slack.com/user_image_24\": string;\n\t\"https://slack.com/user_image_32\": string;\n\t\"https://slack.com/user_image_48\": string;\n\t\"https://slack.com/user_image_72\": string;\n\t\"https://slack.com/user_image_192\": string;\n\t\"https://slack.com/user_image_512\": string;\n\t\"https://slack.com/team_image_34\": string;\n\t\"https://slack.com/team_image_44\": string;\n\t\"https://slack.com/team_image_68\": string;\n\t\"https://slack.com/team_image_88\": string;\n\t\"https://slack.com/team_image_102\": string;\n\t\"https://slack.com/team_image_132\": string;\n\t\"https://slack.com/team_image_230\": string;\n\t\"https://slack.com/team_image_default\": boolean;\n}\n\nexport interface SlackOptions extends ProviderOptions<SlackProfile> {\n\tclientId: string;\n}\n\nexport const slack = (options: SlackOptions) => {\n\treturn {\n\t\tid: \"slack\",\n\t\tname: \"Slack\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\"];\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tconst url = new URL(\"https://slack.com/openid/connect/authorize\");\n\t\t\turl.searchParams.set(\"scope\", _scopes.join(\" \"));\n\t\t\turl.searchParams.set(\"response_type\", \"code\");\n\t\t\turl.searchParams.set(\"client_id\", options.clientId);\n\t\t\turl.searchParams.set(\"redirect_uri\", options.redirectURI || redirectURI);\n\t\t\turl.searchParams.set(\"state\", state);\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint
|
|
1
|
+
{"version":3,"file":"slack.mjs","names":[],"sources":["../../src/social-providers/slack.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { refreshAccessToken, validateAuthorizationCode } from \"../oauth2\";\n\nexport interface SlackProfile extends Record<string, any> {\n\tok: boolean;\n\tsub: string;\n\t\"https://slack.com/user_id\": string;\n\t\"https://slack.com/team_id\": string;\n\temail: string;\n\temail_verified: boolean;\n\tdate_email_verified: number;\n\tname: string;\n\tpicture: string;\n\tgiven_name: string;\n\tfamily_name: string;\n\tlocale: string;\n\t\"https://slack.com/team_name\": string;\n\t\"https://slack.com/team_domain\": string;\n\t\"https://slack.com/user_image_24\": string;\n\t\"https://slack.com/user_image_32\": string;\n\t\"https://slack.com/user_image_48\": string;\n\t\"https://slack.com/user_image_72\": string;\n\t\"https://slack.com/user_image_192\": string;\n\t\"https://slack.com/user_image_512\": string;\n\t\"https://slack.com/team_image_34\": string;\n\t\"https://slack.com/team_image_44\": string;\n\t\"https://slack.com/team_image_68\": string;\n\t\"https://slack.com/team_image_88\": string;\n\t\"https://slack.com/team_image_102\": string;\n\t\"https://slack.com/team_image_132\": string;\n\t\"https://slack.com/team_image_230\": string;\n\t\"https://slack.com/team_image_default\": boolean;\n}\n\nexport interface SlackOptions extends ProviderOptions<SlackProfile> {\n\tclientId: string;\n}\n\nexport const slack = (options: SlackOptions) => {\n\tconst tokenEndpoint = \"https://slack.com/api/openid.connect.token\";\n\treturn {\n\t\tid: \"slack\",\n\t\tname: \"Slack\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\"];\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tconst url = new URL(\"https://slack.com/openid/connect/authorize\");\n\t\t\turl.searchParams.set(\"scope\", _scopes.join(\" \"));\n\t\t\turl.searchParams.set(\"response_type\", \"code\");\n\t\t\turl.searchParams.set(\"client_id\", options.clientId);\n\t\t\turl.searchParams.set(\"redirect_uri\", options.redirectURI || redirectURI);\n\t\t\turl.searchParams.set(\"state\", state);\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<SlackProfile>(\n\t\t\t\t\"https://slack.com/api/openid.connect.userInfo\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tauthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile[\"https://slack.com/user_id\"],\n\t\t\t\t\tname: profile.name || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\temailVerified: profile.email_verified,\n\t\t\t\t\timage: profile.picture || profile[\"https://slack.com/user_image_512\"],\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<SlackProfile>;\n};\n"],"mappings":";;;;;AAuCA,MAAa,SAAS,YAA0B;CAC/C,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GACtD,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAW;IAAQ;AACjC,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;GACjD,MAAM,MAAM,IAAI,IAAI,6CAA6C;AACjE,OAAI,aAAa,IAAI,SAAS,QAAQ,KAAK,IAAI,CAAC;AAChD,OAAI,aAAa,IAAI,iBAAiB,OAAO;AAC7C,OAAI,aAAa,IAAI,aAAa,QAAQ,SAAS;AACnD,OAAI,aAAa,IAAI,gBAAgB,QAAQ,eAAe,YAAY;AACxE,OAAI,aAAa,IAAI,SAAS,MAAM;AACpC,UAAO;;EAER,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,iDACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AAED,OAAI,MACH,QAAO;GAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ;KACtB,OAAO,QAAQ;KACf,eAAe,QAAQ;KACvB,OAAO,QAAQ,WAAW,QAAQ;KAClC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -3,9 +3,9 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
3
3
|
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
4
|
import "../oauth2/index.mjs";
|
|
5
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
6
|
-
|
|
7
6
|
//#region src/social-providers/spotify.ts
|
|
8
7
|
const spotify = (options) => {
|
|
8
|
+
const tokenEndpoint = "https://accounts.spotify.com/api/token";
|
|
9
9
|
return {
|
|
10
10
|
id: "spotify",
|
|
11
11
|
name: "Spotify",
|
|
@@ -29,7 +29,7 @@ const spotify = (options) => {
|
|
|
29
29
|
codeVerifier,
|
|
30
30
|
redirectURI,
|
|
31
31
|
options,
|
|
32
|
-
tokenEndpoint
|
|
32
|
+
tokenEndpoint
|
|
33
33
|
});
|
|
34
34
|
},
|
|
35
35
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -40,7 +40,7 @@ const spotify = (options) => {
|
|
|
40
40
|
clientKey: options.clientKey,
|
|
41
41
|
clientSecret: options.clientSecret
|
|
42
42
|
},
|
|
43
|
-
tokenEndpoint
|
|
43
|
+
tokenEndpoint
|
|
44
44
|
});
|
|
45
45
|
},
|
|
46
46
|
async getUserInfo(token) {
|
|
@@ -66,7 +66,7 @@ const spotify = (options) => {
|
|
|
66
66
|
options
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
|
-
|
|
70
69
|
//#endregion
|
|
71
70
|
export { spotify };
|
|
71
|
+
|
|
72
72
|
//# sourceMappingURL=spotify.mjs.map
|