@better-auth/core 1.5.0-beta.9 → 1.5.0

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 (306) hide show
  1. package/README.md +17 -0
  2. package/dist/api/index.d.mts +144 -41
  3. package/dist/api/index.mjs +2 -1
  4. package/dist/api/index.mjs.map +1 -0
  5. package/dist/async_hooks/index.d.mts +2 -1
  6. package/dist/async_hooks/index.mjs +2 -1
  7. package/dist/async_hooks/index.mjs.map +1 -0
  8. package/dist/async_hooks/pure.index.d.mts +2 -1
  9. package/dist/async_hooks/pure.index.mjs +2 -1
  10. package/dist/async_hooks/pure.index.mjs.map +1 -0
  11. package/dist/context/endpoint-context.d.mts +2 -1
  12. package/dist/context/endpoint-context.mjs +4 -3
  13. package/dist/context/endpoint-context.mjs.map +1 -0
  14. package/dist/context/global.d.mts +2 -2
  15. package/dist/context/global.mjs +3 -2
  16. package/dist/context/global.mjs.map +1 -0
  17. package/dist/context/request-state.d.mts +2 -1
  18. package/dist/context/request-state.mjs +4 -3
  19. package/dist/context/request-state.mjs.map +1 -0
  20. package/dist/context/transaction.d.mts +2 -1
  21. package/dist/context/transaction.mjs +4 -3
  22. package/dist/context/transaction.mjs.map +1 -0
  23. package/dist/db/adapter/factory.d.mts +6 -13
  24. package/dist/db/adapter/factory.mjs +44 -57
  25. package/dist/db/adapter/factory.mjs.map +1 -0
  26. package/dist/db/adapter/get-default-field-name.d.mts +2 -1
  27. package/dist/db/adapter/get-default-field-name.mjs +3 -2
  28. package/dist/db/adapter/get-default-field-name.mjs.map +1 -0
  29. package/dist/db/adapter/get-default-model-name.d.mts +2 -1
  30. package/dist/db/adapter/get-default-model-name.mjs +5 -4
  31. package/dist/db/adapter/get-default-model-name.mjs.map +1 -0
  32. package/dist/db/adapter/get-field-attributes.d.mts +3 -2
  33. package/dist/db/adapter/get-field-attributes.mjs +2 -1
  34. package/dist/db/adapter/get-field-attributes.mjs.map +1 -0
  35. package/dist/db/adapter/get-field-name.d.mts +2 -1
  36. package/dist/db/adapter/get-field-name.mjs +2 -1
  37. package/dist/db/adapter/get-field-name.mjs.map +1 -0
  38. package/dist/db/adapter/get-id-field.d.mts +3 -2
  39. package/dist/db/adapter/get-id-field.mjs +3 -2
  40. package/dist/db/adapter/get-id-field.mjs.map +1 -0
  41. package/dist/db/adapter/get-model-name.d.mts +2 -1
  42. package/dist/db/adapter/get-model-name.mjs +2 -1
  43. package/dist/db/adapter/get-model-name.mjs.map +1 -0
  44. package/dist/db/adapter/index.d.mts +10 -4
  45. package/dist/db/adapter/index.mjs +19 -2
  46. package/dist/db/adapter/index.mjs.map +1 -0
  47. package/dist/db/adapter/types.d.mts +3 -34
  48. package/dist/db/adapter/utils.d.mts +2 -1
  49. package/dist/db/adapter/utils.mjs +2 -1
  50. package/dist/db/adapter/utils.mjs.map +1 -0
  51. package/dist/db/get-tables.d.mts +2 -1
  52. package/dist/db/get-tables.mjs +46 -39
  53. package/dist/db/get-tables.mjs.map +1 -0
  54. package/dist/db/index.d.mts +7 -7
  55. package/dist/db/plugin.d.mts +2 -1
  56. package/dist/db/schema/account.d.mts +8 -4
  57. package/dist/db/schema/account.mjs +2 -1
  58. package/dist/db/schema/account.mjs.map +1 -0
  59. package/dist/db/schema/rate-limit.d.mts +8 -2
  60. package/dist/db/schema/rate-limit.mjs +2 -1
  61. package/dist/db/schema/rate-limit.mjs.map +1 -0
  62. package/dist/db/schema/session.d.mts +8 -4
  63. package/dist/db/schema/session.mjs +2 -1
  64. package/dist/db/schema/session.mjs.map +1 -0
  65. package/dist/db/schema/shared.d.mts +2 -1
  66. package/dist/db/schema/shared.mjs +2 -1
  67. package/dist/db/schema/shared.mjs.map +1 -0
  68. package/dist/db/schema/user.d.mts +8 -4
  69. package/dist/db/schema/user.mjs +2 -1
  70. package/dist/db/schema/user.mjs.map +1 -0
  71. package/dist/db/schema/verification.d.mts +8 -4
  72. package/dist/db/schema/verification.mjs +2 -1
  73. package/dist/db/schema/verification.mjs.map +1 -0
  74. package/dist/db/type.d.mts +28 -2
  75. package/dist/env/color-depth.d.mts +2 -1
  76. package/dist/env/color-depth.mjs +2 -1
  77. package/dist/env/color-depth.mjs.map +1 -0
  78. package/dist/env/env-impl.d.mts +3 -2
  79. package/dist/env/env-impl.mjs +9 -8
  80. package/dist/env/env-impl.mjs.map +1 -0
  81. package/dist/env/logger.d.mts +2 -1
  82. package/dist/env/logger.mjs +3 -2
  83. package/dist/env/logger.mjs.map +1 -0
  84. package/dist/error/codes.d.mts +64 -181
  85. package/dist/error/codes.mjs +6 -2
  86. package/dist/error/codes.mjs.map +1 -0
  87. package/dist/error/index.d.mts +2 -1
  88. package/dist/error/index.mjs +2 -1
  89. package/dist/error/index.mjs.map +1 -0
  90. package/dist/index.d.mts +5 -4
  91. package/dist/oauth2/client-credentials-token.d.mts +25 -3
  92. package/dist/oauth2/client-credentials-token.mjs +15 -2
  93. package/dist/oauth2/client-credentials-token.mjs.map +1 -0
  94. package/dist/oauth2/create-authorization-url.d.mts +5 -2
  95. package/dist/oauth2/create-authorization-url.mjs +3 -1
  96. package/dist/oauth2/create-authorization-url.mjs.map +1 -0
  97. package/dist/oauth2/index.d.mts +4 -4
  98. package/dist/oauth2/index.mjs +4 -4
  99. package/dist/oauth2/oauth-provider.d.mts +3 -2
  100. package/dist/oauth2/refresh-access-token.d.mts +24 -4
  101. package/dist/oauth2/refresh-access-token.mjs +20 -2
  102. package/dist/oauth2/refresh-access-token.mjs.map +1 -0
  103. package/dist/oauth2/utils.d.mts +2 -1
  104. package/dist/oauth2/utils.mjs +2 -1
  105. package/dist/oauth2/utils.mjs.map +1 -0
  106. package/dist/oauth2/validate-authorization-code.d.mts +37 -4
  107. package/dist/oauth2/validate-authorization-code.mjs +25 -13
  108. package/dist/oauth2/validate-authorization-code.mjs.map +1 -0
  109. package/dist/oauth2/verify.d.mts +7 -13
  110. package/dist/oauth2/verify.mjs +2 -1
  111. package/dist/oauth2/verify.mjs.map +1 -0
  112. package/dist/social-providers/apple.d.mts +2 -1
  113. package/dist/social-providers/apple.mjs +22 -21
  114. package/dist/social-providers/apple.mjs.map +1 -0
  115. package/dist/social-providers/atlassian.d.mts +2 -1
  116. package/dist/social-providers/atlassian.mjs +2 -1
  117. package/dist/social-providers/atlassian.mjs.map +1 -0
  118. package/dist/social-providers/cognito.d.mts +2 -1
  119. package/dist/social-providers/cognito.mjs +4 -3
  120. package/dist/social-providers/cognito.mjs.map +1 -0
  121. package/dist/social-providers/discord.d.mts +2 -1
  122. package/dist/social-providers/discord.mjs +2 -1
  123. package/dist/social-providers/discord.mjs.map +1 -0
  124. package/dist/social-providers/dropbox.d.mts +2 -1
  125. package/dist/social-providers/dropbox.mjs +2 -1
  126. package/dist/social-providers/dropbox.mjs.map +1 -0
  127. package/dist/social-providers/facebook.d.mts +2 -1
  128. package/dist/social-providers/facebook.mjs +13 -12
  129. package/dist/social-providers/facebook.mjs.map +1 -0
  130. package/dist/social-providers/figma.d.mts +2 -1
  131. package/dist/social-providers/figma.mjs +2 -1
  132. package/dist/social-providers/figma.mjs.map +1 -0
  133. package/dist/social-providers/github.d.mts +3 -2
  134. package/dist/social-providers/github.mjs +23 -6
  135. package/dist/social-providers/github.mjs.map +1 -0
  136. package/dist/social-providers/gitlab.d.mts +2 -1
  137. package/dist/social-providers/gitlab.mjs +3 -2
  138. package/dist/social-providers/gitlab.mjs.map +1 -0
  139. package/dist/social-providers/google.d.mts +2 -1
  140. package/dist/social-providers/google.mjs +18 -13
  141. package/dist/social-providers/google.mjs.map +1 -0
  142. package/dist/social-providers/huggingface.d.mts +2 -1
  143. package/dist/social-providers/huggingface.mjs +3 -2
  144. package/dist/social-providers/huggingface.mjs.map +1 -0
  145. package/dist/social-providers/index.d.mts +61 -8
  146. package/dist/social-providers/index.mjs +5 -2
  147. package/dist/social-providers/index.mjs.map +1 -0
  148. package/dist/social-providers/kakao.d.mts +3 -2
  149. package/dist/social-providers/kakao.mjs +3 -2
  150. package/dist/social-providers/kakao.mjs.map +1 -0
  151. package/dist/social-providers/kick.d.mts +2 -1
  152. package/dist/social-providers/kick.mjs +2 -1
  153. package/dist/social-providers/kick.mjs.map +1 -0
  154. package/dist/social-providers/line.d.mts +2 -1
  155. package/dist/social-providers/line.mjs +3 -2
  156. package/dist/social-providers/line.mjs.map +1 -0
  157. package/dist/social-providers/linear.d.mts +2 -1
  158. package/dist/social-providers/linear.mjs +2 -1
  159. package/dist/social-providers/linear.mjs.map +1 -0
  160. package/dist/social-providers/linkedin.d.mts +2 -1
  161. package/dist/social-providers/linkedin.mjs +2 -1
  162. package/dist/social-providers/linkedin.mjs.map +1 -0
  163. package/dist/social-providers/microsoft-entra-id.d.mts +4 -1
  164. package/dist/social-providers/microsoft-entra-id.mjs +36 -2
  165. package/dist/social-providers/microsoft-entra-id.mjs.map +1 -0
  166. package/dist/social-providers/naver.d.mts +11 -20
  167. package/dist/social-providers/naver.mjs +3 -2
  168. package/dist/social-providers/naver.mjs.map +1 -0
  169. package/dist/social-providers/notion.d.mts +2 -1
  170. package/dist/social-providers/notion.mjs +3 -2
  171. package/dist/social-providers/notion.mjs.map +1 -0
  172. package/dist/social-providers/paybin.d.mts +2 -1
  173. package/dist/social-providers/paybin.mjs +3 -2
  174. package/dist/social-providers/paybin.mjs.map +1 -0
  175. package/dist/social-providers/paypal.d.mts +2 -1
  176. package/dist/social-providers/paypal.mjs +2 -1
  177. package/dist/social-providers/paypal.mjs.map +1 -0
  178. package/dist/social-providers/polar.d.mts +2 -1
  179. package/dist/social-providers/polar.mjs +3 -2
  180. package/dist/social-providers/polar.mjs.map +1 -0
  181. package/dist/social-providers/railway.d.mts +68 -0
  182. package/dist/social-providers/railway.mjs +78 -0
  183. package/dist/social-providers/railway.mjs.map +1 -0
  184. package/dist/social-providers/reddit.d.mts +2 -1
  185. package/dist/social-providers/reddit.mjs +2 -1
  186. package/dist/social-providers/reddit.mjs.map +1 -0
  187. package/dist/social-providers/roblox.d.mts +2 -1
  188. package/dist/social-providers/roblox.mjs +2 -1
  189. package/dist/social-providers/roblox.mjs.map +1 -0
  190. package/dist/social-providers/salesforce.d.mts +2 -1
  191. package/dist/social-providers/salesforce.mjs +2 -1
  192. package/dist/social-providers/salesforce.mjs.map +1 -0
  193. package/dist/social-providers/slack.d.mts +2 -1
  194. package/dist/social-providers/slack.mjs +2 -1
  195. package/dist/social-providers/slack.mjs.map +1 -0
  196. package/dist/social-providers/spotify.d.mts +2 -1
  197. package/dist/social-providers/spotify.mjs +2 -1
  198. package/dist/social-providers/spotify.mjs.map +1 -0
  199. package/dist/social-providers/tiktok.d.mts +3 -3
  200. package/dist/social-providers/tiktok.mjs +3 -2
  201. package/dist/social-providers/tiktok.mjs.map +1 -0
  202. package/dist/social-providers/twitch.d.mts +2 -1
  203. package/dist/social-providers/twitch.mjs +2 -1
  204. package/dist/social-providers/twitch.mjs.map +1 -0
  205. package/dist/social-providers/twitter.d.mts +14 -25
  206. package/dist/social-providers/twitter.mjs +2 -1
  207. package/dist/social-providers/twitter.mjs.map +1 -0
  208. package/dist/social-providers/vercel.d.mts +2 -1
  209. package/dist/social-providers/vercel.mjs +3 -2
  210. package/dist/social-providers/vercel.mjs.map +1 -0
  211. package/dist/social-providers/vk.d.mts +2 -1
  212. package/dist/social-providers/vk.mjs +2 -1
  213. package/dist/social-providers/vk.mjs.map +1 -0
  214. package/dist/social-providers/zoom.d.mts +3 -10
  215. package/dist/social-providers/zoom.mjs +2 -1
  216. package/dist/social-providers/zoom.mjs.map +1 -0
  217. package/dist/types/context.d.mts +53 -21
  218. package/dist/types/cookie.d.mts +2 -1
  219. package/dist/types/helper.d.mts +4 -1
  220. package/dist/types/index.d.mts +4 -3
  221. package/dist/types/init-options.d.mts +231 -159
  222. package/dist/types/plugin-client.d.mts +4 -1
  223. package/dist/types/plugin.d.mts +12 -11
  224. package/dist/types/secret.d.mts +12 -0
  225. package/dist/utils/db.d.mts +12 -0
  226. package/dist/utils/db.mjs +17 -0
  227. package/dist/utils/db.mjs.map +1 -0
  228. package/dist/utils/deprecate.d.mts +2 -2
  229. package/dist/utils/deprecate.mjs +2 -1
  230. package/dist/utils/deprecate.mjs.map +1 -0
  231. package/dist/utils/error-codes.d.mts +8 -6
  232. package/dist/utils/error-codes.mjs +3 -2
  233. package/dist/utils/error-codes.mjs.map +1 -0
  234. package/dist/utils/id.d.mts +2 -1
  235. package/dist/utils/id.mjs +2 -1
  236. package/dist/utils/id.mjs.map +1 -0
  237. package/dist/utils/ip.d.mts +2 -1
  238. package/dist/utils/ip.mjs +2 -1
  239. package/dist/utils/ip.mjs.map +1 -0
  240. package/dist/utils/json.d.mts +2 -1
  241. package/dist/utils/json.mjs +2 -1
  242. package/dist/utils/json.mjs.map +1 -0
  243. package/dist/utils/string.d.mts +2 -1
  244. package/dist/utils/string.mjs +2 -1
  245. package/dist/utils/string.mjs.map +1 -0
  246. package/dist/utils/url.d.mts +2 -1
  247. package/dist/utils/url.mjs +2 -1
  248. package/dist/utils/url.mjs.map +1 -0
  249. package/package.json +35 -13
  250. package/src/db/adapter/factory.ts +41 -73
  251. package/src/db/adapter/get-id-field.ts +1 -3
  252. package/src/db/adapter/index.ts +20 -15
  253. package/src/db/adapter/types.ts +2 -41
  254. package/src/db/get-tables.ts +48 -37
  255. package/src/db/index.ts +30 -5
  256. package/src/db/schema/account.ts +16 -3
  257. package/src/db/schema/rate-limit.ts +16 -1
  258. package/src/db/schema/session.ts +15 -3
  259. package/src/db/schema/user.ts +15 -3
  260. package/src/db/schema/verification.ts +16 -3
  261. package/src/db/test/get-tables.test.ts +33 -0
  262. package/src/db/type.ts +154 -1
  263. package/src/env/env-impl.ts +2 -2
  264. package/src/env/logger.ts +1 -1
  265. package/src/error/codes.ts +17 -0
  266. package/src/oauth2/client-credentials-token.ts +26 -2
  267. package/src/oauth2/create-authorization-url.ts +3 -1
  268. package/src/oauth2/index.ts +3 -0
  269. package/src/oauth2/oauth-provider.ts +1 -1
  270. package/src/oauth2/refresh-access-token.test.ts +90 -0
  271. package/src/oauth2/refresh-access-token.ts +37 -4
  272. package/src/oauth2/validate-authorization-code.ts +55 -24
  273. package/src/oauth2/validate-token.test.ts +107 -52
  274. package/src/social-providers/apple.ts +29 -29
  275. package/src/social-providers/cognito.ts +6 -5
  276. package/src/social-providers/facebook.ts +3 -3
  277. package/src/social-providers/github.ts +26 -4
  278. package/src/social-providers/gitlab.ts +1 -1
  279. package/src/social-providers/google.ts +18 -14
  280. package/src/social-providers/huggingface.ts +1 -1
  281. package/src/social-providers/index.ts +9 -5
  282. package/src/social-providers/kakao.ts +1 -1
  283. package/src/social-providers/line.ts +1 -1
  284. package/src/social-providers/microsoft-entra-id.ts +84 -1
  285. package/src/social-providers/naver.ts +1 -1
  286. package/src/social-providers/notion.ts +1 -1
  287. package/src/social-providers/paybin.ts +1 -5
  288. package/src/social-providers/polar.ts +1 -1
  289. package/src/social-providers/railway.ts +100 -0
  290. package/src/social-providers/tiktok.ts +2 -1
  291. package/src/social-providers/vercel.ts +1 -1
  292. package/src/social-providers/zoom.ts +0 -8
  293. package/src/types/context.ts +74 -14
  294. package/src/types/helper.ts +9 -0
  295. package/src/types/index.ts +14 -2
  296. package/src/types/init-options.ts +294 -186
  297. package/src/types/plugin-client.ts +1 -0
  298. package/src/types/plugin.ts +11 -6
  299. package/src/types/secret.ts +8 -0
  300. package/src/utils/db.ts +20 -0
  301. package/src/utils/deprecate.test.ts +0 -1
  302. package/src/utils/error-codes.ts +12 -9
  303. package/.turbo/turbo-build.log +0 -182
  304. package/tsconfig.json +0 -7
  305. package/tsdown.config.ts +0 -32
  306. package/vitest.config.ts +0 -3
@@ -78,4 +78,5 @@ declare const facebook: (options: FacebookOptions) => {
78
78
  options: FacebookOptions;
79
79
  };
80
80
  //#endregion
81
- export { FacebookOptions, FacebookProfile, facebook };
81
+ export { FacebookOptions, FacebookProfile, facebook };
82
+ //# sourceMappingURL=facebook.d.mts.map
@@ -17,7 +17,7 @@ const facebook = (options) => {
17
17
  return await createAuthorizationURL({
18
18
  id: "facebook",
19
19
  options,
20
- authorizationEndpoint: "https://www.facebook.com/v21.0/dialog/oauth",
20
+ authorizationEndpoint: "https://www.facebook.com/v24.0/dialog/oauth",
21
21
  scopes: _scopes,
22
22
  state,
23
23
  redirectURI,
@@ -30,7 +30,7 @@ const facebook = (options) => {
30
30
  code,
31
31
  redirectURI,
32
32
  options,
33
- tokenEndpoint: "https://graph.facebook.com/oauth/access_token"
33
+ tokenEndpoint: "https://graph.facebook.com/v24.0/oauth/access_token"
34
34
  });
35
35
  },
36
36
  async verifyIdToken(token, nonce) {
@@ -57,25 +57,25 @@ const facebook = (options) => {
57
57
  clientKey: options.clientKey,
58
58
  clientSecret: options.clientSecret
59
59
  },
60
- tokenEndpoint: "https://graph.facebook.com/v18.0/oauth/access_token"
60
+ tokenEndpoint: "https://graph.facebook.com/v24.0/oauth/access_token"
61
61
  });
62
62
  },
63
63
  async getUserInfo(token) {
64
64
  if (options.getUserInfo) return options.getUserInfo(token);
65
65
  if (token.idToken && token.idToken.split(".").length === 3) {
66
- const profile$1 = decodeJwt(token.idToken);
66
+ const profile = decodeJwt(token.idToken);
67
67
  const user = {
68
- id: profile$1.sub,
69
- name: profile$1.name,
70
- email: profile$1.email,
68
+ id: profile.sub,
69
+ name: profile.name,
70
+ email: profile.email,
71
71
  picture: { data: {
72
- url: profile$1.picture,
72
+ url: profile.picture,
73
73
  height: 100,
74
74
  width: 100,
75
75
  is_silhouette: false
76
76
  } }
77
77
  };
78
- const userMap$1 = await options.mapProfileToUser?.({
78
+ const userMap = await options.mapProfileToUser?.({
79
79
  ...user,
80
80
  email_verified: false
81
81
  });
@@ -83,9 +83,9 @@ const facebook = (options) => {
83
83
  user: {
84
84
  ...user,
85
85
  emailVerified: false,
86
- ...userMap$1
86
+ ...userMap
87
87
  },
88
- data: profile$1
88
+ data: profile
89
89
  };
90
90
  }
91
91
  const { data: profile, error } = await betterFetch("https://graph.facebook.com/me?fields=" + [
@@ -117,4 +117,5 @@ const facebook = (options) => {
117
117
  };
118
118
 
119
119
  //#endregion
120
- export { facebook };
120
+ export { facebook };
121
+ //# sourceMappingURL=facebook.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facebook.mjs","names":[],"sources":["../../src/social-providers/facebook.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { createRemoteJWKSet, decodeJwt, jwtVerify } from \"jose\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\nexport interface FacebookProfile {\n\tid: string;\n\tname: string;\n\temail: string;\n\temail_verified: boolean;\n\tpicture: {\n\t\tdata: {\n\t\t\theight: number;\n\t\t\tis_silhouette: boolean;\n\t\t\turl: string;\n\t\t\twidth: number;\n\t\t};\n\t};\n}\n\nexport interface FacebookOptions extends ProviderOptions<FacebookProfile> {\n\tclientId: string;\n\t/**\n\t * Extend list of fields to retrieve from the Facebook user profile.\n\t *\n\t * @default [\"id\", \"name\", \"email\", \"picture\"]\n\t */\n\tfields?: string[] | undefined;\n\n\t/**\n\t * The config id to use when undergoing oauth\n\t */\n\tconfigId?: string | undefined;\n}\n\nexport const facebook = (options: FacebookOptions) => {\n\treturn {\n\t\tid: \"facebook\",\n\t\tname: \"Facebook\",\n\t\tasync createAuthorizationURL({ state, scopes, redirectURI, loginHint }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"email\", \"public_profile\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: \"facebook\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.facebook.com/v24.0/dialog/oauth\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tloginHint,\n\t\t\t\tadditionalParams: options.configId\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tconfig_id: options.configId,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {},\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint: \"https://graph.facebook.com/v24.0/oauth/access_token\",\n\t\t\t});\n\t\t},\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\n\t\t\t/* limited login */\n\t\t\t// check is limited token\n\t\t\tif (token.split(\".\").length === 3) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\tcreateRemoteJWKSet(\n\t\t\t\t\t\t\t// https://developers.facebook.com/docs/facebook-login/limited-login/token/#jwks\n\t\t\t\t\t\t\tnew URL(\n\t\t\t\t\t\t\t\t\"https://limited.facebook.com/.well-known/oauth/openid/jwks/\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\talgorithms: [\"RS256\"],\n\t\t\t\t\t\t\taudience: options.clientId,\n\t\t\t\t\t\t\tissuer: \"https://www.facebook.com\",\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn !!jwtClaims;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* access_token */\n\t\t\treturn true;\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint:\n\t\t\t\t\t\t\t\"https://graph.facebook.com/v24.0/oauth/access_token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\tif (token.idToken && token.idToken.split(\".\").length === 3) {\n\t\t\t\tconst profile = decodeJwt(token.idToken) as {\n\t\t\t\t\tsub: string;\n\t\t\t\t\temail: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\tpicture: string;\n\t\t\t\t};\n\n\t\t\t\tconst user = {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\tpicture: {\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\turl: profile.picture,\n\t\t\t\t\t\t\theight: 100,\n\t\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\t\tis_silhouette: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t};\n\n\t\t\t\t// https://developers.facebook.com/docs/facebook-login/limited-login/permissions\n\t\t\t\t// Facebook ID token does not include email_verified claim.\n\t\t\t\t// We default to false for security consistency.\n\t\t\t\tconst userMap = await options.mapProfileToUser?.({\n\t\t\t\t\t...user,\n\t\t\t\t\temail_verified: false,\n\t\t\t\t});\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\t...user,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst fields = [\n\t\t\t\t\"id\",\n\t\t\t\t\"name\",\n\t\t\t\t\"email\",\n\t\t\t\t\"picture\",\n\t\t\t\t...(options?.fields || []),\n\t\t\t];\n\t\t\tconst { data: profile, error } = await betterFetch<FacebookProfile>(\n\t\t\t\t\"https://graph.facebook.com/me?fields=\" + fields.join(\",\"),\n\t\t\t\t{\n\t\t\t\t\tauth: {\n\t\t\t\t\t\ttype: \"Bearer\",\n\t\t\t\t\t\ttoken: token.accessToken,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.id,\n\t\t\t\t\tname: profile.name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.picture.data.url,\n\t\t\t\t\temailVerified: profile.email_verified,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<FacebookProfile>;\n};\n"],"mappings":";;;;;;;;AAsCA,MAAa,YAAY,YAA6B;AACrD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,aAAa,aAAa;GACvE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF,CAAC,SAAS,iBAAiB;AAC9B,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,kBAAkB,QAAQ,WACvB,EACA,WAAW,QAAQ,UACnB,GACA,EAAE;IACL,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA,eAAe;IACf,CAAC;;EAEH,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAGR,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;AAK3C,OAAI,MAAM,MAAM,IAAI,CAAC,WAAW,EAC/B,KAAI;IACH,MAAM,EAAE,SAAS,cAAc,MAAM,UACpC,OACA,mBAEC,IAAI,IACH,8DACA,CACD,EACD;KACC,YAAY,CAAC,QAAQ;KACrB,UAAU,QAAQ;KAClB,QAAQ;KACR,CACD;AAED,QAAI,SAAS,UAAU,UAAU,MAChC,QAAO;AAGR,WAAO,CAAC,CAAC;WACF;AACP,WAAO;;AAKT,UAAO;;EAER,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eACC;IACD,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAGlC,OAAI,MAAM,WAAW,MAAM,QAAQ,MAAM,IAAI,CAAC,WAAW,GAAG;IAC3D,MAAM,UAAU,UAAU,MAAM,QAAQ;IAOxC,MAAM,OAAO;KACZ,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,SAAS,EACR,MAAM;MACL,KAAK,QAAQ;MACb,QAAQ;MACR,OAAO;MACP,eAAe;MACf,EACD;KACD;IAKD,MAAM,UAAU,MAAM,QAAQ,mBAAmB;KAChD,GAAG;KACH,gBAAgB;KAChB,CAAC;AAEF,WAAO;KACN,MAAM;MACL,GAAG;MACH,eAAe;MACf,GAAG;MACH;KACD,MAAM;KACN;;GAUF,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,0CARc;IACd;IACA;IACA;IACA;IACA,GAAI,SAAS,UAAU,EAAE;IACzB,CAEiD,KAAK,IAAI,EAC1D,EACC,MAAM;IACL,MAAM;IACN,OAAO,MAAM;IACb,EACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ;KACd,OAAO,QAAQ;KACf,OAAO,QAAQ,QAAQ,KAAK;KAC5B,eAAe,QAAQ;KACvB,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
@@ -60,4 +60,5 @@ declare const figma: (options: FigmaOptions) => {
60
60
  options: FigmaOptions;
61
61
  };
62
62
  //#endregion
63
- export { FigmaOptions, FigmaProfile, figma };
63
+ export { FigmaOptions, FigmaProfile, figma };
64
+ //# sourceMappingURL=figma.d.mts.map
@@ -83,4 +83,5 @@ const figma = (options) => {
83
83
  };
84
84
 
85
85
  //#endregion
86
- export { figma };
86
+ export { figma };
87
+ //# sourceMappingURL=figma.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma.mjs","names":[],"sources":["../../src/social-providers/figma.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport { BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface FigmaProfile {\n\tid: string;\n\temail: string;\n\thandle: string;\n\timg_url: string;\n}\n\nexport interface FigmaOptions extends ProviderOptions<FigmaProfile> {\n\tclientId: string;\n}\n\nexport const figma = (options: FigmaOptions) => {\n\treturn {\n\t\tid: \"figma\",\n\t\tname: \"Figma\",\n\t\tasync createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret are required for Figma. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Figma\");\n\t\t\t}\n\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"current_user:read\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"figma\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.figma.com/oauth\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t});\n\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint: \"https://api.figma.com/v1/oauth/token\",\n\t\t\t\tauthentication: \"basic\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://api.figma.com/v1/oauth/token\",\n\t\t\t\t\t\tauthentication: \"basic\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst { data: profile } = await betterFetch<FigmaProfile>(\n\t\t\t\t\t\"https://api.figma.com/v1/me\",\n\t\t\t\t\t{\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tif (!profile) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user from Figma\");\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\n\t\t\t\treturn {\n\t\t\t\t\tuser: {\n\t\t\t\t\t\tid: profile.id,\n\t\t\t\t\t\tname: profile.handle,\n\t\t\t\t\t\temail: profile.email,\n\t\t\t\t\t\timage: profile.img_url,\n\t\t\t\t\t\temailVerified: false,\n\t\t\t\t\t\t...userMap,\n\t\t\t\t\t},\n\t\t\t\t\tdata: profile,\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to fetch user info from Figma:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<FigmaProfile>;\n};\n"],"mappings":";;;;;;;;;;AAqBA,MAAa,SAAS,YAA0B;AAC/C,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;AAC1E,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MACN,gGACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,qCAAqC;GAGhE,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,oBAAoB;AACxE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAYnC,UAVY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,CAAC;;EAIH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,eAAe;IACf,gBAAgB;IAChB,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eAAe;IACf,gBAAgB;IAChB,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAGlC,OAAI;IACH,MAAM,EAAE,MAAM,YAAY,MAAM,YAC/B,+BACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AAED,QAAI,CAAC,SAAS;AACb,YAAO,MAAM,kCAAkC;AAC/C,YAAO;;IAGR,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAEzD,WAAO;KACN,MAAM;MACL,IAAI,QAAQ;MACZ,MAAM,QAAQ;MACd,OAAO,QAAQ;MACf,OAAO,QAAQ;MACf,eAAe;MACf,GAAG;MACH;KACD,MAAM;KACN;YACO,OAAO;AACf,WAAO,MAAM,yCAAyC,MAAM;AAC5D,WAAO;;;EAGT;EACA"}
@@ -77,7 +77,7 @@ declare const github: (options: GithubOptions) => {
77
77
  redirectURI: string;
78
78
  codeVerifier?: string | undefined;
79
79
  deviceId?: string | undefined;
80
- }) => Promise<OAuth2Tokens>;
80
+ }) => Promise<OAuth2Tokens | null>;
81
81
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
82
82
  getUserInfo(token: OAuth2Tokens & {
83
83
  user?: {
@@ -101,4 +101,5 @@ declare const github: (options: GithubOptions) => {
101
101
  options: GithubOptions;
102
102
  };
103
103
  //#endregion
104
- export { GithubOptions, GithubProfile, github };
104
+ export { GithubOptions, GithubProfile, github };
105
+ //# sourceMappingURL=github.d.mts.map
@@ -1,6 +1,9 @@
1
+ import { logger } from "../env/logger.mjs";
2
+ import "../env/index.mjs";
3
+ import { getOAuth2Tokens } from "../oauth2/utils.mjs";
1
4
  import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
2
5
  import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
3
- import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
6
+ import { createAuthorizationCodeRequest } from "../oauth2/validate-authorization-code.mjs";
4
7
  import "../oauth2/index.mjs";
5
8
  import { betterFetch } from "@better-fetch/fetch";
6
9
 
@@ -27,13 +30,26 @@ const github = (options) => {
27
30
  });
28
31
  },
29
32
  validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
30
- return validateAuthorizationCode({
33
+ const { body, headers: requestHeaders } = createAuthorizationCodeRequest({
31
34
  code,
32
35
  codeVerifier,
33
36
  redirectURI,
34
- options,
35
- tokenEndpoint
37
+ options
38
+ });
39
+ const { data, error } = await betterFetch(tokenEndpoint, {
40
+ method: "POST",
41
+ body,
42
+ headers: requestHeaders
36
43
  });
44
+ if (error) {
45
+ logger.error("GitHub OAuth token exchange failed:", error);
46
+ return null;
47
+ }
48
+ if ("error" in data) {
49
+ logger.error("GitHub OAuth token exchange failed:", data);
50
+ return null;
51
+ }
52
+ return getOAuth2Tokens(data);
37
53
  },
38
54
  refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
39
55
  return refreshAccessToken({
@@ -63,7 +79,7 @@ const github = (options) => {
63
79
  return {
64
80
  user: {
65
81
  id: profile.id,
66
- name: profile.name || profile.login,
82
+ name: profile.name || profile.login || "",
67
83
  email: profile.email,
68
84
  image: profile.avatar_url,
69
85
  emailVerified,
@@ -77,4 +93,5 @@ const github = (options) => {
77
93
  };
78
94
 
79
95
  //#endregion
80
- export { github };
96
+ export { github };
97
+ //# sourceMappingURL=github.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.mjs","names":[],"sources":["../../src/social-providers/github.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { logger } from \"../env\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tgetOAuth2Tokens,\n\trefreshAccessToken,\n} from \"../oauth2\";\nimport { createAuthorizationCodeRequest } from \"../oauth2/validate-authorization-code\";\n\nexport interface GithubProfile {\n\tlogin: string;\n\tid: string;\n\tnode_id: string;\n\tavatar_url: string;\n\tgravatar_id: string;\n\turl: string;\n\thtml_url: string;\n\tfollowers_url: string;\n\tfollowing_url: string;\n\tgists_url: string;\n\tstarred_url: string;\n\tsubscriptions_url: string;\n\torganizations_url: string;\n\trepos_url: string;\n\tevents_url: string;\n\treceived_events_url: string;\n\ttype: string;\n\tsite_admin: boolean;\n\tname: string;\n\tcompany: string;\n\tblog: string;\n\tlocation: string;\n\temail: string;\n\thireable: boolean;\n\tbio: string;\n\ttwitter_username: string;\n\tpublic_repos: string;\n\tpublic_gists: string;\n\tfollowers: string;\n\tfollowing: string;\n\tcreated_at: string;\n\tupdated_at: string;\n\tprivate_gists: string;\n\ttotal_private_repos: string;\n\towned_private_repos: string;\n\tdisk_usage: string;\n\tcollaborators: string;\n\ttwo_factor_authentication: boolean;\n\tplan: {\n\t\tname: string;\n\t\tspace: string;\n\t\tprivate_repos: string;\n\t\tcollaborators: string;\n\t};\n}\n\nexport interface GithubOptions extends ProviderOptions<GithubProfile> {\n\tclientId: string;\n}\nexport const github = (options: GithubOptions) => {\n\tconst tokenEndpoint = \"https://github.com/login/oauth/access_token\";\n\treturn {\n\t\tid: \"github\",\n\t\tname: \"GitHub\",\n\t\tcreateAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tloginHint,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t}) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"read:user\", \"user:email\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"github\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://github.com/login/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tloginHint,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\tconst { body, headers: requestHeaders } = createAuthorizationCodeRequest({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t});\n\n\t\t\tconst { data, error } = await betterFetch<\n\t\t\t\t| { access_token: string; token_type: string; scope: string }\n\t\t\t\t| { error: string; error_description?: string; error_uri?: string }\n\t\t\t>(tokenEndpoint, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tbody: body,\n\t\t\t\theaders: requestHeaders,\n\t\t\t});\n\n\t\t\tif (error) {\n\t\t\t\tlogger.error(\"GitHub OAuth token exchange failed:\", error);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif (\"error\" in data) {\n\t\t\t\tlogger.error(\"GitHub OAuth token exchange failed:\", data);\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn getOAuth2Tokens(data);\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://github.com/login/oauth/access_token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<GithubProfile>(\n\t\t\t\t\"https://api.github.com/user\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"User-Agent\": \"better-auth\",\n\t\t\t\t\t\tauthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst { data: emails } = await betterFetch<\n\t\t\t\t{\n\t\t\t\t\temail: string;\n\t\t\t\t\tprimary: boolean;\n\t\t\t\t\tverified: boolean;\n\t\t\t\t\tvisibility: \"public\" | \"private\";\n\t\t\t\t}[]\n\t\t\t>(\"https://api.github.com/user/emails\", {\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\"User-Agent\": \"better-auth\",\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tif (!profile.email && emails) {\n\t\t\t\tprofile.email = (emails.find((e) => e.primary) ?? emails[0])\n\t\t\t\t\t?.email as string;\n\t\t\t}\n\t\t\tconst emailVerified =\n\t\t\t\temails?.find((e) => e.email === profile.email)?.verified ?? false;\n\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.id,\n\t\t\t\t\tname: profile.name || profile.login || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.avatar_url,\n\t\t\t\t\temailVerified,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<GithubProfile>;\n};\n"],"mappings":";;;;;;;;;;AA4DA,MAAa,UAAU,YAA2B;CACjD,MAAM,gBAAgB;AACtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EACtB,OACA,QACA,WACA,cACA,eACE;GACF,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF,CAAC,aAAa,aAAa;AAC9B,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA;IACA,QAAQ,QAAQ;IAChB,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;GACzE,MAAM,EAAE,MAAM,SAAS,mBAAmB,+BAA+B;IACxE;IACA;IACA;IACA;IACA,CAAC;GAEF,MAAM,EAAE,MAAM,UAAU,MAAM,YAG5B,eAAe;IAChB,QAAQ;IACF;IACN,SAAS;IACT,CAAC;AAEF,OAAI,OAAO;AACV,WAAO,MAAM,uCAAuC,MAAM;AAC1D,WAAO;;AAGR,OAAI,WAAW,MAAM;AACpB,WAAO,MAAM,uCAAuC,KAAK;AACzD,WAAO;;AAGR,UAAO,gBAAgB,KAAK;;EAE7B,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eAAe;IACf,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,+BACA,EACC,SAAS;IACR,cAAc;IACd,eAAe,UAAU,MAAM;IAC/B,EACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,EAAE,MAAM,WAAW,MAAM,YAO7B,sCAAsC,EACvC,SAAS;IACR,eAAe,UAAU,MAAM;IAC/B,cAAc;IACd,EACD,CAAC;AAEF,OAAI,CAAC,QAAQ,SAAS,OACrB,SAAQ,SAAS,OAAO,MAAM,MAAM,EAAE,QAAQ,IAAI,OAAO,KACtD;GAEJ,MAAM,gBACL,QAAQ,MAAM,MAAM,EAAE,UAAU,QAAQ,MAAM,EAAE,YAAY;GAE7D,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ,QAAQ,SAAS;KACvC,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf;KACA,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
@@ -122,4 +122,5 @@ declare const gitlab: (options: GitlabOptions) => {
122
122
  options: GitlabOptions;
123
123
  };
124
124
  //#endregion
125
- export { GitlabOptions, GitlabProfile, gitlab };
125
+ export { GitlabOptions, GitlabProfile, gitlab };
126
+ //# sourceMappingURL=gitlab.d.mts.map
@@ -65,7 +65,7 @@ const gitlab = (options) => {
65
65
  return {
66
66
  user: {
67
67
  id: profile.id,
68
- name: profile.name ?? profile.username,
68
+ name: profile.name ?? profile.username ?? "",
69
69
  email: profile.email,
70
70
  image: profile.avatar_url,
71
71
  emailVerified: profile.email_verified ?? false,
@@ -79,4 +79,5 @@ const gitlab = (options) => {
79
79
  };
80
80
 
81
81
  //#endregion
82
- export { gitlab };
82
+ export { gitlab };
83
+ //# sourceMappingURL=gitlab.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitlab.mjs","names":[],"sources":["../../src/social-providers/gitlab.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface GitlabProfile extends Record<string, any> {\n\tid: number;\n\tusername: string;\n\temail: string;\n\tname: string;\n\tstate: string;\n\tavatar_url: string;\n\tweb_url: string;\n\tcreated_at: string;\n\tbio: string;\n\tlocation?: string | undefined;\n\tpublic_email: string;\n\tskype: string;\n\tlinkedin: string;\n\ttwitter: string;\n\twebsite_url: string;\n\torganization: string;\n\tjob_title: string;\n\tpronouns: string;\n\tbot: boolean;\n\twork_information?: string | undefined;\n\tfollowers: number;\n\tfollowing: number;\n\tlocal_time: string;\n\tlast_sign_in_at: string;\n\tconfirmed_at: string;\n\ttheme_id: number;\n\tlast_activity_on: string;\n\tcolor_scheme_id: number;\n\tprojects_limit: number;\n\tcurrent_sign_in_at: string;\n\tidentities: Array<{\n\t\tprovider: string;\n\t\textern_uid: string;\n\t}>;\n\tcan_create_group: boolean;\n\tcan_create_project: boolean;\n\ttwo_factor_enabled: boolean;\n\texternal: boolean;\n\tprivate_profile: boolean;\n\tcommit_email: string;\n\tshared_runners_minutes_limit: number;\n\textra_shared_runners_minutes_limit: number;\n\temail_verified?: boolean | undefined;\n}\n\nexport interface GitlabOptions extends ProviderOptions<GitlabProfile> {\n\tclientId: string;\n\tissuer?: string | undefined;\n}\n\nconst cleanDoubleSlashes = (input: string = \"\") => {\n\treturn input\n\t\t.split(\"://\")\n\t\t.map((str) => str.replace(/\\/{2,}/g, \"/\"))\n\t\t.join(\"://\");\n};\n\nconst issuerToEndpoints = (issuer?: string | undefined) => {\n\tconst baseUrl = issuer || \"https://gitlab.com\";\n\treturn {\n\t\tauthorizationEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/authorize`),\n\t\ttokenEndpoint: cleanDoubleSlashes(`${baseUrl}/oauth/token`),\n\t\tuserinfoEndpoint: cleanDoubleSlashes(`${baseUrl}/api/v4/user`),\n\t};\n};\n\nexport const gitlab = (options: GitlabOptions) => {\n\tconst { authorizationEndpoint, tokenEndpoint, userinfoEndpoint } =\n\t\tissuerToEndpoints(options.issuer);\n\tconst issuerId = \"gitlab\";\n\tconst issuerName = \"Gitlab\";\n\treturn {\n\t\tid: issuerId,\n\t\tname: issuerName,\n\t\tcreateAuthorizationURL: async ({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tloginHint,\n\t\t\tredirectURI,\n\t\t}) => {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"read_user\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: issuerId,\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t\tcodeVerifier,\n\t\t\t\tloginHint,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI, codeVerifier }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\tcodeVerifier,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: tokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<GitlabProfile>(\n\t\t\t\tuserinfoEndpoint,\n\t\t\t\t{ headers: { authorization: `Bearer ${token.accessToken}` } },\n\t\t\t);\n\t\t\tif (error || profile.state !== \"active\" || profile.locked) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\t// GitLab may provide email_verified claim, but it's not guaranteed.\n\t\t\t// We check for it first, then default to false for security consistency.\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.id,\n\t\t\t\t\tname: profile.name ?? profile.username ?? \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.avatar_url,\n\t\t\t\t\temailVerified: profile.email_verified ?? false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<GitlabProfile>;\n};\n"],"mappings":";;;;;;;AA2DA,MAAM,sBAAsB,QAAgB,OAAO;AAClD,QAAO,MACL,MAAM,MAAM,CACZ,KAAK,QAAQ,IAAI,QAAQ,WAAW,IAAI,CAAC,CACzC,KAAK,MAAM;;AAGd,MAAM,qBAAqB,WAAgC;CAC1D,MAAM,UAAU,UAAU;AAC1B,QAAO;EACN,uBAAuB,mBAAmB,GAAG,QAAQ,kBAAkB;EACvE,eAAe,mBAAmB,GAAG,QAAQ,cAAc;EAC3D,kBAAkB,mBAAmB,GAAG,QAAQ,cAAc;EAC9D;;AAGF,MAAa,UAAU,YAA2B;CACjD,MAAM,EAAE,uBAAuB,eAAe,qBAC7C,kBAAkB,QAAQ,OAAO;CAClC,MAAM,WAAW;AAEjB,QAAO;EACN,IAAI;EACJ,MAHkB;EAIlB,wBAAwB,OAAO,EAC9B,OACA,QACA,cACA,WACA,kBACK;GACL,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,YAAY;AAChE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA;IACA,QAAQ;IACR;IACA;IACA;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,aAAa,mBAAmB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACc;IACf,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,kBACA,EAAE,SAAS,EAAE,eAAe,UAAU,MAAM,eAAe,EAAE,CAC7D;AACD,OAAI,SAAS,QAAQ,UAAU,YAAY,QAAQ,OAClD,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AAGzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ,QAAQ,YAAY;KAC1C,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
@@ -96,4 +96,5 @@ declare const google: (options: GoogleOptions) => {
96
96
  };
97
97
  declare const getGooglePublicKey: (kid: string) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
98
98
  //#endregion
99
- export { GoogleOptions, GoogleProfile, getGooglePublicKey, google };
99
+ export { GoogleOptions, GoogleProfile, getGooglePublicKey, google };
100
+ //# sourceMappingURL=google.d.mts.map
@@ -29,7 +29,7 @@ const google = (options) => {
29
29
  return await createAuthorizationURL({
30
30
  id: "google",
31
31
  options,
32
- authorizationEndpoint: "https://accounts.google.com/o/oauth2/auth",
32
+ authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth",
33
33
  scopes: _scopes,
34
34
  state,
35
35
  codeVerifier,
@@ -59,22 +59,26 @@ const google = (options) => {
59
59
  clientKey: options.clientKey,
60
60
  clientSecret: options.clientSecret
61
61
  },
62
- tokenEndpoint: "https://www.googleapis.com/oauth2/v4/token"
62
+ tokenEndpoint: "https://oauth2.googleapis.com/token"
63
63
  });
64
64
  },
65
65
  async verifyIdToken(token, nonce) {
66
66
  if (options.disableIdTokenSignIn) return false;
67
67
  if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
68
- const { kid, alg: jwtAlg } = decodeProtectedHeader(token);
69
- if (!kid || !jwtAlg) return false;
70
- const { payload: jwtClaims } = await jwtVerify(token, await getGooglePublicKey(kid), {
71
- algorithms: [jwtAlg],
72
- issuer: ["https://accounts.google.com", "accounts.google.com"],
73
- audience: options.clientId,
74
- maxTokenAge: "1h"
75
- });
76
- if (nonce && jwtClaims.nonce !== nonce) return false;
77
- return true;
68
+ try {
69
+ const { kid, alg: jwtAlg } = decodeProtectedHeader(token);
70
+ if (!kid || !jwtAlg) return false;
71
+ const { payload: jwtClaims } = await jwtVerify(token, await getGooglePublicKey(kid), {
72
+ algorithms: [jwtAlg],
73
+ issuer: ["https://accounts.google.com", "accounts.google.com"],
74
+ audience: options.clientId,
75
+ maxTokenAge: "1h"
76
+ });
77
+ if (nonce && jwtClaims.nonce !== nonce) return false;
78
+ return true;
79
+ } catch {
80
+ return false;
81
+ }
78
82
  },
79
83
  async getUserInfo(token) {
80
84
  if (options.getUserInfo) return options.getUserInfo(token);
@@ -105,4 +109,5 @@ const getGooglePublicKey = async (kid) => {
105
109
  };
106
110
 
107
111
  //#endregion
108
- export { getGooglePublicKey, google };
112
+ export { getGooglePublicKey, google };
113
+ //# sourceMappingURL=google.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.mjs","names":[],"sources":["../../src/social-providers/google.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from \"jose\";\nimport { logger } from \"../env\";\nimport { APIError, BetterAuthError } from \"../error\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface GoogleProfile {\n\taud: string;\n\tazp: string;\n\temail: string;\n\temail_verified: boolean;\n\texp: number;\n\t/**\n\t * The family name of the user, or last name in most\n\t * Western languages.\n\t */\n\tfamily_name: string;\n\t/**\n\t * The given name of the user, or first name in most\n\t * Western languages.\n\t */\n\tgiven_name: string;\n\thd?: string | undefined;\n\tiat: number;\n\tiss: string;\n\tjti?: string | undefined;\n\tlocale?: string | undefined;\n\tname: string;\n\tnbf?: number | undefined;\n\tpicture: string;\n\tsub: string;\n}\n\nexport interface GoogleOptions extends ProviderOptions<GoogleProfile> {\n\tclientId: string;\n\t/**\n\t * The access type to use for the authorization code request\n\t */\n\taccessType?: (\"offline\" | \"online\") | undefined;\n\t/**\n\t * The display mode to use for the authorization code request\n\t */\n\tdisplay?: (\"page\" | \"popup\" | \"touch\" | \"wap\") | undefined;\n\t/**\n\t * The hosted domain of the user\n\t */\n\thd?: string | undefined;\n}\n\nexport const google = (options: GoogleOptions) => {\n\treturn {\n\t\tid: \"google\",\n\t\tname: \"Google\",\n\t\tasync createAuthorizationURL({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t\tloginHint,\n\t\t\tdisplay,\n\t\t}) {\n\t\t\tif (!options.clientId || !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Id and Client Secret is required for Google. Make sure to provide them in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_ID_AND_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tif (!codeVerifier) {\n\t\t\t\tthrow new BetterAuthError(\"codeVerifier is required for Google\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"email\", \"profile\", \"openid\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"google\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://accounts.google.com/o/oauth2/v2/auth\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t\taccessType: options.accessType,\n\t\t\t\tdisplay: display || options.display,\n\t\t\t\tloginHint,\n\t\t\t\thd: options.hd,\n\t\t\t\tadditionalParams: {\n\t\t\t\t\tinclude_granted_scopes: \"true\",\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn url;\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint: \"https://oauth2.googleapis.com/token\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://oauth2.googleapis.com/token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync verifyIdToken(token, nonce) {\n\t\t\tif (options.disableIdTokenSignIn) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (options.verifyIdToken) {\n\t\t\t\treturn options.verifyIdToken(token, nonce);\n\t\t\t}\n\n\t\t\t// Verify JWT integrity\n\t\t\t// See https://developers.google.com/identity/sign-in/web/backend-auth#verify-the-integrity-of-the-id-token\n\n\t\t\ttry {\n\t\t\t\tconst { kid, alg: jwtAlg } = decodeProtectedHeader(token);\n\t\t\t\tif (!kid || !jwtAlg) return false;\n\n\t\t\t\tconst publicKey = await getGooglePublicKey(kid);\n\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(token, publicKey, {\n\t\t\t\t\talgorithms: [jwtAlg],\n\t\t\t\t\tissuer: [\"https://accounts.google.com\", \"accounts.google.com\"],\n\t\t\t\t\taudience: options.clientId,\n\t\t\t\t\tmaxTokenAge: \"1h\",\n\t\t\t\t});\n\n\t\t\t\tif (nonce && jwtClaims.nonce !== nonce) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tif (!token.idToken) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst user = decodeJwt(token.idToken) as GoogleProfile;\n\t\t\tconst userMap = await options.mapProfileToUser?.(user);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: user.sub,\n\t\t\t\t\tname: user.name,\n\t\t\t\t\temail: user.email,\n\t\t\t\t\timage: user.picture,\n\t\t\t\t\temailVerified: user.email_verified,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: user,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<GoogleProfile>;\n};\n\nexport const getGooglePublicKey = async (kid: string) => {\n\tconst { data } = await betterFetch<{\n\t\tkeys: Array<{\n\t\t\tkid: string;\n\t\t\talg: string;\n\t\t\tkty: string;\n\t\t\tuse: string;\n\t\t\tn: string;\n\t\t\te: string;\n\t\t}>;\n\t}>(\"https://www.googleapis.com/oauth2/v3/certs\");\n\n\tif (!data?.keys) {\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"Keys not found\",\n\t\t});\n\t}\n\n\tconst jwk = data.keys.find((key) => key.kid === kid);\n\tif (!jwk) {\n\t\tthrow new Error(`JWK with kid ${kid} not found`);\n\t}\n\n\treturn await importJWK(jwk, jwk.alg);\n};\n"],"mappings":";;;;;;;;;;;AAsDA,MAAa,UAAU,YAA2B;AACjD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAC5B,OACA,QACA,cACA,aACA,WACA,WACE;AACF,OAAI,CAAC,QAAQ,YAAY,CAAC,QAAQ,cAAc;AAC/C,WAAO,MACN,gGACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAE3D,OAAI,CAAC,aACJ,OAAM,IAAI,gBAAgB,sCAAsC;GAEjE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAS;IAAW;IAAS;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AAkBnC,UAjBY,MAAM,uBAAuB;IACxC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,QAAQ,QAAQ;IAChB,YAAY,QAAQ;IACpB,SAAS,WAAW,QAAQ;IAC5B;IACA,IAAI,QAAQ;IACZ,kBAAkB,EACjB,wBAAwB,QACxB;IACD,CAAC;;EAGH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,eAAe;IACf,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eAAe;IACf,CAAC;;EAEL,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAER,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;AAM3C,OAAI;IACH,MAAM,EAAE,KAAK,KAAK,WAAW,sBAAsB,MAAM;AACzD,QAAI,CAAC,OAAO,CAAC,OAAQ,QAAO;IAG5B,MAAM,EAAE,SAAS,cAAc,MAAM,UAAU,OAD7B,MAAM,mBAAmB,IAAI,EACkB;KAChE,YAAY,CAAC,OAAO;KACpB,QAAQ,CAAC,+BAA+B,sBAAsB;KAC9D,UAAU,QAAQ;KAClB,aAAa;KACb,CAAC;AAEF,QAAI,SAAS,UAAU,UAAU,MAChC,QAAO;AAGR,WAAO;WACA;AACP,WAAO;;;EAGT,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAElC,OAAI,CAAC,MAAM,QACV,QAAO;GAER,MAAM,OAAO,UAAU,MAAM,QAAQ;GACrC,MAAM,UAAU,MAAM,QAAQ,mBAAmB,KAAK;AACtD,UAAO;IACN,MAAM;KACL,IAAI,KAAK;KACT,MAAM,KAAK;KACX,OAAO,KAAK;KACZ,OAAO,KAAK;KACZ,eAAe,KAAK;KACpB,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA;;AAGF,MAAa,qBAAqB,OAAO,QAAgB;CACxD,MAAM,EAAE,SAAS,MAAM,YASpB,6CAA6C;AAEhD,KAAI,CAAC,MAAM,KACV,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,kBACT,CAAC;CAGH,MAAM,MAAM,KAAK,KAAK,MAAM,QAAQ,IAAI,QAAQ,IAAI;AACpD,KAAI,CAAC,IACJ,OAAM,IAAI,MAAM,gBAAgB,IAAI,YAAY;AAGjD,QAAO,MAAM,UAAU,KAAK,IAAI,IAAI"}
@@ -82,4 +82,5 @@ declare const huggingface: (options: HuggingFaceOptions) => {
82
82
  options: HuggingFaceOptions;
83
83
  };
84
84
  //#endregion
85
- export { HuggingFaceOptions, HuggingFaceProfile, huggingface };
85
+ export { HuggingFaceOptions, HuggingFaceProfile, huggingface };
86
+ //# sourceMappingURL=huggingface.d.mts.map
@@ -58,7 +58,7 @@ const huggingface = (options) => {
58
58
  return {
59
59
  user: {
60
60
  id: profile.sub,
61
- name: profile.name || profile.preferred_username,
61
+ name: profile.name || profile.preferred_username || "",
62
62
  email: profile.email,
63
63
  image: profile.picture,
64
64
  emailVerified: profile.email_verified ?? false,
@@ -72,4 +72,5 @@ const huggingface = (options) => {
72
72
  };
73
73
 
74
74
  //#endregion
75
- export { huggingface };
75
+ export { huggingface };
76
+ //# sourceMappingURL=huggingface.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"huggingface.mjs","names":[],"sources":["../../src/social-providers/huggingface.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\nexport interface HuggingFaceProfile {\n\tsub: string;\n\tname: string;\n\tpreferred_username: string;\n\tprofile: string;\n\tpicture: string;\n\twebsite?: string | undefined;\n\temail?: string | undefined;\n\temail_verified?: boolean | undefined;\n\tisPro: boolean;\n\tcanPay?: boolean | undefined;\n\torgs?:\n\t\t| {\n\t\t\t\tsub: string;\n\t\t\t\tname: string;\n\t\t\t\tpicture: string;\n\t\t\t\tpreferred_username: string;\n\t\t\t\tisEnterprise: boolean | \"plus\";\n\t\t\t\tcanPay?: boolean;\n\t\t\t\troleInOrg?: \"admin\" | \"write\" | \"contributor\" | \"read\";\n\t\t\t\tpendingSSO?: boolean;\n\t\t\t\tmissingMFA?: boolean;\n\t\t\t\tresourceGroups?: {\n\t\t\t\t\tsub: string;\n\t\t\t\t\tname: string;\n\t\t\t\t\trole: \"admin\" | \"write\" | \"contributor\" | \"read\";\n\t\t\t\t}[];\n\t\t }\n\t\t| undefined;\n}\n\nexport interface HuggingFaceOptions\n\textends ProviderOptions<HuggingFaceProfile> {\n\tclientId: string;\n}\n\nexport const huggingface = (options: HuggingFaceOptions) => {\n\treturn {\n\t\tid: \"huggingface\",\n\t\tname: \"Hugging Face\",\n\t\tcreateAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"huggingface\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://huggingface.co/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint: \"https://huggingface.co/oauth/token\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://huggingface.co/oauth/token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<HuggingFaceProfile>(\n\t\t\t\t\"https://huggingface.co/oauth/userinfo\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.sub,\n\t\t\t\t\tname: profile.name || profile.preferred_username || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\timage: profile.picture,\n\t\t\t\t\temailVerified: profile.email_verified ?? false,\n\t\t\t\t\t...userMap,\n\t\t\t\t},\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<HuggingFaceProfile>;\n};\n"],"mappings":";;;;;;;AA4CA,MAAa,eAAe,YAAgC;AAC3D,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;GACpE,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAU;IAAW;IAAQ;AACjC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA,eAAe;IACf,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eAAe;IACf,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,yCACA;IACC,QAAQ;IACR,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B;IACD,CACD;AACD,OAAI,MACH,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,QAAQ,QAAQ,sBAAsB;KACpD,OAAO,QAAQ;KACf,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
@@ -1,5 +1,3 @@
1
- import { OAuth2Tokens } from "../oauth2/oauth-provider.mjs";
2
- import "../oauth2/index.mjs";
3
1
  import { AppleNonConformUser, AppleOptions, AppleProfile, apple, getApplePublicKey } from "./apple.mjs";
4
2
  import { AtlassianOptions, AtlassianProfile, atlassian } from "./atlassian.mjs";
5
3
  import { CognitoOptions, CognitoProfile, cognito, getCognitoPublicKey } from "./cognito.mjs";
@@ -7,7 +5,7 @@ import { DiscordOptions, DiscordProfile, discord } from "./discord.mjs";
7
5
  import { FacebookOptions, FacebookProfile, facebook } from "./facebook.mjs";
8
6
  import { FigmaOptions, FigmaProfile, figma } from "./figma.mjs";
9
7
  import { GithubOptions, GithubProfile, github } from "./github.mjs";
10
- import { MicrosoftEntraIDProfile, MicrosoftOptions, microsoft } from "./microsoft-entra-id.mjs";
8
+ import { MicrosoftEntraIDProfile, MicrosoftOptions, getMicrosoftPublicKey, microsoft } from "./microsoft-entra-id.mjs";
11
9
  import { GoogleOptions, GoogleProfile, getGooglePublicKey, google } from "./google.mjs";
12
10
  import { HuggingFaceOptions, HuggingFaceProfile, huggingface } from "./huggingface.mjs";
13
11
  import { SlackOptions, SlackProfile, slack } from "./slack.mjs";
@@ -32,7 +30,12 @@ import { LineIdTokenPayload, LineOptions, LineUserInfo, line } from "./line.mjs"
32
30
  import { PaybinOptions, PaybinProfile, paybin } from "./paybin.mjs";
33
31
  import { PayPalOptions, PayPalProfile, PayPalTokenResponse, paypal } from "./paypal.mjs";
34
32
  import { PolarOptions, PolarProfile, polar } from "./polar.mjs";
33
+ import { RailwayOptions, RailwayProfile, railway } from "./railway.mjs";
35
34
  import { VercelOptions, VercelProfile, vercel } from "./vercel.mjs";
35
+ import { AwaitableFunction } from "../types/helper.mjs";
36
+ import "../types/index.mjs";
37
+ import { OAuth2Tokens } from "../oauth2/oauth-provider.mjs";
38
+ import "../oauth2/index.mjs";
36
39
  import * as z from "zod";
37
40
 
38
41
  //#region src/social-providers/index.d.ts
@@ -350,7 +353,7 @@ declare const socialProviders: {
350
353
  redirectURI: string;
351
354
  codeVerifier?: string | undefined;
352
355
  deviceId?: string | undefined;
353
- }) => Promise<OAuth2Tokens>;
356
+ }) => Promise<OAuth2Tokens | null>;
354
357
  refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
355
358
  getUserInfo(token: OAuth2Tokens & {
356
359
  user?: {
@@ -394,6 +397,7 @@ declare const socialProviders: {
394
397
  codeVerifier?: string | undefined;
395
398
  deviceId?: string | undefined;
396
399
  }): Promise<OAuth2Tokens>;
400
+ verifyIdToken(token: string, nonce: string | undefined): Promise<boolean>;
397
401
  getUserInfo(token: OAuth2Tokens & {
398
402
  user?: {
399
403
  name?: {
@@ -1332,7 +1336,7 @@ declare const socialProviders: {
1332
1336
  } | {
1333
1337
  user: {
1334
1338
  id: string;
1335
- name: string | undefined;
1339
+ name: string;
1336
1340
  email: string | undefined;
1337
1341
  image: string | undefined;
1338
1342
  emailVerified: boolean;
@@ -1665,6 +1669,54 @@ declare const socialProviders: {
1665
1669
  } | null>;
1666
1670
  options: PolarOptions;
1667
1671
  };
1672
+ railway: (options: RailwayOptions) => {
1673
+ id: "railway";
1674
+ name: string;
1675
+ createAuthorizationURL({
1676
+ state,
1677
+ scopes,
1678
+ codeVerifier,
1679
+ redirectURI
1680
+ }: {
1681
+ state: string;
1682
+ codeVerifier: string;
1683
+ scopes?: string[] | undefined;
1684
+ redirectURI: string;
1685
+ display?: string | undefined;
1686
+ loginHint?: string | undefined;
1687
+ }): Promise<URL>;
1688
+ validateAuthorizationCode: ({
1689
+ code,
1690
+ codeVerifier,
1691
+ redirectURI
1692
+ }: {
1693
+ code: string;
1694
+ redirectURI: string;
1695
+ codeVerifier?: string | undefined;
1696
+ deviceId?: string | undefined;
1697
+ }) => Promise<OAuth2Tokens>;
1698
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
1699
+ getUserInfo(token: OAuth2Tokens & {
1700
+ user?: {
1701
+ name?: {
1702
+ firstName?: string;
1703
+ lastName?: string;
1704
+ };
1705
+ email?: string;
1706
+ } | undefined;
1707
+ }): Promise<{
1708
+ user: {
1709
+ id: string;
1710
+ name?: string;
1711
+ email?: string | null;
1712
+ image?: string;
1713
+ emailVerified: boolean;
1714
+ [key: string]: any;
1715
+ };
1716
+ data: any;
1717
+ } | null>;
1718
+ options: RailwayOptions;
1719
+ };
1668
1720
  vercel: (options: VercelOptions) => {
1669
1721
  id: "vercel";
1670
1722
  name: string;
@@ -1716,9 +1768,10 @@ declare const socialProviders: {
1716
1768
  declare const socialProviderList: ["github", ...(keyof typeof socialProviders)[]];
1717
1769
  declare const SocialProviderListEnum: z.ZodType<SocialProviderList[number] | (string & {})>;
1718
1770
  type SocialProvider = z.infer<typeof SocialProviderListEnum>;
1719
- type SocialProviders = { [K in SocialProviderList[number]]?: Parameters<(typeof socialProviders)[K]>[0] & {
1771
+ type SocialProviders = { [K in SocialProviderList[number]]?: AwaitableFunction<Parameters<(typeof socialProviders)[K]>[0] & {
1720
1772
  enabled?: boolean | undefined;
1721
- } };
1773
+ }> };
1722
1774
  type SocialProviderList = typeof socialProviderList;
1723
1775
  //#endregion
1724
- export { AccountStatus, AppleNonConformUser, AppleOptions, AppleProfile, AtlassianOptions, AtlassianProfile, CognitoOptions, CognitoProfile, DiscordOptions, DiscordProfile, DropboxOptions, DropboxProfile, FacebookOptions, FacebookProfile, FigmaOptions, FigmaProfile, GithubOptions, GithubProfile, GitlabOptions, GitlabProfile, GoogleOptions, GoogleProfile, HuggingFaceOptions, HuggingFaceProfile, KakaoOptions, KakaoProfile, KickOptions, KickProfile, LineIdTokenPayload, LineOptions, LineUserInfo, LinearOptions, LinearProfile, LinearUser, LinkedInOptions, LinkedInProfile, LoginType, MicrosoftEntraIDProfile, MicrosoftOptions, NaverOptions, NaverProfile, NotionOptions, NotionProfile, PayPalOptions, PayPalProfile, PayPalTokenResponse, PaybinOptions, PaybinProfile, PhoneNumber, PolarOptions, PolarProfile, PronounOption, RedditOptions, RedditProfile, RobloxOptions, RobloxProfile, SalesforceOptions, SalesforceProfile, SlackOptions, SlackProfile, SocialProvider, SocialProviderList, SocialProviderListEnum, SocialProviders, SpotifyOptions, SpotifyProfile, TiktokOptions, TiktokProfile, TwitchOptions, TwitchProfile, TwitterOption, TwitterProfile, VercelOptions, VercelProfile, VkOption, VkProfile, ZoomOptions, ZoomProfile, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, getGooglePublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vercel, vk, zoom };
1776
+ export { AccountStatus, AppleNonConformUser, AppleOptions, AppleProfile, AtlassianOptions, AtlassianProfile, CognitoOptions, CognitoProfile, DiscordOptions, DiscordProfile, DropboxOptions, DropboxProfile, FacebookOptions, FacebookProfile, FigmaOptions, FigmaProfile, GithubOptions, GithubProfile, GitlabOptions, GitlabProfile, GoogleOptions, GoogleProfile, HuggingFaceOptions, HuggingFaceProfile, KakaoOptions, KakaoProfile, KickOptions, KickProfile, LineIdTokenPayload, LineOptions, LineUserInfo, LinearOptions, LinearProfile, LinearUser, LinkedInOptions, LinkedInProfile, LoginType, MicrosoftEntraIDProfile, MicrosoftOptions, NaverOptions, NaverProfile, NotionOptions, NotionProfile, PayPalOptions, PayPalProfile, PayPalTokenResponse, PaybinOptions, PaybinProfile, PhoneNumber, PolarOptions, PolarProfile, PronounOption, RailwayOptions, RailwayProfile, RedditOptions, RedditProfile, RobloxOptions, RobloxProfile, SalesforceOptions, SalesforceProfile, SlackOptions, SlackProfile, SocialProvider, SocialProviderList, SocialProviderListEnum, SocialProviders, SpotifyOptions, SpotifyProfile, TiktokOptions, TiktokProfile, TwitchOptions, TwitchProfile, TwitterOption, TwitterProfile, VercelOptions, VercelProfile, VkOption, VkProfile, ZoomOptions, ZoomProfile, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, getGooglePublicKey, getMicrosoftPublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, railway, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vercel, vk, zoom };
1777
+ //# sourceMappingURL=index.d.mts.map
@@ -14,12 +14,13 @@ import { kick } from "./kick.mjs";
14
14
  import { line } from "./line.mjs";
15
15
  import { linear } from "./linear.mjs";
16
16
  import { linkedin } from "./linkedin.mjs";
17
- import { microsoft } from "./microsoft-entra-id.mjs";
17
+ import { getMicrosoftPublicKey, microsoft } from "./microsoft-entra-id.mjs";
18
18
  import { naver } from "./naver.mjs";
19
19
  import { notion } from "./notion.mjs";
20
20
  import { paybin } from "./paybin.mjs";
21
21
  import { paypal } from "./paypal.mjs";
22
22
  import { polar } from "./polar.mjs";
23
+ import { railway } from "./railway.mjs";
23
24
  import { reddit } from "./reddit.mjs";
24
25
  import { roblox } from "./roblox.mjs";
25
26
  import { salesforce } from "./salesforce.mjs";
@@ -67,10 +68,12 @@ const socialProviders = {
67
68
  paybin,
68
69
  paypal,
69
70
  polar,
71
+ railway,
70
72
  vercel
71
73
  };
72
74
  const socialProviderList = Object.keys(socialProviders);
73
75
  const SocialProviderListEnum = z.enum(socialProviderList).or(z.string());
74
76
 
75
77
  //#endregion
76
- export { SocialProviderListEnum, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, getGooglePublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vercel, vk, zoom };
78
+ export { SocialProviderListEnum, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, getGooglePublicKey, getMicrosoftPublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, railway, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vercel, vk, zoom };
79
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/social-providers/index.ts"],"sourcesContent":["import * as z from \"zod\";\nimport type { AwaitableFunction } from \"../types\";\nimport { apple } from \"./apple\";\nimport { atlassian } from \"./atlassian\";\nimport { cognito } from \"./cognito\";\nimport { discord } from \"./discord\";\nimport { dropbox } from \"./dropbox\";\nimport { facebook } from \"./facebook\";\nimport { figma } from \"./figma\";\nimport { github } from \"./github\";\nimport { gitlab } from \"./gitlab\";\nimport { google } from \"./google\";\nimport { huggingface } from \"./huggingface\";\nimport { kakao } from \"./kakao\";\nimport { kick } from \"./kick\";\nimport { line } from \"./line\";\nimport { linear } from \"./linear\";\nimport { linkedin } from \"./linkedin\";\nimport { microsoft } from \"./microsoft-entra-id\";\nimport { naver } from \"./naver\";\nimport { notion } from \"./notion\";\nimport { paybin } from \"./paybin\";\nimport { paypal } from \"./paypal\";\nimport { polar } from \"./polar\";\nimport { railway } from \"./railway\";\nimport { reddit } from \"./reddit\";\nimport { roblox } from \"./roblox\";\nimport { salesforce } from \"./salesforce\";\nimport { slack } from \"./slack\";\nimport { spotify } from \"./spotify\";\nimport { tiktok } from \"./tiktok\";\nimport { twitch } from \"./twitch\";\nimport { twitter } from \"./twitter\";\nimport { vercel } from \"./vercel\";\nimport { vk } from \"./vk\";\nimport { zoom } from \"./zoom\";\n\nexport const socialProviders = {\n\tapple,\n\tatlassian,\n\tcognito,\n\tdiscord,\n\tfacebook,\n\tfigma,\n\tgithub,\n\tmicrosoft,\n\tgoogle,\n\thuggingface,\n\tslack,\n\tspotify,\n\ttwitch,\n\ttwitter,\n\tdropbox,\n\tkick,\n\tlinear,\n\tlinkedin,\n\tgitlab,\n\ttiktok,\n\treddit,\n\troblox,\n\tsalesforce,\n\tvk,\n\tzoom,\n\tnotion,\n\tkakao,\n\tnaver,\n\tline,\n\tpaybin,\n\tpaypal,\n\tpolar,\n\trailway,\n\tvercel,\n};\n\nexport const socialProviderList = Object.keys(socialProviders) as [\n\t\"github\",\n\t...(keyof typeof socialProviders)[],\n];\n\nexport const SocialProviderListEnum = z\n\t.enum(socialProviderList)\n\t.or(z.string()) as z.ZodType<SocialProviderList[number] | (string & {})>;\n\nexport type SocialProvider = z.infer<typeof SocialProviderListEnum>;\n\nexport type SocialProviders = {\n\t[K in SocialProviderList[number]]?: AwaitableFunction<\n\t\tParameters<(typeof socialProviders)[K]>[0] & {\n\t\t\tenabled?: boolean | undefined;\n\t\t}\n\t>;\n};\n\nexport * from \"./apple\";\nexport * from \"./atlassian\";\nexport * from \"./cognito\";\nexport * from \"./discord\";\nexport * from \"./dropbox\";\nexport * from \"./facebook\";\nexport * from \"./figma\";\nexport * from \"./github\";\nexport * from \"./gitlab\";\nexport * from \"./google\";\nexport * from \"./huggingface\";\nexport * from \"./kakao\";\nexport * from \"./kick\";\nexport * from \"./kick\";\nexport * from \"./line\";\nexport * from \"./linear\";\nexport * from \"./linkedin\";\nexport * from \"./linkedin\";\nexport * from \"./microsoft-entra-id\";\nexport * from \"./naver\";\nexport * from \"./notion\";\nexport * from \"./paybin\";\nexport * from \"./paypal\";\nexport * from \"./polar\";\nexport * from \"./railway\";\nexport * from \"./reddit\";\nexport * from \"./roblox\";\nexport * from \"./salesforce\";\nexport * from \"./slack\";\nexport * from \"./spotify\";\nexport * from \"./tiktok\";\nexport * from \"./twitch\";\nexport * from \"./twitter\";\nexport * from \"./vercel\";\nexport * from \"./vk\";\nexport * from \"./zoom\";\n\nexport type SocialProviderList = typeof socialProviderList;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,MAAa,kBAAkB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAED,MAAa,qBAAqB,OAAO,KAAK,gBAAgB;AAK9D,MAAa,yBAAyB,EACpC,KAAK,mBAAmB,CACxB,GAAG,EAAE,QAAQ,CAAC"}
@@ -138,7 +138,7 @@ declare const kakao: (options: KakaoOptions) => {
138
138
  } | {
139
139
  user: {
140
140
  id: string;
141
- name: string | undefined;
141
+ name: string;
142
142
  email: string | undefined;
143
143
  image: string | undefined;
144
144
  emailVerified: boolean;
@@ -160,4 +160,5 @@ declare const kakao: (options: KakaoOptions) => {
160
160
  options: KakaoOptions;
161
161
  };
162
162
  //#endregion
163
- export { KakaoOptions, KakaoProfile, kakao };
163
+ export { KakaoOptions, KakaoProfile, kakao };
164
+ //# sourceMappingURL=kakao.d.mts.map
@@ -55,7 +55,7 @@ const kakao = (options) => {
55
55
  return {
56
56
  user: {
57
57
  id: String(profile.id),
58
- name: kakaoProfile.nickname || account.name || void 0,
58
+ name: kakaoProfile.nickname || account.name || "",
59
59
  email: account.email,
60
60
  image: kakaoProfile.profile_image_url || kakaoProfile.thumbnail_image_url,
61
61
  emailVerified: !!account.is_email_valid && !!account.is_email_verified,
@@ -69,4 +69,5 @@ const kakao = (options) => {
69
69
  };
70
70
 
71
71
  //#endregion
72
- export { kakao };
72
+ export { kakao };
73
+ //# sourceMappingURL=kakao.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kakao.mjs","names":[],"sources":["../../src/social-providers/kakao.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\trefreshAccessToken,\n\tvalidateAuthorizationCode,\n} from \"../oauth2\";\n\ninterface Partner {\n\t/** Partner-specific ID (consent required: kakaotalk_message) */\n\tuuid?: string | undefined;\n}\n\ninterface Profile {\n\t/** Nickname (consent required: profile/nickname) */\n\tnickname?: string | undefined;\n\t/** Thumbnail image URL (consent required: profile/profile image) */\n\tthumbnail_image_url?: string | undefined;\n\t/** Profile image URL (consent required: profile/profile image) */\n\tprofile_image_url?: string | undefined;\n\t/** Whether the profile image is the default */\n\tis_default_image?: boolean | undefined;\n\t/** Whether the nickname is the default */\n\tis_default_nickname?: boolean | undefined;\n}\n\ninterface KakaoAccount {\n\t/** Consent required: profile info (nickname/profile image) */\n\tprofile_needs_agreement?: boolean | undefined;\n\t/** Consent required: nickname */\n\tprofile_nickname_needs_agreement?: boolean | undefined;\n\t/** Consent required: profile image */\n\tprofile_image_needs_agreement?: boolean | undefined;\n\t/** Profile info */\n\tprofile?: Profile | undefined;\n\t/** Consent required: name */\n\tname_needs_agreement?: boolean | undefined;\n\t/** Name */\n\tname?: string | undefined;\n\t/** Consent required: email */\n\temail_needs_agreement?: boolean | undefined;\n\t/** Email valid */\n\tis_email_valid?: boolean | undefined;\n\t/** Email verified */\n\tis_email_verified?: boolean | undefined;\n\t/** Email */\n\temail?: string | undefined;\n\t/** Consent required: age range */\n\tage_range_needs_agreement?: boolean | undefined;\n\t/** Age range */\n\tage_range?: string | undefined;\n\t/** Consent required: birth year */\n\tbirthyear_needs_agreement?: boolean | undefined;\n\t/** Birth year (YYYY) */\n\tbirthyear?: string | undefined;\n\t/** Consent required: birthday */\n\tbirthday_needs_agreement?: boolean | undefined;\n\t/** Birthday (MMDD) */\n\tbirthday?: string | undefined;\n\t/** Birthday type (SOLAR/LUNAR) */\n\tbirthday_type?: string | undefined;\n\t/** Whether birthday is in a leap month */\n\tis_leap_month?: boolean | undefined;\n\t/** Consent required: gender */\n\tgender_needs_agreement?: boolean | undefined;\n\t/** Gender (male/female) */\n\tgender?: string | undefined;\n\t/** Consent required: phone number */\n\tphone_number_needs_agreement?: boolean | undefined;\n\t/** Phone number */\n\tphone_number?: string | undefined;\n\t/** Consent required: CI */\n\tci_needs_agreement?: boolean | undefined;\n\t/** CI (unique identifier) */\n\tci?: string | undefined;\n\t/** CI authentication time (UTC) */\n\tci_authenticated_at?: string | undefined;\n}\n\nexport interface KakaoProfile {\n\t/** Kakao user ID */\n\tid: number;\n\t/**\n\t * Whether the user has signed up (only present if auto-connection is disabled)\n\t * false: preregistered, true: registered\n\t */\n\thas_signed_up?: boolean | undefined;\n\t/** UTC datetime when the user connected the service */\n\tconnected_at?: string | undefined;\n\t/** UTC datetime when the user signed up via Kakao Sync */\n\tsynched_at?: string | undefined;\n\t/** Custom user properties */\n\tproperties?: Record<string, any> | undefined;\n\t/** Kakao account info */\n\tkakao_account: KakaoAccount;\n\t/** Partner info */\n\tfor_partner?: Partner | undefined;\n}\n\nexport interface KakaoOptions extends ProviderOptions<KakaoProfile> {\n\tclientId: string;\n}\n\nexport const kakao = (options: KakaoOptions) => {\n\treturn {\n\t\tid: \"kakao\",\n\t\tname: \"Kakao\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"account_email\", \"profile_image\", \"profile_nickname\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\treturn createAuthorizationURL({\n\t\t\t\tid: \"kakao\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://kauth.kakao.com/oauth/authorize\",\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tredirectURI,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint: \"https://kauth.kakao.com/oauth/token\",\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: \"https://kauth.kakao.com/oauth/token\",\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<KakaoProfile>(\n\t\t\t\t\"https://kapi.kakao.com/v2/user/me\",\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (error || !profile) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\tconst account = profile.kakao_account || {};\n\t\t\tconst kakaoProfile = account.profile || {};\n\t\t\tconst user = {\n\t\t\t\tid: String(profile.id),\n\t\t\t\tname: kakaoProfile.nickname || account.name || \"\",\n\t\t\t\temail: account.email,\n\t\t\t\timage:\n\t\t\t\t\tkakaoProfile.profile_image_url || kakaoProfile.thumbnail_image_url,\n\t\t\t\temailVerified: !!account.is_email_valid && !!account.is_email_verified,\n\t\t\t\t...userMap,\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tuser,\n\t\t\t\tdata: profile,\n\t\t\t};\n\t\t},\n\t\toptions,\n\t} satisfies OAuthProvider<KakaoProfile>;\n};\n"],"mappings":";;;;;;;AAuGA,MAAa,SAAS,YAA0B;AAC/C,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GACtD,MAAM,UAAU,QAAQ,sBACrB,EAAE,GACF;IAAC;IAAiB;IAAiB;IAAmB;AACzD,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,UAAO,uBAAuB;IAC7B,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,kBAAkB;AAC3D,UAAO,0BAA0B;IAChC;IACA;IACA;IACA,eAAe;IACf,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD,eAAe;IACf,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,qCACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AACD,OAAI,SAAS,CAAC,QACb,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;GACzD,MAAM,UAAU,QAAQ,iBAAiB,EAAE;GAC3C,MAAM,eAAe,QAAQ,WAAW,EAAE;AAU1C,UAAO;IACN,MAVY;KACZ,IAAI,OAAO,QAAQ,GAAG;KACtB,MAAM,aAAa,YAAY,QAAQ,QAAQ;KAC/C,OAAO,QAAQ;KACf,OACC,aAAa,qBAAqB,aAAa;KAChD,eAAe,CAAC,CAAC,QAAQ,kBAAkB,CAAC,CAAC,QAAQ;KACrD,GAAG;KACH;IAGA,MAAM;IACN;;EAEF;EACA"}
@@ -72,4 +72,5 @@ declare const kick: (options: KickOptions) => {
72
72
  options: KickOptions;
73
73
  };
74
74
  //#endregion
75
- export { KickOptions, KickProfile, kick };
75
+ export { KickOptions, KickProfile, kick };
76
+ //# sourceMappingURL=kick.d.mts.map
@@ -68,4 +68,5 @@ const kick = (options) => {
68
68
  };
69
69
 
70
70
  //#endregion
71
- export { kick };
71
+ export { kick };
72
+ //# sourceMappingURL=kick.mjs.map