@better-auth/core 1.4.0-beta.13 → 1.4.0-beta.14
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 +37 -45
- package/dist/api/index.cjs +1 -1
- package/dist/api/index.d.cts +2 -6
- package/dist/api/index.d.ts +2 -6
- package/dist/api/index.js +1 -1
- package/dist/async_hooks/index.d.cts +1 -1
- package/dist/async_hooks/index.d.ts +1 -1
- package/dist/context/index.cjs +1 -1
- package/dist/context/index.d.cts +14 -18
- package/dist/context/index.d.ts +14 -18
- package/dist/context/index.js +1 -1
- package/dist/{context-Bm0rm76r.js → context-BAOGRjRS.js} +30 -30
- package/dist/{context-7VgEbfs3.cjs → context-BRDf96na.cjs} +29 -29
- package/dist/db/adapter/index.d.cts +2 -6
- package/dist/db/adapter/index.d.ts +2 -6
- package/dist/db/index.cjs +17 -17
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.js +17 -17
- package/dist/env/index.d.cts +1 -1
- package/dist/env/index.d.ts +1 -1
- package/dist/{index-Cg7SVnu9.d.cts → index-6-zeCbRA.d.cts} +5005 -2553
- package/dist/{index-D5uj-vER.d.ts → index-C8vNYjIq.d.ts} +4 -4
- package/dist/{index-Dy_s5RNc.d.cts → index-DAzyP5GG.d.cts} +4 -4
- package/dist/{index-RfHoxHB4.d.ts → index-DTT2geV_.d.ts} +3662 -1211
- package/dist/index.d.cts +3 -65
- package/dist/index.d.ts +3 -65
- package/dist/oauth2/index.cjs +1 -1
- package/dist/oauth2/index.d.cts +2 -2
- package/dist/oauth2/index.d.ts +2 -2
- package/dist/oauth2/index.js +1 -1
- package/dist/{oauth2-C8-hfKTF.cjs → oauth2-C4Pt8KMZ.cjs} +87 -87
- package/dist/{oauth2-CjVUvPq7.js → oauth2-CP3eVHS_.js} +88 -88
- package/dist/social-providers/index.cjs +891 -891
- package/dist/social-providers/index.d.cts +2 -3
- package/dist/social-providers/index.d.ts +2 -3
- package/dist/social-providers/index.js +891 -891
- package/package.json +4 -3
- package/src/api/index.ts +1 -1
- package/src/context/endpoint-context.ts +1 -1
- package/src/context/index.ts +7 -7
- package/src/context/transaction.ts +2 -2
- package/src/db/adapter/index.ts +1 -1
- package/src/db/index.ts +11 -11
- package/src/db/plugin.ts +1 -1
- package/src/db/type.ts +3 -3
- package/src/env/index.ts +9 -9
- package/src/env/logger.test.ts +2 -2
- package/src/oauth2/client-credentials-token.ts +1 -1
- package/src/oauth2/index.ts +10 -11
- package/src/oauth2/refresh-access-token.ts +1 -1
- package/src/oauth2/validate-authorization-code.ts +1 -1
- package/src/social-providers/apple.ts +1 -1
- package/src/social-providers/atlassian.ts +6 -3
- package/src/social-providers/cognito.ts +7 -4
- package/src/social-providers/facebook.ts +6 -3
- package/src/social-providers/figma.ts +6 -3
- package/src/social-providers/gitlab.ts +1 -1
- package/src/social-providers/google.ts +6 -3
- package/src/social-providers/huggingface.ts +1 -1
- package/src/social-providers/index.ts +25 -25
- package/src/social-providers/kakao.ts +1 -1
- package/src/social-providers/kick.ts +1 -1
- package/src/social-providers/linkedin.ts +1 -1
- package/src/social-providers/microsoft-entra-id.ts +6 -6
- package/src/social-providers/naver.ts +1 -1
- package/src/social-providers/paypal.ts +3 -3
- package/src/social-providers/polar.ts +1 -1
- package/src/social-providers/reddit.ts +1 -1
- package/src/social-providers/roblox.ts +1 -1
- package/src/social-providers/salesforce.ts +6 -3
- package/src/social-providers/slack.ts +1 -1
- package/src/social-providers/spotify.ts +1 -1
- package/src/social-providers/twitch.ts +3 -3
- package/src/social-providers/vk.ts +3 -2
- package/src/social-providers/zoom.ts +1 -1
- package/src/types/context.ts +5 -4
- package/src/types/index.ts +11 -10
- package/src/types/init-options.ts +33 -7
- package/src/types/plugin-client.ts +2 -2
- package/src/types/plugin.ts +3 -3
- package/dist/helper-BH5srn6K.d.ts +0 -6
- package/dist/helper-ChPUVnMr.d.cts +0 -6
- package/dist/index-BCxkjvux.d.cts +0 -344
- package/dist/index-CZCOI9An.d.ts +0 -344
- package/dist/index-DQNPxXof.d.ts +0 -262
- package/dist/index-DXj1sY8B.d.cts +0 -1772
- package/dist/index-DgTKobWC.d.ts +0 -1772
- package/dist/index-daoIWR6L.d.cts +0 -262
- /package/dist/{index-CR-gJyzm.d.ts → index-BzepAavo.d.cts} +0 -0
- /package/dist/{index-CilaMiAm.d.cts → index-DT7CRnvv.d.ts} +0 -0
|
@@ -2,7 +2,7 @@ const require_chunk = require('../chunk-CUT6urMc.cjs');
|
|
|
2
2
|
const require_env = require('../env-CuEMo0ZI.cjs');
|
|
3
3
|
require('../utils-Bs-jKit4.cjs');
|
|
4
4
|
const require_error = require('../error-k9KM7GAb.cjs');
|
|
5
|
-
const require_oauth2 = require('../oauth2-
|
|
5
|
+
const require_oauth2 = require('../oauth2-C4Pt8KMZ.cjs');
|
|
6
6
|
let better_call = require("better-call");
|
|
7
7
|
better_call = require_chunk.__toESM(better_call);
|
|
8
8
|
let zod = require("zod");
|
|
@@ -384,6 +384,74 @@ const discord = (options) => {
|
|
|
384
384
|
};
|
|
385
385
|
};
|
|
386
386
|
|
|
387
|
+
//#endregion
|
|
388
|
+
//#region src/social-providers/dropbox.ts
|
|
389
|
+
const dropbox = (options) => {
|
|
390
|
+
const tokenEndpoint = "https://api.dropboxapi.com/oauth2/token";
|
|
391
|
+
return {
|
|
392
|
+
id: "dropbox",
|
|
393
|
+
name: "Dropbox",
|
|
394
|
+
createAuthorizationURL: async ({ state, scopes, codeVerifier, redirectURI }) => {
|
|
395
|
+
const _scopes = options.disableDefaultScope ? [] : ["account_info.read"];
|
|
396
|
+
options.scope && _scopes.push(...options.scope);
|
|
397
|
+
scopes && _scopes.push(...scopes);
|
|
398
|
+
const additionalParams = {};
|
|
399
|
+
if (options.accessType) additionalParams.token_access_type = options.accessType;
|
|
400
|
+
return await require_oauth2.createAuthorizationURL({
|
|
401
|
+
id: "dropbox",
|
|
402
|
+
options,
|
|
403
|
+
authorizationEndpoint: "https://www.dropbox.com/oauth2/authorize",
|
|
404
|
+
scopes: _scopes,
|
|
405
|
+
state,
|
|
406
|
+
redirectURI,
|
|
407
|
+
codeVerifier,
|
|
408
|
+
additionalParams
|
|
409
|
+
});
|
|
410
|
+
},
|
|
411
|
+
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
412
|
+
return await require_oauth2.validateAuthorizationCode({
|
|
413
|
+
code,
|
|
414
|
+
codeVerifier,
|
|
415
|
+
redirectURI,
|
|
416
|
+
options,
|
|
417
|
+
tokenEndpoint
|
|
418
|
+
});
|
|
419
|
+
},
|
|
420
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
421
|
+
return require_oauth2.refreshAccessToken({
|
|
422
|
+
refreshToken,
|
|
423
|
+
options: {
|
|
424
|
+
clientId: options.clientId,
|
|
425
|
+
clientKey: options.clientKey,
|
|
426
|
+
clientSecret: options.clientSecret
|
|
427
|
+
},
|
|
428
|
+
tokenEndpoint: "https://api.dropbox.com/oauth2/token"
|
|
429
|
+
});
|
|
430
|
+
},
|
|
431
|
+
async getUserInfo(token) {
|
|
432
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
433
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.dropboxapi.com/2/users/get_current_account", {
|
|
434
|
+
method: "POST",
|
|
435
|
+
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
436
|
+
});
|
|
437
|
+
if (error) return null;
|
|
438
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
439
|
+
return {
|
|
440
|
+
user: {
|
|
441
|
+
id: profile.account_id,
|
|
442
|
+
name: profile.name?.display_name,
|
|
443
|
+
email: profile.email,
|
|
444
|
+
emailVerified: profile.email_verified || false,
|
|
445
|
+
image: profile.profile_photo_url,
|
|
446
|
+
...userMap
|
|
447
|
+
},
|
|
448
|
+
data: profile
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
options
|
|
452
|
+
};
|
|
453
|
+
};
|
|
454
|
+
|
|
387
455
|
//#endregion
|
|
388
456
|
//#region src/social-providers/facebook.ts
|
|
389
457
|
const facebook = (options) => {
|
|
@@ -641,6 +709,81 @@ const github = (options) => {
|
|
|
641
709
|
};
|
|
642
710
|
};
|
|
643
711
|
|
|
712
|
+
//#endregion
|
|
713
|
+
//#region src/social-providers/gitlab.ts
|
|
714
|
+
const cleanDoubleSlashes = (input = "") => {
|
|
715
|
+
return input.split("://").map((str) => str.replace(/\/{2,}/g, "/")).join("://");
|
|
716
|
+
};
|
|
717
|
+
const issuerToEndpoints = (issuer) => {
|
|
718
|
+
let baseUrl = issuer || "https://gitlab.com";
|
|
719
|
+
return {
|
|
720
|
+
authorizationEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/authorize`),
|
|
721
|
+
tokenEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/token`),
|
|
722
|
+
userinfoEndpoint: cleanDoubleSlashes(`${baseUrl}/api/v4/user`)
|
|
723
|
+
};
|
|
724
|
+
};
|
|
725
|
+
const gitlab = (options) => {
|
|
726
|
+
const { authorizationEndpoint, tokenEndpoint, userinfoEndpoint } = issuerToEndpoints(options.issuer);
|
|
727
|
+
const issuerId = "gitlab";
|
|
728
|
+
return {
|
|
729
|
+
id: issuerId,
|
|
730
|
+
name: "Gitlab",
|
|
731
|
+
createAuthorizationURL: async ({ state, scopes, codeVerifier, loginHint, redirectURI }) => {
|
|
732
|
+
const _scopes = options.disableDefaultScope ? [] : ["read_user"];
|
|
733
|
+
options.scope && _scopes.push(...options.scope);
|
|
734
|
+
scopes && _scopes.push(...scopes);
|
|
735
|
+
return await require_oauth2.createAuthorizationURL({
|
|
736
|
+
id: issuerId,
|
|
737
|
+
options,
|
|
738
|
+
authorizationEndpoint,
|
|
739
|
+
scopes: _scopes,
|
|
740
|
+
state,
|
|
741
|
+
redirectURI,
|
|
742
|
+
codeVerifier,
|
|
743
|
+
loginHint
|
|
744
|
+
});
|
|
745
|
+
},
|
|
746
|
+
validateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {
|
|
747
|
+
return require_oauth2.validateAuthorizationCode({
|
|
748
|
+
code,
|
|
749
|
+
redirectURI,
|
|
750
|
+
options,
|
|
751
|
+
codeVerifier,
|
|
752
|
+
tokenEndpoint
|
|
753
|
+
});
|
|
754
|
+
},
|
|
755
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
756
|
+
return require_oauth2.refreshAccessToken({
|
|
757
|
+
refreshToken,
|
|
758
|
+
options: {
|
|
759
|
+
clientId: options.clientId,
|
|
760
|
+
clientKey: options.clientKey,
|
|
761
|
+
clientSecret: options.clientSecret
|
|
762
|
+
},
|
|
763
|
+
tokenEndpoint
|
|
764
|
+
});
|
|
765
|
+
},
|
|
766
|
+
async getUserInfo(token) {
|
|
767
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
768
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)(userinfoEndpoint, { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
769
|
+
if (error || profile.state !== "active" || profile.locked) return null;
|
|
770
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
771
|
+
return {
|
|
772
|
+
user: {
|
|
773
|
+
id: profile.id,
|
|
774
|
+
name: profile.name ?? profile.username,
|
|
775
|
+
email: profile.email,
|
|
776
|
+
image: profile.avatar_url,
|
|
777
|
+
emailVerified: true,
|
|
778
|
+
...userMap
|
|
779
|
+
},
|
|
780
|
+
data: profile
|
|
781
|
+
};
|
|
782
|
+
},
|
|
783
|
+
options
|
|
784
|
+
};
|
|
785
|
+
};
|
|
786
|
+
|
|
644
787
|
//#endregion
|
|
645
788
|
//#region src/social-providers/google.ts
|
|
646
789
|
const google = (options) => {
|
|
@@ -724,60 +867,6 @@ const google = (options) => {
|
|
|
724
867
|
};
|
|
725
868
|
};
|
|
726
869
|
|
|
727
|
-
//#endregion
|
|
728
|
-
//#region src/social-providers/kick.ts
|
|
729
|
-
const kick = (options) => {
|
|
730
|
-
return {
|
|
731
|
-
id: "kick",
|
|
732
|
-
name: "Kick",
|
|
733
|
-
createAuthorizationURL({ state, scopes, redirectURI, codeVerifier }) {
|
|
734
|
-
const _scopes = options.disableDefaultScope ? [] : ["user:read"];
|
|
735
|
-
options.scope && _scopes.push(...options.scope);
|
|
736
|
-
scopes && _scopes.push(...scopes);
|
|
737
|
-
return require_oauth2.createAuthorizationURL({
|
|
738
|
-
id: "kick",
|
|
739
|
-
redirectURI,
|
|
740
|
-
options,
|
|
741
|
-
authorizationEndpoint: "https://id.kick.com/oauth/authorize",
|
|
742
|
-
scopes: _scopes,
|
|
743
|
-
codeVerifier,
|
|
744
|
-
state
|
|
745
|
-
});
|
|
746
|
-
},
|
|
747
|
-
async validateAuthorizationCode({ code, redirectURI, codeVerifier }) {
|
|
748
|
-
return require_oauth2.validateAuthorizationCode({
|
|
749
|
-
code,
|
|
750
|
-
redirectURI,
|
|
751
|
-
options,
|
|
752
|
-
tokenEndpoint: "https://id.kick.com/oauth/token",
|
|
753
|
-
codeVerifier
|
|
754
|
-
});
|
|
755
|
-
},
|
|
756
|
-
async getUserInfo(token) {
|
|
757
|
-
if (options.getUserInfo) return options.getUserInfo(token);
|
|
758
|
-
const { data, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.kick.com/public/v1/users", {
|
|
759
|
-
method: "GET",
|
|
760
|
-
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
761
|
-
});
|
|
762
|
-
if (error) return null;
|
|
763
|
-
const profile = data.data[0];
|
|
764
|
-
const userMap = await options.mapProfileToUser?.(profile);
|
|
765
|
-
return {
|
|
766
|
-
user: {
|
|
767
|
-
id: profile.user_id,
|
|
768
|
-
name: profile.name,
|
|
769
|
-
email: profile.email,
|
|
770
|
-
image: profile.profile_picture,
|
|
771
|
-
emailVerified: true,
|
|
772
|
-
...userMap
|
|
773
|
-
},
|
|
774
|
-
data: profile
|
|
775
|
-
};
|
|
776
|
-
},
|
|
777
|
-
options
|
|
778
|
-
};
|
|
779
|
-
};
|
|
780
|
-
|
|
781
870
|
//#endregion
|
|
782
871
|
//#region src/social-providers/huggingface.ts
|
|
783
872
|
const huggingface = (options) => {
|
|
@@ -847,152 +936,115 @@ const huggingface = (options) => {
|
|
|
847
936
|
};
|
|
848
937
|
|
|
849
938
|
//#endregion
|
|
850
|
-
//#region src/social-providers/
|
|
851
|
-
const
|
|
852
|
-
const tenant = options.tenantId || "common";
|
|
853
|
-
const authority = options.authority || "https://login.microsoftonline.com";
|
|
854
|
-
const authorizationEndpoint = `${authority}/${tenant}/oauth2/v2.0/authorize`;
|
|
855
|
-
const tokenEndpoint = `${authority}/${tenant}/oauth2/v2.0/token`;
|
|
939
|
+
//#region src/social-providers/kakao.ts
|
|
940
|
+
const kakao = (options) => {
|
|
856
941
|
return {
|
|
857
|
-
id: "
|
|
858
|
-
name: "
|
|
859
|
-
createAuthorizationURL(
|
|
860
|
-
const
|
|
861
|
-
"
|
|
862
|
-
"
|
|
863
|
-
"
|
|
864
|
-
"User.Read",
|
|
865
|
-
"offline_access"
|
|
942
|
+
id: "kakao",
|
|
943
|
+
name: "Kakao",
|
|
944
|
+
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
945
|
+
const _scopes = options.disableDefaultScope ? [] : [
|
|
946
|
+
"account_email",
|
|
947
|
+
"profile_image",
|
|
948
|
+
"profile_nickname"
|
|
866
949
|
];
|
|
867
|
-
options.scope &&
|
|
868
|
-
|
|
950
|
+
options.scope && _scopes.push(...options.scope);
|
|
951
|
+
scopes && _scopes.push(...scopes);
|
|
869
952
|
return require_oauth2.createAuthorizationURL({
|
|
870
|
-
id: "
|
|
953
|
+
id: "kakao",
|
|
871
954
|
options,
|
|
872
|
-
authorizationEndpoint,
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
redirectURI: data.redirectURI,
|
|
877
|
-
prompt: options.prompt,
|
|
878
|
-
loginHint: data.loginHint
|
|
955
|
+
authorizationEndpoint: "https://kauth.kakao.com/oauth/authorize",
|
|
956
|
+
scopes: _scopes,
|
|
957
|
+
state,
|
|
958
|
+
redirectURI
|
|
879
959
|
});
|
|
880
960
|
},
|
|
881
|
-
validateAuthorizationCode({ code,
|
|
961
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
882
962
|
return require_oauth2.validateAuthorizationCode({
|
|
883
963
|
code,
|
|
884
|
-
codeVerifier,
|
|
885
964
|
redirectURI,
|
|
886
965
|
options,
|
|
887
|
-
tokenEndpoint
|
|
966
|
+
tokenEndpoint: "https://kauth.kakao.com/oauth/token"
|
|
967
|
+
});
|
|
968
|
+
},
|
|
969
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
970
|
+
return require_oauth2.refreshAccessToken({
|
|
971
|
+
refreshToken,
|
|
972
|
+
options: {
|
|
973
|
+
clientId: options.clientId,
|
|
974
|
+
clientKey: options.clientKey,
|
|
975
|
+
clientSecret: options.clientSecret
|
|
976
|
+
},
|
|
977
|
+
tokenEndpoint: "https://kauth.kakao.com/oauth/token"
|
|
888
978
|
});
|
|
889
979
|
},
|
|
890
980
|
async getUserInfo(token) {
|
|
891
981
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
const
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
async onResponse(context) {
|
|
898
|
-
if (options.disableProfilePhoto || !context.response.ok) return;
|
|
899
|
-
try {
|
|
900
|
-
const pictureBuffer = await context.response.clone().arrayBuffer();
|
|
901
|
-
user.picture = `data:image/jpeg;base64, ${__better_auth_utils_base64.base64.encode(pictureBuffer)}`;
|
|
902
|
-
} catch (e) {
|
|
903
|
-
require_env.logger.error(e && typeof e === "object" && "name" in e ? e.name : "", e);
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
});
|
|
907
|
-
const userMap = await options.mapProfileToUser?.(user);
|
|
982
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://kapi.kakao.com/v2/user/me", { headers: { Authorization: `Bearer ${token.accessToken}` } });
|
|
983
|
+
if (error || !profile) return null;
|
|
984
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
985
|
+
const account = profile.kakao_account || {};
|
|
986
|
+
const kakaoProfile = account.profile || {};
|
|
908
987
|
return {
|
|
909
988
|
user: {
|
|
910
|
-
id:
|
|
911
|
-
name:
|
|
912
|
-
email:
|
|
913
|
-
image:
|
|
914
|
-
emailVerified:
|
|
989
|
+
id: String(profile.id),
|
|
990
|
+
name: kakaoProfile.nickname || account.name || void 0,
|
|
991
|
+
email: account.email,
|
|
992
|
+
image: kakaoProfile.profile_image_url || kakaoProfile.thumbnail_image_url,
|
|
993
|
+
emailVerified: !!account.is_email_valid && !!account.is_email_verified,
|
|
915
994
|
...userMap
|
|
916
995
|
},
|
|
917
|
-
data:
|
|
996
|
+
data: profile
|
|
918
997
|
};
|
|
919
998
|
},
|
|
920
|
-
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
921
|
-
const scopes = options.disableDefaultScope ? [] : [
|
|
922
|
-
"openid",
|
|
923
|
-
"profile",
|
|
924
|
-
"email",
|
|
925
|
-
"User.Read",
|
|
926
|
-
"offline_access"
|
|
927
|
-
];
|
|
928
|
-
options.scope && scopes.push(...options.scope);
|
|
929
|
-
return require_oauth2.refreshAccessToken({
|
|
930
|
-
refreshToken,
|
|
931
|
-
options: {
|
|
932
|
-
clientId: options.clientId,
|
|
933
|
-
clientSecret: options.clientSecret
|
|
934
|
-
},
|
|
935
|
-
extraParams: { scope: scopes.join(" ") },
|
|
936
|
-
tokenEndpoint
|
|
937
|
-
});
|
|
938
|
-
},
|
|
939
999
|
options
|
|
940
1000
|
};
|
|
941
1001
|
};
|
|
942
1002
|
|
|
943
1003
|
//#endregion
|
|
944
|
-
//#region src/social-providers/
|
|
945
|
-
const
|
|
1004
|
+
//#region src/social-providers/kick.ts
|
|
1005
|
+
const kick = (options) => {
|
|
946
1006
|
return {
|
|
947
|
-
id: "
|
|
948
|
-
name: "
|
|
949
|
-
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
950
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
951
|
-
"openid",
|
|
952
|
-
"profile",
|
|
953
|
-
"email"
|
|
954
|
-
];
|
|
955
|
-
scopes && _scopes.push(...scopes);
|
|
1007
|
+
id: "kick",
|
|
1008
|
+
name: "Kick",
|
|
1009
|
+
createAuthorizationURL({ state, scopes, redirectURI, codeVerifier }) {
|
|
1010
|
+
const _scopes = options.disableDefaultScope ? [] : ["user:read"];
|
|
956
1011
|
options.scope && _scopes.push(...options.scope);
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
1012
|
+
scopes && _scopes.push(...scopes);
|
|
1013
|
+
return require_oauth2.createAuthorizationURL({
|
|
1014
|
+
id: "kick",
|
|
1015
|
+
redirectURI,
|
|
1016
|
+
options,
|
|
1017
|
+
authorizationEndpoint: "https://id.kick.com/oauth/authorize",
|
|
1018
|
+
scopes: _scopes,
|
|
1019
|
+
codeVerifier,
|
|
1020
|
+
state
|
|
1021
|
+
});
|
|
964
1022
|
},
|
|
965
|
-
|
|
1023
|
+
async validateAuthorizationCode({ code, redirectURI, codeVerifier }) {
|
|
966
1024
|
return require_oauth2.validateAuthorizationCode({
|
|
967
1025
|
code,
|
|
968
1026
|
redirectURI,
|
|
969
1027
|
options,
|
|
970
|
-
tokenEndpoint: "https://
|
|
971
|
-
|
|
972
|
-
},
|
|
973
|
-
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
974
|
-
return require_oauth2.refreshAccessToken({
|
|
975
|
-
refreshToken,
|
|
976
|
-
options: {
|
|
977
|
-
clientId: options.clientId,
|
|
978
|
-
clientKey: options.clientKey,
|
|
979
|
-
clientSecret: options.clientSecret
|
|
980
|
-
},
|
|
981
|
-
tokenEndpoint: "https://slack.com/api/openid.connect.token"
|
|
1028
|
+
tokenEndpoint: "https://id.kick.com/oauth/token",
|
|
1029
|
+
codeVerifier
|
|
982
1030
|
});
|
|
983
1031
|
},
|
|
984
1032
|
async getUserInfo(token) {
|
|
985
1033
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
986
|
-
const { data
|
|
1034
|
+
const { data, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.kick.com/public/v1/users", {
|
|
1035
|
+
method: "GET",
|
|
1036
|
+
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
1037
|
+
});
|
|
987
1038
|
if (error) return null;
|
|
1039
|
+
const profile = data.data[0];
|
|
988
1040
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
989
1041
|
return {
|
|
990
1042
|
user: {
|
|
991
|
-
id: profile
|
|
992
|
-
name: profile.name
|
|
1043
|
+
id: profile.user_id,
|
|
1044
|
+
name: profile.name,
|
|
993
1045
|
email: profile.email,
|
|
994
|
-
|
|
995
|
-
|
|
1046
|
+
image: profile.profile_picture,
|
|
1047
|
+
emailVerified: true,
|
|
996
1048
|
...userMap
|
|
997
1049
|
},
|
|
998
1050
|
data: profile
|
|
@@ -1003,34 +1055,50 @@ const slack = (options) => {
|
|
|
1003
1055
|
};
|
|
1004
1056
|
|
|
1005
1057
|
//#endregion
|
|
1006
|
-
//#region src/social-providers/
|
|
1007
|
-
|
|
1008
|
-
|
|
1058
|
+
//#region src/social-providers/line.ts
|
|
1059
|
+
/**
|
|
1060
|
+
* LINE Login v2.1
|
|
1061
|
+
* - Authorization endpoint: https://access.line.me/oauth2/v2.1/authorize
|
|
1062
|
+
* - Token endpoint: https://api.line.me/oauth2/v2.1/token
|
|
1063
|
+
* - UserInfo endpoint: https://api.line.me/oauth2/v2.1/userinfo
|
|
1064
|
+
* - Verify ID token: https://api.line.me/oauth2/v2.1/verify
|
|
1065
|
+
*
|
|
1066
|
+
* Docs: https://developers.line.biz/en/reference/line-login/#issue-access-token
|
|
1067
|
+
*/
|
|
1068
|
+
const line = (options) => {
|
|
1069
|
+
const authorizationEndpoint = "https://access.line.me/oauth2/v2.1/authorize";
|
|
1070
|
+
const tokenEndpoint = "https://api.line.me/oauth2/v2.1/token";
|
|
1071
|
+
const userInfoEndpoint = "https://api.line.me/oauth2/v2.1/userinfo";
|
|
1072
|
+
const verifyIdTokenEndpoint = "https://api.line.me/oauth2/v2.1/verify";
|
|
1009
1073
|
return {
|
|
1010
|
-
id: "
|
|
1011
|
-
name: "
|
|
1012
|
-
createAuthorizationURL({ state, scopes,
|
|
1013
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
1074
|
+
id: "line",
|
|
1075
|
+
name: "LINE",
|
|
1076
|
+
async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, loginHint }) {
|
|
1077
|
+
const _scopes = options.disableDefaultScope ? [] : [
|
|
1078
|
+
"openid",
|
|
1079
|
+
"profile",
|
|
1080
|
+
"email"
|
|
1081
|
+
];
|
|
1014
1082
|
options.scope && _scopes.push(...options.scope);
|
|
1015
1083
|
scopes && _scopes.push(...scopes);
|
|
1016
|
-
return require_oauth2.createAuthorizationURL({
|
|
1017
|
-
id: "
|
|
1084
|
+
return await require_oauth2.createAuthorizationURL({
|
|
1085
|
+
id: "line",
|
|
1018
1086
|
options,
|
|
1019
|
-
authorizationEndpoint
|
|
1087
|
+
authorizationEndpoint,
|
|
1020
1088
|
scopes: _scopes,
|
|
1021
1089
|
state,
|
|
1090
|
+
codeVerifier,
|
|
1022
1091
|
redirectURI,
|
|
1023
|
-
loginHint
|
|
1024
|
-
additionalParams: { owner: "user" }
|
|
1092
|
+
loginHint
|
|
1025
1093
|
});
|
|
1026
1094
|
},
|
|
1027
|
-
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1095
|
+
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
1028
1096
|
return require_oauth2.validateAuthorizationCode({
|
|
1029
1097
|
code,
|
|
1098
|
+
codeVerifier,
|
|
1030
1099
|
redirectURI,
|
|
1031
1100
|
options,
|
|
1032
|
-
tokenEndpoint
|
|
1033
|
-
authentication: "basic"
|
|
1101
|
+
tokenEndpoint
|
|
1034
1102
|
});
|
|
1035
1103
|
},
|
|
1036
1104
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -1038,32 +1106,53 @@ const notion = (options) => {
|
|
|
1038
1106
|
refreshToken,
|
|
1039
1107
|
options: {
|
|
1040
1108
|
clientId: options.clientId,
|
|
1041
|
-
clientKey: options.clientKey,
|
|
1042
1109
|
clientSecret: options.clientSecret
|
|
1043
1110
|
},
|
|
1044
1111
|
tokenEndpoint
|
|
1045
1112
|
});
|
|
1046
1113
|
},
|
|
1114
|
+
async verifyIdToken(token, nonce) {
|
|
1115
|
+
if (options.disableIdTokenSignIn) return false;
|
|
1116
|
+
if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
|
|
1117
|
+
const body = new URLSearchParams();
|
|
1118
|
+
body.set("id_token", token);
|
|
1119
|
+
body.set("client_id", options.clientId);
|
|
1120
|
+
if (nonce) body.set("nonce", nonce);
|
|
1121
|
+
const { data, error } = await (0, __better_fetch_fetch.betterFetch)(verifyIdTokenEndpoint, {
|
|
1122
|
+
method: "POST",
|
|
1123
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
1124
|
+
body
|
|
1125
|
+
});
|
|
1126
|
+
if (error || !data) return false;
|
|
1127
|
+
if (data.aud !== options.clientId) return false;
|
|
1128
|
+
if (nonce && data.nonce && data.nonce !== nonce) return false;
|
|
1129
|
+
return true;
|
|
1130
|
+
},
|
|
1047
1131
|
async getUserInfo(token) {
|
|
1048
1132
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
} }
|
|
1053
|
-
if (
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1133
|
+
let profile = null;
|
|
1134
|
+
if (token.idToken) try {
|
|
1135
|
+
profile = (0, jose.decodeJwt)(token.idToken);
|
|
1136
|
+
} catch {}
|
|
1137
|
+
if (!profile) {
|
|
1138
|
+
const { data } = await (0, __better_fetch_fetch.betterFetch)(userInfoEndpoint, { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
1139
|
+
profile = data || null;
|
|
1140
|
+
}
|
|
1141
|
+
if (!profile) return null;
|
|
1142
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
1143
|
+
const id = profile.sub || profile.userId;
|
|
1144
|
+
const name = profile.name || profile.displayName;
|
|
1145
|
+
const image = profile.picture || profile.pictureUrl || void 0;
|
|
1057
1146
|
return {
|
|
1058
1147
|
user: {
|
|
1059
|
-
id
|
|
1060
|
-
name
|
|
1061
|
-
email:
|
|
1062
|
-
image
|
|
1063
|
-
emailVerified:
|
|
1148
|
+
id,
|
|
1149
|
+
name,
|
|
1150
|
+
email: profile.email,
|
|
1151
|
+
image,
|
|
1152
|
+
emailVerified: false,
|
|
1064
1153
|
...userMap
|
|
1065
1154
|
},
|
|
1066
|
-
data:
|
|
1155
|
+
data: profile
|
|
1067
1156
|
};
|
|
1068
1157
|
},
|
|
1069
1158
|
options
|
|
@@ -1071,32 +1160,32 @@ const notion = (options) => {
|
|
|
1071
1160
|
};
|
|
1072
1161
|
|
|
1073
1162
|
//#endregion
|
|
1074
|
-
//#region src/social-providers/
|
|
1075
|
-
const
|
|
1163
|
+
//#region src/social-providers/linear.ts
|
|
1164
|
+
const linear = (options) => {
|
|
1165
|
+
const tokenEndpoint = "https://api.linear.app/oauth/token";
|
|
1076
1166
|
return {
|
|
1077
|
-
id: "
|
|
1078
|
-
name: "
|
|
1079
|
-
createAuthorizationURL({ state, scopes,
|
|
1080
|
-
const _scopes = options.disableDefaultScope ? [] : ["
|
|
1167
|
+
id: "linear",
|
|
1168
|
+
name: "Linear",
|
|
1169
|
+
createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
|
|
1170
|
+
const _scopes = options.disableDefaultScope ? [] : ["read"];
|
|
1081
1171
|
options.scope && _scopes.push(...options.scope);
|
|
1082
1172
|
scopes && _scopes.push(...scopes);
|
|
1083
1173
|
return require_oauth2.createAuthorizationURL({
|
|
1084
|
-
id: "
|
|
1174
|
+
id: "linear",
|
|
1085
1175
|
options,
|
|
1086
|
-
authorizationEndpoint: "https://
|
|
1176
|
+
authorizationEndpoint: "https://linear.app/oauth/authorize",
|
|
1087
1177
|
scopes: _scopes,
|
|
1088
1178
|
state,
|
|
1089
|
-
|
|
1090
|
-
|
|
1179
|
+
redirectURI,
|
|
1180
|
+
loginHint
|
|
1091
1181
|
});
|
|
1092
1182
|
},
|
|
1093
|
-
validateAuthorizationCode: async ({ code,
|
|
1183
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1094
1184
|
return require_oauth2.validateAuthorizationCode({
|
|
1095
1185
|
code,
|
|
1096
|
-
codeVerifier,
|
|
1097
1186
|
redirectURI,
|
|
1098
1187
|
options,
|
|
1099
|
-
tokenEndpoint
|
|
1188
|
+
tokenEndpoint
|
|
1100
1189
|
});
|
|
1101
1190
|
},
|
|
1102
1191
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -1107,64 +1196,82 @@ const spotify = (options) => {
|
|
|
1107
1196
|
clientKey: options.clientKey,
|
|
1108
1197
|
clientSecret: options.clientSecret
|
|
1109
1198
|
},
|
|
1110
|
-
tokenEndpoint
|
|
1199
|
+
tokenEndpoint
|
|
1111
1200
|
});
|
|
1112
1201
|
},
|
|
1113
1202
|
async getUserInfo(token) {
|
|
1114
1203
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1115
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.
|
|
1116
|
-
method: "
|
|
1117
|
-
headers: {
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1204
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.linear.app/graphql", {
|
|
1205
|
+
method: "POST",
|
|
1206
|
+
headers: {
|
|
1207
|
+
"Content-Type": "application/json",
|
|
1208
|
+
Authorization: `Bearer ${token.accessToken}`
|
|
1209
|
+
},
|
|
1210
|
+
body: JSON.stringify({ query: `
|
|
1211
|
+
query {
|
|
1212
|
+
viewer {
|
|
1213
|
+
id
|
|
1214
|
+
name
|
|
1215
|
+
email
|
|
1216
|
+
avatarUrl
|
|
1217
|
+
active
|
|
1218
|
+
createdAt
|
|
1219
|
+
updatedAt
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
` })
|
|
1223
|
+
});
|
|
1224
|
+
if (error || !profile?.data?.viewer) return null;
|
|
1225
|
+
const userData = profile.data.viewer;
|
|
1226
|
+
const userMap = await options.mapProfileToUser?.(userData);
|
|
1227
|
+
return {
|
|
1228
|
+
user: {
|
|
1229
|
+
id: profile.data.viewer.id,
|
|
1230
|
+
name: profile.data.viewer.name,
|
|
1231
|
+
email: profile.data.viewer.email,
|
|
1232
|
+
image: profile.data.viewer.avatarUrl,
|
|
1233
|
+
emailVerified: true,
|
|
1234
|
+
...userMap
|
|
1235
|
+
},
|
|
1236
|
+
data: userData
|
|
1237
|
+
};
|
|
1132
1238
|
},
|
|
1133
1239
|
options
|
|
1134
1240
|
};
|
|
1135
1241
|
};
|
|
1136
1242
|
|
|
1137
1243
|
//#endregion
|
|
1138
|
-
//#region src/social-providers/
|
|
1139
|
-
const
|
|
1244
|
+
//#region src/social-providers/linkedin.ts
|
|
1245
|
+
const linkedin = (options) => {
|
|
1246
|
+
const authorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
|
|
1247
|
+
const tokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
|
|
1140
1248
|
return {
|
|
1141
|
-
id: "
|
|
1142
|
-
name: "
|
|
1143
|
-
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
1144
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
1249
|
+
id: "linkedin",
|
|
1250
|
+
name: "Linkedin",
|
|
1251
|
+
createAuthorizationURL: async ({ state, scopes, redirectURI, loginHint }) => {
|
|
1252
|
+
const _scopes = options.disableDefaultScope ? [] : [
|
|
1253
|
+
"profile",
|
|
1254
|
+
"email",
|
|
1255
|
+
"openid"
|
|
1256
|
+
];
|
|
1145
1257
|
options.scope && _scopes.push(...options.scope);
|
|
1146
1258
|
scopes && _scopes.push(...scopes);
|
|
1147
|
-
return require_oauth2.createAuthorizationURL({
|
|
1148
|
-
id: "
|
|
1149
|
-
redirectURI,
|
|
1259
|
+
return await require_oauth2.createAuthorizationURL({
|
|
1260
|
+
id: "linkedin",
|
|
1150
1261
|
options,
|
|
1151
|
-
authorizationEndpoint
|
|
1262
|
+
authorizationEndpoint,
|
|
1152
1263
|
scopes: _scopes,
|
|
1153
1264
|
state,
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
"email_verified",
|
|
1157
|
-
"preferred_username",
|
|
1158
|
-
"picture"
|
|
1159
|
-
]
|
|
1265
|
+
loginHint,
|
|
1266
|
+
redirectURI
|
|
1160
1267
|
});
|
|
1161
1268
|
},
|
|
1162
1269
|
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1163
|
-
return require_oauth2.validateAuthorizationCode({
|
|
1270
|
+
return await require_oauth2.validateAuthorizationCode({
|
|
1164
1271
|
code,
|
|
1165
1272
|
redirectURI,
|
|
1166
1273
|
options,
|
|
1167
|
-
tokenEndpoint
|
|
1274
|
+
tokenEndpoint
|
|
1168
1275
|
});
|
|
1169
1276
|
},
|
|
1170
1277
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -1175,25 +1282,24 @@ const twitch = (options) => {
|
|
|
1175
1282
|
clientKey: options.clientKey,
|
|
1176
1283
|
clientSecret: options.clientSecret
|
|
1177
1284
|
},
|
|
1178
|
-
tokenEndpoint
|
|
1285
|
+
tokenEndpoint
|
|
1179
1286
|
});
|
|
1180
1287
|
},
|
|
1181
1288
|
async getUserInfo(token) {
|
|
1182
1289
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1183
|
-
const
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
const profile = (0, jose.decodeJwt)(idToken);
|
|
1290
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.linkedin.com/v2/userinfo", {
|
|
1291
|
+
method: "GET",
|
|
1292
|
+
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
1293
|
+
});
|
|
1294
|
+
if (error) return null;
|
|
1189
1295
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
1190
1296
|
return {
|
|
1191
1297
|
user: {
|
|
1192
1298
|
id: profile.sub,
|
|
1193
|
-
name: profile.
|
|
1299
|
+
name: profile.name,
|
|
1194
1300
|
email: profile.email,
|
|
1301
|
+
emailVerified: profile.email_verified || false,
|
|
1195
1302
|
image: profile.picture,
|
|
1196
|
-
emailVerified: profile.email_verified,
|
|
1197
1303
|
...userMap
|
|
1198
1304
|
},
|
|
1199
1305
|
data: profile
|
|
@@ -1204,116 +1310,124 @@ const twitch = (options) => {
|
|
|
1204
1310
|
};
|
|
1205
1311
|
|
|
1206
1312
|
//#endregion
|
|
1207
|
-
//#region src/social-providers/
|
|
1208
|
-
const
|
|
1313
|
+
//#region src/social-providers/microsoft-entra-id.ts
|
|
1314
|
+
const microsoft = (options) => {
|
|
1315
|
+
const tenant = options.tenantId || "common";
|
|
1316
|
+
const authority = options.authority || "https://login.microsoftonline.com";
|
|
1317
|
+
const authorizationEndpoint = `${authority}/${tenant}/oauth2/v2.0/authorize`;
|
|
1318
|
+
const tokenEndpoint = `${authority}/${tenant}/oauth2/v2.0/token`;
|
|
1209
1319
|
return {
|
|
1210
|
-
id: "
|
|
1211
|
-
name: "
|
|
1320
|
+
id: "microsoft",
|
|
1321
|
+
name: "Microsoft EntraID",
|
|
1212
1322
|
createAuthorizationURL(data) {
|
|
1213
|
-
const
|
|
1214
|
-
"
|
|
1215
|
-
"
|
|
1216
|
-
"
|
|
1217
|
-
"
|
|
1323
|
+
const scopes = options.disableDefaultScope ? [] : [
|
|
1324
|
+
"openid",
|
|
1325
|
+
"profile",
|
|
1326
|
+
"email",
|
|
1327
|
+
"User.Read",
|
|
1328
|
+
"offline_access"
|
|
1218
1329
|
];
|
|
1219
|
-
options.scope &&
|
|
1220
|
-
data.scopes &&
|
|
1330
|
+
options.scope && scopes.push(...options.scope);
|
|
1331
|
+
data.scopes && scopes.push(...data.scopes);
|
|
1221
1332
|
return require_oauth2.createAuthorizationURL({
|
|
1222
|
-
id: "
|
|
1333
|
+
id: "microsoft",
|
|
1223
1334
|
options,
|
|
1224
|
-
authorizationEndpoint
|
|
1225
|
-
scopes: _scopes,
|
|
1335
|
+
authorizationEndpoint,
|
|
1226
1336
|
state: data.state,
|
|
1227
1337
|
codeVerifier: data.codeVerifier,
|
|
1228
|
-
|
|
1338
|
+
scopes,
|
|
1339
|
+
redirectURI: data.redirectURI,
|
|
1340
|
+
prompt: options.prompt,
|
|
1341
|
+
loginHint: data.loginHint
|
|
1229
1342
|
});
|
|
1230
1343
|
},
|
|
1231
|
-
validateAuthorizationCode
|
|
1344
|
+
validateAuthorizationCode({ code, codeVerifier, redirectURI }) {
|
|
1232
1345
|
return require_oauth2.validateAuthorizationCode({
|
|
1233
1346
|
code,
|
|
1234
1347
|
codeVerifier,
|
|
1235
|
-
authentication: "basic",
|
|
1236
1348
|
redirectURI,
|
|
1237
1349
|
options,
|
|
1238
|
-
tokenEndpoint
|
|
1239
|
-
});
|
|
1240
|
-
},
|
|
1241
|
-
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
1242
|
-
return require_oauth2.refreshAccessToken({
|
|
1243
|
-
refreshToken,
|
|
1244
|
-
options: {
|
|
1245
|
-
clientId: options.clientId,
|
|
1246
|
-
clientKey: options.clientKey,
|
|
1247
|
-
clientSecret: options.clientSecret
|
|
1248
|
-
},
|
|
1249
|
-
authentication: "basic",
|
|
1250
|
-
tokenEndpoint: "https://api.x.com/2/oauth2/token"
|
|
1350
|
+
tokenEndpoint
|
|
1251
1351
|
});
|
|
1252
1352
|
},
|
|
1253
1353
|
async getUserInfo(token) {
|
|
1254
1354
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1355
|
+
if (!token.idToken) return null;
|
|
1356
|
+
const user = (0, jose.decodeJwt)(token.idToken);
|
|
1357
|
+
const profilePhotoSize = options.profilePhotoSize || 48;
|
|
1358
|
+
await (0, __better_fetch_fetch.betterFetch)(`https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`, {
|
|
1359
|
+
headers: { Authorization: `Bearer ${token.accessToken}` },
|
|
1360
|
+
async onResponse(context) {
|
|
1361
|
+
if (options.disableProfilePhoto || !context.response.ok) return;
|
|
1362
|
+
try {
|
|
1363
|
+
const pictureBuffer = await context.response.clone().arrayBuffer();
|
|
1364
|
+
user.picture = `data:image/jpeg;base64, ${__better_auth_utils_base64.base64.encode(pictureBuffer)}`;
|
|
1365
|
+
} catch (e) {
|
|
1366
|
+
require_env.logger.error(e && typeof e === "object" && "name" in e ? e.name : "", e);
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1263
1369
|
});
|
|
1264
|
-
|
|
1265
|
-
if (!emailError && emailData?.data?.confirmed_email) {
|
|
1266
|
-
profile.data.email = emailData.data.confirmed_email;
|
|
1267
|
-
emailVerified = true;
|
|
1268
|
-
}
|
|
1269
|
-
const userMap = await options.mapProfileToUser?.(profile);
|
|
1370
|
+
const userMap = await options.mapProfileToUser?.(user);
|
|
1270
1371
|
return {
|
|
1271
1372
|
user: {
|
|
1272
|
-
id:
|
|
1273
|
-
name:
|
|
1274
|
-
email:
|
|
1275
|
-
image:
|
|
1276
|
-
emailVerified,
|
|
1373
|
+
id: user.sub,
|
|
1374
|
+
name: user.name,
|
|
1375
|
+
email: user.email,
|
|
1376
|
+
image: user.picture,
|
|
1377
|
+
emailVerified: true,
|
|
1277
1378
|
...userMap
|
|
1278
1379
|
},
|
|
1279
|
-
data:
|
|
1380
|
+
data: user
|
|
1280
1381
|
};
|
|
1281
1382
|
},
|
|
1383
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
1384
|
+
const scopes = options.disableDefaultScope ? [] : [
|
|
1385
|
+
"openid",
|
|
1386
|
+
"profile",
|
|
1387
|
+
"email",
|
|
1388
|
+
"User.Read",
|
|
1389
|
+
"offline_access"
|
|
1390
|
+
];
|
|
1391
|
+
options.scope && scopes.push(...options.scope);
|
|
1392
|
+
return require_oauth2.refreshAccessToken({
|
|
1393
|
+
refreshToken,
|
|
1394
|
+
options: {
|
|
1395
|
+
clientId: options.clientId,
|
|
1396
|
+
clientSecret: options.clientSecret
|
|
1397
|
+
},
|
|
1398
|
+
extraParams: { scope: scopes.join(" ") },
|
|
1399
|
+
tokenEndpoint
|
|
1400
|
+
});
|
|
1401
|
+
},
|
|
1282
1402
|
options
|
|
1283
1403
|
};
|
|
1284
1404
|
};
|
|
1285
1405
|
|
|
1286
1406
|
//#endregion
|
|
1287
|
-
//#region src/social-providers/
|
|
1288
|
-
const
|
|
1289
|
-
const tokenEndpoint = "https://api.dropboxapi.com/oauth2/token";
|
|
1407
|
+
//#region src/social-providers/naver.ts
|
|
1408
|
+
const naver = (options) => {
|
|
1290
1409
|
return {
|
|
1291
|
-
id: "
|
|
1292
|
-
name: "
|
|
1293
|
-
createAuthorizationURL
|
|
1294
|
-
const _scopes = options.disableDefaultScope ? [] : ["
|
|
1410
|
+
id: "naver",
|
|
1411
|
+
name: "Naver",
|
|
1412
|
+
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
1413
|
+
const _scopes = options.disableDefaultScope ? [] : ["profile", "email"];
|
|
1295
1414
|
options.scope && _scopes.push(...options.scope);
|
|
1296
1415
|
scopes && _scopes.push(...scopes);
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
return await require_oauth2.createAuthorizationURL({
|
|
1300
|
-
id: "dropbox",
|
|
1416
|
+
return require_oauth2.createAuthorizationURL({
|
|
1417
|
+
id: "naver",
|
|
1301
1418
|
options,
|
|
1302
|
-
authorizationEndpoint: "https://
|
|
1419
|
+
authorizationEndpoint: "https://nid.naver.com/oauth2.0/authorize",
|
|
1303
1420
|
scopes: _scopes,
|
|
1304
1421
|
state,
|
|
1305
|
-
redirectURI
|
|
1306
|
-
codeVerifier,
|
|
1307
|
-
additionalParams
|
|
1422
|
+
redirectURI
|
|
1308
1423
|
});
|
|
1309
1424
|
},
|
|
1310
|
-
validateAuthorizationCode: async ({ code,
|
|
1311
|
-
return
|
|
1425
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1426
|
+
return require_oauth2.validateAuthorizationCode({
|
|
1312
1427
|
code,
|
|
1313
|
-
codeVerifier,
|
|
1314
1428
|
redirectURI,
|
|
1315
1429
|
options,
|
|
1316
|
-
tokenEndpoint
|
|
1430
|
+
tokenEndpoint: "https://nid.naver.com/oauth2.0/token"
|
|
1317
1431
|
});
|
|
1318
1432
|
},
|
|
1319
1433
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -1324,24 +1438,22 @@ const dropbox = (options) => {
|
|
|
1324
1438
|
clientKey: options.clientKey,
|
|
1325
1439
|
clientSecret: options.clientSecret
|
|
1326
1440
|
},
|
|
1327
|
-
tokenEndpoint: "https://
|
|
1441
|
+
tokenEndpoint: "https://nid.naver.com/oauth2.0/token"
|
|
1328
1442
|
});
|
|
1329
1443
|
},
|
|
1330
1444
|
async getUserInfo(token) {
|
|
1331
1445
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1332
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://
|
|
1333
|
-
|
|
1334
|
-
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
1335
|
-
});
|
|
1336
|
-
if (error) return null;
|
|
1446
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://openapi.naver.com/v1/nid/me", { headers: { Authorization: `Bearer ${token.accessToken}` } });
|
|
1447
|
+
if (error || !profile || profile.resultcode !== "00") return null;
|
|
1337
1448
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
1449
|
+
const res = profile.response || {};
|
|
1338
1450
|
return {
|
|
1339
1451
|
user: {
|
|
1340
|
-
id:
|
|
1341
|
-
name:
|
|
1342
|
-
email:
|
|
1343
|
-
|
|
1344
|
-
|
|
1452
|
+
id: res.id,
|
|
1453
|
+
name: res.name || res.nickname,
|
|
1454
|
+
email: res.email,
|
|
1455
|
+
image: res.profile_image,
|
|
1456
|
+
emailVerified: false,
|
|
1345
1457
|
...userMap
|
|
1346
1458
|
},
|
|
1347
1459
|
data: profile
|
|
@@ -1352,24 +1464,25 @@ const dropbox = (options) => {
|
|
|
1352
1464
|
};
|
|
1353
1465
|
|
|
1354
1466
|
//#endregion
|
|
1355
|
-
//#region src/social-providers/
|
|
1356
|
-
const
|
|
1357
|
-
const tokenEndpoint = "https://api.
|
|
1467
|
+
//#region src/social-providers/notion.ts
|
|
1468
|
+
const notion = (options) => {
|
|
1469
|
+
const tokenEndpoint = "https://api.notion.com/v1/oauth/token";
|
|
1358
1470
|
return {
|
|
1359
|
-
id: "
|
|
1360
|
-
name: "
|
|
1471
|
+
id: "notion",
|
|
1472
|
+
name: "Notion",
|
|
1361
1473
|
createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
|
|
1362
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
1474
|
+
const _scopes = options.disableDefaultScope ? [] : [];
|
|
1363
1475
|
options.scope && _scopes.push(...options.scope);
|
|
1364
1476
|
scopes && _scopes.push(...scopes);
|
|
1365
1477
|
return require_oauth2.createAuthorizationURL({
|
|
1366
|
-
id: "
|
|
1478
|
+
id: "notion",
|
|
1367
1479
|
options,
|
|
1368
|
-
authorizationEndpoint: "https://
|
|
1480
|
+
authorizationEndpoint: "https://api.notion.com/v1/oauth/authorize",
|
|
1369
1481
|
scopes: _scopes,
|
|
1370
1482
|
state,
|
|
1371
1483
|
redirectURI,
|
|
1372
|
-
loginHint
|
|
1484
|
+
loginHint,
|
|
1485
|
+
additionalParams: { owner: "user" }
|
|
1373
1486
|
});
|
|
1374
1487
|
},
|
|
1375
1488
|
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
@@ -1377,7 +1490,8 @@ const linear = (options) => {
|
|
|
1377
1490
|
code,
|
|
1378
1491
|
redirectURI,
|
|
1379
1492
|
options,
|
|
1380
|
-
tokenEndpoint
|
|
1493
|
+
tokenEndpoint,
|
|
1494
|
+
authentication: "basic"
|
|
1381
1495
|
});
|
|
1382
1496
|
},
|
|
1383
1497
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -1393,39 +1507,24 @@ const linear = (options) => {
|
|
|
1393
1507
|
},
|
|
1394
1508
|
async getUserInfo(token) {
|
|
1395
1509
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1396
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
viewer {
|
|
1405
|
-
id
|
|
1406
|
-
name
|
|
1407
|
-
email
|
|
1408
|
-
avatarUrl
|
|
1409
|
-
active
|
|
1410
|
-
createdAt
|
|
1411
|
-
updatedAt
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
` })
|
|
1415
|
-
});
|
|
1416
|
-
if (error || !profile?.data?.viewer) return null;
|
|
1417
|
-
const userData = profile.data.viewer;
|
|
1418
|
-
const userMap = await options.mapProfileToUser?.(userData);
|
|
1510
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.notion.com/v1/users/me", { headers: {
|
|
1511
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
1512
|
+
"Notion-Version": "2022-06-28"
|
|
1513
|
+
} });
|
|
1514
|
+
if (error || !profile) return null;
|
|
1515
|
+
const userProfile = profile.bot?.owner?.user;
|
|
1516
|
+
if (!userProfile) return null;
|
|
1517
|
+
const userMap = await options.mapProfileToUser?.(userProfile);
|
|
1419
1518
|
return {
|
|
1420
1519
|
user: {
|
|
1421
|
-
id:
|
|
1422
|
-
name:
|
|
1423
|
-
email:
|
|
1424
|
-
image:
|
|
1425
|
-
emailVerified:
|
|
1520
|
+
id: userProfile.id,
|
|
1521
|
+
name: userProfile.name || "Notion User",
|
|
1522
|
+
email: userProfile.person?.email || null,
|
|
1523
|
+
image: userProfile.avatar_url,
|
|
1524
|
+
emailVerified: !!userProfile.person?.email,
|
|
1426
1525
|
...userMap
|
|
1427
1526
|
},
|
|
1428
|
-
data:
|
|
1527
|
+
data: userProfile
|
|
1429
1528
|
};
|
|
1430
1529
|
},
|
|
1431
1530
|
options
|
|
@@ -1433,65 +1532,196 @@ const linear = (options) => {
|
|
|
1433
1532
|
};
|
|
1434
1533
|
|
|
1435
1534
|
//#endregion
|
|
1436
|
-
//#region src/social-providers/
|
|
1437
|
-
const
|
|
1438
|
-
const
|
|
1439
|
-
const
|
|
1535
|
+
//#region src/social-providers/paypal.ts
|
|
1536
|
+
const paypal = (options) => {
|
|
1537
|
+
const isSandbox = (options.environment || "sandbox") === "sandbox";
|
|
1538
|
+
const authorizationEndpoint = isSandbox ? "https://www.sandbox.paypal.com/signin/authorize" : "https://www.paypal.com/signin/authorize";
|
|
1539
|
+
const tokenEndpoint = isSandbox ? "https://api-m.sandbox.paypal.com/v1/oauth2/token" : "https://api-m.paypal.com/v1/oauth2/token";
|
|
1540
|
+
const userInfoEndpoint = isSandbox ? "https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo" : "https://api-m.paypal.com/v1/identity/oauth2/userinfo";
|
|
1440
1541
|
return {
|
|
1441
|
-
id: "
|
|
1442
|
-
name: "
|
|
1443
|
-
|
|
1542
|
+
id: "paypal",
|
|
1543
|
+
name: "PayPal",
|
|
1544
|
+
async createAuthorizationURL({ state, codeVerifier, redirectURI }) {
|
|
1545
|
+
if (!options.clientId || !options.clientSecret) {
|
|
1546
|
+
require_env.logger.error("Client Id and Client Secret is required for PayPal. Make sure to provide them in the options.");
|
|
1547
|
+
throw new require_error.BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
|
|
1548
|
+
}
|
|
1549
|
+
return await require_oauth2.createAuthorizationURL({
|
|
1550
|
+
id: "paypal",
|
|
1551
|
+
options,
|
|
1552
|
+
authorizationEndpoint,
|
|
1553
|
+
scopes: [],
|
|
1554
|
+
state,
|
|
1555
|
+
codeVerifier,
|
|
1556
|
+
redirectURI,
|
|
1557
|
+
prompt: options.prompt
|
|
1558
|
+
});
|
|
1559
|
+
},
|
|
1560
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1561
|
+
/**
|
|
1562
|
+
* PayPal requires Basic Auth for token exchange
|
|
1563
|
+
**/
|
|
1564
|
+
const credentials = __better_auth_utils_base64.base64.encode(`${options.clientId}:${options.clientSecret}`);
|
|
1565
|
+
try {
|
|
1566
|
+
const response = await (0, __better_fetch_fetch.betterFetch)(tokenEndpoint, {
|
|
1567
|
+
method: "POST",
|
|
1568
|
+
headers: {
|
|
1569
|
+
Authorization: `Basic ${credentials}`,
|
|
1570
|
+
Accept: "application/json",
|
|
1571
|
+
"Accept-Language": "en_US",
|
|
1572
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1573
|
+
},
|
|
1574
|
+
body: new URLSearchParams({
|
|
1575
|
+
grant_type: "authorization_code",
|
|
1576
|
+
code,
|
|
1577
|
+
redirect_uri: redirectURI
|
|
1578
|
+
}).toString()
|
|
1579
|
+
});
|
|
1580
|
+
if (!response.data) throw new require_error.BetterAuthError("FAILED_TO_GET_ACCESS_TOKEN");
|
|
1581
|
+
const data = response.data;
|
|
1582
|
+
return {
|
|
1583
|
+
accessToken: data.access_token,
|
|
1584
|
+
refreshToken: data.refresh_token,
|
|
1585
|
+
accessTokenExpiresAt: data.expires_in ? new Date(Date.now() + data.expires_in * 1e3) : void 0,
|
|
1586
|
+
idToken: data.id_token
|
|
1587
|
+
};
|
|
1588
|
+
} catch (error) {
|
|
1589
|
+
require_env.logger.error("PayPal token exchange failed:", error);
|
|
1590
|
+
throw new require_error.BetterAuthError("FAILED_TO_GET_ACCESS_TOKEN");
|
|
1591
|
+
}
|
|
1592
|
+
},
|
|
1593
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
1594
|
+
const credentials = __better_auth_utils_base64.base64.encode(`${options.clientId}:${options.clientSecret}`);
|
|
1595
|
+
try {
|
|
1596
|
+
const response = await (0, __better_fetch_fetch.betterFetch)(tokenEndpoint, {
|
|
1597
|
+
method: "POST",
|
|
1598
|
+
headers: {
|
|
1599
|
+
Authorization: `Basic ${credentials}`,
|
|
1600
|
+
Accept: "application/json",
|
|
1601
|
+
"Accept-Language": "en_US",
|
|
1602
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
1603
|
+
},
|
|
1604
|
+
body: new URLSearchParams({
|
|
1605
|
+
grant_type: "refresh_token",
|
|
1606
|
+
refresh_token: refreshToken
|
|
1607
|
+
}).toString()
|
|
1608
|
+
});
|
|
1609
|
+
if (!response.data) throw new require_error.BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
|
|
1610
|
+
const data = response.data;
|
|
1611
|
+
return {
|
|
1612
|
+
accessToken: data.access_token,
|
|
1613
|
+
refreshToken: data.refresh_token,
|
|
1614
|
+
accessTokenExpiresAt: data.expires_in ? new Date(Date.now() + data.expires_in * 1e3) : void 0
|
|
1615
|
+
};
|
|
1616
|
+
} catch (error) {
|
|
1617
|
+
require_env.logger.error("PayPal token refresh failed:", error);
|
|
1618
|
+
throw new require_error.BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
|
|
1619
|
+
}
|
|
1620
|
+
},
|
|
1621
|
+
async verifyIdToken(token, nonce) {
|
|
1622
|
+
if (options.disableIdTokenSignIn) return false;
|
|
1623
|
+
if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
|
|
1624
|
+
try {
|
|
1625
|
+
return !!(0, jose.decodeJwt)(token).sub;
|
|
1626
|
+
} catch (error) {
|
|
1627
|
+
require_env.logger.error("Failed to verify PayPal ID token:", error);
|
|
1628
|
+
return false;
|
|
1629
|
+
}
|
|
1630
|
+
},
|
|
1631
|
+
async getUserInfo(token) {
|
|
1632
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1633
|
+
if (!token.accessToken) {
|
|
1634
|
+
require_env.logger.error("Access token is required to fetch PayPal user info");
|
|
1635
|
+
return null;
|
|
1636
|
+
}
|
|
1637
|
+
try {
|
|
1638
|
+
const response = await (0, __better_fetch_fetch.betterFetch)(`${userInfoEndpoint}?schema=paypalv1.1`, { headers: {
|
|
1639
|
+
Authorization: `Bearer ${token.accessToken}`,
|
|
1640
|
+
Accept: "application/json"
|
|
1641
|
+
} });
|
|
1642
|
+
if (!response.data) {
|
|
1643
|
+
require_env.logger.error("Failed to fetch user info from PayPal");
|
|
1644
|
+
return null;
|
|
1645
|
+
}
|
|
1646
|
+
const userInfo = response.data;
|
|
1647
|
+
const userMap = await options.mapProfileToUser?.(userInfo);
|
|
1648
|
+
return {
|
|
1649
|
+
user: {
|
|
1650
|
+
id: userInfo.user_id,
|
|
1651
|
+
name: userInfo.name,
|
|
1652
|
+
email: userInfo.email,
|
|
1653
|
+
image: userInfo.picture,
|
|
1654
|
+
emailVerified: userInfo.email_verified,
|
|
1655
|
+
...userMap
|
|
1656
|
+
},
|
|
1657
|
+
data: userInfo
|
|
1658
|
+
};
|
|
1659
|
+
} catch (error) {
|
|
1660
|
+
require_env.logger.error("Failed to fetch user info from PayPal:", error);
|
|
1661
|
+
return null;
|
|
1662
|
+
}
|
|
1663
|
+
},
|
|
1664
|
+
options
|
|
1665
|
+
};
|
|
1666
|
+
};
|
|
1667
|
+
|
|
1668
|
+
//#endregion
|
|
1669
|
+
//#region src/social-providers/polar.ts
|
|
1670
|
+
const polar = (options) => {
|
|
1671
|
+
return {
|
|
1672
|
+
id: "polar",
|
|
1673
|
+
name: "Polar",
|
|
1674
|
+
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
|
|
1444
1675
|
const _scopes = options.disableDefaultScope ? [] : [
|
|
1676
|
+
"openid",
|
|
1445
1677
|
"profile",
|
|
1446
|
-
"email"
|
|
1447
|
-
"openid"
|
|
1678
|
+
"email"
|
|
1448
1679
|
];
|
|
1449
1680
|
options.scope && _scopes.push(...options.scope);
|
|
1450
1681
|
scopes && _scopes.push(...scopes);
|
|
1451
|
-
return
|
|
1452
|
-
id: "
|
|
1682
|
+
return (0, __better_auth_core_oauth2.createAuthorizationURL)({
|
|
1683
|
+
id: "polar",
|
|
1453
1684
|
options,
|
|
1454
|
-
authorizationEndpoint,
|
|
1685
|
+
authorizationEndpoint: "https://polar.sh/oauth2/authorize",
|
|
1455
1686
|
scopes: _scopes,
|
|
1456
1687
|
state,
|
|
1457
|
-
|
|
1458
|
-
redirectURI
|
|
1688
|
+
codeVerifier,
|
|
1689
|
+
redirectURI,
|
|
1690
|
+
prompt: options.prompt
|
|
1459
1691
|
});
|
|
1460
1692
|
},
|
|
1461
|
-
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1462
|
-
return
|
|
1693
|
+
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
1694
|
+
return (0, __better_auth_core_oauth2.validateAuthorizationCode)({
|
|
1463
1695
|
code,
|
|
1696
|
+
codeVerifier,
|
|
1464
1697
|
redirectURI,
|
|
1465
1698
|
options,
|
|
1466
|
-
tokenEndpoint
|
|
1699
|
+
tokenEndpoint: "https://api.polar.sh/v1/oauth2/token"
|
|
1467
1700
|
});
|
|
1468
1701
|
},
|
|
1469
1702
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
1470
|
-
return
|
|
1703
|
+
return (0, __better_auth_core_oauth2.refreshAccessToken)({
|
|
1471
1704
|
refreshToken,
|
|
1472
1705
|
options: {
|
|
1473
1706
|
clientId: options.clientId,
|
|
1474
1707
|
clientKey: options.clientKey,
|
|
1475
1708
|
clientSecret: options.clientSecret
|
|
1476
1709
|
},
|
|
1477
|
-
tokenEndpoint
|
|
1710
|
+
tokenEndpoint: "https://api.polar.sh/v1/oauth2/token"
|
|
1478
1711
|
});
|
|
1479
1712
|
},
|
|
1480
1713
|
async getUserInfo(token) {
|
|
1481
1714
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1482
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.
|
|
1483
|
-
method: "GET",
|
|
1484
|
-
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
1485
|
-
});
|
|
1715
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.polar.sh/v1/oauth2/userinfo", { headers: { Authorization: `Bearer ${token.accessToken}` } });
|
|
1486
1716
|
if (error) return null;
|
|
1487
1717
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
1488
1718
|
return {
|
|
1489
1719
|
user: {
|
|
1490
|
-
id: profile.
|
|
1491
|
-
name: profile.
|
|
1720
|
+
id: profile.id,
|
|
1721
|
+
name: profile.public_name || profile.username,
|
|
1492
1722
|
email: profile.email,
|
|
1493
|
-
|
|
1494
|
-
|
|
1723
|
+
image: profile.avatar_url,
|
|
1724
|
+
emailVerified: true,
|
|
1495
1725
|
...userMap
|
|
1496
1726
|
},
|
|
1497
1727
|
data: profile
|
|
@@ -1502,139 +1732,8 @@ const linkedin = (options) => {
|
|
|
1502
1732
|
};
|
|
1503
1733
|
|
|
1504
1734
|
//#endregion
|
|
1505
|
-
//#region src/social-providers/
|
|
1506
|
-
const
|
|
1507
|
-
return input.split("://").map((str) => str.replace(/\/{2,}/g, "/")).join("://");
|
|
1508
|
-
};
|
|
1509
|
-
const issuerToEndpoints = (issuer) => {
|
|
1510
|
-
let baseUrl = issuer || "https://gitlab.com";
|
|
1511
|
-
return {
|
|
1512
|
-
authorizationEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/authorize`),
|
|
1513
|
-
tokenEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/token`),
|
|
1514
|
-
userinfoEndpoint: cleanDoubleSlashes(`${baseUrl}/api/v4/user`)
|
|
1515
|
-
};
|
|
1516
|
-
};
|
|
1517
|
-
const gitlab = (options) => {
|
|
1518
|
-
const { authorizationEndpoint, tokenEndpoint, userinfoEndpoint } = issuerToEndpoints(options.issuer);
|
|
1519
|
-
const issuerId = "gitlab";
|
|
1520
|
-
return {
|
|
1521
|
-
id: issuerId,
|
|
1522
|
-
name: "Gitlab",
|
|
1523
|
-
createAuthorizationURL: async ({ state, scopes, codeVerifier, loginHint, redirectURI }) => {
|
|
1524
|
-
const _scopes = options.disableDefaultScope ? [] : ["read_user"];
|
|
1525
|
-
options.scope && _scopes.push(...options.scope);
|
|
1526
|
-
scopes && _scopes.push(...scopes);
|
|
1527
|
-
return await require_oauth2.createAuthorizationURL({
|
|
1528
|
-
id: issuerId,
|
|
1529
|
-
options,
|
|
1530
|
-
authorizationEndpoint,
|
|
1531
|
-
scopes: _scopes,
|
|
1532
|
-
state,
|
|
1533
|
-
redirectURI,
|
|
1534
|
-
codeVerifier,
|
|
1535
|
-
loginHint
|
|
1536
|
-
});
|
|
1537
|
-
},
|
|
1538
|
-
validateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {
|
|
1539
|
-
return require_oauth2.validateAuthorizationCode({
|
|
1540
|
-
code,
|
|
1541
|
-
redirectURI,
|
|
1542
|
-
options,
|
|
1543
|
-
codeVerifier,
|
|
1544
|
-
tokenEndpoint
|
|
1545
|
-
});
|
|
1546
|
-
},
|
|
1547
|
-
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
1548
|
-
return require_oauth2.refreshAccessToken({
|
|
1549
|
-
refreshToken,
|
|
1550
|
-
options: {
|
|
1551
|
-
clientId: options.clientId,
|
|
1552
|
-
clientKey: options.clientKey,
|
|
1553
|
-
clientSecret: options.clientSecret
|
|
1554
|
-
},
|
|
1555
|
-
tokenEndpoint
|
|
1556
|
-
});
|
|
1557
|
-
},
|
|
1558
|
-
async getUserInfo(token) {
|
|
1559
|
-
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1560
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)(userinfoEndpoint, { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
1561
|
-
if (error || profile.state !== "active" || profile.locked) return null;
|
|
1562
|
-
const userMap = await options.mapProfileToUser?.(profile);
|
|
1563
|
-
return {
|
|
1564
|
-
user: {
|
|
1565
|
-
id: profile.id,
|
|
1566
|
-
name: profile.name ?? profile.username,
|
|
1567
|
-
email: profile.email,
|
|
1568
|
-
image: profile.avatar_url,
|
|
1569
|
-
emailVerified: true,
|
|
1570
|
-
...userMap
|
|
1571
|
-
},
|
|
1572
|
-
data: profile
|
|
1573
|
-
};
|
|
1574
|
-
},
|
|
1575
|
-
options
|
|
1576
|
-
};
|
|
1577
|
-
};
|
|
1578
|
-
|
|
1579
|
-
//#endregion
|
|
1580
|
-
//#region src/social-providers/tiktok.ts
|
|
1581
|
-
const tiktok = (options) => {
|
|
1582
|
-
return {
|
|
1583
|
-
id: "tiktok",
|
|
1584
|
-
name: "TikTok",
|
|
1585
|
-
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
1586
|
-
const _scopes = options.disableDefaultScope ? [] : ["user.info.profile"];
|
|
1587
|
-
options.scope && _scopes.push(...options.scope);
|
|
1588
|
-
scopes && _scopes.push(...scopes);
|
|
1589
|
-
return new URL(`https://www.tiktok.com/v2/auth/authorize?scope=${_scopes.join(",")}&response_type=code&client_key=${options.clientKey}&redirect_uri=${encodeURIComponent(options.redirectURI || redirectURI)}&state=${state}`);
|
|
1590
|
-
},
|
|
1591
|
-
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1592
|
-
return require_oauth2.validateAuthorizationCode({
|
|
1593
|
-
code,
|
|
1594
|
-
redirectURI: options.redirectURI || redirectURI,
|
|
1595
|
-
options: {
|
|
1596
|
-
clientKey: options.clientKey,
|
|
1597
|
-
clientSecret: options.clientSecret
|
|
1598
|
-
},
|
|
1599
|
-
tokenEndpoint: "https://open.tiktokapis.com/v2/oauth/token/"
|
|
1600
|
-
});
|
|
1601
|
-
},
|
|
1602
|
-
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
1603
|
-
return require_oauth2.refreshAccessToken({
|
|
1604
|
-
refreshToken,
|
|
1605
|
-
options: { clientSecret: options.clientSecret },
|
|
1606
|
-
tokenEndpoint: "https://open.tiktokapis.com/v2/oauth/token/",
|
|
1607
|
-
authentication: "post",
|
|
1608
|
-
extraParams: { client_key: options.clientKey }
|
|
1609
|
-
});
|
|
1610
|
-
},
|
|
1611
|
-
async getUserInfo(token) {
|
|
1612
|
-
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1613
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)(`https://open.tiktokapis.com/v2/user/info/?fields=${[
|
|
1614
|
-
"open_id",
|
|
1615
|
-
"avatar_large_url",
|
|
1616
|
-
"display_name",
|
|
1617
|
-
"username"
|
|
1618
|
-
].join(",")}`, { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
1619
|
-
if (error) return null;
|
|
1620
|
-
return {
|
|
1621
|
-
user: {
|
|
1622
|
-
email: profile.data.user.email || profile.data.user.username,
|
|
1623
|
-
id: profile.data.user.open_id,
|
|
1624
|
-
name: profile.data.user.display_name || profile.data.user.username,
|
|
1625
|
-
image: profile.data.user.avatar_large_url,
|
|
1626
|
-
emailVerified: profile.data.user.email ? true : false
|
|
1627
|
-
},
|
|
1628
|
-
data: profile
|
|
1629
|
-
};
|
|
1630
|
-
},
|
|
1631
|
-
options
|
|
1632
|
-
};
|
|
1633
|
-
};
|
|
1634
|
-
|
|
1635
|
-
//#endregion
|
|
1636
|
-
//#region src/social-providers/reddit.ts
|
|
1637
|
-
const reddit = (options) => {
|
|
1735
|
+
//#region src/social-providers/reddit.ts
|
|
1736
|
+
const reddit = (options) => {
|
|
1638
1737
|
return {
|
|
1639
1738
|
id: "reddit",
|
|
1640
1739
|
name: "Reddit",
|
|
@@ -1842,33 +1941,33 @@ const salesforce = (options) => {
|
|
|
1842
1941
|
};
|
|
1843
1942
|
|
|
1844
1943
|
//#endregion
|
|
1845
|
-
//#region src/social-providers/
|
|
1846
|
-
const
|
|
1944
|
+
//#region src/social-providers/slack.ts
|
|
1945
|
+
const slack = (options) => {
|
|
1847
1946
|
return {
|
|
1848
|
-
id: "
|
|
1849
|
-
name: "
|
|
1850
|
-
|
|
1851
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
1852
|
-
|
|
1947
|
+
id: "slack",
|
|
1948
|
+
name: "Slack",
|
|
1949
|
+
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
1950
|
+
const _scopes = options.disableDefaultScope ? [] : [
|
|
1951
|
+
"openid",
|
|
1952
|
+
"profile",
|
|
1953
|
+
"email"
|
|
1954
|
+
];
|
|
1853
1955
|
scopes && _scopes.push(...scopes);
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
});
|
|
1956
|
+
options.scope && _scopes.push(...options.scope);
|
|
1957
|
+
const url = new URL("https://slack.com/openid/connect/authorize");
|
|
1958
|
+
url.searchParams.set("scope", _scopes.join(" "));
|
|
1959
|
+
url.searchParams.set("response_type", "code");
|
|
1960
|
+
url.searchParams.set("client_id", options.clientId);
|
|
1961
|
+
url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
|
|
1962
|
+
url.searchParams.set("state", state);
|
|
1963
|
+
return url;
|
|
1863
1964
|
},
|
|
1864
|
-
validateAuthorizationCode: async ({ code,
|
|
1965
|
+
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
1865
1966
|
return require_oauth2.validateAuthorizationCode({
|
|
1866
1967
|
code,
|
|
1867
|
-
|
|
1868
|
-
redirectURI: options.redirectURI || redirectURI,
|
|
1968
|
+
redirectURI,
|
|
1869
1969
|
options,
|
|
1870
|
-
|
|
1871
|
-
tokenEndpoint: "https://id.vk.com/oauth2/auth"
|
|
1970
|
+
tokenEndpoint: "https://slack.com/api/openid.connect.token"
|
|
1872
1971
|
});
|
|
1873
1972
|
},
|
|
1874
1973
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -1879,35 +1978,21 @@ const vk = (options) => {
|
|
|
1879
1978
|
clientKey: options.clientKey,
|
|
1880
1979
|
clientSecret: options.clientSecret
|
|
1881
1980
|
},
|
|
1882
|
-
tokenEndpoint: "https://
|
|
1981
|
+
tokenEndpoint: "https://slack.com/api/openid.connect.token"
|
|
1883
1982
|
});
|
|
1884
1983
|
},
|
|
1885
|
-
async getUserInfo(
|
|
1886
|
-
if (options.getUserInfo) return options.getUserInfo(
|
|
1887
|
-
|
|
1888
|
-
const formBody = new URLSearchParams({
|
|
1889
|
-
access_token: data.accessToken,
|
|
1890
|
-
client_id: options.clientId
|
|
1891
|
-
}).toString();
|
|
1892
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://id.vk.com/oauth2/user_info", {
|
|
1893
|
-
method: "POST",
|
|
1894
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
1895
|
-
body: formBody
|
|
1896
|
-
});
|
|
1984
|
+
async getUserInfo(token) {
|
|
1985
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
1986
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://slack.com/api/openid.connect.userInfo", { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
1897
1987
|
if (error) return null;
|
|
1898
|
-
if (!profile.user.email) return null;
|
|
1899
1988
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
1900
1989
|
return {
|
|
1901
1990
|
user: {
|
|
1902
|
-
id: profile.
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
image: profile.
|
|
1907
|
-
emailVerified: !!profile.user.email,
|
|
1908
|
-
birthday: profile.user.birthday,
|
|
1909
|
-
sex: profile.user.sex,
|
|
1910
|
-
name: `${profile.user.first_name} ${profile.user.last_name}`,
|
|
1991
|
+
id: profile["https://slack.com/user_id"],
|
|
1992
|
+
name: profile.name || "",
|
|
1993
|
+
email: profile.email,
|
|
1994
|
+
emailVerified: profile.email_verified,
|
|
1995
|
+
image: profile.picture || profile["https://slack.com/user_image_512"],
|
|
1911
1996
|
...userMap
|
|
1912
1997
|
},
|
|
1913
1998
|
data: profile
|
|
@@ -1918,118 +2003,117 @@ const vk = (options) => {
|
|
|
1918
2003
|
};
|
|
1919
2004
|
|
|
1920
2005
|
//#endregion
|
|
1921
|
-
//#region src/social-providers/
|
|
1922
|
-
const
|
|
1923
|
-
const options = {
|
|
1924
|
-
pkce: true,
|
|
1925
|
-
...userOptions
|
|
1926
|
-
};
|
|
2006
|
+
//#region src/social-providers/spotify.ts
|
|
2007
|
+
const spotify = (options) => {
|
|
1927
2008
|
return {
|
|
1928
|
-
id: "
|
|
1929
|
-
name: "
|
|
1930
|
-
createAuthorizationURL
|
|
1931
|
-
const
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
2009
|
+
id: "spotify",
|
|
2010
|
+
name: "Spotify",
|
|
2011
|
+
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
|
|
2012
|
+
const _scopes = options.disableDefaultScope ? [] : ["user-read-email"];
|
|
2013
|
+
options.scope && _scopes.push(...options.scope);
|
|
2014
|
+
scopes && _scopes.push(...scopes);
|
|
2015
|
+
return require_oauth2.createAuthorizationURL({
|
|
2016
|
+
id: "spotify",
|
|
2017
|
+
options,
|
|
2018
|
+
authorizationEndpoint: "https://accounts.spotify.com/authorize",
|
|
2019
|
+
scopes: _scopes,
|
|
2020
|
+
state,
|
|
2021
|
+
codeVerifier,
|
|
2022
|
+
redirectURI
|
|
1936
2023
|
});
|
|
1937
|
-
if (options.pkce) {
|
|
1938
|
-
const codeChallenge = await require_oauth2.generateCodeChallenge(codeVerifier);
|
|
1939
|
-
params.set("code_challenge_method", "S256");
|
|
1940
|
-
params.set("code_challenge", codeChallenge);
|
|
1941
|
-
}
|
|
1942
|
-
const url = new URL("https://zoom.us/oauth/authorize");
|
|
1943
|
-
url.search = params.toString();
|
|
1944
|
-
return url;
|
|
1945
2024
|
},
|
|
1946
|
-
validateAuthorizationCode: async ({ code,
|
|
2025
|
+
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
1947
2026
|
return require_oauth2.validateAuthorizationCode({
|
|
1948
2027
|
code,
|
|
1949
|
-
redirectURI: options.redirectURI || redirectURI,
|
|
1950
2028
|
codeVerifier,
|
|
2029
|
+
redirectURI,
|
|
1951
2030
|
options,
|
|
1952
|
-
tokenEndpoint: "https://
|
|
1953
|
-
authentication: "post"
|
|
2031
|
+
tokenEndpoint: "https://accounts.spotify.com/api/token"
|
|
1954
2032
|
});
|
|
1955
2033
|
},
|
|
1956
|
-
async
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
2034
|
+
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
2035
|
+
return require_oauth2.refreshAccessToken({
|
|
2036
|
+
refreshToken,
|
|
2037
|
+
options: {
|
|
2038
|
+
clientId: options.clientId,
|
|
2039
|
+
clientKey: options.clientKey,
|
|
2040
|
+
clientSecret: options.clientSecret
|
|
2041
|
+
},
|
|
2042
|
+
tokenEndpoint: "https://accounts.spotify.com/api/token"
|
|
2043
|
+
});
|
|
2044
|
+
},
|
|
2045
|
+
async getUserInfo(token) {
|
|
2046
|
+
if (options.getUserInfo) return options.getUserInfo(token);
|
|
2047
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.spotify.com/v1/me", {
|
|
2048
|
+
method: "GET",
|
|
2049
|
+
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
2050
|
+
});
|
|
2051
|
+
if (error) return null;
|
|
2052
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
2053
|
+
return {
|
|
2054
|
+
user: {
|
|
2055
|
+
id: profile.id,
|
|
2056
|
+
name: profile.display_name,
|
|
1966
2057
|
email: profile.email,
|
|
1967
|
-
|
|
2058
|
+
image: profile.images[0]?.url,
|
|
2059
|
+
emailVerified: false,
|
|
1968
2060
|
...userMap
|
|
1969
2061
|
},
|
|
1970
|
-
data:
|
|
2062
|
+
data: profile
|
|
1971
2063
|
};
|
|
1972
|
-
}
|
|
2064
|
+
},
|
|
2065
|
+
options
|
|
1973
2066
|
};
|
|
1974
2067
|
};
|
|
1975
2068
|
|
|
1976
2069
|
//#endregion
|
|
1977
|
-
//#region src/social-providers/
|
|
1978
|
-
const
|
|
2070
|
+
//#region src/social-providers/tiktok.ts
|
|
2071
|
+
const tiktok = (options) => {
|
|
1979
2072
|
return {
|
|
1980
|
-
id: "
|
|
1981
|
-
name: "
|
|
2073
|
+
id: "tiktok",
|
|
2074
|
+
name: "TikTok",
|
|
1982
2075
|
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
1983
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
1984
|
-
"account_email",
|
|
1985
|
-
"profile_image",
|
|
1986
|
-
"profile_nickname"
|
|
1987
|
-
];
|
|
2076
|
+
const _scopes = options.disableDefaultScope ? [] : ["user.info.profile"];
|
|
1988
2077
|
options.scope && _scopes.push(...options.scope);
|
|
1989
2078
|
scopes && _scopes.push(...scopes);
|
|
1990
|
-
return
|
|
1991
|
-
id: "kakao",
|
|
1992
|
-
options,
|
|
1993
|
-
authorizationEndpoint: "https://kauth.kakao.com/oauth/authorize",
|
|
1994
|
-
scopes: _scopes,
|
|
1995
|
-
state,
|
|
1996
|
-
redirectURI
|
|
1997
|
-
});
|
|
2079
|
+
return new URL(`https://www.tiktok.com/v2/auth/authorize?scope=${_scopes.join(",")}&response_type=code&client_key=${options.clientKey}&redirect_uri=${encodeURIComponent(options.redirectURI || redirectURI)}&state=${state}`);
|
|
1998
2080
|
},
|
|
1999
2081
|
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
2000
2082
|
return require_oauth2.validateAuthorizationCode({
|
|
2001
2083
|
code,
|
|
2002
|
-
redirectURI,
|
|
2003
|
-
options
|
|
2004
|
-
|
|
2084
|
+
redirectURI: options.redirectURI || redirectURI,
|
|
2085
|
+
options: {
|
|
2086
|
+
clientKey: options.clientKey,
|
|
2087
|
+
clientSecret: options.clientSecret
|
|
2088
|
+
},
|
|
2089
|
+
tokenEndpoint: "https://open.tiktokapis.com/v2/oauth/token/"
|
|
2005
2090
|
});
|
|
2006
2091
|
},
|
|
2007
2092
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
2008
2093
|
return require_oauth2.refreshAccessToken({
|
|
2009
2094
|
refreshToken,
|
|
2010
|
-
options: {
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
},
|
|
2015
|
-
tokenEndpoint: "https://kauth.kakao.com/oauth/token"
|
|
2095
|
+
options: { clientSecret: options.clientSecret },
|
|
2096
|
+
tokenEndpoint: "https://open.tiktokapis.com/v2/oauth/token/",
|
|
2097
|
+
authentication: "post",
|
|
2098
|
+
extraParams: { client_key: options.clientKey }
|
|
2016
2099
|
});
|
|
2017
2100
|
},
|
|
2018
2101
|
async getUserInfo(token) {
|
|
2019
2102
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
2020
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)(
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2103
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)(`https://open.tiktokapis.com/v2/user/info/?fields=${[
|
|
2104
|
+
"open_id",
|
|
2105
|
+
"avatar_large_url",
|
|
2106
|
+
"display_name",
|
|
2107
|
+
"username"
|
|
2108
|
+
].join(",")}`, { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
2109
|
+
if (error) return null;
|
|
2025
2110
|
return {
|
|
2026
2111
|
user: {
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
image:
|
|
2031
|
-
emailVerified:
|
|
2032
|
-
...userMap
|
|
2112
|
+
email: profile.data.user.email || profile.data.user.username,
|
|
2113
|
+
id: profile.data.user.open_id,
|
|
2114
|
+
name: profile.data.user.display_name || profile.data.user.username,
|
|
2115
|
+
image: profile.data.user.avatar_large_url,
|
|
2116
|
+
emailVerified: profile.data.user.email ? true : false
|
|
2033
2117
|
},
|
|
2034
2118
|
data: profile
|
|
2035
2119
|
};
|
|
@@ -2039,22 +2123,28 @@ const kakao = (options) => {
|
|
|
2039
2123
|
};
|
|
2040
2124
|
|
|
2041
2125
|
//#endregion
|
|
2042
|
-
//#region src/social-providers/
|
|
2043
|
-
const
|
|
2126
|
+
//#region src/social-providers/twitch.ts
|
|
2127
|
+
const twitch = (options) => {
|
|
2044
2128
|
return {
|
|
2045
|
-
id: "
|
|
2046
|
-
name: "
|
|
2129
|
+
id: "twitch",
|
|
2130
|
+
name: "Twitch",
|
|
2047
2131
|
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
2048
|
-
const _scopes = options.disableDefaultScope ? [] : ["
|
|
2132
|
+
const _scopes = options.disableDefaultScope ? [] : ["user:read:email", "openid"];
|
|
2049
2133
|
options.scope && _scopes.push(...options.scope);
|
|
2050
2134
|
scopes && _scopes.push(...scopes);
|
|
2051
2135
|
return require_oauth2.createAuthorizationURL({
|
|
2052
|
-
id: "
|
|
2136
|
+
id: "twitch",
|
|
2137
|
+
redirectURI,
|
|
2053
2138
|
options,
|
|
2054
|
-
authorizationEndpoint: "https://
|
|
2139
|
+
authorizationEndpoint: "https://id.twitch.tv/oauth2/authorize",
|
|
2055
2140
|
scopes: _scopes,
|
|
2056
2141
|
state,
|
|
2057
|
-
|
|
2142
|
+
claims: options.claims || [
|
|
2143
|
+
"email",
|
|
2144
|
+
"email_verified",
|
|
2145
|
+
"preferred_username",
|
|
2146
|
+
"picture"
|
|
2147
|
+
]
|
|
2058
2148
|
});
|
|
2059
2149
|
},
|
|
2060
2150
|
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
@@ -2062,7 +2152,7 @@ const naver = (options) => {
|
|
|
2062
2152
|
code,
|
|
2063
2153
|
redirectURI,
|
|
2064
2154
|
options,
|
|
2065
|
-
tokenEndpoint: "https://
|
|
2155
|
+
tokenEndpoint: "https://id.twitch.tv/oauth2/token"
|
|
2066
2156
|
});
|
|
2067
2157
|
},
|
|
2068
2158
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -2073,22 +2163,25 @@ const naver = (options) => {
|
|
|
2073
2163
|
clientKey: options.clientKey,
|
|
2074
2164
|
clientSecret: options.clientSecret
|
|
2075
2165
|
},
|
|
2076
|
-
tokenEndpoint: "https://
|
|
2166
|
+
tokenEndpoint: "https://id.twitch.tv/oauth2/token"
|
|
2077
2167
|
});
|
|
2078
2168
|
},
|
|
2079
2169
|
async getUserInfo(token) {
|
|
2080
2170
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
2081
|
-
const
|
|
2082
|
-
if (
|
|
2171
|
+
const idToken = token.idToken;
|
|
2172
|
+
if (!idToken) {
|
|
2173
|
+
require_env.logger.error("No idToken found in token");
|
|
2174
|
+
return null;
|
|
2175
|
+
}
|
|
2176
|
+
const profile = (0, jose.decodeJwt)(idToken);
|
|
2083
2177
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
2084
|
-
const res = profile.response || {};
|
|
2085
2178
|
return {
|
|
2086
2179
|
user: {
|
|
2087
|
-
id:
|
|
2088
|
-
name:
|
|
2089
|
-
email:
|
|
2090
|
-
image:
|
|
2091
|
-
emailVerified:
|
|
2180
|
+
id: profile.sub,
|
|
2181
|
+
name: profile.preferred_username,
|
|
2182
|
+
email: profile.email,
|
|
2183
|
+
image: profile.picture,
|
|
2184
|
+
emailVerified: profile.email_verified,
|
|
2092
2185
|
...userMap
|
|
2093
2186
|
},
|
|
2094
2187
|
data: profile
|
|
@@ -2099,50 +2192,38 @@ const naver = (options) => {
|
|
|
2099
2192
|
};
|
|
2100
2193
|
|
|
2101
2194
|
//#endregion
|
|
2102
|
-
//#region src/social-providers/
|
|
2103
|
-
|
|
2104
|
-
* LINE Login v2.1
|
|
2105
|
-
* - Authorization endpoint: https://access.line.me/oauth2/v2.1/authorize
|
|
2106
|
-
* - Token endpoint: https://api.line.me/oauth2/v2.1/token
|
|
2107
|
-
* - UserInfo endpoint: https://api.line.me/oauth2/v2.1/userinfo
|
|
2108
|
-
* - Verify ID token: https://api.line.me/oauth2/v2.1/verify
|
|
2109
|
-
*
|
|
2110
|
-
* Docs: https://developers.line.biz/en/reference/line-login/#issue-access-token
|
|
2111
|
-
*/
|
|
2112
|
-
const line = (options) => {
|
|
2113
|
-
const authorizationEndpoint = "https://access.line.me/oauth2/v2.1/authorize";
|
|
2114
|
-
const tokenEndpoint = "https://api.line.me/oauth2/v2.1/token";
|
|
2115
|
-
const userInfoEndpoint = "https://api.line.me/oauth2/v2.1/userinfo";
|
|
2116
|
-
const verifyIdTokenEndpoint = "https://api.line.me/oauth2/v2.1/verify";
|
|
2195
|
+
//#region src/social-providers/twitter.ts
|
|
2196
|
+
const twitter = (options) => {
|
|
2117
2197
|
return {
|
|
2118
|
-
id: "
|
|
2119
|
-
name: "
|
|
2120
|
-
|
|
2198
|
+
id: "twitter",
|
|
2199
|
+
name: "Twitter",
|
|
2200
|
+
createAuthorizationURL(data) {
|
|
2121
2201
|
const _scopes = options.disableDefaultScope ? [] : [
|
|
2122
|
-
"
|
|
2123
|
-
"
|
|
2124
|
-
"
|
|
2202
|
+
"users.read",
|
|
2203
|
+
"tweet.read",
|
|
2204
|
+
"offline.access",
|
|
2205
|
+
"users.email"
|
|
2125
2206
|
];
|
|
2126
2207
|
options.scope && _scopes.push(...options.scope);
|
|
2127
|
-
scopes && _scopes.push(...scopes);
|
|
2128
|
-
return
|
|
2129
|
-
id: "
|
|
2208
|
+
data.scopes && _scopes.push(...data.scopes);
|
|
2209
|
+
return require_oauth2.createAuthorizationURL({
|
|
2210
|
+
id: "twitter",
|
|
2130
2211
|
options,
|
|
2131
|
-
authorizationEndpoint,
|
|
2212
|
+
authorizationEndpoint: "https://x.com/i/oauth2/authorize",
|
|
2132
2213
|
scopes: _scopes,
|
|
2133
|
-
state,
|
|
2134
|
-
codeVerifier,
|
|
2135
|
-
redirectURI
|
|
2136
|
-
loginHint
|
|
2214
|
+
state: data.state,
|
|
2215
|
+
codeVerifier: data.codeVerifier,
|
|
2216
|
+
redirectURI: data.redirectURI
|
|
2137
2217
|
});
|
|
2138
2218
|
},
|
|
2139
2219
|
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
2140
2220
|
return require_oauth2.validateAuthorizationCode({
|
|
2141
2221
|
code,
|
|
2142
2222
|
codeVerifier,
|
|
2223
|
+
authentication: "basic",
|
|
2143
2224
|
redirectURI,
|
|
2144
2225
|
options,
|
|
2145
|
-
tokenEndpoint
|
|
2226
|
+
tokenEndpoint: "https://api.x.com/2/oauth2/token"
|
|
2146
2227
|
});
|
|
2147
2228
|
},
|
|
2148
2229
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
@@ -2150,50 +2231,37 @@ const line = (options) => {
|
|
|
2150
2231
|
refreshToken,
|
|
2151
2232
|
options: {
|
|
2152
2233
|
clientId: options.clientId,
|
|
2234
|
+
clientKey: options.clientKey,
|
|
2153
2235
|
clientSecret: options.clientSecret
|
|
2154
2236
|
},
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
},
|
|
2158
|
-
async verifyIdToken(token, nonce) {
|
|
2159
|
-
if (options.disableIdTokenSignIn) return false;
|
|
2160
|
-
if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
|
|
2161
|
-
const body = new URLSearchParams();
|
|
2162
|
-
body.set("id_token", token);
|
|
2163
|
-
body.set("client_id", options.clientId);
|
|
2164
|
-
if (nonce) body.set("nonce", nonce);
|
|
2165
|
-
const { data, error } = await (0, __better_fetch_fetch.betterFetch)(verifyIdTokenEndpoint, {
|
|
2166
|
-
method: "POST",
|
|
2167
|
-
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
2168
|
-
body
|
|
2237
|
+
authentication: "basic",
|
|
2238
|
+
tokenEndpoint: "https://api.x.com/2/oauth2/token"
|
|
2169
2239
|
});
|
|
2170
|
-
if (error || !data) return false;
|
|
2171
|
-
if (data.aud !== options.clientId) return false;
|
|
2172
|
-
if (nonce && data.nonce && data.nonce !== nonce) return false;
|
|
2173
|
-
return true;
|
|
2174
2240
|
},
|
|
2175
2241
|
async getUserInfo(token) {
|
|
2176
2242
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
}
|
|
2181
|
-
if (
|
|
2182
|
-
|
|
2183
|
-
|
|
2243
|
+
const { data: profile, error: profileError } = await (0, __better_fetch_fetch.betterFetch)("https://api.x.com/2/users/me?user.fields=profile_image_url", {
|
|
2244
|
+
method: "GET",
|
|
2245
|
+
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
2246
|
+
});
|
|
2247
|
+
if (profileError) return null;
|
|
2248
|
+
const { data: emailData, error: emailError } = await (0, __better_fetch_fetch.betterFetch)("https://api.x.com/2/users/me?user.fields=confirmed_email", {
|
|
2249
|
+
method: "GET",
|
|
2250
|
+
headers: { Authorization: `Bearer ${token.accessToken}` }
|
|
2251
|
+
});
|
|
2252
|
+
let emailVerified = false;
|
|
2253
|
+
if (!emailError && emailData?.data?.confirmed_email) {
|
|
2254
|
+
profile.data.email = emailData.data.confirmed_email;
|
|
2255
|
+
emailVerified = true;
|
|
2184
2256
|
}
|
|
2185
|
-
if (!profile) return null;
|
|
2186
2257
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
2187
|
-
const id = profile.sub || profile.userId;
|
|
2188
|
-
const name = profile.name || profile.displayName;
|
|
2189
|
-
const image = profile.picture || profile.pictureUrl || void 0;
|
|
2190
2258
|
return {
|
|
2191
2259
|
user: {
|
|
2192
|
-
id,
|
|
2193
|
-
name,
|
|
2194
|
-
email: profile.email,
|
|
2195
|
-
image,
|
|
2196
|
-
emailVerified
|
|
2260
|
+
id: profile.data.id,
|
|
2261
|
+
name: profile.data.name,
|
|
2262
|
+
email: profile.data.email || profile.data.username || null,
|
|
2263
|
+
image: profile.data.profile_image_url,
|
|
2264
|
+
emailVerified,
|
|
2197
2265
|
...userMap
|
|
2198
2266
|
},
|
|
2199
2267
|
data: profile
|
|
@@ -2204,202 +2272,134 @@ const line = (options) => {
|
|
|
2204
2272
|
};
|
|
2205
2273
|
|
|
2206
2274
|
//#endregion
|
|
2207
|
-
//#region src/social-providers/
|
|
2208
|
-
const
|
|
2209
|
-
const isSandbox = (options.environment || "sandbox") === "sandbox";
|
|
2210
|
-
const authorizationEndpoint = isSandbox ? "https://www.sandbox.paypal.com/signin/authorize" : "https://www.paypal.com/signin/authorize";
|
|
2211
|
-
const tokenEndpoint = isSandbox ? "https://api-m.sandbox.paypal.com/v1/oauth2/token" : "https://api-m.paypal.com/v1/oauth2/token";
|
|
2212
|
-
const userInfoEndpoint = isSandbox ? "https://api-m.sandbox.paypal.com/v1/identity/oauth2/userinfo" : "https://api-m.paypal.com/v1/identity/oauth2/userinfo";
|
|
2213
|
-
return {
|
|
2214
|
-
id: "paypal",
|
|
2215
|
-
name: "PayPal",
|
|
2216
|
-
async createAuthorizationURL({ state, codeVerifier, redirectURI }) {
|
|
2217
|
-
if (!options.clientId || !options.clientSecret) {
|
|
2218
|
-
require_env.logger.error("Client Id and Client Secret is required for PayPal. Make sure to provide them in the options.");
|
|
2219
|
-
throw new require_error.BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
|
|
2220
|
-
}
|
|
2221
|
-
return await require_oauth2.createAuthorizationURL({
|
|
2222
|
-
id: "paypal",
|
|
2223
|
-
options,
|
|
2224
|
-
authorizationEndpoint,
|
|
2225
|
-
scopes: [],
|
|
2226
|
-
state,
|
|
2227
|
-
codeVerifier,
|
|
2228
|
-
redirectURI,
|
|
2229
|
-
prompt: options.prompt
|
|
2230
|
-
});
|
|
2231
|
-
},
|
|
2232
|
-
validateAuthorizationCode: async ({ code, redirectURI }) => {
|
|
2233
|
-
/**
|
|
2234
|
-
* PayPal requires Basic Auth for token exchange
|
|
2235
|
-
**/
|
|
2236
|
-
const credentials = __better_auth_utils_base64.base64.encode(`${options.clientId}:${options.clientSecret}`);
|
|
2237
|
-
try {
|
|
2238
|
-
const response = await (0, __better_fetch_fetch.betterFetch)(tokenEndpoint, {
|
|
2239
|
-
method: "POST",
|
|
2240
|
-
headers: {
|
|
2241
|
-
Authorization: `Basic ${credentials}`,
|
|
2242
|
-
Accept: "application/json",
|
|
2243
|
-
"Accept-Language": "en_US",
|
|
2244
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
2245
|
-
},
|
|
2246
|
-
body: new URLSearchParams({
|
|
2247
|
-
grant_type: "authorization_code",
|
|
2248
|
-
code,
|
|
2249
|
-
redirect_uri: redirectURI
|
|
2250
|
-
}).toString()
|
|
2251
|
-
});
|
|
2252
|
-
if (!response.data) throw new require_error.BetterAuthError("FAILED_TO_GET_ACCESS_TOKEN");
|
|
2253
|
-
const data = response.data;
|
|
2254
|
-
return {
|
|
2255
|
-
accessToken: data.access_token,
|
|
2256
|
-
refreshToken: data.refresh_token,
|
|
2257
|
-
accessTokenExpiresAt: data.expires_in ? new Date(Date.now() + data.expires_in * 1e3) : void 0,
|
|
2258
|
-
idToken: data.id_token
|
|
2259
|
-
};
|
|
2260
|
-
} catch (error) {
|
|
2261
|
-
require_env.logger.error("PayPal token exchange failed:", error);
|
|
2262
|
-
throw new require_error.BetterAuthError("FAILED_TO_GET_ACCESS_TOKEN");
|
|
2263
|
-
}
|
|
2264
|
-
},
|
|
2265
|
-
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
2266
|
-
const credentials = __better_auth_utils_base64.base64.encode(`${options.clientId}:${options.clientSecret}`);
|
|
2267
|
-
try {
|
|
2268
|
-
const response = await (0, __better_fetch_fetch.betterFetch)(tokenEndpoint, {
|
|
2269
|
-
method: "POST",
|
|
2270
|
-
headers: {
|
|
2271
|
-
Authorization: `Basic ${credentials}`,
|
|
2272
|
-
Accept: "application/json",
|
|
2273
|
-
"Accept-Language": "en_US",
|
|
2274
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
2275
|
-
},
|
|
2276
|
-
body: new URLSearchParams({
|
|
2277
|
-
grant_type: "refresh_token",
|
|
2278
|
-
refresh_token: refreshToken
|
|
2279
|
-
}).toString()
|
|
2280
|
-
});
|
|
2281
|
-
if (!response.data) throw new require_error.BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
|
|
2282
|
-
const data = response.data;
|
|
2283
|
-
return {
|
|
2284
|
-
accessToken: data.access_token,
|
|
2285
|
-
refreshToken: data.refresh_token,
|
|
2286
|
-
accessTokenExpiresAt: data.expires_in ? new Date(Date.now() + data.expires_in * 1e3) : void 0
|
|
2287
|
-
};
|
|
2288
|
-
} catch (error) {
|
|
2289
|
-
require_env.logger.error("PayPal token refresh failed:", error);
|
|
2290
|
-
throw new require_error.BetterAuthError("FAILED_TO_REFRESH_ACCESS_TOKEN");
|
|
2291
|
-
}
|
|
2292
|
-
},
|
|
2293
|
-
async verifyIdToken(token, nonce) {
|
|
2294
|
-
if (options.disableIdTokenSignIn) return false;
|
|
2295
|
-
if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
|
|
2296
|
-
try {
|
|
2297
|
-
return !!(0, jose.decodeJwt)(token).sub;
|
|
2298
|
-
} catch (error) {
|
|
2299
|
-
require_env.logger.error("Failed to verify PayPal ID token:", error);
|
|
2300
|
-
return false;
|
|
2301
|
-
}
|
|
2302
|
-
},
|
|
2303
|
-
async getUserInfo(token) {
|
|
2304
|
-
if (options.getUserInfo) return options.getUserInfo(token);
|
|
2305
|
-
if (!token.accessToken) {
|
|
2306
|
-
require_env.logger.error("Access token is required to fetch PayPal user info");
|
|
2307
|
-
return null;
|
|
2308
|
-
}
|
|
2309
|
-
try {
|
|
2310
|
-
const response = await (0, __better_fetch_fetch.betterFetch)(`${userInfoEndpoint}?schema=paypalv1.1`, { headers: {
|
|
2311
|
-
Authorization: `Bearer ${token.accessToken}`,
|
|
2312
|
-
Accept: "application/json"
|
|
2313
|
-
} });
|
|
2314
|
-
if (!response.data) {
|
|
2315
|
-
require_env.logger.error("Failed to fetch user info from PayPal");
|
|
2316
|
-
return null;
|
|
2317
|
-
}
|
|
2318
|
-
const userInfo = response.data;
|
|
2319
|
-
const userMap = await options.mapProfileToUser?.(userInfo);
|
|
2320
|
-
return {
|
|
2321
|
-
user: {
|
|
2322
|
-
id: userInfo.user_id,
|
|
2323
|
-
name: userInfo.name,
|
|
2324
|
-
email: userInfo.email,
|
|
2325
|
-
image: userInfo.picture,
|
|
2326
|
-
emailVerified: userInfo.email_verified,
|
|
2327
|
-
...userMap
|
|
2328
|
-
},
|
|
2329
|
-
data: userInfo
|
|
2330
|
-
};
|
|
2331
|
-
} catch (error) {
|
|
2332
|
-
require_env.logger.error("Failed to fetch user info from PayPal:", error);
|
|
2333
|
-
return null;
|
|
2334
|
-
}
|
|
2335
|
-
},
|
|
2336
|
-
options
|
|
2337
|
-
};
|
|
2338
|
-
};
|
|
2339
|
-
|
|
2340
|
-
//#endregion
|
|
2341
|
-
//#region src/social-providers/polar.ts
|
|
2342
|
-
const polar = (options) => {
|
|
2275
|
+
//#region src/social-providers/vk.ts
|
|
2276
|
+
const vk = (options) => {
|
|
2343
2277
|
return {
|
|
2344
|
-
id: "
|
|
2345
|
-
name: "
|
|
2346
|
-
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
|
|
2347
|
-
const _scopes = options.disableDefaultScope ? [] : [
|
|
2348
|
-
"openid",
|
|
2349
|
-
"profile",
|
|
2350
|
-
"email"
|
|
2351
|
-
];
|
|
2278
|
+
id: "vk",
|
|
2279
|
+
name: "VK",
|
|
2280
|
+
async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {
|
|
2281
|
+
const _scopes = options.disableDefaultScope ? [] : ["email", "phone"];
|
|
2352
2282
|
options.scope && _scopes.push(...options.scope);
|
|
2353
2283
|
scopes && _scopes.push(...scopes);
|
|
2354
|
-
return
|
|
2355
|
-
id: "
|
|
2284
|
+
return require_oauth2.createAuthorizationURL({
|
|
2285
|
+
id: "vk",
|
|
2356
2286
|
options,
|
|
2357
|
-
authorizationEndpoint: "https://
|
|
2287
|
+
authorizationEndpoint: "https://id.vk.com/authorize",
|
|
2358
2288
|
scopes: _scopes,
|
|
2359
2289
|
state,
|
|
2360
|
-
codeVerifier,
|
|
2361
2290
|
redirectURI,
|
|
2362
|
-
|
|
2291
|
+
codeVerifier
|
|
2363
2292
|
});
|
|
2364
2293
|
},
|
|
2365
|
-
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
2366
|
-
return
|
|
2294
|
+
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI, deviceId }) => {
|
|
2295
|
+
return require_oauth2.validateAuthorizationCode({
|
|
2367
2296
|
code,
|
|
2368
2297
|
codeVerifier,
|
|
2369
|
-
redirectURI,
|
|
2298
|
+
redirectURI: options.redirectURI || redirectURI,
|
|
2370
2299
|
options,
|
|
2371
|
-
|
|
2300
|
+
deviceId,
|
|
2301
|
+
tokenEndpoint: "https://id.vk.com/oauth2/auth"
|
|
2372
2302
|
});
|
|
2373
2303
|
},
|
|
2374
2304
|
refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
|
|
2375
|
-
return
|
|
2305
|
+
return require_oauth2.refreshAccessToken({
|
|
2376
2306
|
refreshToken,
|
|
2377
2307
|
options: {
|
|
2378
2308
|
clientId: options.clientId,
|
|
2379
2309
|
clientKey: options.clientKey,
|
|
2380
2310
|
clientSecret: options.clientSecret
|
|
2381
2311
|
},
|
|
2382
|
-
tokenEndpoint: "https://
|
|
2312
|
+
tokenEndpoint: "https://id.vk.com/oauth2/auth"
|
|
2313
|
+
});
|
|
2314
|
+
},
|
|
2315
|
+
async getUserInfo(data) {
|
|
2316
|
+
if (options.getUserInfo) return options.getUserInfo(data);
|
|
2317
|
+
if (!data.accessToken) return null;
|
|
2318
|
+
const formBody = new URLSearchParams({
|
|
2319
|
+
access_token: data.accessToken,
|
|
2320
|
+
client_id: options.clientId
|
|
2321
|
+
}).toString();
|
|
2322
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://id.vk.com/oauth2/user_info", {
|
|
2323
|
+
method: "POST",
|
|
2324
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
2325
|
+
body: formBody
|
|
2326
|
+
});
|
|
2327
|
+
if (error) return null;
|
|
2328
|
+
if (!profile.user.email) return null;
|
|
2329
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
2330
|
+
return {
|
|
2331
|
+
user: {
|
|
2332
|
+
id: profile.user.user_id,
|
|
2333
|
+
first_name: profile.user.first_name,
|
|
2334
|
+
last_name: profile.user.last_name,
|
|
2335
|
+
email: profile.user.email,
|
|
2336
|
+
image: profile.user.avatar,
|
|
2337
|
+
emailVerified: !!profile.user.email,
|
|
2338
|
+
birthday: profile.user.birthday,
|
|
2339
|
+
sex: profile.user.sex,
|
|
2340
|
+
name: `${profile.user.first_name} ${profile.user.last_name}`,
|
|
2341
|
+
...userMap
|
|
2342
|
+
},
|
|
2343
|
+
data: profile
|
|
2344
|
+
};
|
|
2345
|
+
},
|
|
2346
|
+
options
|
|
2347
|
+
};
|
|
2348
|
+
};
|
|
2349
|
+
|
|
2350
|
+
//#endregion
|
|
2351
|
+
//#region src/social-providers/zoom.ts
|
|
2352
|
+
const zoom = (userOptions) => {
|
|
2353
|
+
const options = {
|
|
2354
|
+
pkce: true,
|
|
2355
|
+
...userOptions
|
|
2356
|
+
};
|
|
2357
|
+
return {
|
|
2358
|
+
id: "zoom",
|
|
2359
|
+
name: "Zoom",
|
|
2360
|
+
createAuthorizationURL: async ({ state, redirectURI, codeVerifier }) => {
|
|
2361
|
+
const params = new URLSearchParams({
|
|
2362
|
+
response_type: "code",
|
|
2363
|
+
redirect_uri: options.redirectURI ? options.redirectURI : redirectURI,
|
|
2364
|
+
client_id: options.clientId,
|
|
2365
|
+
state
|
|
2366
|
+
});
|
|
2367
|
+
if (options.pkce) {
|
|
2368
|
+
const codeChallenge = await require_oauth2.generateCodeChallenge(codeVerifier);
|
|
2369
|
+
params.set("code_challenge_method", "S256");
|
|
2370
|
+
params.set("code_challenge", codeChallenge);
|
|
2371
|
+
}
|
|
2372
|
+
const url = new URL("https://zoom.us/oauth/authorize");
|
|
2373
|
+
url.search = params.toString();
|
|
2374
|
+
return url;
|
|
2375
|
+
},
|
|
2376
|
+
validateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {
|
|
2377
|
+
return require_oauth2.validateAuthorizationCode({
|
|
2378
|
+
code,
|
|
2379
|
+
redirectURI: options.redirectURI || redirectURI,
|
|
2380
|
+
codeVerifier,
|
|
2381
|
+
options,
|
|
2382
|
+
tokenEndpoint: "https://zoom.us/oauth/token",
|
|
2383
|
+
authentication: "post"
|
|
2383
2384
|
});
|
|
2384
2385
|
},
|
|
2385
2386
|
async getUserInfo(token) {
|
|
2386
2387
|
if (options.getUserInfo) return options.getUserInfo(token);
|
|
2387
|
-
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.
|
|
2388
|
+
const { data: profile, error } = await (0, __better_fetch_fetch.betterFetch)("https://api.zoom.us/v2/users/me", { headers: { authorization: `Bearer ${token.accessToken}` } });
|
|
2388
2389
|
if (error) return null;
|
|
2389
2390
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
2390
2391
|
return {
|
|
2391
2392
|
user: {
|
|
2392
2393
|
id: profile.id,
|
|
2393
|
-
name: profile.
|
|
2394
|
+
name: profile.display_name,
|
|
2395
|
+
image: profile.pic_url,
|
|
2394
2396
|
email: profile.email,
|
|
2395
|
-
|
|
2396
|
-
emailVerified: true,
|
|
2397
|
+
emailVerified: Boolean(profile.verified),
|
|
2397
2398
|
...userMap
|
|
2398
2399
|
},
|
|
2399
|
-
data: profile
|
|
2400
|
+
data: { ...profile }
|
|
2400
2401
|
};
|
|
2401
|
-
}
|
|
2402
|
-
options
|
|
2402
|
+
}
|
|
2403
2403
|
};
|
|
2404
2404
|
};
|
|
2405
2405
|
|