@better-auth/core 1.4.0-beta.13 → 1.4.0-beta.15

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