@better-auth/core 1.5.0-beta.8 → 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 (313) 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/index.d.mts +2 -2
  18. package/dist/context/index.mjs +2 -2
  19. package/dist/context/request-state.d.mts +2 -1
  20. package/dist/context/request-state.mjs +4 -3
  21. package/dist/context/request-state.mjs.map +1 -0
  22. package/dist/context/transaction.d.mts +12 -3
  23. package/dist/context/transaction.mjs +55 -11
  24. package/dist/context/transaction.mjs.map +1 -0
  25. package/dist/db/adapter/factory.d.mts +6 -13
  26. package/dist/db/adapter/factory.mjs +44 -57
  27. package/dist/db/adapter/factory.mjs.map +1 -0
  28. package/dist/db/adapter/get-default-field-name.d.mts +2 -1
  29. package/dist/db/adapter/get-default-field-name.mjs +3 -2
  30. package/dist/db/adapter/get-default-field-name.mjs.map +1 -0
  31. package/dist/db/adapter/get-default-model-name.d.mts +2 -1
  32. package/dist/db/adapter/get-default-model-name.mjs +5 -4
  33. package/dist/db/adapter/get-default-model-name.mjs.map +1 -0
  34. package/dist/db/adapter/get-field-attributes.d.mts +3 -2
  35. package/dist/db/adapter/get-field-attributes.mjs +2 -1
  36. package/dist/db/adapter/get-field-attributes.mjs.map +1 -0
  37. package/dist/db/adapter/get-field-name.d.mts +2 -1
  38. package/dist/db/adapter/get-field-name.mjs +2 -1
  39. package/dist/db/adapter/get-field-name.mjs.map +1 -0
  40. package/dist/db/adapter/get-id-field.d.mts +3 -2
  41. package/dist/db/adapter/get-id-field.mjs +3 -2
  42. package/dist/db/adapter/get-id-field.mjs.map +1 -0
  43. package/dist/db/adapter/get-model-name.d.mts +2 -1
  44. package/dist/db/adapter/get-model-name.mjs +2 -1
  45. package/dist/db/adapter/get-model-name.mjs.map +1 -0
  46. package/dist/db/adapter/index.d.mts +10 -4
  47. package/dist/db/adapter/index.mjs +19 -2
  48. package/dist/db/adapter/index.mjs.map +1 -0
  49. package/dist/db/adapter/types.d.mts +3 -34
  50. package/dist/db/adapter/utils.d.mts +2 -1
  51. package/dist/db/adapter/utils.mjs +2 -1
  52. package/dist/db/adapter/utils.mjs.map +1 -0
  53. package/dist/db/get-tables.d.mts +2 -1
  54. package/dist/db/get-tables.mjs +46 -39
  55. package/dist/db/get-tables.mjs.map +1 -0
  56. package/dist/db/index.d.mts +7 -7
  57. package/dist/db/plugin.d.mts +2 -1
  58. package/dist/db/schema/account.d.mts +8 -4
  59. package/dist/db/schema/account.mjs +2 -1
  60. package/dist/db/schema/account.mjs.map +1 -0
  61. package/dist/db/schema/rate-limit.d.mts +8 -2
  62. package/dist/db/schema/rate-limit.mjs +2 -1
  63. package/dist/db/schema/rate-limit.mjs.map +1 -0
  64. package/dist/db/schema/session.d.mts +8 -4
  65. package/dist/db/schema/session.mjs +2 -1
  66. package/dist/db/schema/session.mjs.map +1 -0
  67. package/dist/db/schema/shared.d.mts +2 -1
  68. package/dist/db/schema/shared.mjs +2 -1
  69. package/dist/db/schema/shared.mjs.map +1 -0
  70. package/dist/db/schema/user.d.mts +8 -4
  71. package/dist/db/schema/user.mjs +2 -1
  72. package/dist/db/schema/user.mjs.map +1 -0
  73. package/dist/db/schema/verification.d.mts +8 -4
  74. package/dist/db/schema/verification.mjs +2 -1
  75. package/dist/db/schema/verification.mjs.map +1 -0
  76. package/dist/db/type.d.mts +28 -2
  77. package/dist/env/color-depth.d.mts +2 -1
  78. package/dist/env/color-depth.mjs +2 -1
  79. package/dist/env/color-depth.mjs.map +1 -0
  80. package/dist/env/env-impl.d.mts +3 -2
  81. package/dist/env/env-impl.mjs +9 -8
  82. package/dist/env/env-impl.mjs.map +1 -0
  83. package/dist/env/logger.d.mts +2 -1
  84. package/dist/env/logger.mjs +3 -2
  85. package/dist/env/logger.mjs.map +1 -0
  86. package/dist/error/codes.d.mts +64 -181
  87. package/dist/error/codes.mjs +6 -2
  88. package/dist/error/codes.mjs.map +1 -0
  89. package/dist/error/index.d.mts +2 -1
  90. package/dist/error/index.mjs +2 -1
  91. package/dist/error/index.mjs.map +1 -0
  92. package/dist/index.d.mts +5 -4
  93. package/dist/oauth2/client-credentials-token.d.mts +25 -3
  94. package/dist/oauth2/client-credentials-token.mjs +15 -2
  95. package/dist/oauth2/client-credentials-token.mjs.map +1 -0
  96. package/dist/oauth2/create-authorization-url.d.mts +5 -2
  97. package/dist/oauth2/create-authorization-url.mjs +3 -1
  98. package/dist/oauth2/create-authorization-url.mjs.map +1 -0
  99. package/dist/oauth2/index.d.mts +4 -4
  100. package/dist/oauth2/index.mjs +4 -4
  101. package/dist/oauth2/oauth-provider.d.mts +3 -2
  102. package/dist/oauth2/refresh-access-token.d.mts +24 -4
  103. package/dist/oauth2/refresh-access-token.mjs +20 -2
  104. package/dist/oauth2/refresh-access-token.mjs.map +1 -0
  105. package/dist/oauth2/utils.d.mts +2 -1
  106. package/dist/oauth2/utils.mjs +2 -1
  107. package/dist/oauth2/utils.mjs.map +1 -0
  108. package/dist/oauth2/validate-authorization-code.d.mts +37 -4
  109. package/dist/oauth2/validate-authorization-code.mjs +25 -13
  110. package/dist/oauth2/validate-authorization-code.mjs.map +1 -0
  111. package/dist/oauth2/verify.d.mts +7 -13
  112. package/dist/oauth2/verify.mjs +2 -1
  113. package/dist/oauth2/verify.mjs.map +1 -0
  114. package/dist/social-providers/apple.d.mts +2 -1
  115. package/dist/social-providers/apple.mjs +22 -21
  116. package/dist/social-providers/apple.mjs.map +1 -0
  117. package/dist/social-providers/atlassian.d.mts +2 -1
  118. package/dist/social-providers/atlassian.mjs +2 -1
  119. package/dist/social-providers/atlassian.mjs.map +1 -0
  120. package/dist/social-providers/cognito.d.mts +2 -1
  121. package/dist/social-providers/cognito.mjs +4 -3
  122. package/dist/social-providers/cognito.mjs.map +1 -0
  123. package/dist/social-providers/discord.d.mts +2 -1
  124. package/dist/social-providers/discord.mjs +2 -1
  125. package/dist/social-providers/discord.mjs.map +1 -0
  126. package/dist/social-providers/dropbox.d.mts +2 -1
  127. package/dist/social-providers/dropbox.mjs +3 -2
  128. package/dist/social-providers/dropbox.mjs.map +1 -0
  129. package/dist/social-providers/facebook.d.mts +2 -1
  130. package/dist/social-providers/facebook.mjs +13 -12
  131. package/dist/social-providers/facebook.mjs.map +1 -0
  132. package/dist/social-providers/figma.d.mts +2 -1
  133. package/dist/social-providers/figma.mjs +2 -1
  134. package/dist/social-providers/figma.mjs.map +1 -0
  135. package/dist/social-providers/github.d.mts +3 -2
  136. package/dist/social-providers/github.mjs +23 -6
  137. package/dist/social-providers/github.mjs.map +1 -0
  138. package/dist/social-providers/gitlab.d.mts +2 -1
  139. package/dist/social-providers/gitlab.mjs +3 -2
  140. package/dist/social-providers/gitlab.mjs.map +1 -0
  141. package/dist/social-providers/google.d.mts +2 -1
  142. package/dist/social-providers/google.mjs +18 -13
  143. package/dist/social-providers/google.mjs.map +1 -0
  144. package/dist/social-providers/huggingface.d.mts +2 -1
  145. package/dist/social-providers/huggingface.mjs +3 -2
  146. package/dist/social-providers/huggingface.mjs.map +1 -0
  147. package/dist/social-providers/index.d.mts +61 -8
  148. package/dist/social-providers/index.mjs +5 -2
  149. package/dist/social-providers/index.mjs.map +1 -0
  150. package/dist/social-providers/kakao.d.mts +3 -2
  151. package/dist/social-providers/kakao.mjs +3 -2
  152. package/dist/social-providers/kakao.mjs.map +1 -0
  153. package/dist/social-providers/kick.d.mts +2 -1
  154. package/dist/social-providers/kick.mjs +2 -1
  155. package/dist/social-providers/kick.mjs.map +1 -0
  156. package/dist/social-providers/line.d.mts +2 -1
  157. package/dist/social-providers/line.mjs +3 -2
  158. package/dist/social-providers/line.mjs.map +1 -0
  159. package/dist/social-providers/linear.d.mts +2 -1
  160. package/dist/social-providers/linear.mjs +2 -1
  161. package/dist/social-providers/linear.mjs.map +1 -0
  162. package/dist/social-providers/linkedin.d.mts +2 -1
  163. package/dist/social-providers/linkedin.mjs +2 -1
  164. package/dist/social-providers/linkedin.mjs.map +1 -0
  165. package/dist/social-providers/microsoft-entra-id.d.mts +4 -1
  166. package/dist/social-providers/microsoft-entra-id.mjs +36 -2
  167. package/dist/social-providers/microsoft-entra-id.mjs.map +1 -0
  168. package/dist/social-providers/naver.d.mts +11 -20
  169. package/dist/social-providers/naver.mjs +3 -2
  170. package/dist/social-providers/naver.mjs.map +1 -0
  171. package/dist/social-providers/notion.d.mts +2 -1
  172. package/dist/social-providers/notion.mjs +3 -2
  173. package/dist/social-providers/notion.mjs.map +1 -0
  174. package/dist/social-providers/paybin.d.mts +2 -1
  175. package/dist/social-providers/paybin.mjs +3 -2
  176. package/dist/social-providers/paybin.mjs.map +1 -0
  177. package/dist/social-providers/paypal.d.mts +2 -1
  178. package/dist/social-providers/paypal.mjs +2 -1
  179. package/dist/social-providers/paypal.mjs.map +1 -0
  180. package/dist/social-providers/polar.d.mts +2 -1
  181. package/dist/social-providers/polar.mjs +3 -2
  182. package/dist/social-providers/polar.mjs.map +1 -0
  183. package/dist/social-providers/railway.d.mts +68 -0
  184. package/dist/social-providers/railway.mjs +78 -0
  185. package/dist/social-providers/railway.mjs.map +1 -0
  186. package/dist/social-providers/reddit.d.mts +2 -1
  187. package/dist/social-providers/reddit.mjs +2 -1
  188. package/dist/social-providers/reddit.mjs.map +1 -0
  189. package/dist/social-providers/roblox.d.mts +2 -1
  190. package/dist/social-providers/roblox.mjs +2 -1
  191. package/dist/social-providers/roblox.mjs.map +1 -0
  192. package/dist/social-providers/salesforce.d.mts +2 -1
  193. package/dist/social-providers/salesforce.mjs +2 -1
  194. package/dist/social-providers/salesforce.mjs.map +1 -0
  195. package/dist/social-providers/slack.d.mts +2 -1
  196. package/dist/social-providers/slack.mjs +2 -1
  197. package/dist/social-providers/slack.mjs.map +1 -0
  198. package/dist/social-providers/spotify.d.mts +2 -1
  199. package/dist/social-providers/spotify.mjs +2 -1
  200. package/dist/social-providers/spotify.mjs.map +1 -0
  201. package/dist/social-providers/tiktok.d.mts +3 -3
  202. package/dist/social-providers/tiktok.mjs +3 -2
  203. package/dist/social-providers/tiktok.mjs.map +1 -0
  204. package/dist/social-providers/twitch.d.mts +2 -1
  205. package/dist/social-providers/twitch.mjs +2 -1
  206. package/dist/social-providers/twitch.mjs.map +1 -0
  207. package/dist/social-providers/twitter.d.mts +14 -25
  208. package/dist/social-providers/twitter.mjs +2 -1
  209. package/dist/social-providers/twitter.mjs.map +1 -0
  210. package/dist/social-providers/vercel.d.mts +2 -1
  211. package/dist/social-providers/vercel.mjs +3 -2
  212. package/dist/social-providers/vercel.mjs.map +1 -0
  213. package/dist/social-providers/vk.d.mts +2 -1
  214. package/dist/social-providers/vk.mjs +2 -1
  215. package/dist/social-providers/vk.mjs.map +1 -0
  216. package/dist/social-providers/zoom.d.mts +3 -10
  217. package/dist/social-providers/zoom.mjs +2 -1
  218. package/dist/social-providers/zoom.mjs.map +1 -0
  219. package/dist/types/context.d.mts +54 -21
  220. package/dist/types/cookie.d.mts +2 -1
  221. package/dist/types/helper.d.mts +4 -1
  222. package/dist/types/index.d.mts +4 -3
  223. package/dist/types/init-options.d.mts +235 -144
  224. package/dist/types/plugin-client.d.mts +4 -1
  225. package/dist/types/plugin.d.mts +12 -11
  226. package/dist/types/secret.d.mts +12 -0
  227. package/dist/utils/db.d.mts +12 -0
  228. package/dist/utils/db.mjs +17 -0
  229. package/dist/utils/db.mjs.map +1 -0
  230. package/dist/utils/deprecate.d.mts +2 -2
  231. package/dist/utils/deprecate.mjs +2 -1
  232. package/dist/utils/deprecate.mjs.map +1 -0
  233. package/dist/utils/error-codes.d.mts +8 -6
  234. package/dist/utils/error-codes.mjs +3 -2
  235. package/dist/utils/error-codes.mjs.map +1 -0
  236. package/dist/utils/id.d.mts +2 -1
  237. package/dist/utils/id.mjs +2 -1
  238. package/dist/utils/id.mjs.map +1 -0
  239. package/dist/utils/ip.d.mts +55 -0
  240. package/dist/utils/ip.mjs +119 -0
  241. package/dist/utils/ip.mjs.map +1 -0
  242. package/dist/utils/json.d.mts +2 -1
  243. package/dist/utils/json.mjs +2 -1
  244. package/dist/utils/json.mjs.map +1 -0
  245. package/dist/utils/string.d.mts +2 -1
  246. package/dist/utils/string.mjs +2 -1
  247. package/dist/utils/string.mjs.map +1 -0
  248. package/dist/utils/url.d.mts +2 -1
  249. package/dist/utils/url.mjs +2 -1
  250. package/dist/utils/url.mjs.map +1 -0
  251. package/package.json +35 -13
  252. package/src/context/index.ts +1 -0
  253. package/src/context/transaction.ts +72 -9
  254. package/src/db/adapter/factory.ts +41 -73
  255. package/src/db/adapter/get-id-field.ts +1 -3
  256. package/src/db/adapter/index.ts +20 -15
  257. package/src/db/adapter/types.ts +2 -41
  258. package/src/db/get-tables.ts +48 -37
  259. package/src/db/index.ts +30 -5
  260. package/src/db/schema/account.ts +16 -3
  261. package/src/db/schema/rate-limit.ts +16 -1
  262. package/src/db/schema/session.ts +15 -3
  263. package/src/db/schema/user.ts +15 -3
  264. package/src/db/schema/verification.ts +16 -3
  265. package/src/db/test/get-tables.test.ts +33 -0
  266. package/src/db/type.ts +154 -1
  267. package/src/env/env-impl.ts +2 -2
  268. package/src/env/logger.ts +1 -1
  269. package/src/error/codes.ts +17 -0
  270. package/src/oauth2/client-credentials-token.ts +26 -2
  271. package/src/oauth2/create-authorization-url.ts +3 -1
  272. package/src/oauth2/index.ts +3 -0
  273. package/src/oauth2/oauth-provider.ts +1 -1
  274. package/src/oauth2/refresh-access-token.test.ts +90 -0
  275. package/src/oauth2/refresh-access-token.ts +37 -4
  276. package/src/oauth2/validate-authorization-code.ts +55 -29
  277. package/src/oauth2/validate-token.test.ts +229 -0
  278. package/src/social-providers/apple.ts +29 -29
  279. package/src/social-providers/cognito.ts +6 -5
  280. package/src/social-providers/dropbox.ts +1 -1
  281. package/src/social-providers/facebook.ts +3 -3
  282. package/src/social-providers/github.ts +26 -4
  283. package/src/social-providers/gitlab.ts +1 -1
  284. package/src/social-providers/google.ts +18 -14
  285. package/src/social-providers/huggingface.ts +1 -1
  286. package/src/social-providers/index.ts +9 -5
  287. package/src/social-providers/kakao.ts +1 -1
  288. package/src/social-providers/line.ts +1 -1
  289. package/src/social-providers/microsoft-entra-id.ts +84 -1
  290. package/src/social-providers/naver.ts +1 -1
  291. package/src/social-providers/notion.ts +1 -1
  292. package/src/social-providers/paybin.ts +1 -5
  293. package/src/social-providers/polar.ts +1 -1
  294. package/src/social-providers/railway.ts +100 -0
  295. package/src/social-providers/tiktok.ts +2 -1
  296. package/src/social-providers/vercel.ts +1 -1
  297. package/src/social-providers/zoom.ts +0 -8
  298. package/src/types/context.ts +79 -15
  299. package/src/types/helper.ts +9 -0
  300. package/src/types/index.ts +14 -2
  301. package/src/types/init-options.ts +298 -171
  302. package/src/types/plugin-client.ts +1 -0
  303. package/src/types/plugin.ts +11 -6
  304. package/src/types/secret.ts +8 -0
  305. package/src/utils/db.ts +20 -0
  306. package/src/utils/deprecate.test.ts +0 -1
  307. package/src/utils/error-codes.ts +12 -9
  308. package/src/utils/ip.test.ts +255 -0
  309. package/src/utils/ip.ts +211 -0
  310. package/.turbo/turbo-build.log +0 -180
  311. package/tsconfig.json +0 -7
  312. package/tsdown.config.ts +0 -32
  313. package/vitest.config.ts +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cognito.mjs","names":[],"sources":["../../src/social-providers/cognito.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 CognitoProfile {\n\tsub: string;\n\temail: string;\n\temail_verified: boolean;\n\tname: string;\n\tgiven_name?: string | undefined;\n\tfamily_name?: string | undefined;\n\tpicture?: string | undefined;\n\tusername?: string | undefined;\n\tlocale?: string | undefined;\n\tphone_number?: string | undefined;\n\tphone_number_verified?: boolean | undefined;\n\taud: string;\n\tiss: string;\n\texp: number;\n\tiat: number;\n\t// Custom attributes from Cognito can be added here\n\t[key: string]: any;\n}\n\nexport interface CognitoOptions extends ProviderOptions<CognitoProfile> {\n\tclientId: string;\n\t/**\n\t * The Cognito domain (e.g., \"your-app.auth.us-east-1.amazoncognito.com\")\n\t */\n\tdomain: string;\n\t/**\n\t * AWS region where User Pool is hosted (e.g., \"us-east-1\")\n\t */\n\tregion: string;\n\tuserPoolId: string;\n\trequireClientSecret?: boolean | undefined;\n}\n\nexport const cognito = (options: CognitoOptions) => {\n\tif (!options.domain || !options.region || !options.userPoolId) {\n\t\tlogger.error(\n\t\t\t\"Domain, region and userPoolId are required for Amazon Cognito. Make sure to provide them in the options.\",\n\t\t);\n\t\tthrow new BetterAuthError(\"DOMAIN_AND_REGION_REQUIRED\");\n\t}\n\n\tconst cleanDomain = options.domain.replace(/^https?:\\/\\//, \"\");\n\tconst authorizationEndpoint = `https://${cleanDomain}/oauth2/authorize`;\n\tconst tokenEndpoint = `https://${cleanDomain}/oauth2/token`;\n\tconst userInfoEndpoint = `https://${cleanDomain}/oauth2/userinfo`;\n\n\treturn {\n\t\tid: \"cognito\",\n\t\tname: \"Cognito\",\n\t\tasync createAuthorizationURL({ state, scopes, codeVerifier, redirectURI }) {\n\t\t\tif (!options.clientId) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"ClientId is required for Amazon Cognito. 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\n\t\t\tif (options.requireClientSecret && !options.clientSecret) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t\"Client Secret is required when requireClientSecret is true. Make sure to provide it in the options.\",\n\t\t\t\t);\n\t\t\t\tthrow new BetterAuthError(\"CLIENT_SECRET_REQUIRED\");\n\t\t\t}\n\t\t\tconst _scopes = options.disableDefaultScope\n\t\t\t\t? []\n\t\t\t\t: [\"openid\", \"profile\", \"email\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: \"cognito\",\n\t\t\t\toptions: {\n\t\t\t\t\t...options,\n\t\t\t\t},\n\t\t\t\tauthorizationEndpoint,\n\t\t\t\tscopes: _scopes,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\tprompt: options.prompt,\n\t\t\t});\n\t\t\t// AWS Cognito requires scopes to be encoded with %20 instead of +\n\t\t\t// URLSearchParams encodes spaces as + by default, so we need to fix this\n\t\t\tconst scopeValue = url.searchParams.get(\"scope\");\n\t\t\tif (scopeValue) {\n\t\t\t\turl.searchParams.delete(\"scope\");\n\t\t\t\tconst encodedScope = encodeURIComponent(scopeValue);\n\t\t\t\t// Manually append the scope with proper encoding to the URL\n\t\t\t\tconst urlString = url.toString();\n\t\t\t\tconst separator = urlString.includes(\"?\") ? \"&\" : \"?\";\n\t\t\t\treturn new URL(`${urlString}${separator}scope=${encodedScope}`);\n\t\t\t}\n\t\t\treturn url;\n\t\t},\n\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\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\ttry {\n\t\t\t\tconst decodedHeader = decodeProtectedHeader(token);\n\t\t\t\tconst { kid, alg: jwtAlg } = decodedHeader;\n\t\t\t\tif (!kid || !jwtAlg) return false;\n\n\t\t\t\tconst publicKey = await getCognitoPublicKey(\n\t\t\t\t\tkid,\n\t\t\t\t\toptions.region,\n\t\t\t\t\toptions.userPoolId,\n\t\t\t\t);\n\t\t\t\tconst expectedIssuer = `https://cognito-idp.${options.region}.amazonaws.com/${options.userPoolId}`;\n\n\t\t\t\tconst { payload: jwtClaims } = await jwtVerify(token, publicKey, {\n\t\t\t\t\talgorithms: [jwtAlg],\n\t\t\t\t\tissuer: expectedIssuer,\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\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Failed to verify ID token:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\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) {\n\t\t\t\ttry {\n\t\t\t\t\tconst profile = decodeJwt<CognitoProfile>(token.idToken);\n\t\t\t\t\tif (!profile) {\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\tconst name =\n\t\t\t\t\t\tprofile.name || profile.given_name || profile.username || \"\";\n\t\t\t\t\tconst enrichedProfile = {\n\t\t\t\t\t\t...profile,\n\t\t\t\t\t\tname,\n\t\t\t\t\t};\n\t\t\t\t\tconst userMap = await options.mapProfileToUser?.(enrichedProfile);\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\tid: profile.sub,\n\t\t\t\t\t\t\tname: enrichedProfile.name,\n\t\t\t\t\t\t\temail: profile.email,\n\t\t\t\t\t\t\timage: profile.picture,\n\t\t\t\t\t\t\temailVerified: profile.email_verified,\n\t\t\t\t\t\t\t...userMap,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdata: enrichedProfile,\n\t\t\t\t\t};\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(\"Failed to decode ID token:\", error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (token.accessToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { data: userInfo } = await betterFetch<CognitoProfile>(\n\t\t\t\t\t\tuserInfoEndpoint,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\n\t\t\t\t\tif (userInfo) {\n\t\t\t\t\t\tconst userMap = await options.mapProfileToUser?.(userInfo);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\tid: userInfo.sub,\n\t\t\t\t\t\t\t\tname:\n\t\t\t\t\t\t\t\t\tuserInfo.name ||\n\t\t\t\t\t\t\t\t\tuserInfo.given_name ||\n\t\t\t\t\t\t\t\t\tuserInfo.username ||\n\t\t\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\t\temail: userInfo.email,\n\t\t\t\t\t\t\t\timage: userInfo.picture,\n\t\t\t\t\t\t\t\temailVerified: userInfo.email_verified,\n\t\t\t\t\t\t\t\t...userMap,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tdata: userInfo,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(\"Failed to fetch user info from Cognito:\", error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\n\t\toptions,\n\t} satisfies OAuthProvider<CognitoProfile>;\n};\n\nexport const getCognitoPublicKey = async (\n\tkid: string,\n\tregion: string,\n\tuserPoolId: string,\n) => {\n\tconst COGNITO_JWKS_URI = `https://cognito-idp.${region}.amazonaws.com/${userPoolId}/.well-known/jwks.json`;\n\n\ttry {\n\t\tconst { data } = await betterFetch<{\n\t\t\tkeys: Array<{\n\t\t\t\tkid: string;\n\t\t\t\talg: string;\n\t\t\t\tkty: string;\n\t\t\t\tuse: string;\n\t\t\t\tn: string;\n\t\t\t\te: string;\n\t\t\t}>;\n\t\t}>(COGNITO_JWKS_URI);\n\n\t\tif (!data?.keys) {\n\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\tmessage: \"Keys not found\",\n\t\t\t});\n\t\t}\n\n\t\tconst jwk = data.keys.find((key) => key.kid === kid);\n\t\tif (!jwk) {\n\t\t\tthrow new Error(`JWK with kid ${kid} not found`);\n\t\t}\n\n\t\treturn await importJWK(jwk, jwk.alg);\n\t} catch (error) {\n\t\tlogger.error(\"Failed to fetch Cognito public key:\", error);\n\t\tthrow error;\n\t}\n};\n"],"mappings":";;;;;;;;;;;AA6CA,MAAa,WAAW,YAA4B;AACnD,KAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,UAAU,CAAC,QAAQ,YAAY;AAC9D,SAAO,MACN,2GACA;AACD,QAAM,IAAI,gBAAgB,6BAA6B;;CAGxD,MAAM,cAAc,QAAQ,OAAO,QAAQ,gBAAgB,GAAG;CAC9D,MAAM,wBAAwB,WAAW,YAAY;CACrD,MAAM,gBAAgB,WAAW,YAAY;CAC7C,MAAM,mBAAmB,WAAW,YAAY;AAEhD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,MAAM,uBAAuB,EAAE,OAAO,QAAQ,cAAc,eAAe;AAC1E,OAAI,CAAC,QAAQ,UAAU;AACtB,WAAO,MACN,qFACA;AACD,UAAM,IAAI,gBAAgB,gCAAgC;;AAG3D,OAAI,QAAQ,uBAAuB,CAAC,QAAQ,cAAc;AACzD,WAAO,MACN,sGACA;AACD,UAAM,IAAI,gBAAgB,yBAAyB;;GAEpD,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;GAEnC,MAAM,MAAM,MAAM,uBAAuB;IACxC,IAAI;IACJ,SAAS,EACR,GAAG,SACH;IACD;IACA,QAAQ;IACR;IACA;IACA;IACA,QAAQ,QAAQ;IAChB,CAAC;GAGF,MAAM,aAAa,IAAI,aAAa,IAAI,QAAQ;AAChD,OAAI,YAAY;AACf,QAAI,aAAa,OAAO,QAAQ;IAChC,MAAM,eAAe,mBAAmB,WAAW;IAEnD,MAAM,YAAY,IAAI,UAAU;IAChC,MAAM,YAAY,UAAU,SAAS,IAAI,GAAG,MAAM;AAClD,WAAO,IAAI,IAAI,GAAG,YAAY,UAAU,QAAQ,eAAe;;AAEhE,UAAO;;EAGR,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,0BAA0B;IAChC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAGH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAGL,MAAM,cAAc,OAAO,OAAO;AACjC,OAAI,QAAQ,qBACX,QAAO;AAER,OAAI,QAAQ,cACX,QAAO,QAAQ,cAAc,OAAO,MAAM;AAG3C,OAAI;IAEH,MAAM,EAAE,KAAK,KAAK,WADI,sBAAsB,MAAM;AAElD,QAAI,CAAC,OAAO,CAAC,OAAQ,QAAO;IAE5B,MAAM,YAAY,MAAM,oBACvB,KACA,QAAQ,QACR,QAAQ,WACR;IACD,MAAM,iBAAiB,uBAAuB,QAAQ,OAAO,iBAAiB,QAAQ;IAEtF,MAAM,EAAE,SAAS,cAAc,MAAM,UAAU,OAAO,WAAW;KAChE,YAAY,CAAC,OAAO;KACpB,QAAQ;KACR,UAAU,QAAQ;KAClB,aAAa;KACb,CAAC;AAEF,QAAI,SAAS,UAAU,UAAU,MAChC,QAAO;AAER,WAAO;YACC,OAAO;AACf,WAAO,MAAM,8BAA8B,MAAM;AACjD,WAAO;;;EAIT,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;AAGlC,OAAI,MAAM,QACT,KAAI;IACH,MAAM,UAAU,UAA0B,MAAM,QAAQ;AACxD,QAAI,CAAC,QACJ,QAAO;IAER,MAAM,OACL,QAAQ,QAAQ,QAAQ,cAAc,QAAQ,YAAY;IAC3D,MAAM,kBAAkB;KACvB,GAAG;KACH;KACA;IACD,MAAM,UAAU,MAAM,QAAQ,mBAAmB,gBAAgB;AAEjE,WAAO;KACN,MAAM;MACL,IAAI,QAAQ;MACZ,MAAM,gBAAgB;MACtB,OAAO,QAAQ;MACf,OAAO,QAAQ;MACf,eAAe,QAAQ;MACvB,GAAG;MACH;KACD,MAAM;KACN;YACO,OAAO;AACf,WAAO,MAAM,8BAA8B,MAAM;;AAInD,OAAI,MAAM,YACT,KAAI;IACH,MAAM,EAAE,MAAM,aAAa,MAAM,YAChC,kBACA,EACC,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B,EACD,CACD;AAED,QAAI,UAAU;KACb,MAAM,UAAU,MAAM,QAAQ,mBAAmB,SAAS;AAC1D,YAAO;MACN,MAAM;OACL,IAAI,SAAS;OACb,MACC,SAAS,QACT,SAAS,cACT,SAAS,YACT;OACD,OAAO,SAAS;OAChB,OAAO,SAAS;OAChB,eAAe,SAAS;OACxB,GAAG;OACH;MACD,MAAM;MACN;;YAEM,OAAO;AACf,WAAO,MAAM,2CAA2C,MAAM;;AAIhE,UAAO;;EAGR;EACA;;AAGF,MAAa,sBAAsB,OAClC,KACA,QACA,eACI;CACJ,MAAM,mBAAmB,uBAAuB,OAAO,iBAAiB,WAAW;AAEnF,KAAI;EACH,MAAM,EAAE,SAAS,MAAM,YASpB,iBAAiB;AAEpB,MAAI,CAAC,MAAM,KACV,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,kBACT,CAAC;EAGH,MAAM,MAAM,KAAK,KAAK,MAAM,QAAQ,IAAI,QAAQ,IAAI;AACpD,MAAI,CAAC,IACJ,OAAM,IAAI,MAAM,gBAAgB,IAAI,YAAY;AAGjD,SAAO,MAAM,UAAU,KAAK,IAAI,IAAI;UAC5B,OAAO;AACf,SAAO,MAAM,uCAAuC,MAAM;AAC1D,QAAM"}
@@ -123,4 +123,5 @@ declare const discord: (options: DiscordOptions) => {
123
123
  options: DiscordOptions;
124
124
  };
125
125
  //#endregion
126
- export { DiscordOptions, DiscordProfile, discord };
126
+ export { DiscordOptions, DiscordProfile, discord };
127
+ //# sourceMappingURL=discord.d.mts.map
@@ -61,4 +61,5 @@ const discord = (options) => {
61
61
  };
62
62
 
63
63
  //#endregion
64
- export { discord };
64
+ export { discord };
65
+ //# sourceMappingURL=discord.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.mjs","names":[],"sources":["../../src/social-providers/discord.ts"],"sourcesContent":["import { betterFetch } from \"@better-fetch/fetch\";\nimport type { OAuthProvider, ProviderOptions } from \"../oauth2\";\nimport { refreshAccessToken, validateAuthorizationCode } from \"../oauth2\";\nexport interface DiscordProfile extends Record<string, any> {\n\t/** the user's id (i.e. the numerical snowflake) */\n\tid: string;\n\t/** the user's username, not unique across the platform */\n\tusername: string;\n\t/** the user's Discord-tag */\n\tdiscriminator: string;\n\t/** the user's display name, if it is set */\n\tglobal_name: string | null;\n\t/**\n\t * the user's avatar hash:\n\t * https://discord.com/developers/docs/reference#image-formatting\n\t */\n\tavatar: string | null;\n\t/** whether the user belongs to an OAuth2 application */\n\tbot?: boolean | undefined;\n\t/**\n\t * whether the user is an Official Discord System user (part of the urgent\n\t * message system)\n\t */\n\tsystem?: boolean | undefined;\n\t/** whether the user has two factor enabled on their account */\n\tmfa_enabled: boolean;\n\t/**\n\t * the user's banner hash:\n\t * https://discord.com/developers/docs/reference#image-formatting\n\t */\n\tbanner: string | null;\n\n\t/** the user's banner color encoded as an integer representation of hexadecimal color code */\n\taccent_color: number | null;\n\n\t/**\n\t * the user's chosen language option:\n\t * https://discord.com/developers/docs/reference#locales\n\t */\n\tlocale: string;\n\t/** whether the email on this account has been verified */\n\tverified: boolean;\n\t/** the user's email */\n\temail: string;\n\t/**\n\t * the flags on a user's account:\n\t * https://discord.com/developers/docs/resources/user#user-object-user-flags\n\t */\n\tflags: number;\n\t/**\n\t * the type of Nitro subscription on a user's account:\n\t * https://discord.com/developers/docs/resources/user#user-object-premium-types\n\t */\n\tpremium_type: number;\n\t/**\n\t * the public flags on a user's account:\n\t * https://discord.com/developers/docs/resources/user#user-object-user-flags\n\t */\n\tpublic_flags: number;\n\t/** undocumented field; corresponds to the user's custom nickname */\n\tdisplay_name: string | null;\n\t/**\n\t * undocumented field; corresponds to the Discord feature where you can e.g.\n\t * put your avatar inside of an ice cube\n\t */\n\tavatar_decoration: string | null;\n\t/**\n\t * undocumented field; corresponds to the premium feature where you can\n\t * select a custom banner color\n\t */\n\tbanner_color: string | null;\n\t/** undocumented field; the CDN URL of their profile picture */\n\timage_url: string;\n}\n\nexport interface DiscordOptions extends ProviderOptions<DiscordProfile> {\n\tclientId: string;\n\tprompt?: (\"none\" | \"consent\") | undefined;\n\tpermissions?: number | undefined;\n}\n\nexport const discord = (options: DiscordOptions) => {\n\treturn {\n\t\tid: \"discord\",\n\t\tname: \"Discord\",\n\t\tcreateAuthorizationURL({ state, scopes, redirectURI }) {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"identify\", \"email\"];\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tconst hasBotScope = _scopes.includes(\"bot\");\n\t\t\tconst permissionsParam =\n\t\t\t\thasBotScope && options.permissions !== undefined\n\t\t\t\t\t? `&permissions=${options.permissions}`\n\t\t\t\t\t: \"\";\n\t\t\treturn new URL(\n\t\t\t\t`https://discord.com/api/oauth2/authorize?scope=${_scopes.join(\n\t\t\t\t\t\"+\",\n\t\t\t\t)}&response_type=code&client_id=${\n\t\t\t\t\toptions.clientId\n\t\t\t\t}&redirect_uri=${encodeURIComponent(\n\t\t\t\t\toptions.redirectURI || redirectURI,\n\t\t\t\t)}&state=${state}&prompt=${\n\t\t\t\t\toptions.prompt || \"none\"\n\t\t\t\t}${permissionsParam}`,\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://discord.com/api/oauth2/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://discord.com/api/oauth2/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<DiscordProfile>(\n\t\t\t\t\"https://discord.com/api/users/@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\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (profile.avatar === null) {\n\t\t\t\tconst defaultAvatarNumber =\n\t\t\t\t\tprofile.discriminator === \"0\"\n\t\t\t\t\t\t? Number(BigInt(profile.id) >> BigInt(22)) % 6\n\t\t\t\t\t\t: parseInt(profile.discriminator) % 5;\n\t\t\t\tprofile.image_url = `https://cdn.discordapp.com/embed/avatars/${defaultAvatarNumber}.png`;\n\t\t\t} else {\n\t\t\t\tconst format = profile.avatar.startsWith(\"a_\") ? \"gif\" : \"png\";\n\t\t\t\tprofile.image_url = `https://cdn.discordapp.com/avatars/${profile.id}/${profile.avatar}.${format}`;\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.global_name || profile.username || \"\",\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\temailVerified: profile.verified,\n\t\t\t\t\timage: profile.image_url,\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<DiscordProfile>;\n};\n"],"mappings":";;;;;;AAiFA,MAAa,WAAW,YAA4B;AACnD,QAAO;EACN,IAAI;EACJ,MAAM;EACN,uBAAuB,EAAE,OAAO,QAAQ,eAAe;GACtD,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,YAAY,QAAQ;AACxE,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;AACnC,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;GAEjD,MAAM,mBADc,QAAQ,SAAS,MAAM,IAE3B,QAAQ,gBAAgB,SACpC,gBAAgB,QAAQ,gBACxB;AACJ,UAAO,IAAI,IACV,kDAAkD,QAAQ,KACzD,IACA,CAAC,gCACD,QAAQ,SACR,gBAAgB,mBAChB,QAAQ,eAAe,YACvB,CAAC,SAAS,MAAM,UAChB,QAAQ,UAAU,SAChB,mBACH;;EAEF,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;AAED,OAAI,MACH,QAAO;AAER,OAAI,QAAQ,WAAW,KAKtB,SAAQ,YAAY,4CAHnB,QAAQ,kBAAkB,MACvB,OAAO,OAAO,QAAQ,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,IAC3C,SAAS,QAAQ,cAAc,GAAG,EAC8C;QAC9E;IACN,MAAM,SAAS,QAAQ,OAAO,WAAW,KAAK,GAAG,QAAQ;AACzD,YAAQ,YAAY,sCAAsC,QAAQ,GAAG,GAAG,QAAQ,OAAO,GAAG;;GAE3F,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,eAAe,QAAQ,YAAY;KACjD,OAAO,QAAQ;KACf,eAAe,QAAQ;KACvB,OAAO,QAAQ;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
@@ -68,4 +68,5 @@ declare const dropbox: (options: DropboxOptions) => {
68
68
  options: DropboxOptions;
69
69
  };
70
70
  //#endregion
71
- export { DropboxOptions, DropboxProfile, dropbox };
71
+ export { DropboxOptions, DropboxProfile, dropbox };
72
+ //# sourceMappingURL=dropbox.d.mts.map
@@ -44,7 +44,7 @@ const dropbox = (options) => {
44
44
  clientKey: options.clientKey,
45
45
  clientSecret: options.clientSecret
46
46
  },
47
- tokenEndpoint: "https://api.dropbox.com/oauth2/token"
47
+ tokenEndpoint
48
48
  });
49
49
  },
50
50
  async getUserInfo(token) {
@@ -72,4 +72,5 @@ const dropbox = (options) => {
72
72
  };
73
73
 
74
74
  //#endregion
75
- export { dropbox };
75
+ export { dropbox };
76
+ //# sourceMappingURL=dropbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropbox.mjs","names":[],"sources":["../../src/social-providers/dropbox.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 DropboxProfile {\n\taccount_id: string;\n\tname: {\n\t\tgiven_name: string;\n\t\tsurname: string;\n\t\tfamiliar_name: string;\n\t\tdisplay_name: string;\n\t\tabbreviated_name: string;\n\t};\n\temail: string;\n\temail_verified: boolean;\n\tprofile_photo_url: string;\n}\n\nexport interface DropboxOptions extends ProviderOptions<DropboxProfile> {\n\tclientId: string;\n\taccessType?: (\"offline\" | \"online\" | \"legacy\") | undefined;\n}\n\nexport const dropbox = (options: DropboxOptions) => {\n\tconst tokenEndpoint = \"https://api.dropboxapi.com/oauth2/token\";\n\n\treturn {\n\t\tid: \"dropbox\",\n\t\tname: \"Dropbox\",\n\t\tcreateAuthorizationURL: async ({\n\t\t\tstate,\n\t\t\tscopes,\n\t\t\tcodeVerifier,\n\t\t\tredirectURI,\n\t\t}) => {\n\t\t\tconst _scopes = options.disableDefaultScope ? [] : [\"account_info.read\"];\n\t\t\tif (options.scope) _scopes.push(...options.scope);\n\t\t\tif (scopes) _scopes.push(...scopes);\n\t\t\tconst additionalParams: Record<string, string> = {};\n\t\t\tif (options.accessType) {\n\t\t\t\tadditionalParams.token_access_type = options.accessType;\n\t\t\t}\n\t\t\treturn await createAuthorizationURL({\n\t\t\t\tid: \"dropbox\",\n\t\t\t\toptions,\n\t\t\t\tauthorizationEndpoint: \"https://www.dropbox.com/oauth2/authorize\",\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\tadditionalParams,\n\t\t\t});\n\t\t},\n\t\tvalidateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {\n\t\t\treturn await validateAuthorizationCode({\n\t\t\t\tcode,\n\t\t\t\tcodeVerifier,\n\t\t\t\tredirectURI,\n\t\t\t\toptions,\n\t\t\t\ttokenEndpoint,\n\t\t\t});\n\t\t},\n\t\trefreshAccessToken: options.refreshAccessToken\n\t\t\t? options.refreshAccessToken\n\t\t\t: async (refreshToken) => {\n\t\t\t\t\treturn refreshAccessToken({\n\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\tclientKey: options.clientKey,\n\t\t\t\t\t\t\tclientSecret: options.clientSecret,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\tasync getUserInfo(token) {\n\t\t\tif (options.getUserInfo) {\n\t\t\t\treturn options.getUserInfo(token);\n\t\t\t}\n\t\t\tconst { data: profile, error } = await betterFetch<DropboxProfile>(\n\t\t\t\t\"https://api.dropboxapi.com/2/users/get_current_account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${token.accessToken}`,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (error) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst userMap = await options.mapProfileToUser?.(profile);\n\t\t\treturn {\n\t\t\t\tuser: {\n\t\t\t\t\tid: profile.account_id,\n\t\t\t\t\tname: profile.name?.display_name,\n\t\t\t\t\temail: profile.email,\n\t\t\t\t\temailVerified: profile.email_verified || false,\n\t\t\t\t\timage: profile.profile_photo_url,\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<DropboxProfile>;\n};\n"],"mappings":";;;;;;;AA2BA,MAAa,WAAW,YAA4B;CACnD,MAAM,gBAAgB;AAEtB,QAAO;EACN,IAAI;EACJ,MAAM;EACN,wBAAwB,OAAO,EAC9B,OACA,QACA,cACA,kBACK;GACL,MAAM,UAAU,QAAQ,sBAAsB,EAAE,GAAG,CAAC,oBAAoB;AACxE,OAAI,QAAQ,MAAO,SAAQ,KAAK,GAAG,QAAQ,MAAM;AACjD,OAAI,OAAQ,SAAQ,KAAK,GAAG,OAAO;GACnC,MAAM,mBAA2C,EAAE;AACnD,OAAI,QAAQ,WACX,kBAAiB,oBAAoB,QAAQ;AAE9C,UAAO,MAAM,uBAAuB;IACnC,IAAI;IACJ;IACA,uBAAuB;IACvB,QAAQ;IACR;IACA;IACA;IACA;IACA,CAAC;;EAEH,2BAA2B,OAAO,EAAE,MAAM,cAAc,kBAAkB;AACzE,UAAO,MAAM,0BAA0B;IACtC;IACA;IACA;IACA;IACA;IACA,CAAC;;EAEH,oBAAoB,QAAQ,qBACzB,QAAQ,qBACR,OAAO,iBAAiB;AACxB,UAAO,mBAAmB;IACzB;IACA,SAAS;KACR,UAAU,QAAQ;KAClB,WAAW,QAAQ;KACnB,cAAc,QAAQ;KACtB;IACD;IACA,CAAC;;EAEL,MAAM,YAAY,OAAO;AACxB,OAAI,QAAQ,YACX,QAAO,QAAQ,YAAY,MAAM;GAElC,MAAM,EAAE,MAAM,SAAS,UAAU,MAAM,YACtC,0DACA;IACC,QAAQ;IACR,SAAS,EACR,eAAe,UAAU,MAAM,eAC/B;IACD,CACD;AAED,OAAI,MACH,QAAO;GAER,MAAM,UAAU,MAAM,QAAQ,mBAAmB,QAAQ;AACzD,UAAO;IACN,MAAM;KACL,IAAI,QAAQ;KACZ,MAAM,QAAQ,MAAM;KACpB,OAAO,QAAQ;KACf,eAAe,QAAQ,kBAAkB;KACzC,OAAO,QAAQ;KACf,GAAG;KACH;IACD,MAAM;IACN;;EAEF;EACA"}
@@ -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