@better-auth/core 1.5.6 → 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 -11
- 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 -1
- 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.mjs +1 -2
- 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.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.mjs +1 -2
- 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.mjs +1 -2
- package/dist/db/adapter/index.mjs.map +1 -1
- package/dist/db/adapter/utils.mjs +1 -1
- package/dist/db/adapter/utils.mjs.map +1 -1
- package/dist/db/get-tables.mjs +1 -1
- package/dist/db/index.mjs +1 -2
- package/dist/db/schema/account.mjs +1 -2
- package/dist/db/schema/account.mjs.map +1 -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.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.mjs +1 -2
- package/dist/db/schema/user.mjs.map +1 -1
- package/dist/db/schema/verification.mjs +1 -2
- package/dist/db/schema/verification.mjs.map +1 -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.mjs +1 -2
- package/dist/instrumentation/attributes.mjs.map +1 -1
- package/dist/instrumentation/index.mjs +1 -2
- package/dist/instrumentation/tracer.mjs +2 -3
- package/dist/instrumentation/tracer.mjs.map +1 -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.mjs +1 -2
- package/dist/oauth2/create-authorization-url.mjs.map +1 -1
- package/dist/oauth2/index.mjs +1 -2
- 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.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.mjs +1 -2
- package/dist/social-providers/apple.mjs.map +1 -1
- package/dist/social-providers/atlassian.mjs +1 -2
- package/dist/social-providers/atlassian.mjs.map +1 -1
- package/dist/social-providers/cognito.mjs +1 -2
- package/dist/social-providers/cognito.mjs.map +1 -1
- package/dist/social-providers/discord.mjs +1 -2
- package/dist/social-providers/discord.mjs.map +1 -1
- package/dist/social-providers/dropbox.mjs +1 -2
- package/dist/social-providers/dropbox.mjs.map +1 -1
- package/dist/social-providers/facebook.mjs +1 -2
- package/dist/social-providers/facebook.mjs.map +1 -1
- package/dist/social-providers/figma.mjs +1 -2
- package/dist/social-providers/figma.mjs.map +1 -1
- package/dist/social-providers/github.mjs +1 -2
- package/dist/social-providers/github.mjs.map +1 -1
- package/dist/social-providers/gitlab.mjs +1 -2
- package/dist/social-providers/gitlab.mjs.map +1 -1
- package/dist/social-providers/google.mjs +1 -2
- package/dist/social-providers/google.mjs.map +1 -1
- package/dist/social-providers/huggingface.mjs +1 -2
- package/dist/social-providers/huggingface.mjs.map +1 -1
- package/dist/social-providers/index.mjs +1 -2
- package/dist/social-providers/index.mjs.map +1 -1
- package/dist/social-providers/kakao.mjs +1 -2
- package/dist/social-providers/kakao.mjs.map +1 -1
- package/dist/social-providers/kick.mjs +1 -2
- package/dist/social-providers/kick.mjs.map +1 -1
- package/dist/social-providers/line.mjs +1 -2
- package/dist/social-providers/line.mjs.map +1 -1
- package/dist/social-providers/linear.mjs +1 -2
- package/dist/social-providers/linear.mjs.map +1 -1
- package/dist/social-providers/linkedin.mjs +1 -2
- package/dist/social-providers/linkedin.mjs.map +1 -1
- 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.mjs +1 -2
- package/dist/social-providers/naver.mjs.map +1 -1
- package/dist/social-providers/notion.mjs +1 -2
- package/dist/social-providers/notion.mjs.map +1 -1
- package/dist/social-providers/paybin.mjs +1 -2
- package/dist/social-providers/paybin.mjs.map +1 -1
- package/dist/social-providers/paypal.mjs +1 -2
- package/dist/social-providers/paypal.mjs.map +1 -1
- package/dist/social-providers/polar.mjs +1 -2
- package/dist/social-providers/polar.mjs.map +1 -1
- package/dist/social-providers/railway.mjs +1 -2
- package/dist/social-providers/railway.mjs.map +1 -1
- package/dist/social-providers/reddit.mjs +1 -2
- package/dist/social-providers/reddit.mjs.map +1 -1
- package/dist/social-providers/roblox.mjs +1 -2
- package/dist/social-providers/roblox.mjs.map +1 -1
- package/dist/social-providers/salesforce.mjs +1 -2
- package/dist/social-providers/salesforce.mjs.map +1 -1
- package/dist/social-providers/slack.mjs +1 -2
- package/dist/social-providers/slack.mjs.map +1 -1
- package/dist/social-providers/spotify.mjs +1 -2
- package/dist/social-providers/spotify.mjs.map +1 -1
- package/dist/social-providers/tiktok.mjs +1 -2
- package/dist/social-providers/tiktok.mjs.map +1 -1
- package/dist/social-providers/twitch.mjs +1 -2
- package/dist/social-providers/twitch.mjs.map +1 -1
- package/dist/social-providers/twitter.mjs +1 -2
- package/dist/social-providers/twitter.mjs.map +1 -1
- package/dist/social-providers/vercel.mjs +1 -2
- package/dist/social-providers/vercel.mjs.map +1 -1
- package/dist/social-providers/vk.mjs +1 -2
- package/dist/social-providers/vk.mjs.map +1 -1
- package/dist/social-providers/wechat.mjs +1 -2
- package/dist/social-providers/wechat.mjs.map +1 -1
- package/dist/social-providers/zoom.mjs +1 -2
- package/dist/social-providers/zoom.mjs.map +1 -1
- package/dist/types/context.d.mts +1 -3
- package/dist/types/plugin.d.mts +4 -1
- 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 +5 -5
- package/src/api/index.ts +151 -41
- package/src/context/endpoint-context.ts +2 -1
- package/src/types/context.ts +1 -3
- package/src/types/plugin.ts +14 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facebook.mjs","names":[],"sources":["../../src/social-providers/facebook.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { createRemoteJWKSet, decodeJwt, jwtVerify } from \"jose\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\nexport interface FacebookProfile {\n\tid: string;\n\tname: string;\n\temail: string;\n\temail_verified: boolean;\n\tpicture: {\n\t\tdata: {\n\t\t\theight: number;\n\t\t\tis_silhouette: boolean;\n\t\t\turl: string;\n\t\t\twidth: number;\n\t\t};\n\t};\n}\n\nexport interface FacebookOptions extends ProviderOptions<FacebookProfile> {\n\tclientId: string;\n\t/**\n\t * Extend list of fields to retrieve from the Facebook user profile.\n\t *\n\t * @default [\"id\", \"name\", \"email\", \"picture\"]\n\t */\n\tfields?: string[] | undefined;\n\n\t/**\n\t * The config id to use when undergoing oauth\n\t */\n\tconfigId?: string | undefined;\n}\n\nexport const facebook = (options: FacebookOptions) => {\n\treturn {\n\t\tid: \"facebook\",\n\t\tname: \"Facebook\",\n\t\tasync createAuthorizationURL({ state, scopes, redirectURI, loginHint }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"email\", \"public_profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: \"facebook\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.facebook.com/v24.0/dialog/oauth\",\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: options.configId\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tconfig_id: options.configId,\n\t\t\t\t\t\t}\n\t\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: \"https://graph.facebook.com/v24.0/oauth/access_token\",\n\t\t\t});\n\t\t},\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\n\t\t\t/* limited login */\n\t\t\t// check is limited token\n\t\t\tif (token.split(\".\").length === 3) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\tcreateRemoteJWKSet(\n\t\t\t\t\t\t\t// https://developers.facebook.com/docs/facebook-login/limited-login/token/#jwks\n\t\t\t\t\t\t\tnew URL(\n\t\t\t\t\t\t\t\t\"https://limited.facebook.com/.well-known/oauth/openid/jwks/\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\talgorithms: [\"RS256\"],\n\t\t\t\t\t\t\taudience: options.clientId,\n\t\t\t\t\t\t\tissuer: \"https://www.facebook.com\",\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn !!jwtClaims;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* access_token */\n\t\t\treturn true;\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\t\t\"https://graph.facebook.com/v24.0/oauth/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\tif (token.idToken && token.idToken.split(\".\").length === 3) {\n\t\t\t\tconst profile = decodeJwt(token.idToken) as {\n\t\t\t\t\tsub: string;\n\t\t\t\t\temail: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\tpicture: string;\n\t\t\t\t};\n\n\t\t\t\tconst user = {\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\tpicture: {\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\turl: profile.picture,\n\t\t\t\t\t\t\theight: 100,\n\t\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\t\tis_silhouette: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\t// https://developers.facebook.com/docs/facebook-login/limited-login/permissions\n\t\t\t\t// Facebook ID token does not include email_verified claim.\n\t\t\t\t// We default to false for security consistency.\n\t\t\t\tconst userMap = await options.mapProfileToUser?.({\n\t\t\t\t\t...user,\n\t\t\t\t\temail_verified: false,\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\t...user,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst fields = [\n\t\t\t\t\"id\",\n\t\t\t\t\"name\",\n\t\t\t\t\"email\",\n\t\t\t\t\"picture\",\n\t\t\t\t...(options?.fields || []),\n\t\t\t];\n\t\t\tconst { data: profile, error } = await betterFetch<FacebookProfile>(\n\t\t\t\t\"https://graph.facebook.com/me?fields=\" + fields.join(\",\"),\n\t\t\t\t{\n\t\t\t\t\tauth: {\n\t\t\t\t\t\ttype: \"Bearer\",\n\t\t\t\t\t\ttoken: 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\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.email,\n\t\t\t\t\timage: profile.picture.data.url,\n\t\t\t\t\temailVerified: profile.email_verified,\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<FacebookProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"facebook.mjs","names":[],"sources":["../../src/social-providers/facebook.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { createRemoteJWKSet, decodeJwt, jwtVerify } from \"jose\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\nexport interface FacebookProfile {\n\tid: string;\n\tname: string;\n\temail: string;\n\temail_verified: boolean;\n\tpicture: {\n\t\tdata: {\n\t\t\theight: number;\n\t\t\tis_silhouette: boolean;\n\t\t\turl: string;\n\t\t\twidth: number;\n\t\t};\n\t};\n}\n\nexport interface FacebookOptions extends ProviderOptions<FacebookProfile> {\n\tclientId: string;\n\t/**\n\t * Extend list of fields to retrieve from the Facebook user profile.\n\t *\n\t * @default [\"id\", \"name\", \"email\", \"picture\"]\n\t */\n\tfields?: string[] | undefined;\n\n\t/**\n\t * The config id to use when undergoing oauth\n\t */\n\tconfigId?: string | undefined;\n}\n\nexport const facebook = (options: FacebookOptions) => {\n\treturn {\n\t\tid: \"facebook\",\n\t\tname: \"Facebook\",\n\t\tasync createAuthorizationURL({ state, scopes, redirectURI, loginHint }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"email\", \"public_profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: \"facebook\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.facebook.com/v24.0/dialog/oauth\",\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: options.configId\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tconfig_id: options.configId,\n\t\t\t\t\t\t}\n\t\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: \"https://graph.facebook.com/v24.0/oauth/access_token\",\n\t\t\t});\n\t\t},\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\n\t\t\t/* limited login */\n\t\t\t// check is limited token\n\t\t\tif (token.split(\".\").length === 3) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\tcreateRemoteJWKSet(\n\t\t\t\t\t\t\t// https://developers.facebook.com/docs/facebook-login/limited-login/token/#jwks\n\t\t\t\t\t\t\tnew URL(\n\t\t\t\t\t\t\t\t\"https://limited.facebook.com/.well-known/oauth/openid/jwks/\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\talgorithms: [\"RS256\"],\n\t\t\t\t\t\t\taudience: options.clientId,\n\t\t\t\t\t\t\tissuer: \"https://www.facebook.com\",\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn !!jwtClaims;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* access_token */\n\t\t\treturn true;\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\t\t\"https://graph.facebook.com/v24.0/oauth/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\tif (token.idToken && token.idToken.split(\".\").length === 3) {\n\t\t\t\tconst profile = decodeJwt(token.idToken) as {\n\t\t\t\t\tsub: string;\n\t\t\t\t\temail: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\tpicture: string;\n\t\t\t\t};\n\n\t\t\t\tconst user = {\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\tpicture: {\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\turl: profile.picture,\n\t\t\t\t\t\t\theight: 100,\n\t\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\t\tis_silhouette: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\t// https://developers.facebook.com/docs/facebook-login/limited-login/permissions\n\t\t\t\t// Facebook ID token does not include email_verified claim.\n\t\t\t\t// We default to false for security consistency.\n\t\t\t\tconst userMap = await options.mapProfileToUser?.({\n\t\t\t\t\t...user,\n\t\t\t\t\temail_verified: false,\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\t...user,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst fields = [\n\t\t\t\t\"id\",\n\t\t\t\t\"name\",\n\t\t\t\t\"email\",\n\t\t\t\t\"picture\",\n\t\t\t\t...(options?.fields || []),\n\t\t\t];\n\t\t\tconst { data: profile, error } = await betterFetch<FacebookProfile>(\n\t\t\t\t\"https://graph.facebook.com/me?fields=\" + fields.join(\",\"),\n\t\t\t\t{\n\t\t\t\t\tauth: {\n\t\t\t\t\t\ttype: \"Bearer\",\n\t\t\t\t\t\ttoken: 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\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.email,\n\t\t\t\t\timage: profile.picture.data.url,\n\t\t\t\t\temailVerified: profile.email_verified,\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<FacebookProfile>;\n};\n"],"mappings":";;;;;;;AAsCA,MAAa,YAAY,YAA6B;AACrD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,aAAa,aAAa;GACvE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF,CAAC,SAAS,iBAAiB;AAC9B,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,kBAAkB,QAAQ,WACvB,EACA,WAAW,QAAQ,UACnB,GACA,EAAE;IACL,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA,eAAe;IACf,CAAC;;EAEH,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAGR,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;AAK3C,OAAI,MAAM,MAAM,IAAI,CAAC,WAAW,EAC/B,KAAI;IACH,MAAM,EAAE,SAAS,cAAc,MAAM,UACpC,OACA,mBAEC,IAAI,IACH,8DACA,CACD,EACD;KACC,YAAY,CAAC,QAAQ;KACrB,UAAU,QAAQ;KAClB,QAAQ;KACR,CACD;AAED,QAAI,SAAS,UAAU,UAAU,MAChC,QAAO;AAGR,WAAO,CAAC,CAAC;WACF;AACP,WAAO;;AAKT,UAAO;;EAER,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eACC;IACD,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAGlC,OAAI,MAAM,WAAW,MAAM,QAAQ,MAAM,IAAI,CAAC,WAAW,GAAG;IAC3D,MAAM,UAAU,UAAU,MAAM,QAAQ;IAOxC,MAAM,OAAO;KACZ,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,SAAS,EACR,MAAM;MACL,KAAK,QAAQ;MACb,QAAQ;MACR,OAAO;MACP,eAAe;MACf,EACD;KACD;IAKD,MAAM,UAAU,MAAM,QAAQ,mBAAmB;KAChD,GAAG;KACH,gBAAgB;KAChB,CAAC;AAEF,WAAO;KACN,MAAM;MACL,GAAG;MACH,eAAe;MACf,GAAG;MACH;KACD,MAAM;KACN;;GAUF,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,0CARc;IACd;IACA;IACA;IACA;IACA,GAAI,SAAS,UAAU,EAAE;IACzB,CAEiD,KAAK,IAAI,EAC1D,EACC,MAAM;IACL,MAAM;IACN,OAAO,MAAM;IACb,EACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,OAAO,QAAQ,QAAQ,KAAK;KAC5B,eAAe,QAAQ;KACvB,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 { betterFetch } from "@better-fetch/fetch";
|
|
9
|
-
|
|
10
9
|
//#region src/social-providers/figma.ts
|
|
11
10
|
const figma = (options) => {
|
|
12
11
|
const tokenEndpoint = "https://api.figma.com/v1/oauth/token";
|
|
@@ -82,7 +81,7 @@ const figma = (options) => {
|
|
|
82
81
|
options
|
|
83
82
|
};
|
|
84
83
|
};
|
|
85
|
-
|
|
86
84
|
//#endregion
|
|
87
85
|
export { figma };
|
|
86
|
+
|
|
88
87
|
//# sourceMappingURL=figma.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figma.mjs","names":[],"sources":["../../src/social-providers/figma.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 FigmaProfile {\n\tid: string;\n\temail: string;\n\thandle: string;\n\timg_url: string;\n}\n\nexport interface FigmaOptions extends ProviderOptions<FigmaProfile> {\n\tclientId: string;\n}\n\nexport const figma = (options: FigmaOptions) => {\n\tconst tokenEndpoint = \"https://api.figma.com/v1/oauth/token\";\n\treturn {\n\t\tid: \"figma\",\n\t\tname: \"Figma\",\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 Figma. 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 Figma\");\n\t\t\t}\n\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"current_user:read\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"figma\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.figma.com/oauth\",\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\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\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\n\t\t\ttry {\n\t\t\t\tconst { data: profile } = await betterFetch<FigmaProfile>(\n\t\t\t\t\t\"https://api.figma.com/v1/me\",\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 (!profile) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user from Figma\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: profile.id,\n\t\t\t\t\t\tname: profile.handle,\n\t\t\t\t\t\temail: profile.email,\n\t\t\t\t\t\timage: profile.img_url,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from Figma:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<FigmaProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"figma.mjs","names":[],"sources":["../../src/social-providers/figma.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 FigmaProfile {\n\tid: string;\n\temail: string;\n\thandle: string;\n\timg_url: string;\n}\n\nexport interface FigmaOptions extends ProviderOptions<FigmaProfile> {\n\tclientId: string;\n}\n\nexport const figma = (options: FigmaOptions) => {\n\tconst tokenEndpoint = \"https://api.figma.com/v1/oauth/token\";\n\treturn {\n\t\tid: \"figma\",\n\t\tname: \"Figma\",\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 Figma. 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 Figma\");\n\t\t\t}\n\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"current_user:read\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"figma\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.figma.com/oauth\",\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\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\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\n\t\t\ttry {\n\t\t\t\tconst { data: profile } = await betterFetch<FigmaProfile>(\n\t\t\t\t\t\"https://api.figma.com/v1/me\",\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 (!profile) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user from Figma\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: profile.id,\n\t\t\t\t\t\tname: profile.handle,\n\t\t\t\t\t\temail: profile.email,\n\t\t\t\t\t\timage: profile.img_url,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from Figma:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<FigmaProfile>;\n};\n"],"mappings":";;;;;;;;;AAqBA,MAAa,SAAS,YAA0B;CAC/C,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;AAC1E,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MACN,gGACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,qCAAqC;GAGhE,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,oBAAoB;AACxE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAYnC,UAVY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,CAAC;;EAIH,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;AAGlC,OAAI;IACH,MAAM,EAAE,MAAM,YAAY,MAAM,YAC/B,+BACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AAED,QAAI,CAAC,SAAS;AACb,YAAO,MAAM,kCAAkC;AAC/C,YAAO;;IAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAEzD,WAAO;KACN,MAAM;MACL,IAAI,QAAQ;MACZ,MAAM,QAAQ;MACd,OAAO,QAAQ;MACf,OAAO,QAAQ;MACf,eAAe;MACf,GAAG;MACH;KACD,MAAM;KACN;YACO,OAAO;AACf,WAAO,MAAM,yCAAyC,MAAM;AAC5D,WAAO;;;EAGT;EACA"}
|
|
@@ -6,7 +6,6 @@ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
|
6
6
|
import { createAuthorizationCodeRequest } 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/github.ts
|
|
11
10
|
const github = (options) => {
|
|
12
11
|
const tokenEndpoint = "https://github.com/login/oauth/access_token";
|
|
@@ -91,7 +90,7 @@ const github = (options) => {
|
|
|
91
90
|
options
|
|
92
91
|
};
|
|
93
92
|
};
|
|
94
|
-
|
|
95
93
|
//#endregion
|
|
96
94
|
export { github };
|
|
95
|
+
|
|
97
96
|
//# sourceMappingURL=github.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.mjs","names":[],"sources":["../../src/social-providers/github.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tgetOAuth2Tokens,\n\trefreshAccessToken,\n} from \"../oauth2\";\nimport { createAuthorizationCodeRequest } from \"../oauth2/validate-authorization-code\";\n\nexport interface GithubProfile {\n\tlogin: string;\n\tid: string;\n\tnode_id: string;\n\tavatar_url: string;\n\tgravatar_id: string;\n\turl: string;\n\thtml_url: string;\n\tfollowers_url: string;\n\tfollowing_url: string;\n\tgists_url: string;\n\tstarred_url: string;\n\tsubscriptions_url: string;\n\torganizations_url: string;\n\trepos_url: string;\n\tevents_url: string;\n\treceived_events_url: string;\n\ttype: string;\n\tsite_admin: boolean;\n\tname: string;\n\tcompany: string;\n\tblog: string;\n\tlocation: string;\n\temail: string;\n\thireable: boolean;\n\tbio: string;\n\ttwitter_username: string;\n\tpublic_repos: string;\n\tpublic_gists: string;\n\tfollowers: string;\n\tfollowing: string;\n\tcreated_at: string;\n\tupdated_at: string;\n\tprivate_gists: string;\n\ttotal_private_repos: string;\n\towned_private_repos: string;\n\tdisk_usage: string;\n\tcollaborators: string;\n\ttwo_factor_authentication: boolean;\n\tplan: {\n\t\tname: string;\n\t\tspace: string;\n\t\tprivate_repos: string;\n\t\tcollaborators: string;\n\t};\n}\n\nexport interface GithubOptions extends ProviderOptions<GithubProfile> {\n\tclientId: string;\n}\nexport const github = (options: GithubOptions) => {\n\tconst tokenEndpoint = \"https://github.com/login/oauth/access_token\";\n\treturn {\n\t\tid: \"github\",\n\t\tname: \"GitHub\",\n\t\tcreateAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tloginHint,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t}) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"read:user\", \"user: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: \"github\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://github.com/login/oauth/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\tloginHint,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\tconst { body, headers: requestHeaders } = createAuthorizationCodeRequest({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\tconst { data, error } = await betterFetch<\n\t\t\t\t| { access_token: string; token_type: string; scope: string }\n\t\t\t\t| { error: string; error_description?: string; error_uri?: string }\n\t\t\t>(tokenEndpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: body,\n\t\t\t\theaders: requestHeaders,\n\t\t\t});\n\n\t\t\tif (error) {\n\t\t\t\tlogger.error(\"GitHub OAuth token exchange failed:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (\"error\" in data) {\n\t\t\t\tlogger.error(\"GitHub OAuth token exchange failed:\", data);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn getOAuth2Tokens(data);\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<GithubProfile>(\n\t\t\t\t\"https://api.github.com/user\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": \"better-auth\",\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 { data: emails } = await betterFetch<\n\t\t\t\t{\n\t\t\t\t\temail: string;\n\t\t\t\t\tprimary: boolean;\n\t\t\t\t\tverified: boolean;\n\t\t\t\t\tvisibility: \"public\" | \"private\";\n\t\t\t\t}[]\n\t\t\t>(\"https://api.github.com/user/emails\", {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\"User-Agent\": \"better-auth\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!profile.email && emails) {\n\t\t\t\tprofile.email = (emails.find((e) => e.primary) ?? emails[0])\n\t\t\t\t\t?.email as string;\n\t\t\t}\n\t\t\tconst emailVerified =\n\t\t\t\temails?.find((e) => e.email === profile.email)?.verified ?? false;\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.id,\n\t\t\t\t\tname: profile.name || profile.login || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.avatar_url,\n\t\t\t\t\temailVerified,\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<GithubProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"github.mjs","names":[],"sources":["../../src/social-providers/github.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tgetOAuth2Tokens,\n\trefreshAccessToken,\n} from \"../oauth2\";\nimport { createAuthorizationCodeRequest } from \"../oauth2/validate-authorization-code\";\n\nexport interface GithubProfile {\n\tlogin: string;\n\tid: string;\n\tnode_id: string;\n\tavatar_url: string;\n\tgravatar_id: string;\n\turl: string;\n\thtml_url: string;\n\tfollowers_url: string;\n\tfollowing_url: string;\n\tgists_url: string;\n\tstarred_url: string;\n\tsubscriptions_url: string;\n\torganizations_url: string;\n\trepos_url: string;\n\tevents_url: string;\n\treceived_events_url: string;\n\ttype: string;\n\tsite_admin: boolean;\n\tname: string;\n\tcompany: string;\n\tblog: string;\n\tlocation: string;\n\temail: string;\n\thireable: boolean;\n\tbio: string;\n\ttwitter_username: string;\n\tpublic_repos: string;\n\tpublic_gists: string;\n\tfollowers: string;\n\tfollowing: string;\n\tcreated_at: string;\n\tupdated_at: string;\n\tprivate_gists: string;\n\ttotal_private_repos: string;\n\towned_private_repos: string;\n\tdisk_usage: string;\n\tcollaborators: string;\n\ttwo_factor_authentication: boolean;\n\tplan: {\n\t\tname: string;\n\t\tspace: string;\n\t\tprivate_repos: string;\n\t\tcollaborators: string;\n\t};\n}\n\nexport interface GithubOptions extends ProviderOptions<GithubProfile> {\n\tclientId: string;\n}\nexport const github = (options: GithubOptions) => {\n\tconst tokenEndpoint = \"https://github.com/login/oauth/access_token\";\n\treturn {\n\t\tid: \"github\",\n\t\tname: \"GitHub\",\n\t\tcreateAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tloginHint,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t}) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"read:user\", \"user: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: \"github\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://github.com/login/oauth/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\tloginHint,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\tconst { body, headers: requestHeaders } = createAuthorizationCodeRequest({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\tconst { data, error } = await betterFetch<\n\t\t\t\t| { access_token: string; token_type: string; scope: string }\n\t\t\t\t| { error: string; error_description?: string; error_uri?: string }\n\t\t\t>(tokenEndpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: body,\n\t\t\t\theaders: requestHeaders,\n\t\t\t});\n\n\t\t\tif (error) {\n\t\t\t\tlogger.error(\"GitHub OAuth token exchange failed:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (\"error\" in data) {\n\t\t\t\tlogger.error(\"GitHub OAuth token exchange failed:\", data);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn getOAuth2Tokens(data);\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<GithubProfile>(\n\t\t\t\t\"https://api.github.com/user\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": \"better-auth\",\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 { data: emails } = await betterFetch<\n\t\t\t\t{\n\t\t\t\t\temail: string;\n\t\t\t\t\tprimary: boolean;\n\t\t\t\t\tverified: boolean;\n\t\t\t\t\tvisibility: \"public\" | \"private\";\n\t\t\t\t}[]\n\t\t\t>(\"https://api.github.com/user/emails\", {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\"User-Agent\": \"better-auth\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!profile.email && emails) {\n\t\t\t\tprofile.email = (emails.find((e) => e.primary) ?? emails[0])\n\t\t\t\t\t?.email as string;\n\t\t\t}\n\t\t\tconst emailVerified =\n\t\t\t\temails?.find((e) => e.email === profile.email)?.verified ?? false;\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.id,\n\t\t\t\t\tname: profile.name || profile.login || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.avatar_url,\n\t\t\t\t\temailVerified,\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<GithubProfile>;\n};\n"],"mappings":";;;;;;;;;AA4DA,MAAa,UAAU,YAA2B;CACjD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EACtB,OACA,QACA,WACA,cACA,eACE;GACF,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF,CAAC,aAAa,aAAa;AAC9B,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;IACA,QAAQ,QAAQ;IAChB,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;GACzE,MAAM,EAAE,MAAM,SAAS,mBAAmB,+BAA+B;IACxE;IACA;IACA;IACA;IACA,CAAC;GAEF,MAAM,EAAE,MAAM,UAAU,MAAM,YAG5B,eAAe;IAChB,QAAQ;IACF;IACN,SAAS;IACT,CAAC;AAEF,OAAI,OAAO;AACV,WAAO,MAAM,uCAAuC,MAAM;AAC1D,WAAO;;AAGR,OAAI,WAAW,MAAM;AACpB,WAAO,MAAM,uCAAuC,KAAK;AACzD,WAAO;;AAGR,UAAO,gBAAgB,KAAK;;EAE7B,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,+BACA,EACC,SAAS;IACR,cAAc;IACd,eAAe,UAAU,MAAM;IAC/B,EACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,EAAE,MAAM,WAAW,MAAM,YAO7B,sCAAsC,EACvC,SAAS;IACR,eAAe,UAAU,MAAM;IAC/B,cAAc;IACd,EACD,CAAC;AAEF,OAAI,CAAC,QAAQ,SAAS,OACrB,SAAQ,SAAS,OAAO,MAAM,MAAM,EAAE,QAAQ,IAAI,OAAO,KACtD;GAEJ,MAAM,gBACL,QAAQ,MAAM,MAAM,EAAE,UAAU,QAAQ,MAAM,EAAE,YAAY;GAE7D,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ,QAAQ,SAAS;KACvC,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf;KACA,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/gitlab.ts
|
|
8
7
|
const cleanDoubleSlashes = (input = "") => {
|
|
9
8
|
return input.split("://").map((str) => str.replace(/\/{2,}/g, "/")).join("://");
|
|
@@ -77,7 +76,7 @@ const gitlab = (options) => {
|
|
|
77
76
|
options
|
|
78
77
|
};
|
|
79
78
|
};
|
|
80
|
-
|
|
81
79
|
//#endregion
|
|
82
80
|
export { gitlab };
|
|
81
|
+
|
|
83
82
|
//# sourceMappingURL=gitlab.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlab.mjs","names":[],"sources":["../../src/social-providers/gitlab.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 GitlabProfile extends Record<string, any> {\n\tid: number;\n\tusername: string;\n\temail: string;\n\tname: string;\n\tstate: string;\n\tavatar_url: string;\n\tweb_url: string;\n\tcreated_at: string;\n\tbio: string;\n\tlocation?: string | undefined;\n\tpublic_email: string;\n\tskype: string;\n\tlinkedin: string;\n\ttwitter: string;\n\twebsite_url: string;\n\torganization: string;\n\tjob_title: string;\n\tpronouns: string;\n\tbot: boolean;\n\twork_information?: string | undefined;\n\tfollowers: number;\n\tfollowing: number;\n\tlocal_time: string;\n\tlast_sign_in_at: string;\n\tconfirmed_at: string;\n\ttheme_id: number;\n\tlast_activity_on: string;\n\tcolor_scheme_id: number;\n\tprojects_limit: number;\n\tcurrent_sign_in_at: string;\n\tidentities: Array<{\n\t\tprovider: string;\n\t\textern_uid: string;\n\t}>;\n\tcan_create_group: boolean;\n\tcan_create_project: boolean;\n\ttwo_factor_enabled: boolean;\n\texternal: boolean;\n\tprivate_profile: boolean;\n\tcommit_email: string;\n\tshared_runners_minutes_limit: number;\n\textra_shared_runners_minutes_limit: number;\n\temail_verified?: boolean | undefined;\n}\n\nexport interface GitlabOptions extends ProviderOptions<GitlabProfile> {\n\tclientId: string;\n\tissuer?: string | undefined;\n}\n\nconst cleanDoubleSlashes = (input: string = \"\") => {\n\treturn input\n\t\t.split(\"://\")\n\t\t.map((str) => str.replace(/\\/{2,}/g, \"/\"))\n\t\t.join(\"://\");\n};\n\nconst issuerToEndpoints = (issuer?: string | undefined) => {\n\tconst baseUrl = issuer || \"https://gitlab.com\";\n\treturn {\n\t\tauthorizationEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/authorize`),\n\t\ttokenEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/token`),\n\t\tuserinfoEndpoint: cleanDoubleSlashes(`${baseUrl}/api/v4/user`),\n\t};\n};\n\nexport const gitlab = (options: GitlabOptions) => {\n\tconst { authorizationEndpoint, tokenEndpoint, userinfoEndpoint } =\n\t\tissuerToEndpoints(options.issuer);\n\tconst issuerId = \"gitlab\";\n\tconst issuerName = \"Gitlab\";\n\treturn {\n\t\tid: issuerId,\n\t\tname: issuerName,\n\t\tcreateAuthorizationURL: async ({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tloginHint,\n\t\t\tredirectURI,\n\t\t}) => {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"read_user\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: issuerId,\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\tredirectURI,\n\t\t\t\tcodeVerifier,\n\t\t\t\tloginHint,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\tcodeVerifier,\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: tokenEndpoint,\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<GitlabProfile>(\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.state !== \"active\" || profile.locked) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// GitLab 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.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<GitlabProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"gitlab.mjs","names":[],"sources":["../../src/social-providers/gitlab.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 GitlabProfile extends Record<string, any> {\n\tid: number;\n\tusername: string;\n\temail: string;\n\tname: string;\n\tstate: string;\n\tavatar_url: string;\n\tweb_url: string;\n\tcreated_at: string;\n\tbio: string;\n\tlocation?: string | undefined;\n\tpublic_email: string;\n\tskype: string;\n\tlinkedin: string;\n\ttwitter: string;\n\twebsite_url: string;\n\torganization: string;\n\tjob_title: string;\n\tpronouns: string;\n\tbot: boolean;\n\twork_information?: string | undefined;\n\tfollowers: number;\n\tfollowing: number;\n\tlocal_time: string;\n\tlast_sign_in_at: string;\n\tconfirmed_at: string;\n\ttheme_id: number;\n\tlast_activity_on: string;\n\tcolor_scheme_id: number;\n\tprojects_limit: number;\n\tcurrent_sign_in_at: string;\n\tidentities: Array<{\n\t\tprovider: string;\n\t\textern_uid: string;\n\t}>;\n\tcan_create_group: boolean;\n\tcan_create_project: boolean;\n\ttwo_factor_enabled: boolean;\n\texternal: boolean;\n\tprivate_profile: boolean;\n\tcommit_email: string;\n\tshared_runners_minutes_limit: number;\n\textra_shared_runners_minutes_limit: number;\n\temail_verified?: boolean | undefined;\n}\n\nexport interface GitlabOptions extends ProviderOptions<GitlabProfile> {\n\tclientId: string;\n\tissuer?: string | undefined;\n}\n\nconst cleanDoubleSlashes = (input: string = \"\") => {\n\treturn input\n\t\t.split(\"://\")\n\t\t.map((str) => str.replace(/\\/{2,}/g, \"/\"))\n\t\t.join(\"://\");\n};\n\nconst issuerToEndpoints = (issuer?: string | undefined) => {\n\tconst baseUrl = issuer || \"https://gitlab.com\";\n\treturn {\n\t\tauthorizationEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/authorize`),\n\t\ttokenEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/token`),\n\t\tuserinfoEndpoint: cleanDoubleSlashes(`${baseUrl}/api/v4/user`),\n\t};\n};\n\nexport const gitlab = (options: GitlabOptions) => {\n\tconst { authorizationEndpoint, tokenEndpoint, userinfoEndpoint } =\n\t\tissuerToEndpoints(options.issuer);\n\tconst issuerId = \"gitlab\";\n\tconst issuerName = \"Gitlab\";\n\treturn {\n\t\tid: issuerId,\n\t\tname: issuerName,\n\t\tcreateAuthorizationURL: async ({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tloginHint,\n\t\t\tredirectURI,\n\t\t}) => {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"read_user\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: issuerId,\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\tredirectURI,\n\t\t\t\tcodeVerifier,\n\t\t\t\tloginHint,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\tcodeVerifier,\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: tokenEndpoint,\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<GitlabProfile>(\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.state !== \"active\" || profile.locked) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// GitLab 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.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<GitlabProfile>;\n};\n"],"mappings":";;;;;;AA2DA,MAAM,sBAAsB,QAAgB,OAAO;AAClD,QAAO,MACL,MAAM,MAAM,CACZ,KAAK,QAAQ,IAAI,QAAQ,WAAW,IAAI,CAAC,CACzC,KAAK,MAAM;;AAGd,MAAM,qBAAqB,WAAgC;CAC1D,MAAM,UAAU,UAAU;AAC1B,QAAO;EACN,uBAAuB,mBAAmB,GAAG,QAAQ,kBAAkB;EACvE,eAAe,mBAAmB,GAAG,QAAQ,cAAc;EAC3D,kBAAkB,mBAAmB,GAAG,QAAQ,cAAc;EAC9D;;AAGF,MAAa,UAAU,YAA2B;CACjD,MAAM,EAAE,uBAAuB,eAAe,qBAC7C,kBAAkB,QAAQ,OAAO;CAClC,MAAM,WAAW;AAEjB,QAAO;EACN,IAAI;EACJ,MAHkB;EAIlB,wBAAwB,OAAO,EAC9B,OACA,QACA,cACA,WACA,kBACK;GACL,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,YAAY;AAChE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,aAAa,mBAAmB;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;IACc;IACf,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,QAAQ,UAAU,YAAY,QAAQ,OAClD,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAGzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ,QAAQ,YAAY;KAC1C,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -7,7 +7,6 @@ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code
|
|
|
7
7
|
import "../oauth2/index.mjs";
|
|
8
8
|
import { betterFetch } from "@better-fetch/fetch";
|
|
9
9
|
import { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from "jose";
|
|
10
|
-
|
|
11
10
|
//#region src/social-providers/google.ts
|
|
12
11
|
const google = (options) => {
|
|
13
12
|
return {
|
|
@@ -107,7 +106,7 @@ const getGooglePublicKey = async (kid) => {
|
|
|
107
106
|
if (!jwk) throw new Error(`JWK with kid ${kid} not found`);
|
|
108
107
|
return await importJWK(jwk, jwk.alg);
|
|
109
108
|
};
|
|
110
|
-
|
|
111
109
|
//#endregion
|
|
112
110
|
export { getGooglePublicKey, google };
|
|
111
|
+
|
|
113
112
|
//# sourceMappingURL=google.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.mjs","names":[],"sources":["../../src/social-providers/google.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from \"jose\";\nimport { logger } from \"../env\";\nimport { APIError, BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface GoogleProfile {\n\taud: string;\n\tazp: string;\n\temail: string;\n\temail_verified: boolean;\n\texp: number;\n\t/**\n\t * The family name of the user, or last name in most\n\t * Western languages.\n\t */\n\tfamily_name: string;\n\t/**\n\t * The given name of the user, or first name in most\n\t * Western languages.\n\t */\n\tgiven_name: string;\n\thd?: string | undefined;\n\tiat: number;\n\tiss: string;\n\tjti?: string | undefined;\n\tlocale?: string | undefined;\n\tname: string;\n\tnbf?: number | undefined;\n\tpicture: string;\n\tsub: string;\n}\n\nexport interface GoogleOptions extends ProviderOptions<GoogleProfile> {\n\tclientId: string;\n\t/**\n\t * The access type to use for the authorization code request\n\t */\n\taccessType?: (\"offline\" | \"online\") | undefined;\n\t/**\n\t * The display mode to use for the authorization code request\n\t */\n\tdisplay?: (\"page\" | \"popup\" | \"touch\" | \"wap\") | undefined;\n\t/**\n\t * The hosted domain of the user\n\t */\n\thd?: string | undefined;\n}\n\nexport const google = (options: GoogleOptions) => {\n\treturn {\n\t\tid: \"google\",\n\t\tname: \"Google\",\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\tdisplay,\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 Google. 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 Google\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"email\", \"profile\", \"openid\"];\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: \"google\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://accounts.google.com/o/oauth2/v2/auth\",\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\taccessType: options.accessType,\n\t\t\t\tdisplay: display || options.display,\n\t\t\t\tloginHint,\n\t\t\t\thd: options.hd,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\tinclude_granted_scopes: \"true\",\n\t\t\t\t},\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: \"https://oauth2.googleapis.com/token\",\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: \"https://oauth2.googleapis.com/token\",\n\t\t\t\t\t});\n\t\t\t\t},\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\n\t\t\t// Verify JWT integrity\n\t\t\t// See https://developers.google.com/identity/sign-in/web/backend-auth#verify-the-integrity-of-the-id-token\n\n\t\t\ttry {\n\t\t\t\tconst { kid, alg: jwtAlg } = decodeProtectedHeader(token);\n\t\t\t\tif (!kid || !jwtAlg) return false;\n\n\t\t\t\tconst publicKey = await getGooglePublicKey(kid);\n\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(token, publicKey, {\n\t\t\t\t\talgorithms: [jwtAlg],\n\t\t\t\t\tissuer: [\"https://accounts.google.com\", \"accounts.google.com\"],\n\t\t\t\t\taudience: options.clientId,\n\t\t\t\t\tmaxTokenAge: \"1h\",\n\t\t\t\t});\n\n\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\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 GoogleProfile;\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,\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,\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<GoogleProfile>;\n};\n\nexport const getGooglePublicKey = async (kid: string) => {\n\tconst { data } = await betterFetch<{\n\t\tkeys: Array<{\n\t\t\tkid: string;\n\t\t\talg: string;\n\t\t\tkty: string;\n\t\t\tuse: string;\n\t\t\tn: string;\n\t\t\te: string;\n\t\t}>;\n\t}>(\"https://www.googleapis.com/oauth2/v3/certs\");\n\n\tif (!data?.keys) {\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"Keys not found\",\n\t\t});\n\t}\n\n\tconst jwk = data.keys.find((key) => key.kid === kid);\n\tif (!jwk) {\n\t\tthrow new Error(`JWK with kid ${kid} not found`);\n\t}\n\n\treturn await importJWK(jwk, jwk.alg);\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"google.mjs","names":[],"sources":["../../src/social-providers/google.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from \"jose\";\nimport { logger } from \"../env\";\nimport { APIError, BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface GoogleProfile {\n\taud: string;\n\tazp: string;\n\temail: string;\n\temail_verified: boolean;\n\texp: number;\n\t/**\n\t * The family name of the user, or last name in most\n\t * Western languages.\n\t */\n\tfamily_name: string;\n\t/**\n\t * The given name of the user, or first name in most\n\t * Western languages.\n\t */\n\tgiven_name: string;\n\thd?: string | undefined;\n\tiat: number;\n\tiss: string;\n\tjti?: string | undefined;\n\tlocale?: string | undefined;\n\tname: string;\n\tnbf?: number | undefined;\n\tpicture: string;\n\tsub: string;\n}\n\nexport interface GoogleOptions extends ProviderOptions<GoogleProfile> {\n\tclientId: string;\n\t/**\n\t * The access type to use for the authorization code request\n\t */\n\taccessType?: (\"offline\" | \"online\") | undefined;\n\t/**\n\t * The display mode to use for the authorization code request\n\t */\n\tdisplay?: (\"page\" | \"popup\" | \"touch\" | \"wap\") | undefined;\n\t/**\n\t * The hosted domain of the user\n\t */\n\thd?: string | undefined;\n}\n\nexport const google = (options: GoogleOptions) => {\n\treturn {\n\t\tid: \"google\",\n\t\tname: \"Google\",\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\tdisplay,\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 Google. 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 Google\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"email\", \"profile\", \"openid\"];\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: \"google\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://accounts.google.com/o/oauth2/v2/auth\",\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\taccessType: options.accessType,\n\t\t\t\tdisplay: display || options.display,\n\t\t\t\tloginHint,\n\t\t\t\thd: options.hd,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\tinclude_granted_scopes: \"true\",\n\t\t\t\t},\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: \"https://oauth2.googleapis.com/token\",\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: \"https://oauth2.googleapis.com/token\",\n\t\t\t\t\t});\n\t\t\t\t},\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\n\t\t\t// Verify JWT integrity\n\t\t\t// See https://developers.google.com/identity/sign-in/web/backend-auth#verify-the-integrity-of-the-id-token\n\n\t\t\ttry {\n\t\t\t\tconst { kid, alg: jwtAlg } = decodeProtectedHeader(token);\n\t\t\t\tif (!kid || !jwtAlg) return false;\n\n\t\t\t\tconst publicKey = await getGooglePublicKey(kid);\n\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(token, publicKey, {\n\t\t\t\t\talgorithms: [jwtAlg],\n\t\t\t\t\tissuer: [\"https://accounts.google.com\", \"accounts.google.com\"],\n\t\t\t\t\taudience: options.clientId,\n\t\t\t\t\tmaxTokenAge: \"1h\",\n\t\t\t\t});\n\n\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\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 GoogleProfile;\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,\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,\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<GoogleProfile>;\n};\n\nexport const getGooglePublicKey = async (kid: string) => {\n\tconst { data } = await betterFetch<{\n\t\tkeys: Array<{\n\t\t\tkid: string;\n\t\t\talg: string;\n\t\t\tkty: string;\n\t\t\tuse: string;\n\t\t\tn: string;\n\t\t\te: string;\n\t\t}>;\n\t}>(\"https://www.googleapis.com/oauth2/v3/certs\");\n\n\tif (!data?.keys) {\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"Keys not found\",\n\t\t});\n\t}\n\n\tconst jwk = data.keys.find((key) => key.kid === kid);\n\tif (!jwk) {\n\t\tthrow new Error(`JWK with kid ${kid} not found`);\n\t}\n\n\treturn await importJWK(jwk, jwk.alg);\n};\n"],"mappings":";;;;;;;;;;AAsDA,MAAa,UAAU,YAA2B;AACjD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAC5B,OACA,QACA,cACA,aACA,WACA,WACE;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;IAAS;IAAW;IAAS;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAkBnC,UAjBY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,QAAQ,QAAQ;IAChB,YAAY,QAAQ;IACpB,SAAS,WAAW,QAAQ;IAC5B;IACA,IAAI,QAAQ;IACZ,kBAAkB,EACjB,wBAAwB,QACxB;IACD,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,eAAe;IACf,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,eAAe;IACf,CAAC;;EAEL,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAER,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;AAM3C,OAAI;IACH,MAAM,EAAE,KAAK,KAAK,WAAW,sBAAsB,MAAM;AACzD,QAAI,CAAC,OAAO,CAAC,OAAQ,QAAO;IAG5B,MAAM,EAAE,SAAS,cAAc,MAAM,UAAU,OAD7B,MAAM,mBAAmB,IAAI,EACkB;KAChE,YAAY,CAAC,OAAO;KACpB,QAAQ,CAAC,+BAA+B,sBAAsB;KAC9D,UAAU,QAAQ;KAClB,aAAa;KACb,CAAC;AAEF,QAAI,SAAS,UAAU,UAAU,MAChC,QAAO;AAGR,WAAO;WACA;AACP,WAAO;;;EAGT,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;KACX,OAAO,KAAK;KACZ,OAAO,KAAK;KACZ,eAAe,KAAK;KACpB,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA;;AAGF,MAAa,qBAAqB,OAAO,QAAgB;CACxD,MAAM,EAAE,SAAS,MAAM,YASpB,6CAA6C;AAEhD,KAAI,CAAC,MAAM,KACV,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,kBACT,CAAC;CAGH,MAAM,MAAM,KAAK,KAAK,MAAM,QAAQ,IAAI,QAAQ,IAAI;AACpD,KAAI,CAAC,IACJ,OAAM,IAAI,MAAM,gBAAgB,IAAI,YAAY;AAGjD,QAAO,MAAM,UAAU,KAAK,IAAI,IAAI"}
|
|
@@ -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/huggingface.ts
|
|
8
7
|
const huggingface = (options) => {
|
|
9
8
|
const tokenEndpoint = "https://huggingface.co/oauth/token";
|
|
@@ -71,7 +70,7 @@ const huggingface = (options) => {
|
|
|
71
70
|
options
|
|
72
71
|
};
|
|
73
72
|
};
|
|
74
|
-
|
|
75
73
|
//#endregion
|
|
76
74
|
export { huggingface };
|
|
75
|
+
|
|
77
76
|
//# sourceMappingURL=huggingface.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"huggingface.mjs","names":[],"sources":["../../src/social-providers/huggingface.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 HuggingFaceProfile {\n\tsub: string;\n\tname: string;\n\tpreferred_username: string;\n\tprofile: string;\n\tpicture: string;\n\twebsite?: string | undefined;\n\temail?: string | undefined;\n\temail_verified?: boolean | undefined;\n\tisPro: boolean;\n\tcanPay?: boolean | undefined;\n\torgs?:\n\t\t| {\n\t\t\t\tsub: string;\n\t\t\t\tname: string;\n\t\t\t\tpicture: string;\n\t\t\t\tpreferred_username: string;\n\t\t\t\tisEnterprise: boolean | \"plus\";\n\t\t\t\tcanPay?: boolean;\n\t\t\t\troleInOrg?: \"admin\" | \"write\" | \"contributor\" | \"read\";\n\t\t\t\tpendingSSO?: boolean;\n\t\t\t\tmissingMFA?: boolean;\n\t\t\t\tresourceGroups?: {\n\t\t\t\t\tsub: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\trole: \"admin\" | \"write\" | \"contributor\" | \"read\";\n\t\t\t\t}[];\n\t\t }\n\t\t| undefined;\n}\n\nexport interface HuggingFaceOptions\n\textends ProviderOptions<HuggingFaceProfile> {\n\tclientId: string;\n}\n\nexport const huggingface = (options: HuggingFaceOptions) => {\n\tconst tokenEndpoint = \"https://huggingface.co/oauth/token\";\n\treturn {\n\t\tid: \"huggingface\",\n\t\tname: \"Hugging Face\",\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: \"huggingface\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://huggingface.co/oauth/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});\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<HuggingFaceProfile>(\n\t\t\t\t\"https://huggingface.co/oauth/userinfo\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\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\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.name || profile.preferred_username || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.picture,\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<HuggingFaceProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"huggingface.mjs","names":[],"sources":["../../src/social-providers/huggingface.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 HuggingFaceProfile {\n\tsub: string;\n\tname: string;\n\tpreferred_username: string;\n\tprofile: string;\n\tpicture: string;\n\twebsite?: string | undefined;\n\temail?: string | undefined;\n\temail_verified?: boolean | undefined;\n\tisPro: boolean;\n\tcanPay?: boolean | undefined;\n\torgs?:\n\t\t| {\n\t\t\t\tsub: string;\n\t\t\t\tname: string;\n\t\t\t\tpicture: string;\n\t\t\t\tpreferred_username: string;\n\t\t\t\tisEnterprise: boolean | \"plus\";\n\t\t\t\tcanPay?: boolean;\n\t\t\t\troleInOrg?: \"admin\" | \"write\" | \"contributor\" | \"read\";\n\t\t\t\tpendingSSO?: boolean;\n\t\t\t\tmissingMFA?: boolean;\n\t\t\t\tresourceGroups?: {\n\t\t\t\t\tsub: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\trole: \"admin\" | \"write\" | \"contributor\" | \"read\";\n\t\t\t\t}[];\n\t\t }\n\t\t| undefined;\n}\n\nexport interface HuggingFaceOptions\n\textends ProviderOptions<HuggingFaceProfile> {\n\tclientId: string;\n}\n\nexport const huggingface = (options: HuggingFaceOptions) => {\n\tconst tokenEndpoint = \"https://huggingface.co/oauth/token\";\n\treturn {\n\t\tid: \"huggingface\",\n\t\tname: \"Hugging Face\",\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: \"huggingface\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://huggingface.co/oauth/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});\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<HuggingFaceProfile>(\n\t\t\t\t\"https://huggingface.co/oauth/userinfo\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\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\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.name || profile.preferred_username || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.picture,\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<HuggingFaceProfile>;\n};\n"],"mappings":";;;;;;AA4CA,MAAa,eAAe,YAAgC;CAC3D,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,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,yCACA;IACC,QAAQ;IACR,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B;IACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ,QAAQ,sBAAsB;KACpD,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -34,7 +34,6 @@ import { vk } from "./vk.mjs";
|
|
|
34
34
|
import { wechat } from "./wechat.mjs";
|
|
35
35
|
import { zoom } from "./zoom.mjs";
|
|
36
36
|
import * as z from "zod";
|
|
37
|
-
|
|
38
37
|
//#region src/social-providers/index.ts
|
|
39
38
|
const socialProviders = {
|
|
40
39
|
apple,
|
|
@@ -75,7 +74,7 @@ const socialProviders = {
|
|
|
75
74
|
};
|
|
76
75
|
const socialProviderList = Object.keys(socialProviders);
|
|
77
76
|
const SocialProviderListEnum = z.enum(socialProviderList).or(z.string());
|
|
78
|
-
|
|
79
77
|
//#endregion
|
|
80
78
|
export { SocialProviderListEnum, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, getGooglePublicKey, getMicrosoftPublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, railway, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vercel, vk, wechat, zoom };
|
|
79
|
+
|
|
81
80
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/social-providers/index.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { AwaitableFunction } from \"../types\";\nimport { apple } from \"./apple\";\nimport { atlassian } from \"./atlassian\";\nimport { cognito } from \"./cognito\";\nimport { discord } from \"./discord\";\nimport { dropbox } from \"./dropbox\";\nimport { facebook } from \"./facebook\";\nimport { figma } from \"./figma\";\nimport { github } from \"./github\";\nimport { gitlab } from \"./gitlab\";\nimport { google } from \"./google\";\nimport { huggingface } from \"./huggingface\";\nimport { kakao } from \"./kakao\";\nimport { kick } from \"./kick\";\nimport { line } from \"./line\";\nimport { linear } from \"./linear\";\nimport { linkedin } from \"./linkedin\";\nimport { microsoft } from \"./microsoft-entra-id\";\nimport { naver } from \"./naver\";\nimport { notion } from \"./notion\";\nimport { paybin } from \"./paybin\";\nimport { paypal } from \"./paypal\";\nimport { polar } from \"./polar\";\nimport { railway } from \"./railway\";\nimport { reddit } from \"./reddit\";\nimport { roblox } from \"./roblox\";\nimport { salesforce } from \"./salesforce\";\nimport { slack } from \"./slack\";\nimport { spotify } from \"./spotify\";\nimport { tiktok } from \"./tiktok\";\nimport { twitch } from \"./twitch\";\nimport { twitter } from \"./twitter\";\nimport { vercel } from \"./vercel\";\nimport { vk } from \"./vk\";\nimport { wechat } from \"./wechat\";\nimport { zoom } from \"./zoom\";\n\nexport const socialProviders = {\n\tapple,\n\tatlassian,\n\tcognito,\n\tdiscord,\n\tfacebook,\n\tfigma,\n\tgithub,\n\tmicrosoft,\n\tgoogle,\n\thuggingface,\n\tslack,\n\tspotify,\n\ttwitch,\n\ttwitter,\n\tdropbox,\n\tkick,\n\tlinear,\n\tlinkedin,\n\tgitlab,\n\ttiktok,\n\treddit,\n\troblox,\n\tsalesforce,\n\tvk,\n\tzoom,\n\tnotion,\n\tkakao,\n\tnaver,\n\tline,\n\tpaybin,\n\tpaypal,\n\tpolar,\n\trailway,\n\tvercel,\n\twechat,\n};\n\nexport const socialProviderList = Object.keys(socialProviders) as [\n\t\"github\",\n\t...(keyof typeof socialProviders)[],\n];\n\nexport const SocialProviderListEnum = z\n\t.enum(socialProviderList)\n\t.or(z.string()) as z.ZodType<SocialProviderList[number] | (string & {})>;\n\nexport type SocialProvider = z.infer<typeof SocialProviderListEnum>;\n\nexport type SocialProviders = {\n\t[K in SocialProviderList[number]]?: AwaitableFunction<\n\t\tParameters<(typeof socialProviders)[K]>[0] & {\n\t\t\tenabled?: boolean | undefined;\n\t\t}\n\t>;\n};\n\nexport * from \"./apple\";\nexport * from \"./atlassian\";\nexport * from \"./cognito\";\nexport * from \"./discord\";\nexport * from \"./dropbox\";\nexport * from \"./facebook\";\nexport * from \"./figma\";\nexport * from \"./github\";\nexport * from \"./gitlab\";\nexport * from \"./google\";\nexport * from \"./huggingface\";\nexport * from \"./kakao\";\nexport * from \"./kick\";\nexport * from \"./kick\";\nexport * from \"./line\";\nexport * from \"./linear\";\nexport * from \"./linkedin\";\nexport * from \"./linkedin\";\nexport * from \"./microsoft-entra-id\";\nexport * from \"./naver\";\nexport * from \"./notion\";\nexport * from \"./paybin\";\nexport * from \"./paypal\";\nexport * from \"./polar\";\nexport * from \"./railway\";\nexport * from \"./reddit\";\nexport * from \"./roblox\";\nexport * from \"./salesforce\";\nexport * from \"./slack\";\nexport * from \"./spotify\";\nexport * from \"./tiktok\";\nexport * from \"./twitch\";\nexport * from \"./twitter\";\nexport * from \"./vercel\";\nexport * from \"./vk\";\nexport * from \"./wechat\";\nexport * from \"./zoom\";\n\nexport type SocialProviderList = typeof socialProviderList;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/social-providers/index.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { AwaitableFunction } from \"../types\";\nimport { apple } from \"./apple\";\nimport { atlassian } from \"./atlassian\";\nimport { cognito } from \"./cognito\";\nimport { discord } from \"./discord\";\nimport { dropbox } from \"./dropbox\";\nimport { facebook } from \"./facebook\";\nimport { figma } from \"./figma\";\nimport { github } from \"./github\";\nimport { gitlab } from \"./gitlab\";\nimport { google } from \"./google\";\nimport { huggingface } from \"./huggingface\";\nimport { kakao } from \"./kakao\";\nimport { kick } from \"./kick\";\nimport { line } from \"./line\";\nimport { linear } from \"./linear\";\nimport { linkedin } from \"./linkedin\";\nimport { microsoft } from \"./microsoft-entra-id\";\nimport { naver } from \"./naver\";\nimport { notion } from \"./notion\";\nimport { paybin } from \"./paybin\";\nimport { paypal } from \"./paypal\";\nimport { polar } from \"./polar\";\nimport { railway } from \"./railway\";\nimport { reddit } from \"./reddit\";\nimport { roblox } from \"./roblox\";\nimport { salesforce } from \"./salesforce\";\nimport { slack } from \"./slack\";\nimport { spotify } from \"./spotify\";\nimport { tiktok } from \"./tiktok\";\nimport { twitch } from \"./twitch\";\nimport { twitter } from \"./twitter\";\nimport { vercel } from \"./vercel\";\nimport { vk } from \"./vk\";\nimport { wechat } from \"./wechat\";\nimport { zoom } from \"./zoom\";\n\nexport const socialProviders = {\n\tapple,\n\tatlassian,\n\tcognito,\n\tdiscord,\n\tfacebook,\n\tfigma,\n\tgithub,\n\tmicrosoft,\n\tgoogle,\n\thuggingface,\n\tslack,\n\tspotify,\n\ttwitch,\n\ttwitter,\n\tdropbox,\n\tkick,\n\tlinear,\n\tlinkedin,\n\tgitlab,\n\ttiktok,\n\treddit,\n\troblox,\n\tsalesforce,\n\tvk,\n\tzoom,\n\tnotion,\n\tkakao,\n\tnaver,\n\tline,\n\tpaybin,\n\tpaypal,\n\tpolar,\n\trailway,\n\tvercel,\n\twechat,\n};\n\nexport const socialProviderList = Object.keys(socialProviders) as [\n\t\"github\",\n\t...(keyof typeof socialProviders)[],\n];\n\nexport const SocialProviderListEnum = z\n\t.enum(socialProviderList)\n\t.or(z.string()) as z.ZodType<SocialProviderList[number] | (string & {})>;\n\nexport type SocialProvider = z.infer<typeof SocialProviderListEnum>;\n\nexport type SocialProviders = {\n\t[K in SocialProviderList[number]]?: AwaitableFunction<\n\t\tParameters<(typeof socialProviders)[K]>[0] & {\n\t\t\tenabled?: boolean | undefined;\n\t\t}\n\t>;\n};\n\nexport * from \"./apple\";\nexport * from \"./atlassian\";\nexport * from \"./cognito\";\nexport * from \"./discord\";\nexport * from \"./dropbox\";\nexport * from \"./facebook\";\nexport * from \"./figma\";\nexport * from \"./github\";\nexport * from \"./gitlab\";\nexport * from \"./google\";\nexport * from \"./huggingface\";\nexport * from \"./kakao\";\nexport * from \"./kick\";\nexport * from \"./kick\";\nexport * from \"./line\";\nexport * from \"./linear\";\nexport * from \"./linkedin\";\nexport * from \"./linkedin\";\nexport * from \"./microsoft-entra-id\";\nexport * from \"./naver\";\nexport * from \"./notion\";\nexport * from \"./paybin\";\nexport * from \"./paypal\";\nexport * from \"./polar\";\nexport * from \"./railway\";\nexport * from \"./reddit\";\nexport * from \"./roblox\";\nexport * from \"./salesforce\";\nexport * from \"./slack\";\nexport * from \"./spotify\";\nexport * from \"./tiktok\";\nexport * from \"./twitch\";\nexport * from \"./twitter\";\nexport * from \"./vercel\";\nexport * from \"./vk\";\nexport * from \"./wechat\";\nexport * from \"./zoom\";\n\nexport type SocialProviderList = typeof socialProviderList;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,MAAa,kBAAkB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAED,MAAa,qBAAqB,OAAO,KAAK,gBAAgB;AAK9D,MAAa,yBAAyB,EACpC,KAAK,mBAAmB,CACxB,GAAG,EAAE,QAAQ,CAAC"}
|
|
@@ -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/kakao.ts
|
|
8
7
|
const kakao = (options) => {
|
|
9
8
|
const tokenEndpoint = "https://kauth.kakao.com/oauth/token";
|
|
@@ -68,7 +67,7 @@ const kakao = (options) => {
|
|
|
68
67
|
options
|
|
69
68
|
};
|
|
70
69
|
};
|
|
71
|
-
|
|
72
70
|
//#endregion
|
|
73
71
|
export { kakao };
|
|
72
|
+
|
|
74
73
|
//# sourceMappingURL=kakao.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kakao.mjs","names":[],"sources":["../../src/social-providers/kakao.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\ninterface Partner {\n\t/** Partner-specific ID (consent required: kakaotalk_message) */\n\tuuid?: string | undefined;\n}\n\ninterface Profile {\n\t/** Nickname (consent required: profile/nickname) */\n\tnickname?: string | undefined;\n\t/** Thumbnail image URL (consent required: profile/profile image) */\n\tthumbnail_image_url?: string | undefined;\n\t/** Profile image URL (consent required: profile/profile image) */\n\tprofile_image_url?: string | undefined;\n\t/** Whether the profile image is the default */\n\tis_default_image?: boolean | undefined;\n\t/** Whether the nickname is the default */\n\tis_default_nickname?: boolean | undefined;\n}\n\ninterface KakaoAccount {\n\t/** Consent required: profile info (nickname/profile image) */\n\tprofile_needs_agreement?: boolean | undefined;\n\t/** Consent required: nickname */\n\tprofile_nickname_needs_agreement?: boolean | undefined;\n\t/** Consent required: profile image */\n\tprofile_image_needs_agreement?: boolean | undefined;\n\t/** Profile info */\n\tprofile?: Profile | undefined;\n\t/** Consent required: name */\n\tname_needs_agreement?: boolean | undefined;\n\t/** Name */\n\tname?: string | undefined;\n\t/** Consent required: email */\n\temail_needs_agreement?: boolean | undefined;\n\t/** Email valid */\n\tis_email_valid?: boolean | undefined;\n\t/** Email verified */\n\tis_email_verified?: boolean | undefined;\n\t/** Email */\n\temail?: string | undefined;\n\t/** Consent required: age range */\n\tage_range_needs_agreement?: boolean | undefined;\n\t/** Age range */\n\tage_range?: string | undefined;\n\t/** Consent required: birth year */\n\tbirthyear_needs_agreement?: boolean | undefined;\n\t/** Birth year (YYYY) */\n\tbirthyear?: string | undefined;\n\t/** Consent required: birthday */\n\tbirthday_needs_agreement?: boolean | undefined;\n\t/** Birthday (MMDD) */\n\tbirthday?: string | undefined;\n\t/** Birthday type (SOLAR/LUNAR) */\n\tbirthday_type?: string | undefined;\n\t/** Whether birthday is in a leap month */\n\tis_leap_month?: boolean | undefined;\n\t/** Consent required: gender */\n\tgender_needs_agreement?: boolean | undefined;\n\t/** Gender (male/female) */\n\tgender?: string | undefined;\n\t/** Consent required: phone number */\n\tphone_number_needs_agreement?: boolean | undefined;\n\t/** Phone number */\n\tphone_number?: string | undefined;\n\t/** Consent required: CI */\n\tci_needs_agreement?: boolean | undefined;\n\t/** CI (unique identifier) */\n\tci?: string | undefined;\n\t/** CI authentication time (UTC) */\n\tci_authenticated_at?: string | undefined;\n}\n\nexport interface KakaoProfile {\n\t/** Kakao user ID */\n\tid: number;\n\t/**\n\t * Whether the user has signed up (only present if auto-connection is disabled)\n\t * false: preregistered, true: registered\n\t */\n\thas_signed_up?: boolean | undefined;\n\t/** UTC datetime when the user connected the service */\n\tconnected_at?: string | undefined;\n\t/** UTC datetime when the user signed up via Kakao Sync */\n\tsynched_at?: string | undefined;\n\t/** Custom user properties */\n\tproperties?: Record<string, any> | undefined;\n\t/** Kakao account info */\n\tkakao_account: KakaoAccount;\n\t/** Partner info */\n\tfor_partner?: Partner | undefined;\n}\n\nexport interface KakaoOptions extends ProviderOptions<KakaoProfile> {\n\tclientId: string;\n}\n\nexport const kakao = (options: KakaoOptions) => {\n\tconst tokenEndpoint = \"https://kauth.kakao.com/oauth/token\";\n\treturn {\n\t\tid: \"kakao\",\n\t\tname: \"Kakao\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"account_email\", \"profile_image\", \"profile_nickname\"];\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: \"kakao\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://kauth.kakao.com/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\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});\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<KakaoProfile>(\n\t\t\t\t\"https://kapi.kakao.com/v2/user/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},\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 userMap = await options.mapProfileToUser?.(profile);\n\t\t\tconst account = profile.kakao_account || {};\n\t\t\tconst kakaoProfile = account.profile || {};\n\t\t\tconst user = {\n\t\t\t\tid: String(profile.id),\n\t\t\t\tname: kakaoProfile.nickname || account.name || \"\",\n\t\t\t\temail: account.email,\n\t\t\t\timage:\n\t\t\t\t\tkakaoProfile.profile_image_url || kakaoProfile.thumbnail_image_url,\n\t\t\t\temailVerified: !!account.is_email_valid && !!account.is_email_verified,\n\t\t\t\t...userMap,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tuser,\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<KakaoProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"kakao.mjs","names":[],"sources":["../../src/social-providers/kakao.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\ninterface Partner {\n\t/** Partner-specific ID (consent required: kakaotalk_message) */\n\tuuid?: string | undefined;\n}\n\ninterface Profile {\n\t/** Nickname (consent required: profile/nickname) */\n\tnickname?: string | undefined;\n\t/** Thumbnail image URL (consent required: profile/profile image) */\n\tthumbnail_image_url?: string | undefined;\n\t/** Profile image URL (consent required: profile/profile image) */\n\tprofile_image_url?: string | undefined;\n\t/** Whether the profile image is the default */\n\tis_default_image?: boolean | undefined;\n\t/** Whether the nickname is the default */\n\tis_default_nickname?: boolean | undefined;\n}\n\ninterface KakaoAccount {\n\t/** Consent required: profile info (nickname/profile image) */\n\tprofile_needs_agreement?: boolean | undefined;\n\t/** Consent required: nickname */\n\tprofile_nickname_needs_agreement?: boolean | undefined;\n\t/** Consent required: profile image */\n\tprofile_image_needs_agreement?: boolean | undefined;\n\t/** Profile info */\n\tprofile?: Profile | undefined;\n\t/** Consent required: name */\n\tname_needs_agreement?: boolean | undefined;\n\t/** Name */\n\tname?: string | undefined;\n\t/** Consent required: email */\n\temail_needs_agreement?: boolean | undefined;\n\t/** Email valid */\n\tis_email_valid?: boolean | undefined;\n\t/** Email verified */\n\tis_email_verified?: boolean | undefined;\n\t/** Email */\n\temail?: string | undefined;\n\t/** Consent required: age range */\n\tage_range_needs_agreement?: boolean | undefined;\n\t/** Age range */\n\tage_range?: string | undefined;\n\t/** Consent required: birth year */\n\tbirthyear_needs_agreement?: boolean | undefined;\n\t/** Birth year (YYYY) */\n\tbirthyear?: string | undefined;\n\t/** Consent required: birthday */\n\tbirthday_needs_agreement?: boolean | undefined;\n\t/** Birthday (MMDD) */\n\tbirthday?: string | undefined;\n\t/** Birthday type (SOLAR/LUNAR) */\n\tbirthday_type?: string | undefined;\n\t/** Whether birthday is in a leap month */\n\tis_leap_month?: boolean | undefined;\n\t/** Consent required: gender */\n\tgender_needs_agreement?: boolean | undefined;\n\t/** Gender (male/female) */\n\tgender?: string | undefined;\n\t/** Consent required: phone number */\n\tphone_number_needs_agreement?: boolean | undefined;\n\t/** Phone number */\n\tphone_number?: string | undefined;\n\t/** Consent required: CI */\n\tci_needs_agreement?: boolean | undefined;\n\t/** CI (unique identifier) */\n\tci?: string | undefined;\n\t/** CI authentication time (UTC) */\n\tci_authenticated_at?: string | undefined;\n}\n\nexport interface KakaoProfile {\n\t/** Kakao user ID */\n\tid: number;\n\t/**\n\t * Whether the user has signed up (only present if auto-connection is disabled)\n\t * false: preregistered, true: registered\n\t */\n\thas_signed_up?: boolean | undefined;\n\t/** UTC datetime when the user connected the service */\n\tconnected_at?: string | undefined;\n\t/** UTC datetime when the user signed up via Kakao Sync */\n\tsynched_at?: string | undefined;\n\t/** Custom user properties */\n\tproperties?: Record<string, any> | undefined;\n\t/** Kakao account info */\n\tkakao_account: KakaoAccount;\n\t/** Partner info */\n\tfor_partner?: Partner | undefined;\n}\n\nexport interface KakaoOptions extends ProviderOptions<KakaoProfile> {\n\tclientId: string;\n}\n\nexport const kakao = (options: KakaoOptions) => {\n\tconst tokenEndpoint = \"https://kauth.kakao.com/oauth/token\";\n\treturn {\n\t\tid: \"kakao\",\n\t\tname: \"Kakao\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"account_email\", \"profile_image\", \"profile_nickname\"];\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: \"kakao\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://kauth.kakao.com/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\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});\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<KakaoProfile>(\n\t\t\t\t\"https://kapi.kakao.com/v2/user/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},\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 userMap = await options.mapProfileToUser?.(profile);\n\t\t\tconst account = profile.kakao_account || {};\n\t\t\tconst kakaoProfile = account.profile || {};\n\t\t\tconst user = {\n\t\t\t\tid: String(profile.id),\n\t\t\t\tname: kakaoProfile.nickname || account.name || \"\",\n\t\t\t\temail: account.email,\n\t\t\t\timage:\n\t\t\t\t\tkakaoProfile.profile_image_url || kakaoProfile.thumbnail_image_url,\n\t\t\t\temailVerified: !!account.is_email_valid && !!account.is_email_verified,\n\t\t\t\t...userMap,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tuser,\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<KakaoProfile>;\n};\n"],"mappings":";;;;;;AAuGA,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;IAAiB;IAAiB;IAAmB;AACzD,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,CAAC;;EAEH,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,qCACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AACD,OAAI,SAAS,CAAC,QACb,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;GACzD,MAAM,UAAU,QAAQ,iBAAiB,EAAE;GAC3C,MAAM,eAAe,QAAQ,WAAW,EAAE;AAU1C,UAAO;IACN,MAVY;KACZ,IAAI,OAAO,QAAQ,GAAG;KACtB,MAAM,aAAa,YAAY,QAAQ,QAAQ;KAC/C,OAAO,QAAQ;KACf,OACC,aAAa,qBAAqB,aAAa;KAChD,eAAe,CAAC,CAAC,QAAQ,kBAAkB,CAAC,CAAC,QAAQ;KACrD,GAAG;KACH;IAGA,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/kick.ts
|
|
8
7
|
const kick = (options) => {
|
|
9
8
|
return {
|
|
@@ -66,7 +65,7 @@ const kick = (options) => {
|
|
|
66
65
|
options
|
|
67
66
|
};
|
|
68
67
|
};
|
|
69
|
-
|
|
70
68
|
//#endregion
|
|
71
69
|
export { kick };
|
|
70
|
+
|
|
72
71
|
//# sourceMappingURL=kick.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kick.mjs","names":[],"sources":["../../src/social-providers/kick.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 KickProfile {\n\t/**\n\t * The user id of the user\n\t */\n\tuser_id: string;\n\t/**\n\t * The name of the user\n\t */\n\tname: string;\n\t/**\n\t * The email of the user\n\t */\n\temail: string;\n\t/**\n\t * The picture of the user\n\t */\n\tprofile_picture: string;\n}\n\nexport interface KickOptions extends ProviderOptions<KickProfile> {\n\tclientId: string;\n}\n\nexport const kick = (options: KickOptions) => {\n\treturn {\n\t\tid: \"kick\",\n\t\tname: \"Kick\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI, codeVerifier }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"user:read\"];\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: \"kick\",\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://id.kick.com/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tcodeVerifier,\n\t\t\t\tstate,\n\t\t\t});\n\t\t},\n\t\tasync validateAuthorizationCode({ code, redirectURI, codeVerifier }) {\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: \"https://id.kick.com/oauth/token\",\n\t\t\t\tcodeVerifier,\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\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://id.kick.com/oauth/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, error } = await betterFetch<{\n\t\t\t\tdata: KickProfile[];\n\t\t\t}>(\"https://api.kick.com/public/v1/users\", {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\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 profile = data.data[0]!;\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// Kick does not provide 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.user_id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.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<KickProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"kick.mjs","names":[],"sources":["../../src/social-providers/kick.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 KickProfile {\n\t/**\n\t * The user id of the user\n\t */\n\tuser_id: string;\n\t/**\n\t * The name of the user\n\t */\n\tname: string;\n\t/**\n\t * The email of the user\n\t */\n\temail: string;\n\t/**\n\t * The picture of the user\n\t */\n\tprofile_picture: string;\n}\n\nexport interface KickOptions extends ProviderOptions<KickProfile> {\n\tclientId: string;\n}\n\nexport const kick = (options: KickOptions) => {\n\treturn {\n\t\tid: \"kick\",\n\t\tname: \"Kick\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI, codeVerifier }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"user:read\"];\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: \"kick\",\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://id.kick.com/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tcodeVerifier,\n\t\t\t\tstate,\n\t\t\t});\n\t\t},\n\t\tasync validateAuthorizationCode({ code, redirectURI, codeVerifier }) {\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: \"https://id.kick.com/oauth/token\",\n\t\t\t\tcodeVerifier,\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\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://id.kick.com/oauth/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, error } = await betterFetch<{\n\t\t\t\tdata: KickProfile[];\n\t\t\t}>(\"https://api.kick.com/public/v1/users\", {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\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 profile = data.data[0]!;\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// Kick does not provide 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.user_id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.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<KickProfile>;\n};\n"],"mappings":";;;;;;AA+BA,MAAa,QAAQ,YAAyB;AAC7C,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,aAAa,gBAAgB;GACpE,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,YAAY;AAChE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAEnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA,CAAC;;EAEH,MAAM,0BAA0B,EAAE,MAAM,aAAa,gBAAgB;AACpE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA,eAAe;IACf;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,cAAc,QAAQ;KACtB;IACD,eAAe;IACf,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAGlC,MAAM,EAAE,MAAM,UAAU,MAAM,YAE3B,wCAAwC;IAC1C,QAAQ;IACR,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B;IACD,CAAC;AAEF,OAAI,MACH,QAAO;GAGR,MAAM,UAAU,KAAK,KAAK;GAE1B,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 { validateAuthorizationCode } from "../oauth2/validate-authorization-code
|
|
|
4
4
|
import "../oauth2/index.mjs";
|
|
5
5
|
import { betterFetch } from "@better-fetch/fetch";
|
|
6
6
|
import { decodeJwt } from "jose";
|
|
7
|
-
|
|
8
7
|
//#region src/social-providers/line.ts
|
|
9
8
|
/**
|
|
10
9
|
* LINE Login v2.1
|
|
@@ -108,7 +107,7 @@ const line = (options) => {
|
|
|
108
107
|
options
|
|
109
108
|
};
|
|
110
109
|
};
|
|
111
|
-
|
|
112
110
|
//#endregion
|
|
113
111
|
export { line };
|
|
112
|
+
|
|
114
113
|
//# sourceMappingURL=line.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"line.mjs","names":[],"sources":["../../src/social-providers/line.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt } from \"jose\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface LineIdTokenPayload {\n\tiss: string;\n\tsub: string;\n\taud: string;\n\texp: number;\n\tiat: number;\n\tname?: string | undefined;\n\tpicture?: string | undefined;\n\temail?: string | undefined;\n\tamr?: string[] | undefined;\n\tnonce?: string | undefined;\n}\n\nexport interface LineUserInfo {\n\tsub: string;\n\tname?: string | undefined;\n\tpicture?: string | undefined;\n\temail?: string | undefined;\n}\n\nexport interface LineOptions\n\textends ProviderOptions<LineUserInfo | LineIdTokenPayload> {\n\tclientId: string;\n}\n\n/**\n * LINE Login v2.1\n * - Authorization endpoint: https://access.line.me/oauth2/v2.1/authorize\n * - Token endpoint: https://api.line.me/oauth2/v2.1/token\n * - UserInfo endpoint: https://api.line.me/oauth2/v2.1/userinfo\n * - Verify ID token: https://api.line.me/oauth2/v2.1/verify\n *\n * Docs: https://developers.line.biz/en/reference/line-login/#issue-access-token\n */\nexport const line = (options: LineOptions) => {\n\tconst authorizationEndpoint = \"https://access.line.me/oauth2/v2.1/authorize\";\n\tconst tokenEndpoint = \"https://api.line.me/oauth2/v2.1/token\";\n\tconst userInfoEndpoint = \"https://api.line.me/oauth2/v2.1/userinfo\";\n\tconst verifyIdTokenEndpoint = \"https://api.line.me/oauth2/v2.1/verify\";\n\n\treturn {\n\t\tid: \"line\",\n\t\tname: \"LINE\",\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\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 await createAuthorizationURL({\n\t\t\t\tid: \"line\",\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\tloginHint,\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\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 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\tconst body = new URLSearchParams();\n\t\t\tbody.set(\"id_token\", token);\n\t\t\tbody.set(\"client_id\", options.clientId);\n\t\t\tif (nonce) body.set(\"nonce\", nonce);\n\t\t\tconst { data, error } = await betterFetch<LineIdTokenPayload>(\n\t\t\t\tverifyIdTokenEndpoint,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\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,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error || !data) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// aud must match clientId; nonce (if provided) must also match nonce\n\t\t\tif (data.aud !== options.clientId) return false;\n\t\t\tif (data.nonce && data.nonce !== nonce) return false;\n\t\t\treturn true;\n\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\tlet profile: LineUserInfo | LineIdTokenPayload | null = null;\n\t\t\t// Prefer ID token if available\n\t\t\tif (token.idToken) {\n\t\t\t\ttry {\n\t\t\t\t\tprofile = decodeJwt(token.idToken) as LineIdTokenPayload;\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t\t// Fallback to UserInfo endpoint\n\t\t\tif (!profile) {\n\t\t\t\tconst { data } = await betterFetch<LineUserInfo>(userInfoEndpoint, {\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\tprofile = data || null;\n\t\t\t}\n\t\t\tif (!profile) return null;\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile as any);\n\t\t\t// ID preference order\n\t\t\tconst id = (profile as any).sub || (profile as any).userId;\n\t\t\tconst name = (profile as any).name || (profile as any).displayName || \"\";\n\t\t\tconst image =\n\t\t\t\t(profile as any).picture || (profile as any).pictureUrl || undefined;\n\t\t\tconst email = (profile as any).email;\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid,\n\t\t\t\t\tname,\n\t\t\t\t\temail,\n\t\t\t\t\timage,\n\t\t\t\t\t// LINE does not expose email verification status in ID token/userinfo\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 as any,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<LineUserInfo | LineIdTokenPayload, LineOptions>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"line.mjs","names":[],"sources":["../../src/social-providers/line.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt } from \"jose\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface LineIdTokenPayload {\n\tiss: string;\n\tsub: string;\n\taud: string;\n\texp: number;\n\tiat: number;\n\tname?: string | undefined;\n\tpicture?: string | undefined;\n\temail?: string | undefined;\n\tamr?: string[] | undefined;\n\tnonce?: string | undefined;\n}\n\nexport interface LineUserInfo {\n\tsub: string;\n\tname?: string | undefined;\n\tpicture?: string | undefined;\n\temail?: string | undefined;\n}\n\nexport interface LineOptions\n\textends ProviderOptions<LineUserInfo | LineIdTokenPayload> {\n\tclientId: string;\n}\n\n/**\n * LINE Login v2.1\n * - Authorization endpoint: https://access.line.me/oauth2/v2.1/authorize\n * - Token endpoint: https://api.line.me/oauth2/v2.1/token\n * - UserInfo endpoint: https://api.line.me/oauth2/v2.1/userinfo\n * - Verify ID token: https://api.line.me/oauth2/v2.1/verify\n *\n * Docs: https://developers.line.biz/en/reference/line-login/#issue-access-token\n */\nexport const line = (options: LineOptions) => {\n\tconst authorizationEndpoint = \"https://access.line.me/oauth2/v2.1/authorize\";\n\tconst tokenEndpoint = \"https://api.line.me/oauth2/v2.1/token\";\n\tconst userInfoEndpoint = \"https://api.line.me/oauth2/v2.1/userinfo\";\n\tconst verifyIdTokenEndpoint = \"https://api.line.me/oauth2/v2.1/verify\";\n\n\treturn {\n\t\tid: \"line\",\n\t\tname: \"LINE\",\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\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 await createAuthorizationURL({\n\t\t\t\tid: \"line\",\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\tloginHint,\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\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 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\tconst body = new URLSearchParams();\n\t\t\tbody.set(\"id_token\", token);\n\t\t\tbody.set(\"client_id\", options.clientId);\n\t\t\tif (nonce) body.set(\"nonce\", nonce);\n\t\t\tconst { data, error } = await betterFetch<LineIdTokenPayload>(\n\t\t\t\tverifyIdTokenEndpoint,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\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,\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error || !data) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// aud must match clientId; nonce (if provided) must also match nonce\n\t\t\tif (data.aud !== options.clientId) return false;\n\t\t\tif (data.nonce && data.nonce !== nonce) return false;\n\t\t\treturn true;\n\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\tlet profile: LineUserInfo | LineIdTokenPayload | null = null;\n\t\t\t// Prefer ID token if available\n\t\t\tif (token.idToken) {\n\t\t\t\ttry {\n\t\t\t\t\tprofile = decodeJwt(token.idToken) as LineIdTokenPayload;\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t\t// Fallback to UserInfo endpoint\n\t\t\tif (!profile) {\n\t\t\t\tconst { data } = await betterFetch<LineUserInfo>(userInfoEndpoint, {\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\tprofile = data || null;\n\t\t\t}\n\t\t\tif (!profile) return null;\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile as any);\n\t\t\t// ID preference order\n\t\t\tconst id = (profile as any).sub || (profile as any).userId;\n\t\t\tconst name = (profile as any).name || (profile as any).displayName || \"\";\n\t\t\tconst image =\n\t\t\t\t(profile as any).picture || (profile as any).pictureUrl || undefined;\n\t\t\tconst email = (profile as any).email;\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid,\n\t\t\t\t\tname,\n\t\t\t\t\temail,\n\t\t\t\t\timage,\n\t\t\t\t\t// LINE does not expose email verification status in ID token/userinfo\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 as any,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<LineUserInfo | LineIdTokenPayload, LineOptions>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AA2CA,MAAa,QAAQ,YAAyB;CAC7C,MAAM,wBAAwB;CAC9B,MAAM,gBAAgB;CACtB,MAAM,mBAAmB;CACzB,MAAM,wBAAwB;AAE9B,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAC5B,OACA,QACA,cACA,aACA,aACE;GACF,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,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA;IACA,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,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAER,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;GAE3C,MAAM,OAAO,IAAI,iBAAiB;AAClC,QAAK,IAAI,YAAY,MAAM;AAC3B,QAAK,IAAI,aAAa,QAAQ,SAAS;AACvC,OAAI,MAAO,MAAK,IAAI,SAAS,MAAM;GACnC,MAAM,EAAE,MAAM,UAAU,MAAM,YAC7B,uBACA;IACC,QAAQ;IACR,SAAS,EACR,gBAAgB,qCAChB;IACD;IACA,CACD;AACD,OAAI,SAAS,CAAC,KACb,QAAO;AAGR,OAAI,KAAK,QAAQ,QAAQ,SAAU,QAAO;AAC1C,OAAI,KAAK,SAAS,KAAK,UAAU,MAAO,QAAO;AAC/C,UAAO;;EAER,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,IAAI,UAAoD;AAExD,OAAI,MAAM,QACT,KAAI;AACH,cAAU,UAAU,MAAM,QAAQ;WAC3B;AAGT,OAAI,CAAC,SAAS;IACb,MAAM,EAAE,SAAS,MAAM,YAA0B,kBAAkB,EAClE,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CAAC;AACF,cAAU,QAAQ;;AAEnB,OAAI,CAAC,QAAS,QAAO;GACrB,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAe;GAEhE,MAAM,KAAM,QAAgB,OAAQ,QAAgB;GACpD,MAAM,OAAQ,QAAgB,QAAS,QAAgB,eAAe;GACtE,MAAM,QACJ,QAAgB,WAAY,QAAgB,cAAc,KAAA;AAE5D,UAAO;IACN,MAAM;KACL;KACA;KACA,OALa,QAAgB;KAM7B;KAEA,eAAe;KACf,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/linear.ts
|
|
8
7
|
const linear = (options) => {
|
|
9
8
|
const tokenEndpoint = "https://api.linear.app/oauth/token";
|
|
@@ -83,7 +82,7 @@ const linear = (options) => {
|
|
|
83
82
|
options
|
|
84
83
|
};
|
|
85
84
|
};
|
|
86
|
-
|
|
87
85
|
//#endregion
|
|
88
86
|
export { linear };
|
|
87
|
+
|
|
89
88
|
//# sourceMappingURL=linear.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linear.mjs","names":[],"sources":["../../src/social-providers/linear.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 LinearUser {\n\tid: string;\n\tname: string;\n\temail: string;\n\tavatarUrl?: string | undefined;\n\tactive: boolean;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface LinearProfile {\n\tdata: {\n\t\tviewer: LinearUser;\n\t};\n}\n\nexport interface LinearOptions extends ProviderOptions<LinearUser> {\n\tclientId: string;\n}\n\nexport const linear = (options: LinearOptions) => {\n\tconst tokenEndpoint = \"https://api.linear.app/oauth/token\";\n\treturn {\n\t\tid: \"linear\",\n\t\tname: \"Linear\",\n\t\tcreateAuthorizationURL({ state, scopes, loginHint, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"read\"];\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: \"linear\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://linear.app/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});\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\n\t\t\tconst { data: profile, error } = await betterFetch<LinearProfile>(\n\t\t\t\t\"https://api.linear.app/graphql\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tquery: `\n\t\t\t\t\t\t\tquery {\n\t\t\t\t\t\t\t\tviewer {\n\t\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t\t\tname\n\t\t\t\t\t\t\t\t\temail\n\t\t\t\t\t\t\t\t\tavatarUrl\n\t\t\t\t\t\t\t\t\tactive\n\t\t\t\t\t\t\t\t\tcreatedAt\n\t\t\t\t\t\t\t\t\tupdatedAt\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t`,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error || !profile?.data?.viewer) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst userData = profile.data.viewer;\n\t\t\tconst userMap = await options.mapProfileToUser?.(userData);\n\t\t\t// Linear does not provide 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.data.viewer.id,\n\t\t\t\t\tname: profile.data.viewer.name,\n\t\t\t\t\temail: profile.data.viewer.email,\n\t\t\t\t\timage: profile.data.viewer.avatarUrl,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: userData,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<LinearUser>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"linear.mjs","names":[],"sources":["../../src/social-providers/linear.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 LinearUser {\n\tid: string;\n\tname: string;\n\temail: string;\n\tavatarUrl?: string | undefined;\n\tactive: boolean;\n\tcreatedAt: string;\n\tupdatedAt: string;\n}\n\nexport interface LinearProfile {\n\tdata: {\n\t\tviewer: LinearUser;\n\t};\n}\n\nexport interface LinearOptions extends ProviderOptions<LinearUser> {\n\tclientId: string;\n}\n\nexport const linear = (options: LinearOptions) => {\n\tconst tokenEndpoint = \"https://api.linear.app/oauth/token\";\n\treturn {\n\t\tid: \"linear\",\n\t\tname: \"Linear\",\n\t\tcreateAuthorizationURL({ state, scopes, loginHint, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"read\"];\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: \"linear\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://linear.app/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});\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\n\t\t\tconst { data: profile, error } = await betterFetch<LinearProfile>(\n\t\t\t\t\"https://api.linear.app/graphql\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tquery: `\n\t\t\t\t\t\t\tquery {\n\t\t\t\t\t\t\t\tviewer {\n\t\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t\t\tname\n\t\t\t\t\t\t\t\t\temail\n\t\t\t\t\t\t\t\t\tavatarUrl\n\t\t\t\t\t\t\t\t\tactive\n\t\t\t\t\t\t\t\t\tcreatedAt\n\t\t\t\t\t\t\t\t\tupdatedAt\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t`,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error || !profile?.data?.viewer) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst userData = profile.data.viewer;\n\t\t\tconst userMap = await options.mapProfileToUser?.(userData);\n\t\t\t// Linear does not provide 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.data.viewer.id,\n\t\t\t\t\tname: profile.data.viewer.name,\n\t\t\t\t\temail: profile.data.viewer.email,\n\t\t\t\t\timage: profile.data.viewer.avatarUrl,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: userData,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<LinearUser>;\n};\n"],"mappings":";;;;;;AA4BA,MAAa,UAAU,YAA2B;CACjD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,WAAW,eAAe;GACjE,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,OAAO;AAC3D,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,CAAC;;EAEH,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;GAGlC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,kCACA;IACC,QAAQ;IACR,SAAS;KACR,gBAAgB;KAChB,eAAe,UAAU,MAAM;KAC/B;IACD,MAAM,KAAK,UAAU,EACpB,OAAO;;;;;;;;;;;;SAaP,CAAC;IACF,CACD;AACD,OAAI,SAAS,CAAC,SAAS,MAAM,OAC5B,QAAO;GAGR,MAAM,WAAW,QAAQ,KAAK;GAC9B,MAAM,UAAU,MAAM,QAAQ,mBAAmB,SAAS;AAG1D,UAAO;IACN,MAAM;KACL,IAAI,QAAQ,KAAK,OAAO;KACxB,MAAM,QAAQ,KAAK,OAAO;KAC1B,OAAO,QAAQ,KAAK,OAAO;KAC3B,OAAO,QAAQ,KAAK,OAAO;KAC3B,eAAe;KACf,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/linkedin.ts
|
|
8
7
|
const linkedin = (options) => {
|
|
9
8
|
const authorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
|
|
@@ -71,7 +70,7 @@ const linkedin = (options) => {
|
|
|
71
70
|
options
|
|
72
71
|
};
|
|
73
72
|
};
|
|
74
|
-
|
|
75
73
|
//#endregion
|
|
76
74
|
export { linkedin };
|
|
75
|
+
|
|
77
76
|
//# sourceMappingURL=linkedin.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linkedin.mjs","names":[],"sources":["../../src/social-providers/linkedin.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 LinkedInProfile {\n\tsub: string;\n\tname: string;\n\tgiven_name: string;\n\tfamily_name: string;\n\tpicture: string;\n\tlocale: {\n\t\tcountry: string;\n\t\tlanguage: string;\n\t};\n\temail: string;\n\temail_verified: boolean;\n}\n\nexport interface LinkedInOptions extends ProviderOptions<LinkedInProfile> {\n\tclientId: string;\n}\n\nexport const linkedin = (options: LinkedInOptions) => {\n\tconst authorizationEndpoint =\n\t\t\"https://www.linkedin.com/oauth/v2/authorization\";\n\tconst tokenEndpoint = \"https://www.linkedin.com/oauth/v2/accessToken\";\n\n\treturn {\n\t\tid: \"linkedin\",\n\t\tname: \"Linkedin\",\n\t\tcreateAuthorizationURL: async ({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tredirectURI,\n\t\t\tloginHint,\n\t\t}) => {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"profile\", \"email\", \"openid\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: \"linkedin\",\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\tloginHint,\n\t\t\t\tredirectURI,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn await 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<LinkedInProfile>(\n\t\t\t\t\"https://api.linkedin.com/v2/userinfo\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\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.sub,\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 || false,\n\t\t\t\t\timage: profile.picture,\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<LinkedInProfile>;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"linkedin.mjs","names":[],"sources":["../../src/social-providers/linkedin.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 LinkedInProfile {\n\tsub: string;\n\tname: string;\n\tgiven_name: string;\n\tfamily_name: string;\n\tpicture: string;\n\tlocale: {\n\t\tcountry: string;\n\t\tlanguage: string;\n\t};\n\temail: string;\n\temail_verified: boolean;\n}\n\nexport interface LinkedInOptions extends ProviderOptions<LinkedInProfile> {\n\tclientId: string;\n}\n\nexport const linkedin = (options: LinkedInOptions) => {\n\tconst authorizationEndpoint =\n\t\t\"https://www.linkedin.com/oauth/v2/authorization\";\n\tconst tokenEndpoint = \"https://www.linkedin.com/oauth/v2/accessToken\";\n\n\treturn {\n\t\tid: \"linkedin\",\n\t\tname: \"Linkedin\",\n\t\tcreateAuthorizationURL: async ({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tredirectURI,\n\t\t\tloginHint,\n\t\t}) => {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"profile\", \"email\", \"openid\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: \"linkedin\",\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\tloginHint,\n\t\t\t\tredirectURI,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn await 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<LinkedInProfile>(\n\t\t\t\t\"https://api.linkedin.com/v2/userinfo\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\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.sub,\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 || false,\n\t\t\t\t\timage: profile.picture,\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<LinkedInProfile>;\n};\n"],"mappings":";;;;;;AA0BA,MAAa,YAAY,YAA6B;CACrD,MAAM,wBACL;CACD,MAAM,gBAAgB;AAEtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,wBAAwB,OAAO,EAC9B,OACA,QACA,aACA,gBACK;GACL,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAW;IAAS;IAAS;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,MAAM,0BAA0B;IACtC;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,wCACA;IACC,QAAQ;IACR,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B;IACD,CACD;AAED,OAAI,MACH,QAAO;GAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,OAAO,QAAQ;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -8,7 +8,6 @@ import "../oauth2/index.mjs";
|
|
|
8
8
|
import { base64 } from "@better-auth/utils/base64";
|
|
9
9
|
import { betterFetch } from "@better-fetch/fetch";
|
|
10
10
|
import { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from "jose";
|
|
11
|
-
|
|
12
11
|
//#region src/social-providers/microsoft-entra-id.ts
|
|
13
12
|
const microsoft = (options) => {
|
|
14
13
|
const tenant = options.tenantId || "common";
|
|
@@ -134,7 +133,7 @@ const getMicrosoftPublicKey = async (kid, tenant, authority) => {
|
|
|
134
133
|
if (!jwk) throw new Error(`JWK with kid ${kid} not found`);
|
|
135
134
|
return await importJWK(jwk, jwk.alg);
|
|
136
135
|
};
|
|
137
|
-
|
|
138
136
|
//#endregion
|
|
139
137
|
export { getMicrosoftPublicKey, microsoft };
|
|
138
|
+
|
|
140
139
|
//# sourceMappingURL=microsoft-entra-id.mjs.map
|