@hammadj/better-auth-core 1.5.0-beta.9
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/.turbo/turbo-build.log +266 -0
- package/.turbo/turbo-test.log +2 -0
- package/LICENSE.md +20 -0
- package/dist/api/index.d.mts +181 -0
- package/dist/api/index.mjs +34 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/async_hooks/index.d.mts +7 -0
- package/dist/async_hooks/index.mjs +22 -0
- package/dist/async_hooks/index.mjs.map +1 -0
- package/dist/async_hooks/pure.index.d.mts +7 -0
- package/dist/async_hooks/pure.index.mjs +35 -0
- package/dist/async_hooks/pure.index.mjs.map +1 -0
- package/dist/context/endpoint-context.d.mts +19 -0
- package/dist/context/endpoint-context.mjs +32 -0
- package/dist/context/endpoint-context.mjs.map +1 -0
- package/dist/context/global.d.mts +7 -0
- package/dist/context/global.mjs +38 -0
- package/dist/context/global.mjs.map +1 -0
- package/dist/context/index.d.mts +5 -0
- package/dist/context/index.mjs +6 -0
- package/dist/context/request-state.d.mts +26 -0
- package/dist/context/request-state.mjs +50 -0
- package/dist/context/request-state.mjs.map +1 -0
- package/dist/context/transaction.d.mts +25 -0
- package/dist/context/transaction.mjs +96 -0
- package/dist/context/transaction.mjs.map +1 -0
- package/dist/db/adapter/factory.d.mts +28 -0
- package/dist/db/adapter/factory.mjs +716 -0
- package/dist/db/adapter/factory.mjs.map +1 -0
- package/dist/db/adapter/get-default-field-name.d.mts +19 -0
- package/dist/db/adapter/get-default-field-name.mjs +39 -0
- package/dist/db/adapter/get-default-field-name.mjs.map +1 -0
- package/dist/db/adapter/get-default-model-name.d.mts +13 -0
- package/dist/db/adapter/get-default-model-name.mjs +33 -0
- package/dist/db/adapter/get-default-model-name.mjs.map +1 -0
- package/dist/db/adapter/get-field-attributes.d.mts +30 -0
- package/dist/db/adapter/get-field-attributes.mjs +40 -0
- package/dist/db/adapter/get-field-attributes.mjs.map +1 -0
- package/dist/db/adapter/get-field-name.d.mts +19 -0
- package/dist/db/adapter/get-field-name.mjs +34 -0
- package/dist/db/adapter/get-field-name.mjs.map +1 -0
- package/dist/db/adapter/get-id-field.d.mts +40 -0
- package/dist/db/adapter/get-id-field.mjs +68 -0
- package/dist/db/adapter/get-id-field.mjs.map +1 -0
- package/dist/db/adapter/get-model-name.d.mts +13 -0
- package/dist/db/adapter/get-model-name.mjs +24 -0
- package/dist/db/adapter/get-model-name.mjs.map +1 -0
- package/dist/db/adapter/index.d.mts +515 -0
- package/dist/db/adapter/index.mjs +10 -0
- package/dist/db/adapter/types.d.mts +140 -0
- package/dist/db/adapter/utils.d.mts +8 -0
- package/dist/db/adapter/utils.mjs +39 -0
- package/dist/db/adapter/utils.mjs.map +1 -0
- package/dist/db/get-tables.d.mts +9 -0
- package/dist/db/get-tables.mjs +267 -0
- package/dist/db/get-tables.mjs.map +1 -0
- package/dist/db/index.d.mts +10 -0
- package/dist/db/index.mjs +9 -0
- package/dist/db/plugin.d.mts +13 -0
- package/dist/db/schema/account.d.mts +27 -0
- package/dist/db/schema/account.mjs +20 -0
- package/dist/db/schema/account.mjs.map +1 -0
- package/dist/db/schema/rate-limit.d.mts +15 -0
- package/dist/db/schema/rate-limit.mjs +12 -0
- package/dist/db/schema/rate-limit.mjs.map +1 -0
- package/dist/db/schema/session.d.mts +22 -0
- package/dist/db/schema/session.mjs +15 -0
- package/dist/db/schema/session.mjs.map +1 -0
- package/dist/db/schema/shared.d.mts +11 -0
- package/dist/db/schema/shared.mjs +12 -0
- package/dist/db/schema/shared.mjs.map +1 -0
- package/dist/db/schema/user.d.mts +21 -0
- package/dist/db/schema/user.mjs +14 -0
- package/dist/db/schema/user.mjs.map +1 -0
- package/dist/db/schema/verification.d.mts +20 -0
- package/dist/db/schema/verification.mjs +13 -0
- package/dist/db/schema/verification.mjs.map +1 -0
- package/dist/db/type.d.mts +147 -0
- package/dist/env/color-depth.d.mts +5 -0
- package/dist/env/color-depth.mjs +89 -0
- package/dist/env/color-depth.mjs.map +1 -0
- package/dist/env/env-impl.d.mts +33 -0
- package/dist/env/env-impl.mjs +83 -0
- package/dist/env/env-impl.mjs.map +1 -0
- package/dist/env/index.d.mts +4 -0
- package/dist/env/index.mjs +5 -0
- package/dist/env/logger.d.mts +49 -0
- package/dist/env/logger.mjs +82 -0
- package/dist/env/logger.mjs.map +1 -0
- package/dist/error/codes.d.mts +199 -0
- package/dist/error/codes.mjs +57 -0
- package/dist/error/codes.mjs.map +1 -0
- package/dist/error/index.d.mts +20 -0
- package/dist/error/index.mjs +30 -0
- package/dist/error/index.mjs.map +1 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +1 -0
- package/dist/oauth2/client-credentials-token.d.mts +37 -0
- package/dist/oauth2/client-credentials-token.mjs +55 -0
- package/dist/oauth2/client-credentials-token.mjs.map +1 -0
- package/dist/oauth2/create-authorization-url.d.mts +46 -0
- package/dist/oauth2/create-authorization-url.mjs +43 -0
- package/dist/oauth2/create-authorization-url.mjs.map +1 -0
- package/dist/oauth2/index.d.mts +8 -0
- package/dist/oauth2/index.mjs +8 -0
- package/dist/oauth2/oauth-provider.d.mts +195 -0
- package/dist/oauth2/refresh-access-token.d.mts +36 -0
- package/dist/oauth2/refresh-access-token.mjs +59 -0
- package/dist/oauth2/refresh-access-token.mjs.map +1 -0
- package/dist/oauth2/utils.d.mts +8 -0
- package/dist/oauth2/utils.mjs +28 -0
- package/dist/oauth2/utils.mjs.map +1 -0
- package/dist/oauth2/validate-authorization-code.d.mts +56 -0
- package/dist/oauth2/validate-authorization-code.mjs +72 -0
- package/dist/oauth2/validate-authorization-code.mjs.map +1 -0
- package/dist/oauth2/verify.d.mts +43 -0
- package/dist/oauth2/verify.mjs +96 -0
- package/dist/oauth2/verify.mjs.map +1 -0
- package/dist/social-providers/apple.d.mts +120 -0
- package/dist/social-providers/apple.mjs +105 -0
- package/dist/social-providers/apple.mjs.map +1 -0
- package/dist/social-providers/atlassian.d.mts +73 -0
- package/dist/social-providers/atlassian.mjs +84 -0
- package/dist/social-providers/atlassian.mjs.map +1 -0
- package/dist/social-providers/cognito.d.mts +88 -0
- package/dist/social-providers/cognito.mjs +166 -0
- package/dist/social-providers/cognito.mjs.map +1 -0
- package/dist/social-providers/discord.d.mts +127 -0
- package/dist/social-providers/discord.mjs +65 -0
- package/dist/social-providers/discord.mjs.map +1 -0
- package/dist/social-providers/dropbox.d.mts +72 -0
- package/dist/social-providers/dropbox.mjs +76 -0
- package/dist/social-providers/dropbox.mjs.map +1 -0
- package/dist/social-providers/facebook.d.mts +82 -0
- package/dist/social-providers/facebook.mjs +121 -0
- package/dist/social-providers/facebook.mjs.map +1 -0
- package/dist/social-providers/figma.d.mts +64 -0
- package/dist/social-providers/figma.mjs +87 -0
- package/dist/social-providers/figma.mjs.map +1 -0
- package/dist/social-providers/github.d.mts +105 -0
- package/dist/social-providers/github.mjs +97 -0
- package/dist/social-providers/github.mjs.map +1 -0
- package/dist/social-providers/gitlab.d.mts +126 -0
- package/dist/social-providers/gitlab.mjs +83 -0
- package/dist/social-providers/gitlab.mjs.map +1 -0
- package/dist/social-providers/google.d.mts +100 -0
- package/dist/social-providers/google.mjs +109 -0
- package/dist/social-providers/google.mjs.map +1 -0
- package/dist/social-providers/huggingface.d.mts +86 -0
- package/dist/social-providers/huggingface.mjs +76 -0
- package/dist/social-providers/huggingface.mjs.map +1 -0
- package/dist/social-providers/index.d.mts +1725 -0
- package/dist/social-providers/index.mjs +77 -0
- package/dist/social-providers/index.mjs.map +1 -0
- package/dist/social-providers/kakao.d.mts +164 -0
- package/dist/social-providers/kakao.mjs +73 -0
- package/dist/social-providers/kakao.mjs.map +1 -0
- package/dist/social-providers/kick.d.mts +76 -0
- package/dist/social-providers/kick.mjs +72 -0
- package/dist/social-providers/kick.mjs.map +1 -0
- package/dist/social-providers/line.d.mts +108 -0
- package/dist/social-providers/line.mjs +114 -0
- package/dist/social-providers/line.mjs.map +1 -0
- package/dist/social-providers/linear.d.mts +71 -0
- package/dist/social-providers/linear.mjs +89 -0
- package/dist/social-providers/linear.mjs.map +1 -0
- package/dist/social-providers/linkedin.d.mts +70 -0
- package/dist/social-providers/linkedin.mjs +77 -0
- package/dist/social-providers/linkedin.mjs.map +1 -0
- package/dist/social-providers/microsoft-entra-id.d.mts +175 -0
- package/dist/social-providers/microsoft-entra-id.mjs +107 -0
- package/dist/social-providers/microsoft-entra-id.mjs.map +1 -0
- package/dist/social-providers/naver.d.mts +95 -0
- package/dist/social-providers/naver.mjs +68 -0
- package/dist/social-providers/naver.mjs.map +1 -0
- package/dist/social-providers/notion.d.mts +67 -0
- package/dist/social-providers/notion.mjs +76 -0
- package/dist/social-providers/notion.mjs.map +1 -0
- package/dist/social-providers/paybin.d.mts +74 -0
- package/dist/social-providers/paybin.mjs +86 -0
- package/dist/social-providers/paybin.mjs.map +1 -0
- package/dist/social-providers/paypal.d.mts +132 -0
- package/dist/social-providers/paypal.mjs +145 -0
- package/dist/social-providers/paypal.mjs.map +1 -0
- package/dist/social-providers/polar.d.mts +77 -0
- package/dist/social-providers/polar.mjs +74 -0
- package/dist/social-providers/polar.mjs.map +1 -0
- package/dist/social-providers/reddit.d.mts +65 -0
- package/dist/social-providers/reddit.mjs +84 -0
- package/dist/social-providers/reddit.mjs.map +1 -0
- package/dist/social-providers/roblox.d.mts +73 -0
- package/dist/social-providers/roblox.mjs +60 -0
- package/dist/social-providers/roblox.mjs.map +1 -0
- package/dist/social-providers/salesforce.d.mts +82 -0
- package/dist/social-providers/salesforce.mjs +92 -0
- package/dist/social-providers/salesforce.mjs.map +1 -0
- package/dist/social-providers/slack.d.mts +86 -0
- package/dist/social-providers/slack.mjs +69 -0
- package/dist/social-providers/slack.mjs.map +1 -0
- package/dist/social-providers/spotify.d.mts +66 -0
- package/dist/social-providers/spotify.mjs +72 -0
- package/dist/social-providers/spotify.mjs.map +1 -0
- package/dist/social-providers/tiktok.d.mts +171 -0
- package/dist/social-providers/tiktok.mjs +63 -0
- package/dist/social-providers/tiktok.mjs.map +1 -0
- package/dist/social-providers/twitch.d.mts +82 -0
- package/dist/social-providers/twitch.mjs +79 -0
- package/dist/social-providers/twitch.mjs.map +1 -0
- package/dist/social-providers/twitter.d.mts +129 -0
- package/dist/social-providers/twitter.mjs +88 -0
- package/dist/social-providers/twitter.mjs.map +1 -0
- package/dist/social-providers/vercel.d.mts +65 -0
- package/dist/social-providers/vercel.mjs +62 -0
- package/dist/social-providers/vercel.mjs.map +1 -0
- package/dist/social-providers/vk.d.mts +73 -0
- package/dist/social-providers/vk.mjs +84 -0
- package/dist/social-providers/vk.mjs.map +1 -0
- package/dist/social-providers/zoom.d.mts +173 -0
- package/dist/social-providers/zoom.mjs +73 -0
- package/dist/social-providers/zoom.mjs.map +1 -0
- package/dist/types/context.d.mts +267 -0
- package/dist/types/cookie.d.mts +16 -0
- package/dist/types/helper.d.mts +10 -0
- package/dist/types/index.d.mts +8 -0
- package/dist/types/init-options.d.mts +1314 -0
- package/dist/types/plugin-client.d.mts +112 -0
- package/dist/types/plugin.d.mts +125 -0
- package/dist/utils/db.d.mts +12 -0
- package/dist/utils/db.mjs +17 -0
- package/dist/utils/db.mjs.map +1 -0
- package/dist/utils/deprecate.d.mts +10 -0
- package/dist/utils/deprecate.mjs +18 -0
- package/dist/utils/deprecate.mjs.map +1 -0
- package/dist/utils/error-codes.d.mts +13 -0
- package/dist/utils/error-codes.mjs +12 -0
- package/dist/utils/error-codes.mjs.map +1 -0
- package/dist/utils/id.d.mts +5 -0
- package/dist/utils/id.mjs +10 -0
- package/dist/utils/id.mjs.map +1 -0
- package/dist/utils/ip.d.mts +55 -0
- package/dist/utils/ip.mjs +119 -0
- package/dist/utils/ip.mjs.map +1 -0
- package/dist/utils/json.d.mts +5 -0
- package/dist/utils/json.mjs +26 -0
- package/dist/utils/json.mjs.map +1 -0
- package/dist/utils/string.d.mts +5 -0
- package/dist/utils/string.mjs +8 -0
- package/dist/utils/string.mjs.map +1 -0
- package/dist/utils/url.d.mts +21 -0
- package/dist/utils/url.mjs +33 -0
- package/dist/utils/url.mjs.map +1 -0
- package/package.json +147 -0
- package/src/api/index.ts +106 -0
- package/src/async_hooks/index.ts +40 -0
- package/src/async_hooks/pure.index.ts +46 -0
- package/src/context/endpoint-context.ts +50 -0
- package/src/context/global.ts +57 -0
- package/src/context/index.ts +23 -0
- package/src/context/request-state.test.ts +94 -0
- package/src/context/request-state.ts +91 -0
- package/src/context/transaction.ts +136 -0
- package/src/db/adapter/factory.ts +1362 -0
- package/src/db/adapter/get-default-field-name.ts +59 -0
- package/src/db/adapter/get-default-model-name.ts +51 -0
- package/src/db/adapter/get-field-attributes.ts +62 -0
- package/src/db/adapter/get-field-name.ts +43 -0
- package/src/db/adapter/get-id-field.ts +141 -0
- package/src/db/adapter/get-model-name.ts +36 -0
- package/src/db/adapter/index.ts +554 -0
- package/src/db/adapter/types.ts +171 -0
- package/src/db/adapter/utils.ts +61 -0
- package/src/db/get-tables.ts +296 -0
- package/src/db/index.ts +18 -0
- package/src/db/plugin.ts +11 -0
- package/src/db/schema/account.ts +34 -0
- package/src/db/schema/rate-limit.ts +21 -0
- package/src/db/schema/session.ts +17 -0
- package/src/db/schema/shared.ts +7 -0
- package/src/db/schema/user.ts +16 -0
- package/src/db/schema/verification.ts +15 -0
- package/src/db/test/get-tables.test.ts +116 -0
- package/src/db/type.ts +180 -0
- package/src/env/color-depth.ts +172 -0
- package/src/env/env-impl.ts +124 -0
- package/src/env/index.ts +23 -0
- package/src/env/logger.test.ts +34 -0
- package/src/env/logger.ts +145 -0
- package/src/error/codes.ts +58 -0
- package/src/error/index.ts +35 -0
- package/src/index.ts +1 -0
- package/src/oauth2/client-credentials-token.ts +102 -0
- package/src/oauth2/create-authorization-url.ts +87 -0
- package/src/oauth2/index.ts +26 -0
- package/src/oauth2/oauth-provider.ts +222 -0
- package/src/oauth2/refresh-access-token.ts +124 -0
- package/src/oauth2/utils.ts +38 -0
- package/src/oauth2/validate-authorization-code.ts +149 -0
- package/src/oauth2/validate-token.test.ts +174 -0
- package/src/oauth2/verify.ts +221 -0
- package/src/social-providers/apple.ts +223 -0
- package/src/social-providers/atlassian.ts +132 -0
- package/src/social-providers/cognito.ts +279 -0
- package/src/social-providers/discord.ts +169 -0
- package/src/social-providers/dropbox.ts +112 -0
- package/src/social-providers/facebook.ts +206 -0
- package/src/social-providers/figma.ts +117 -0
- package/src/social-providers/github.ts +184 -0
- package/src/social-providers/gitlab.ts +155 -0
- package/src/social-providers/google.ts +199 -0
- package/src/social-providers/huggingface.ts +118 -0
- package/src/social-providers/index.ts +127 -0
- package/src/social-providers/kakao.ts +178 -0
- package/src/social-providers/kick.ts +109 -0
- package/src/social-providers/line.ts +169 -0
- package/src/social-providers/linear.ts +121 -0
- package/src/social-providers/linkedin.ts +110 -0
- package/src/social-providers/microsoft-entra-id.ts +259 -0
- package/src/social-providers/naver.ts +112 -0
- package/src/social-providers/notion.ts +108 -0
- package/src/social-providers/paybin.ts +122 -0
- package/src/social-providers/paypal.ts +263 -0
- package/src/social-providers/polar.ts +110 -0
- package/src/social-providers/reddit.ts +122 -0
- package/src/social-providers/roblox.ts +111 -0
- package/src/social-providers/salesforce.ts +159 -0
- package/src/social-providers/slack.ts +111 -0
- package/src/social-providers/spotify.ts +93 -0
- package/src/social-providers/tiktok.ts +209 -0
- package/src/social-providers/twitch.ts +111 -0
- package/src/social-providers/twitter.ts +198 -0
- package/src/social-providers/vercel.ts +87 -0
- package/src/social-providers/vk.ts +124 -0
- package/src/social-providers/zoom.ts +238 -0
- package/src/types/context.ts +396 -0
- package/src/types/cookie.ts +10 -0
- package/src/types/helper.ts +26 -0
- package/src/types/index.ts +32 -0
- package/src/types/init-options.ts +1529 -0
- package/src/types/plugin-client.ts +127 -0
- package/src/types/plugin.ts +157 -0
- package/src/utils/db.ts +20 -0
- package/src/utils/deprecate.test.ts +72 -0
- package/src/utils/deprecate.ts +21 -0
- package/src/utils/error-codes.ts +65 -0
- package/src/utils/id.ts +5 -0
- package/src/utils/ip.test.ts +255 -0
- package/src/utils/ip.ts +211 -0
- package/src/utils/json.ts +25 -0
- package/src/utils/string.ts +3 -0
- package/src/utils/url.ts +43 -0
- package/tsconfig.json +7 -0
- package/tsdown.config.ts +35 -0
- package/vitest.config.ts +3 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { logger } from "../env/logger.mjs";
|
|
2
|
+
import "../env/index.mjs";
|
|
3
|
+
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
4
|
+
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
5
|
+
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
6
|
+
import "../oauth2/index.mjs";
|
|
7
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
8
|
+
import { decodeJwt } from "jose";
|
|
9
|
+
import { base64 } from "@better-auth/utils/base64";
|
|
10
|
+
|
|
11
|
+
//#region src/social-providers/microsoft-entra-id.ts
|
|
12
|
+
const microsoft = (options) => {
|
|
13
|
+
const tenant = options.tenantId || "common";
|
|
14
|
+
const authority = options.authority || "https://login.microsoftonline.com";
|
|
15
|
+
const authorizationEndpoint = `${authority}/${tenant}/oauth2/v2.0/authorize`;
|
|
16
|
+
const tokenEndpoint = `${authority}/${tenant}/oauth2/v2.0/token`;
|
|
17
|
+
return {
|
|
18
|
+
id: "microsoft",
|
|
19
|
+
name: "Microsoft EntraID",
|
|
20
|
+
createAuthorizationURL(data) {
|
|
21
|
+
const scopes = options.disableDefaultScope ? [] : [
|
|
22
|
+
"openid",
|
|
23
|
+
"profile",
|
|
24
|
+
"email",
|
|
25
|
+
"User.Read",
|
|
26
|
+
"offline_access"
|
|
27
|
+
];
|
|
28
|
+
if (options.scope) scopes.push(...options.scope);
|
|
29
|
+
if (data.scopes) scopes.push(...data.scopes);
|
|
30
|
+
return createAuthorizationURL({
|
|
31
|
+
id: "microsoft",
|
|
32
|
+
options,
|
|
33
|
+
authorizationEndpoint,
|
|
34
|
+
state: data.state,
|
|
35
|
+
codeVerifier: data.codeVerifier,
|
|
36
|
+
scopes,
|
|
37
|
+
redirectURI: data.redirectURI,
|
|
38
|
+
prompt: options.prompt,
|
|
39
|
+
loginHint: data.loginHint
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
validateAuthorizationCode({ code, codeVerifier, redirectURI }) {
|
|
43
|
+
return validateAuthorizationCode({
|
|
44
|
+
code,
|
|
45
|
+
codeVerifier,
|
|
46
|
+
redirectURI,
|
|
47
|
+
options,
|
|
48
|
+
tokenEndpoint
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
async getUserInfo(token) {
|
|
52
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
53
|
+
if (!token.idToken) return null;
|
|
54
|
+
const user = decodeJwt(token.idToken);
|
|
55
|
+
const profilePhotoSize = options.profilePhotoSize || 48;
|
|
56
|
+
await betterFetch(`https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`, {
|
|
57
|
+
headers: { Authorization: `Bearer ${token.accessToken}` },
|
|
58
|
+
async onResponse(context) {
|
|
59
|
+
if (options.disableProfilePhoto || !context.response.ok) return;
|
|
60
|
+
try {
|
|
61
|
+
const pictureBuffer = await context.response.clone().arrayBuffer();
|
|
62
|
+
user.picture = `data:image/jpeg;base64, ${base64.encode(pictureBuffer)}`;
|
|
63
|
+
} catch (e) {
|
|
64
|
+
logger.error(e && typeof e === "object" && "name" in e ? e.name : "", e);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const userMap = await options.mapProfileToUser?.(user);
|
|
69
|
+
const emailVerified = user.email_verified !== void 0 ? user.email_verified : user.email && (user.verified_primary_email?.includes(user.email) || user.verified_secondary_email?.includes(user.email)) ? true : false;
|
|
70
|
+
return {
|
|
71
|
+
user: {
|
|
72
|
+
id: user.sub,
|
|
73
|
+
name: user.name,
|
|
74
|
+
email: user.email,
|
|
75
|
+
image: user.picture,
|
|
76
|
+
emailVerified,
|
|
77
|
+
...userMap
|
|
78
|
+
},
|
|
79
|
+
data: user
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
83
|
+
const scopes = options.disableDefaultScope ? [] : [
|
|
84
|
+
"openid",
|
|
85
|
+
"profile",
|
|
86
|
+
"email",
|
|
87
|
+
"User.Read",
|
|
88
|
+
"offline_access"
|
|
89
|
+
];
|
|
90
|
+
if (options.scope) scopes.push(...options.scope);
|
|
91
|
+
return refreshAccessToken({
|
|
92
|
+
refreshToken,
|
|
93
|
+
options: {
|
|
94
|
+
clientId: options.clientId,
|
|
95
|
+
clientSecret: options.clientSecret
|
|
96
|
+
},
|
|
97
|
+
extraParams: { scope: scopes.join(" ") },
|
|
98
|
+
tokenEndpoint
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
options
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
export { microsoft };
|
|
107
|
+
//# sourceMappingURL=microsoft-entra-id.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"microsoft-entra-id.mjs","names":[],"sources":["../../src/social-providers/microsoft-entra-id.ts"],"sourcesContent":["import { base64 } from \"@better-auth/utils/base64\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt } from \"jose\";\nimport { logger } from \"../env\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\n/**\n * @see [Microsoft Identity Platform - Optional claims reference](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims-reference)\n */\nexport interface MicrosoftEntraIDProfile extends Record<string, any> {\n\t/** Identifies the intended recipient of the token */\n\taud: string;\n\t/** Identifies the issuer, or \"authorization server\" that constructs and returns the token */\n\tiss: string;\n\t/** Indicates when the authentication for the token occurred */\n\tiat: Date;\n\t/** Records the identity provider that authenticated the subject of the token */\n\tidp: string;\n\t/** Identifies the time before which the JWT can't be accepted for processing */\n\tnbf: Date;\n\t/** Identifies the expiration time on or after which the JWT can't be accepted for processing */\n\texp: Date;\n\t/** Code hash included in ID tokens when issued with an OAuth 2.0 authorization code */\n\tc_hash: string;\n\t/** Access token hash included in ID tokens when issued with an OAuth 2.0 access token */\n\tat_hash: string;\n\t/** Internal claim used to record data for token reuse */\n\taio: string;\n\t/** The primary username that represents the user */\n\tpreferred_username: string;\n\t/** User's email address */\n\temail: string;\n\t/** Human-readable value that identifies the subject of the token */\n\tname: string;\n\t/** Matches the parameter included in the original authorize request */\n\tnonce: string;\n\t/** User's profile picture */\n\tpicture: string;\n\t/** Immutable identifier for the user account */\n\toid: string;\n\t/** Set of roles assigned to the user */\n\troles: string[];\n\t/** Internal claim used to revalidate tokens */\n\trh: string;\n\t/** Subject identifier - unique to application ID */\n\tsub: string;\n\t/** Tenant ID the user is signing in to */\n\ttid: string;\n\t/** Unique identifier for a session */\n\tsid: string;\n\t/** Token identifier claim */\n\tuti: string;\n\t/** Indicates if user is in at least one group */\n\thasgroups: boolean;\n\t/** User account status in tenant (0 = member, 1 = guest) */\n\tacct: 0 | 1;\n\t/** Auth Context IDs */\n\tacrs: string;\n\t/** Time when the user last authenticated */\n\tauth_time: Date;\n\t/** User's country/region */\n\tctry: string;\n\t/** IP address of requesting client when inside VNET */\n\tfwd: string;\n\t/** Group claims */\n\tgroups: string;\n\t/** Login hint for SSO */\n\tlogin_hint: string;\n\t/** Resource tenant's country/region */\n\ttenant_ctry: string;\n\t/** Region of the resource tenant */\n\ttenant_region_scope: string;\n\t/** UserPrincipalName */\n\tupn: string;\n\t/** User's verified primary email addresses */\n\tverified_primary_email: string[];\n\t/** User's verified secondary email addresses */\n\tverified_secondary_email: string[];\n\t/** Whether the user's email is verified (optional claim, must be configured in app registration) */\n\temail_verified?: boolean | undefined;\n\t/** VNET specifier information */\n\tvnet: string;\n\t/** Client Capabilities */\n\txms_cc: string;\n\t/** Whether user's email domain is verified */\n\txms_edov: boolean;\n\t/** Preferred data location for Multi-Geo tenants */\n\txms_pdl: string;\n\t/** User preferred language */\n\txms_pl: string;\n\t/** Tenant preferred language */\n\txms_tpl: string;\n\t/** Zero-touch Deployment ID */\n\tztdid: string;\n\t/** IP Address */\n\tipaddr: string;\n\t/** On-premises Security Identifier */\n\tonprem_sid: string;\n\t/** Password Expiration Time */\n\tpwd_exp: number;\n\t/** Change Password URL */\n\tpwd_url: string;\n\t/** Inside Corporate Network flag */\n\tin_corp: string;\n\t/** User's family name/surname */\n\tfamily_name: string;\n\t/** User's given/first name */\n\tgiven_name: string;\n}\n\nexport interface MicrosoftOptions\n\textends ProviderOptions<MicrosoftEntraIDProfile> {\n\tclientId: string;\n\t/**\n\t * The tenant ID of the Microsoft account\n\t * @default \"common\"\n\t */\n\ttenantId?: string | undefined;\n\t/**\n\t * The authentication authority URL. Use the default \"https://login.microsoftonline.com\" for standard Entra ID or \"https://<tenant-id>.ciamlogin.com\" for CIAM scenarios.\n\t * @default \"https://login.microsoftonline.com\"\n\t */\n\tauthority?: string | undefined;\n\t/**\n\t * The size of the profile photo\n\t * @default 48\n\t */\n\tprofilePhotoSize?:\n\t\t| (48 | 64 | 96 | 120 | 240 | 360 | 432 | 504 | 648)\n\t\t| undefined;\n\t/**\n\t * Disable profile photo\n\t */\n\tdisableProfilePhoto?: boolean | undefined;\n}\n\nexport const microsoft = (options: MicrosoftOptions) => {\n\tconst tenant = options.tenantId || \"common\";\n\tconst authority = options.authority || \"https://login.microsoftonline.com\";\n\tconst authorizationEndpoint = `${authority}/${tenant}/oauth2/v2.0/authorize`;\n\tconst tokenEndpoint = `${authority}/${tenant}/oauth2/v2.0/token`;\n\treturn {\n\t\tid: \"microsoft\",\n\t\tname: \"Microsoft EntraID\",\n\t\tcreateAuthorizationURL(data) {\n\t\t\tconst scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\", \"User.Read\", \"offline_access\"];\n\t\t\tif (options.scope) scopes.push(...options.scope);\n\t\t\tif (data.scopes) scopes.push(...data.scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"microsoft\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tstate: data.state,\n\t\t\t\tcodeVerifier: data.codeVerifier,\n\t\t\t\tscopes,\n\t\t\t\tredirectURI: data.redirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t\tloginHint: data.loginHint,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode({ 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\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 MicrosoftEntraIDProfile;\n\t\t\tconst profilePhotoSize = options.profilePhotoSize || 48;\n\t\t\tawait betterFetch<ArrayBuffer>(\n\t\t\t\t`https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`,\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\tasync onResponse(context) {\n\t\t\t\t\t\tif (options.disableProfilePhoto || !context.response.ok) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst response = context.response.clone();\n\t\t\t\t\t\t\tconst pictureBuffer = await response.arrayBuffer();\n\t\t\t\t\t\t\tconst pictureBase64 = base64.encode(pictureBuffer);\n\t\t\t\t\t\t\tuser.picture = `data:image/jpeg;base64, ${pictureBase64}`;\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t\t\te && typeof e === \"object\" && \"name\" in e\n\t\t\t\t\t\t\t\t\t? (e.name as string)\n\t\t\t\t\t\t\t\t\t: \"\",\n\t\t\t\t\t\t\t\te,\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\tconst userMap = await options.mapProfileToUser?.(user);\n\t\t\t// Microsoft Entra ID does NOT include email_verified claim by default.\n\t\t\t// It must be configured as an optional claim in the app registration.\n\t\t\t// We default to false when not provided for security consistency.\n\t\t\t// We can also check verified_primary_email/verified_secondary_email arrays as fallback.\n\t\t\tconst emailVerified =\n\t\t\t\tuser.email_verified !== undefined\n\t\t\t\t\t? user.email_verified\n\t\t\t\t\t: user.email &&\n\t\t\t\t\t\t\t(user.verified_primary_email?.includes(user.email) ||\n\t\t\t\t\t\t\t\tuser.verified_secondary_email?.includes(user.email))\n\t\t\t\t\t\t? true\n\t\t\t\t\t\t: false;\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,\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\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\tconst scopes = options.disableDefaultScope\n\t\t\t\t\t\t? []\n\t\t\t\t\t\t: [\"openid\", \"profile\", \"email\", \"User.Read\", \"offline_access\"];\n\t\t\t\t\tif (options.scope) scopes.push(...options.scope);\n\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\textraParams: {\n\t\t\t\t\t\t\tscope: scopes.join(\" \"), // Include the scopes in request to microsoft\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\toptions,\n\t} satisfies OAuthProvider;\n};\n"],"mappings":";;;;;;;;;;;AA6IA,MAAa,aAAa,YAA8B;CACvD,MAAM,SAAS,QAAQ,YAAY;CACnC,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,wBAAwB,GAAG,UAAU,GAAG,OAAO;CACrD,MAAM,gBAAgB,GAAG,UAAU,GAAG,OAAO;AAC7C,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,MAAM;GAC5B,MAAM,SAAS,QAAQ,sBACpB,EAAE,GACF;IAAC;IAAU;IAAW;IAAS;IAAa;IAAiB;AAChE,OAAI,QAAQ,MAAO,QAAO,KAAK,GAAG,QAAQ,MAAM;AAChD,OAAI,KAAK,OAAQ,QAAO,KAAK,GAAG,KAAK,OAAO;AAC5C,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA;IACA,OAAO,KAAK;IACZ,cAAc,KAAK;IACnB;IACA,aAAa,KAAK;IAClB,QAAQ,QAAQ;IAChB,WAAW,KAAK;IAChB,CAAC;;EAEH,0BAA0B,EAAE,MAAM,cAAc,eAAe;AAC9D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,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,mBAAmB,QAAQ,oBAAoB;AACrD,SAAM,YACL,8CAA8C,iBAAiB,GAAG,iBAAiB,UACnF;IACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B;IACD,MAAM,WAAW,SAAS;AACzB,SAAI,QAAQ,uBAAuB,CAAC,QAAQ,SAAS,GACpD;AAED,SAAI;MAEH,MAAM,gBAAgB,MADL,QAAQ,SAAS,OAAO,CACJ,aAAa;AAElD,WAAK,UAAU,2BADO,OAAO,OAAO,cAAc;cAE1C,GAAG;AACX,aAAO,MACN,KAAK,OAAO,MAAM,YAAY,UAAU,IACpC,EAAE,OACH,IACH,EACA;;;IAGH,CACD;GACD,MAAM,UAAU,MAAM,QAAQ,mBAAmB,KAAK;GAKtD,MAAM,gBACL,KAAK,mBAAmB,SACrB,KAAK,iBACL,KAAK,UACJ,KAAK,wBAAwB,SAAS,KAAK,MAAM,IACjD,KAAK,0BAA0B,SAAS,KAAK,MAAM,IACnD,OACA;AACL,UAAO;IACN,MAAM;KACL,IAAI,KAAK;KACT,MAAM,KAAK;KACX,OAAO,KAAK;KACZ,OAAO,KAAK;KACZ;KACA,GAAG;KACH;IACD,MAAM;IACN;;EAEF,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;GACxB,MAAM,SAAS,QAAQ,sBACpB,EAAE,GACF;IAAC;IAAU;IAAW;IAAS;IAAa;IAAiB;AAChE,OAAI,QAAQ,MAAO,QAAO,KAAK,GAAG,QAAQ,MAAM;AAEhD,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,cAAc,QAAQ;KACtB;IACD,aAAa,EACZ,OAAO,OAAO,KAAK,IAAI,EACvB;IACD;IACA,CAAC;;EAEL;EACA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/social-providers/naver.d.ts
|
|
5
|
+
interface NaverProfile {
|
|
6
|
+
/** API response result code */
|
|
7
|
+
resultcode: string;
|
|
8
|
+
/** API response message */
|
|
9
|
+
message: string;
|
|
10
|
+
response: {
|
|
11
|
+
/** Unique Naver user identifier */id: string; /** User nickname */
|
|
12
|
+
nickname: string; /** User real name */
|
|
13
|
+
name: string; /** User email address */
|
|
14
|
+
email: string; /** Gender (F: female, M: male, U: unknown) */
|
|
15
|
+
gender: string; /** Age range */
|
|
16
|
+
age: string; /** Birthday (MM-DD format) */
|
|
17
|
+
birthday: string; /** Birth year */
|
|
18
|
+
birthyear: string; /** Profile image URL */
|
|
19
|
+
profile_image: string; /** Mobile phone number */
|
|
20
|
+
mobile: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
interface NaverOptions extends ProviderOptions<NaverProfile> {
|
|
24
|
+
clientId: string;
|
|
25
|
+
}
|
|
26
|
+
declare const naver: (options: NaverOptions) => {
|
|
27
|
+
id: "naver";
|
|
28
|
+
name: string;
|
|
29
|
+
createAuthorizationURL({
|
|
30
|
+
state,
|
|
31
|
+
scopes,
|
|
32
|
+
redirectURI
|
|
33
|
+
}: {
|
|
34
|
+
state: string;
|
|
35
|
+
codeVerifier: string;
|
|
36
|
+
scopes?: string[] | undefined;
|
|
37
|
+
redirectURI: string;
|
|
38
|
+
display?: string | undefined;
|
|
39
|
+
loginHint?: string | undefined;
|
|
40
|
+
}): Promise<URL>;
|
|
41
|
+
validateAuthorizationCode: ({
|
|
42
|
+
code,
|
|
43
|
+
redirectURI
|
|
44
|
+
}: {
|
|
45
|
+
code: string;
|
|
46
|
+
redirectURI: string;
|
|
47
|
+
codeVerifier?: string | undefined;
|
|
48
|
+
deviceId?: string | undefined;
|
|
49
|
+
}) => Promise<OAuth2Tokens>;
|
|
50
|
+
refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
|
|
51
|
+
getUserInfo(token: OAuth2Tokens & {
|
|
52
|
+
user?: {
|
|
53
|
+
name?: {
|
|
54
|
+
firstName?: string;
|
|
55
|
+
lastName?: string;
|
|
56
|
+
};
|
|
57
|
+
email?: string;
|
|
58
|
+
} | undefined;
|
|
59
|
+
}): Promise<{
|
|
60
|
+
user: {
|
|
61
|
+
id: string;
|
|
62
|
+
name?: string;
|
|
63
|
+
email?: string | null;
|
|
64
|
+
image?: string;
|
|
65
|
+
emailVerified: boolean;
|
|
66
|
+
[key: string]: any;
|
|
67
|
+
};
|
|
68
|
+
data: any;
|
|
69
|
+
} | {
|
|
70
|
+
user: {
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
email: string;
|
|
74
|
+
image: string;
|
|
75
|
+
emailVerified: boolean;
|
|
76
|
+
} | {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
email: string | null;
|
|
80
|
+
image: string;
|
|
81
|
+
emailVerified: boolean;
|
|
82
|
+
} | {
|
|
83
|
+
id: string;
|
|
84
|
+
name: string;
|
|
85
|
+
email: string | null;
|
|
86
|
+
image: string;
|
|
87
|
+
emailVerified: boolean;
|
|
88
|
+
};
|
|
89
|
+
data: NaverProfile;
|
|
90
|
+
} | null>;
|
|
91
|
+
options: NaverOptions;
|
|
92
|
+
};
|
|
93
|
+
//#endregion
|
|
94
|
+
export { NaverOptions, NaverProfile, naver };
|
|
95
|
+
//# sourceMappingURL=naver.d.mts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
|
+
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
|
+
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
|
+
import "../oauth2/index.mjs";
|
|
5
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
6
|
+
|
|
7
|
+
//#region src/social-providers/naver.ts
|
|
8
|
+
const naver = (options) => {
|
|
9
|
+
return {
|
|
10
|
+
id: "naver",
|
|
11
|
+
name: "Naver",
|
|
12
|
+
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
13
|
+
const _scopes = options.disableDefaultScope ? [] : ["profile", "email"];
|
|
14
|
+
if (options.scope) _scopes.push(...options.scope);
|
|
15
|
+
if (scopes) _scopes.push(...scopes);
|
|
16
|
+
return createAuthorizationURL({
|
|
17
|
+
id: "naver",
|
|
18
|
+
options,
|
|
19
|
+
authorizationEndpoint: "https://nid.naver.com/oauth2.0/authorize",
|
|
20
|
+
scopes: _scopes,
|
|
21
|
+
state,
|
|
22
|
+
redirectURI
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
26
|
+
return validateAuthorizationCode({
|
|
27
|
+
code,
|
|
28
|
+
redirectURI,
|
|
29
|
+
options,
|
|
30
|
+
tokenEndpoint: "https://nid.naver.com/oauth2.0/token"
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
34
|
+
return refreshAccessToken({
|
|
35
|
+
refreshToken,
|
|
36
|
+
options: {
|
|
37
|
+
clientId: options.clientId,
|
|
38
|
+
clientKey: options.clientKey,
|
|
39
|
+
clientSecret: options.clientSecret
|
|
40
|
+
},
|
|
41
|
+
tokenEndpoint: "https://nid.naver.com/oauth2.0/token"
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
async getUserInfo(token) {
|
|
45
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
46
|
+
const { data: profile, error } = await betterFetch("https://openapi.naver.com/v1/nid/me", { headers: { Authorization: `Bearer ${token.accessToken}` } });
|
|
47
|
+
if (error || !profile || profile.resultcode !== "00") return null;
|
|
48
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
49
|
+
const res = profile.response || {};
|
|
50
|
+
return {
|
|
51
|
+
user: {
|
|
52
|
+
id: res.id,
|
|
53
|
+
name: res.name || res.nickname,
|
|
54
|
+
email: res.email,
|
|
55
|
+
image: res.profile_image,
|
|
56
|
+
emailVerified: false,
|
|
57
|
+
...userMap
|
|
58
|
+
},
|
|
59
|
+
data: profile
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
options
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { naver };
|
|
68
|
+
//# sourceMappingURL=naver.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naver.mjs","names":[],"sources":["../../src/social-providers/naver.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 NaverProfile {\n\t/** API response result code */\n\tresultcode: string;\n\t/** API response message */\n\tmessage: string;\n\tresponse: {\n\t\t/** Unique Naver user identifier */\n\t\tid: string;\n\t\t/** User nickname */\n\t\tnickname: string;\n\t\t/** User real name */\n\t\tname: string;\n\t\t/** User email address */\n\t\temail: string;\n\t\t/** Gender (F: female, M: male, U: unknown) */\n\t\tgender: string;\n\t\t/** Age range */\n\t\tage: string;\n\t\t/** Birthday (MM-DD format) */\n\t\tbirthday: string;\n\t\t/** Birth year */\n\t\tbirthyear: string;\n\t\t/** Profile image URL */\n\t\tprofile_image: string;\n\t\t/** Mobile phone number */\n\t\tmobile: string;\n\t};\n}\n\nexport interface NaverOptions extends ProviderOptions<NaverProfile> {\n\tclientId: string;\n}\n\nexport const naver = (options: NaverOptions) => {\n\treturn {\n\t\tid: \"naver\",\n\t\tname: \"Naver\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"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: \"naver\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://nid.naver.com/oauth2.0/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: \"https://nid.naver.com/oauth2.0/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://nid.naver.com/oauth2.0/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\t\t\tconst { data: profile, error } = await betterFetch<NaverProfile>(\n\t\t\t\t\"https://openapi.naver.com/v1/nid/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 || profile.resultcode !== \"00\") {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\tconst res = profile.response || {};\n\t\t\tconst user = {\n\t\t\t\tid: res.id,\n\t\t\t\tname: res.name || res.nickname,\n\t\t\t\temail: res.email,\n\t\t\t\timage: res.profile_image,\n\t\t\t\temailVerified: false,\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<NaverProfile>;\n};\n"],"mappings":";;;;;;;AAyCA,MAAa,SAAS,YAA0B;AAC/C,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GACtD,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,WAAW,QAAQ;AACvE,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,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,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,uCACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AACD,OAAI,SAAS,CAAC,WAAW,QAAQ,eAAe,KAC/C,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;GACzD,MAAM,MAAM,QAAQ,YAAY,EAAE;AASlC,UAAO;IACN,MATY;KACZ,IAAI,IAAI;KACR,MAAM,IAAI,QAAQ,IAAI;KACtB,OAAO,IAAI;KACX,OAAO,IAAI;KACX,eAAe;KACf,GAAG;KACH;IAGA,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/social-providers/notion.d.ts
|
|
5
|
+
interface NotionProfile {
|
|
6
|
+
object: "user";
|
|
7
|
+
id: string;
|
|
8
|
+
type: "person" | "bot";
|
|
9
|
+
name?: string | undefined;
|
|
10
|
+
avatar_url?: string | undefined;
|
|
11
|
+
person?: {
|
|
12
|
+
email?: string;
|
|
13
|
+
} | undefined;
|
|
14
|
+
}
|
|
15
|
+
interface NotionOptions extends ProviderOptions<NotionProfile> {
|
|
16
|
+
clientId: string;
|
|
17
|
+
}
|
|
18
|
+
declare const notion: (options: NotionOptions) => {
|
|
19
|
+
id: "notion";
|
|
20
|
+
name: string;
|
|
21
|
+
createAuthorizationURL({
|
|
22
|
+
state,
|
|
23
|
+
scopes,
|
|
24
|
+
loginHint,
|
|
25
|
+
redirectURI
|
|
26
|
+
}: {
|
|
27
|
+
state: string;
|
|
28
|
+
codeVerifier: string;
|
|
29
|
+
scopes?: string[] | undefined;
|
|
30
|
+
redirectURI: string;
|
|
31
|
+
display?: string | undefined;
|
|
32
|
+
loginHint?: string | undefined;
|
|
33
|
+
}): Promise<URL>;
|
|
34
|
+
validateAuthorizationCode: ({
|
|
35
|
+
code,
|
|
36
|
+
redirectURI
|
|
37
|
+
}: {
|
|
38
|
+
code: string;
|
|
39
|
+
redirectURI: string;
|
|
40
|
+
codeVerifier?: string | undefined;
|
|
41
|
+
deviceId?: string | undefined;
|
|
42
|
+
}) => Promise<OAuth2Tokens>;
|
|
43
|
+
refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
|
|
44
|
+
getUserInfo(token: OAuth2Tokens & {
|
|
45
|
+
user?: {
|
|
46
|
+
name?: {
|
|
47
|
+
firstName?: string;
|
|
48
|
+
lastName?: string;
|
|
49
|
+
};
|
|
50
|
+
email?: string;
|
|
51
|
+
} | undefined;
|
|
52
|
+
}): Promise<{
|
|
53
|
+
user: {
|
|
54
|
+
id: string;
|
|
55
|
+
name?: string;
|
|
56
|
+
email?: string | null;
|
|
57
|
+
image?: string;
|
|
58
|
+
emailVerified: boolean;
|
|
59
|
+
[key: string]: any;
|
|
60
|
+
};
|
|
61
|
+
data: any;
|
|
62
|
+
} | null>;
|
|
63
|
+
options: NotionOptions;
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { NotionOptions, NotionProfile, notion };
|
|
67
|
+
//# sourceMappingURL=notion.d.mts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
2
|
+
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
3
|
+
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
4
|
+
import "../oauth2/index.mjs";
|
|
5
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
6
|
+
|
|
7
|
+
//#region src/social-providers/notion.ts
|
|
8
|
+
const notion = (options) => {
|
|
9
|
+
const tokenEndpoint = "https://api.notion.com/v1/oauth/token";
|
|
10
|
+
return {
|
|
11
|
+
id: "notion",
|
|
12
|
+
name: "Notion",
|
|
13
|
+
createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
|
|
14
|
+
const _scopes = options.disableDefaultScope ? [] : [];
|
|
15
|
+
if (options.scope) _scopes.push(...options.scope);
|
|
16
|
+
if (scopes) _scopes.push(...scopes);
|
|
17
|
+
return createAuthorizationURL({
|
|
18
|
+
id: "notion",
|
|
19
|
+
options,
|
|
20
|
+
authorizationEndpoint: "https://api.notion.com/v1/oauth/authorize",
|
|
21
|
+
scopes: _scopes,
|
|
22
|
+
state,
|
|
23
|
+
redirectURI,
|
|
24
|
+
loginHint,
|
|
25
|
+
additionalParams: { owner: "user" }
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
29
|
+
return validateAuthorizationCode({
|
|
30
|
+
code,
|
|
31
|
+
redirectURI,
|
|
32
|
+
options,
|
|
33
|
+
tokenEndpoint,
|
|
34
|
+
authentication: "basic"
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
38
|
+
return refreshAccessToken({
|
|
39
|
+
refreshToken,
|
|
40
|
+
options: {
|
|
41
|
+
clientId: options.clientId,
|
|
42
|
+
clientKey: options.clientKey,
|
|
43
|
+
clientSecret: options.clientSecret
|
|
44
|
+
},
|
|
45
|
+
tokenEndpoint
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
async getUserInfo(token) {
|
|
49
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
50
|
+
const { data: profile, error } = await betterFetch("https://api.notion.com/v1/users/me", { headers: {
|
|
51
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
52
|
+
"Notion-Version": "2022-06-28"
|
|
53
|
+
} });
|
|
54
|
+
if (error || !profile) return null;
|
|
55
|
+
const userProfile = profile.bot?.owner?.user;
|
|
56
|
+
if (!userProfile) return null;
|
|
57
|
+
const userMap = await options.mapProfileToUser?.(userProfile);
|
|
58
|
+
return {
|
|
59
|
+
user: {
|
|
60
|
+
id: userProfile.id,
|
|
61
|
+
name: userProfile.name || "Notion User",
|
|
62
|
+
email: userProfile.person?.email || null,
|
|
63
|
+
image: userProfile.avatar_url,
|
|
64
|
+
emailVerified: false,
|
|
65
|
+
...userMap
|
|
66
|
+
},
|
|
67
|
+
data: userProfile
|
|
68
|
+
};
|
|
69
|
+
},
|
|
70
|
+
options
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
export { notion };
|
|
76
|
+
//# sourceMappingURL=notion.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion.mjs","names":[],"sources":["../../src/social-providers/notion.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface NotionProfile {\n\tobject: \"user\";\n\tid: string;\n\ttype: \"person\" | \"bot\";\n\tname?: string | undefined;\n\tavatar_url?: string | undefined;\n\tperson?:\n\t\t| {\n\t\t\t\temail?: string;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface NotionOptions extends ProviderOptions<NotionProfile> {\n\tclientId: string;\n}\n\nexport const notion = (options: NotionOptions) => {\n\tconst tokenEndpoint = \"https://api.notion.com/v1/oauth/token\";\n\treturn {\n\t\tid: \"notion\",\n\t\tname: \"Notion\",\n\t\tcreateAuthorizationURL({ state, scopes, loginHint, redirectURI }) {\n\t\t\tconst _scopes: string[] = options.disableDefaultScope ? [] : [];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"notion\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://api.notion.com/v1/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tloginHint,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\towner: \"user\",\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t\tauthentication: \"basic\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<{\n\t\t\t\tbot: {\n\t\t\t\t\towner: {\n\t\t\t\t\t\tuser: NotionProfile;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}>(\"https://api.notion.com/v1/users/me\", {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\"Notion-Version\": \"2022-06-28\",\n\t\t\t\t},\n\t\t\t});\n\t\t\tif (error || !profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userProfile = profile.bot?.owner?.user;\n\t\t\tif (!userProfile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(userProfile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: userProfile.id,\n\t\t\t\t\tname: userProfile.name || \"Notion User\",\n\t\t\t\t\temail: userProfile.person?.email || null,\n\t\t\t\t\timage: userProfile.avatar_url,\n\t\t\t\t\temailVerified: false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: userProfile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<NotionProfile>;\n};\n"],"mappings":";;;;;;;AAyBA,MAAa,UAAU,YAA2B;CACjD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,WAAW,eAAe;GACjE,MAAM,UAAoB,QAAQ,sBAAsB,EAAE,GAAG,EAAE;AAC/D,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,kBAAkB,EACjB,OAAO,QACP;IACD,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,gBAAgB;IAChB,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YAMpC,sCAAsC,EACxC,SAAS;IACR,eAAe,UAAU,MAAM;IAC/B,kBAAkB;IAClB,EACD,CAAC;AACF,OAAI,SAAS,CAAC,QACb,QAAO;GAER,MAAM,cAAc,QAAQ,KAAK,OAAO;AACxC,OAAI,CAAC,YACJ,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,YAAY;AAC7D,UAAO;IACN,MAAM;KACL,IAAI,YAAY;KAChB,MAAM,YAAY,QAAQ;KAC1B,OAAO,YAAY,QAAQ,SAAS;KACpC,OAAO,YAAY;KACnB,eAAe;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/social-providers/paybin.d.ts
|
|
5
|
+
interface PaybinProfile {
|
|
6
|
+
sub: string;
|
|
7
|
+
email: string;
|
|
8
|
+
email_verified?: boolean | undefined;
|
|
9
|
+
name?: string | undefined;
|
|
10
|
+
preferred_username?: string | undefined;
|
|
11
|
+
picture?: string | undefined;
|
|
12
|
+
given_name?: string | undefined;
|
|
13
|
+
family_name?: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
interface PaybinOptions extends ProviderOptions<PaybinProfile> {
|
|
16
|
+
clientId: string;
|
|
17
|
+
/**
|
|
18
|
+
* The issuer URL of your Paybin OAuth server
|
|
19
|
+
* @default "https://idp.paybin.io"
|
|
20
|
+
*/
|
|
21
|
+
issuer?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
declare const paybin: (options: PaybinOptions) => {
|
|
24
|
+
id: "paybin";
|
|
25
|
+
name: string;
|
|
26
|
+
createAuthorizationURL({
|
|
27
|
+
state,
|
|
28
|
+
scopes,
|
|
29
|
+
codeVerifier,
|
|
30
|
+
redirectURI,
|
|
31
|
+
loginHint
|
|
32
|
+
}: {
|
|
33
|
+
state: string;
|
|
34
|
+
codeVerifier: string;
|
|
35
|
+
scopes?: string[] | undefined;
|
|
36
|
+
redirectURI: string;
|
|
37
|
+
display?: string | undefined;
|
|
38
|
+
loginHint?: string | undefined;
|
|
39
|
+
}): Promise<URL>;
|
|
40
|
+
validateAuthorizationCode: ({
|
|
41
|
+
code,
|
|
42
|
+
codeVerifier,
|
|
43
|
+
redirectURI
|
|
44
|
+
}: {
|
|
45
|
+
code: string;
|
|
46
|
+
redirectURI: string;
|
|
47
|
+
codeVerifier?: string | undefined;
|
|
48
|
+
deviceId?: string | undefined;
|
|
49
|
+
}) => Promise<OAuth2Tokens>;
|
|
50
|
+
refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
|
|
51
|
+
getUserInfo(token: OAuth2Tokens & {
|
|
52
|
+
user?: {
|
|
53
|
+
name?: {
|
|
54
|
+
firstName?: string;
|
|
55
|
+
lastName?: string;
|
|
56
|
+
};
|
|
57
|
+
email?: string;
|
|
58
|
+
} | undefined;
|
|
59
|
+
}): Promise<{
|
|
60
|
+
user: {
|
|
61
|
+
id: string;
|
|
62
|
+
name?: string;
|
|
63
|
+
email?: string | null;
|
|
64
|
+
image?: string;
|
|
65
|
+
emailVerified: boolean;
|
|
66
|
+
[key: string]: any;
|
|
67
|
+
};
|
|
68
|
+
data: any;
|
|
69
|
+
} | null>;
|
|
70
|
+
options: PaybinOptions;
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
export { PaybinOptions, PaybinProfile, paybin };
|
|
74
|
+
//# sourceMappingURL=paybin.d.mts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { logger } from "../env/logger.mjs";
|
|
2
|
+
import "../env/index.mjs";
|
|
3
|
+
import { BetterAuthError } from "../error/index.mjs";
|
|
4
|
+
import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
|
|
5
|
+
import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
|
|
6
|
+
import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
|
|
7
|
+
import "../oauth2/index.mjs";
|
|
8
|
+
import { decodeJwt } from "jose";
|
|
9
|
+
|
|
10
|
+
//#region src/social-providers/paybin.ts
|
|
11
|
+
const paybin = (options) => {
|
|
12
|
+
const issuer = options.issuer || "https://idp.paybin.io";
|
|
13
|
+
const authorizationEndpoint = `${issuer}/oauth2/authorize`;
|
|
14
|
+
const tokenEndpoint = `${issuer}/oauth2/token`;
|
|
15
|
+
return {
|
|
16
|
+
id: "paybin",
|
|
17
|
+
name: "Paybin",
|
|
18
|
+
async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, loginHint }) {
|
|
19
|
+
if (!options.clientId || !options.clientSecret) {
|
|
20
|
+
logger.error("Client Id and Client Secret is required for Paybin. Make sure to provide them in the options.");
|
|
21
|
+
throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
|
|
22
|
+
}
|
|
23
|
+
if (!codeVerifier) throw new BetterAuthError("codeVerifier is required for Paybin");
|
|
24
|
+
const _scopes = options.disableDefaultScope ? [] : [
|
|
25
|
+
"openid",
|
|
26
|
+
"email",
|
|
27
|
+
"profile"
|
|
28
|
+
];
|
|
29
|
+
if (options.scope) _scopes.push(...options.scope);
|
|
30
|
+
if (scopes) _scopes.push(...scopes);
|
|
31
|
+
return await createAuthorizationURL({
|
|
32
|
+
id: "paybin",
|
|
33
|
+
options,
|
|
34
|
+
authorizationEndpoint,
|
|
35
|
+
scopes: _scopes,
|
|
36
|
+
state,
|
|
37
|
+
codeVerifier,
|
|
38
|
+
redirectURI,
|
|
39
|
+
prompt: options.prompt,
|
|
40
|
+
loginHint
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
44
|
+
return validateAuthorizationCode({
|
|
45
|
+
code,
|
|
46
|
+
codeVerifier,
|
|
47
|
+
redirectURI,
|
|
48
|
+
options,
|
|
49
|
+
tokenEndpoint
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
53
|
+
return refreshAccessToken({
|
|
54
|
+
refreshToken,
|
|
55
|
+
options: {
|
|
56
|
+
clientId: options.clientId,
|
|
57
|
+
clientKey: options.clientKey,
|
|
58
|
+
clientSecret: options.clientSecret
|
|
59
|
+
},
|
|
60
|
+
tokenEndpoint
|
|
61
|
+
});
|
|
62
|
+
},
|
|
63
|
+
async getUserInfo(token) {
|
|
64
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
65
|
+
if (!token.idToken) return null;
|
|
66
|
+
const user = decodeJwt(token.idToken);
|
|
67
|
+
const userMap = await options.mapProfileToUser?.(user);
|
|
68
|
+
return {
|
|
69
|
+
user: {
|
|
70
|
+
id: user.sub,
|
|
71
|
+
name: user.name || user.preferred_username || (user.email ? user.email.split("@")[0] : "User") || "User",
|
|
72
|
+
email: user.email,
|
|
73
|
+
image: user.picture,
|
|
74
|
+
emailVerified: user.email_verified || false,
|
|
75
|
+
...userMap
|
|
76
|
+
},
|
|
77
|
+
data: user
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
options
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
export { paybin };
|
|
86
|
+
//# sourceMappingURL=paybin.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paybin.mjs","names":[],"sources":["../../src/social-providers/paybin.ts"],"sourcesContent":["import { decodeJwt } from \"jose\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface PaybinProfile {\n\tsub: string;\n\temail: string;\n\temail_verified?: boolean | undefined;\n\tname?: string | undefined;\n\tpreferred_username?: string | undefined;\n\tpicture?: string | undefined;\n\tgiven_name?: string | undefined;\n\tfamily_name?: string | undefined;\n}\n\nexport interface PaybinOptions extends ProviderOptions<PaybinProfile> {\n\tclientId: string;\n\t/**\n\t * The issuer URL of your Paybin OAuth server\n\t * @default \"https://idp.paybin.io\"\n\t */\n\tissuer?: string | undefined;\n}\n\nexport const paybin = (options: PaybinOptions) => {\n\tconst issuer = options.issuer || \"https://idp.paybin.io\";\n\tconst authorizationEndpoint = `${issuer}/oauth2/authorize`;\n\tconst tokenEndpoint = `${issuer}/oauth2/token`;\n\n\treturn {\n\t\tid: \"paybin\",\n\t\tname: \"Paybin\",\n\t\tasync createAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t\tloginHint,\n\t\t}) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret is required for Paybin. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Paybin\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"email\", \"profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"paybin\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t\tloginHint,\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tif (!token.idToken) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst user = decodeJwt(token.idToken) as PaybinProfile;\n\t\t\tconst userMap = await options.mapProfileToUser?.(user);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: user.sub,\n\t\t\t\t\tname:\n\t\t\t\t\t\tuser.name ||\n\t\t\t\t\t\tuser.preferred_username ||\n\t\t\t\t\t\t(user.email ? user.email.split(\"@\")[0] : \"User\") ||\n\t\t\t\t\t\t\"User\",\n\t\t\t\t\temail: user.email,\n\t\t\t\t\timage: user.picture,\n\t\t\t\t\temailVerified: user.email_verified || false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: user,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<PaybinProfile>;\n};\n"],"mappings":";;;;;;;;;;AA8BA,MAAa,UAAU,YAA2B;CACjD,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,wBAAwB,GAAG,OAAO;CACxC,MAAM,gBAAgB,GAAG,OAAO;AAEhC,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAC5B,OACA,QACA,cACA,aACA,aACE;AACF,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MACN,gGACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,sCAAsC;GAEjE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAS;IAAU;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAYnC,UAXY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA,QAAQ,QAAQ;IAChB;IACA,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAElC,OAAI,CAAC,MAAM,QACV,QAAO;GAER,MAAM,OAAO,UAAU,MAAM,QAAQ;GACrC,MAAM,UAAU,MAAM,QAAQ,mBAAmB,KAAK;AACtD,UAAO;IACN,MAAM;KACL,IAAI,KAAK;KACT,MACC,KAAK,QACL,KAAK,uBACJ,KAAK,QAAQ,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,WACzC;KACD,OAAO,KAAK;KACZ,OAAO,KAAK;KACZ,eAAe,KAAK,kBAAkB;KACtC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
|