@depup/better-auth__core 1.6.23-depup.2

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 (310) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +32 -0
  3. package/changes.json +14 -0
  4. package/dist/api/index.d.mts +281 -0
  5. package/dist/api/index.mjs +92 -0
  6. package/dist/async_hooks/index.d.mts +6 -0
  7. package/dist/async_hooks/index.mjs +20 -0
  8. package/dist/async_hooks/pure.index.d.mts +6 -0
  9. package/dist/async_hooks/pure.index.mjs +33 -0
  10. package/dist/context/endpoint-context.d.mts +18 -0
  11. package/dist/context/endpoint-context.mjs +29 -0
  12. package/dist/context/global.d.mts +6 -0
  13. package/dist/context/global.mjs +36 -0
  14. package/dist/context/index.d.mts +5 -0
  15. package/dist/context/index.mjs +5 -0
  16. package/dist/context/request-state.d.mts +27 -0
  17. package/dist/context/request-state.mjs +47 -0
  18. package/dist/context/transaction.d.mts +27 -0
  19. package/dist/context/transaction.mjs +96 -0
  20. package/dist/db/adapter/factory.d.mts +17 -0
  21. package/dist/db/adapter/factory.mjs +905 -0
  22. package/dist/db/adapter/get-default-field-name.d.mts +18 -0
  23. package/dist/db/adapter/get-default-field-name.mjs +36 -0
  24. package/dist/db/adapter/get-default-model-name.d.mts +12 -0
  25. package/dist/db/adapter/get-default-model-name.mjs +30 -0
  26. package/dist/db/adapter/get-field-attributes.d.mts +26 -0
  27. package/dist/db/adapter/get-field-attributes.mjs +37 -0
  28. package/dist/db/adapter/get-field-name.d.mts +18 -0
  29. package/dist/db/adapter/get-field-name.mjs +31 -0
  30. package/dist/db/adapter/get-id-field.d.mts +36 -0
  31. package/dist/db/adapter/get-id-field.mjs +64 -0
  32. package/dist/db/adapter/get-model-name.d.mts +12 -0
  33. package/dist/db/adapter/get-model-name.mjs +21 -0
  34. package/dist/db/adapter/index.d.mts +615 -0
  35. package/dist/db/adapter/index.mjs +24 -0
  36. package/dist/db/adapter/types.d.mts +105 -0
  37. package/dist/db/adapter/utils.d.mts +7 -0
  38. package/dist/db/adapter/utils.mjs +37 -0
  39. package/dist/db/get-tables.d.mts +6 -0
  40. package/dist/db/get-tables.mjs +266 -0
  41. package/dist/db/index.d.mts +10 -0
  42. package/dist/db/index.mjs +8 -0
  43. package/dist/db/plugin.d.mts +12 -0
  44. package/dist/db/schema/account.d.mts +28 -0
  45. package/dist/db/schema/account.mjs +17 -0
  46. package/dist/db/schema/rate-limit.d.mts +18 -0
  47. package/dist/db/schema/rate-limit.mjs +9 -0
  48. package/dist/db/schema/session.d.mts +23 -0
  49. package/dist/db/schema/session.mjs +12 -0
  50. package/dist/db/schema/shared.d.mts +10 -0
  51. package/dist/db/schema/shared.mjs +9 -0
  52. package/dist/db/schema/user.d.mts +22 -0
  53. package/dist/db/schema/user.mjs +11 -0
  54. package/dist/db/schema/verification.d.mts +21 -0
  55. package/dist/db/schema/verification.mjs +10 -0
  56. package/dist/db/type.d.mts +194 -0
  57. package/dist/env/color-depth.d.mts +4 -0
  58. package/dist/env/color-depth.mjs +86 -0
  59. package/dist/env/env-impl.d.mts +32 -0
  60. package/dist/env/env-impl.mjs +81 -0
  61. package/dist/env/index.d.mts +4 -0
  62. package/dist/env/index.mjs +4 -0
  63. package/dist/env/logger.d.mts +48 -0
  64. package/dist/env/logger.mjs +79 -0
  65. package/dist/error/codes.d.mts +69 -0
  66. package/dist/error/codes.mjs +55 -0
  67. package/dist/error/index.d.mts +26 -0
  68. package/dist/error/index.mjs +27 -0
  69. package/dist/index.d.mts +9 -0
  70. package/dist/index.mjs +1 -0
  71. package/dist/instrumentation/api.mjs +12 -0
  72. package/dist/instrumentation/attributes.d.mts +11 -0
  73. package/dist/instrumentation/attributes.mjs +10 -0
  74. package/dist/instrumentation/index.d.mts +3 -0
  75. package/dist/instrumentation/index.mjs +3 -0
  76. package/dist/instrumentation/noop.mjs +42 -0
  77. package/dist/instrumentation/pure.index.d.mts +7 -0
  78. package/dist/instrumentation/pure.index.mjs +7 -0
  79. package/dist/instrumentation/tracer.d.mts +13 -0
  80. package/dist/instrumentation/tracer.mjs +53 -0
  81. package/dist/oauth2/client-credentials-token.d.mts +56 -0
  82. package/dist/oauth2/client-credentials-token.mjs +64 -0
  83. package/dist/oauth2/create-authorization-url.d.mts +44 -0
  84. package/dist/oauth2/create-authorization-url.mjs +41 -0
  85. package/dist/oauth2/index.d.mts +8 -0
  86. package/dist/oauth2/index.mjs +7 -0
  87. package/dist/oauth2/oauth-provider.d.mts +192 -0
  88. package/dist/oauth2/refresh-access-token.d.mts +54 -0
  89. package/dist/oauth2/refresh-access-token.mjs +73 -0
  90. package/dist/oauth2/reject-redirects.mjs +60 -0
  91. package/dist/oauth2/utils.d.mts +24 -0
  92. package/dist/oauth2/utils.mjs +48 -0
  93. package/dist/oauth2/validate-authorization-code.d.mts +85 -0
  94. package/dist/oauth2/validate-authorization-code.mjs +86 -0
  95. package/dist/oauth2/verify.d.mts +65 -0
  96. package/dist/oauth2/verify.mjs +202 -0
  97. package/dist/social-providers/apple.d.mts +133 -0
  98. package/dist/social-providers/apple.mjs +117 -0
  99. package/dist/social-providers/atlassian.d.mts +70 -0
  100. package/dist/social-providers/atlassian.mjs +80 -0
  101. package/dist/social-providers/cognito.d.mts +85 -0
  102. package/dist/social-providers/cognito.mjs +162 -0
  103. package/dist/social-providers/discord.d.mts +124 -0
  104. package/dist/social-providers/discord.mjs +62 -0
  105. package/dist/social-providers/dropbox.d.mts +69 -0
  106. package/dist/social-providers/dropbox.mjs +72 -0
  107. package/dist/social-providers/facebook.d.mts +79 -0
  108. package/dist/social-providers/facebook.mjs +157 -0
  109. package/dist/social-providers/figma.d.mts +61 -0
  110. package/dist/social-providers/figma.mjs +83 -0
  111. package/dist/social-providers/github.d.mts +102 -0
  112. package/dist/social-providers/github.mjs +92 -0
  113. package/dist/social-providers/gitlab.d.mts +123 -0
  114. package/dist/social-providers/gitlab.mjs +79 -0
  115. package/dist/social-providers/google.d.mts +123 -0
  116. package/dist/social-providers/google.mjs +137 -0
  117. package/dist/social-providers/huggingface.d.mts +83 -0
  118. package/dist/social-providers/huggingface.mjs +73 -0
  119. package/dist/social-providers/index.d.mts +1834 -0
  120. package/dist/social-providers/index.mjs +78 -0
  121. package/dist/social-providers/kakao.d.mts +161 -0
  122. package/dist/social-providers/kakao.mjs +70 -0
  123. package/dist/social-providers/kick.d.mts +73 -0
  124. package/dist/social-providers/kick.mjs +68 -0
  125. package/dist/social-providers/line.d.mts +105 -0
  126. package/dist/social-providers/line.mjs +110 -0
  127. package/dist/social-providers/linear.d.mts +68 -0
  128. package/dist/social-providers/linear.mjs +85 -0
  129. package/dist/social-providers/linkedin.d.mts +67 -0
  130. package/dist/social-providers/linkedin.mjs +73 -0
  131. package/dist/social-providers/microsoft-entra-id.d.mts +174 -0
  132. package/dist/social-providers/microsoft-entra-id.mjs +152 -0
  133. package/dist/social-providers/naver.d.mts +92 -0
  134. package/dist/social-providers/naver.mjs +65 -0
  135. package/dist/social-providers/notion.d.mts +64 -0
  136. package/dist/social-providers/notion.mjs +72 -0
  137. package/dist/social-providers/paybin.d.mts +71 -0
  138. package/dist/social-providers/paybin.mjs +81 -0
  139. package/dist/social-providers/paypal.d.mts +131 -0
  140. package/dist/social-providers/paypal.mjs +188 -0
  141. package/dist/social-providers/polar.d.mts +74 -0
  142. package/dist/social-providers/polar.mjs +71 -0
  143. package/dist/social-providers/railway.d.mts +65 -0
  144. package/dist/social-providers/railway.mjs +74 -0
  145. package/dist/social-providers/reddit.d.mts +62 -0
  146. package/dist/social-providers/reddit.mjs +81 -0
  147. package/dist/social-providers/roblox.d.mts +70 -0
  148. package/dist/social-providers/roblox.mjs +57 -0
  149. package/dist/social-providers/salesforce.d.mts +79 -0
  150. package/dist/social-providers/salesforce.mjs +87 -0
  151. package/dist/social-providers/slack.d.mts +83 -0
  152. package/dist/social-providers/slack.mjs +66 -0
  153. package/dist/social-providers/spotify.d.mts +63 -0
  154. package/dist/social-providers/spotify.mjs +69 -0
  155. package/dist/social-providers/tiktok.d.mts +168 -0
  156. package/dist/social-providers/tiktok.mjs +60 -0
  157. package/dist/social-providers/twitch.d.mts +79 -0
  158. package/dist/social-providers/twitch.mjs +75 -0
  159. package/dist/social-providers/twitter.d.mts +126 -0
  160. package/dist/social-providers/twitter.mjs +85 -0
  161. package/dist/social-providers/vercel.d.mts +62 -0
  162. package/dist/social-providers/vercel.mjs +58 -0
  163. package/dist/social-providers/vk.d.mts +70 -0
  164. package/dist/social-providers/vk.mjs +81 -0
  165. package/dist/social-providers/wechat.d.mts +113 -0
  166. package/dist/social-providers/wechat.mjs +81 -0
  167. package/dist/social-providers/zoom.d.mts +163 -0
  168. package/dist/social-providers/zoom.mjs +69 -0
  169. package/dist/types/context.d.mts +319 -0
  170. package/dist/types/cookie.d.mts +15 -0
  171. package/dist/types/helper.d.mts +10 -0
  172. package/dist/types/index.d.mts +9 -0
  173. package/dist/types/init-options.d.mts +1430 -0
  174. package/dist/types/plugin-client.d.mts +123 -0
  175. package/dist/types/plugin.d.mts +124 -0
  176. package/dist/types/secret.d.mts +11 -0
  177. package/dist/utils/async.d.mts +22 -0
  178. package/dist/utils/async.mjs +32 -0
  179. package/dist/utils/db.d.mts +9 -0
  180. package/dist/utils/db.mjs +15 -0
  181. package/dist/utils/deprecate.d.mts +9 -0
  182. package/dist/utils/deprecate.mjs +16 -0
  183. package/dist/utils/error-codes.d.mts +13 -0
  184. package/dist/utils/error-codes.mjs +10 -0
  185. package/dist/utils/fetch-metadata.d.mts +4 -0
  186. package/dist/utils/fetch-metadata.mjs +6 -0
  187. package/dist/utils/host.d.mts +147 -0
  188. package/dist/utils/host.mjs +295 -0
  189. package/dist/utils/id.d.mts +4 -0
  190. package/dist/utils/id.mjs +7 -0
  191. package/dist/utils/ip.d.mts +77 -0
  192. package/dist/utils/ip.mjs +230 -0
  193. package/dist/utils/is-api-error.d.mts +6 -0
  194. package/dist/utils/is-api-error.mjs +8 -0
  195. package/dist/utils/json.d.mts +4 -0
  196. package/dist/utils/json.mjs +41 -0
  197. package/dist/utils/redirect-uri.d.mts +20 -0
  198. package/dist/utils/redirect-uri.mjs +48 -0
  199. package/dist/utils/string.d.mts +8 -0
  200. package/dist/utils/string.mjs +25 -0
  201. package/dist/utils/url.d.mts +37 -0
  202. package/dist/utils/url.mjs +61 -0
  203. package/package.json +216 -0
  204. package/src/api/index.ts +185 -0
  205. package/src/async_hooks/index.ts +40 -0
  206. package/src/async_hooks/pure.index.ts +46 -0
  207. package/src/context/endpoint-context.ts +50 -0
  208. package/src/context/global.ts +57 -0
  209. package/src/context/index.ts +23 -0
  210. package/src/context/request-state.ts +91 -0
  211. package/src/context/transaction.ts +169 -0
  212. package/src/db/adapter/factory.ts +1740 -0
  213. package/src/db/adapter/get-default-field-name.ts +59 -0
  214. package/src/db/adapter/get-default-model-name.ts +51 -0
  215. package/src/db/adapter/get-field-attributes.ts +62 -0
  216. package/src/db/adapter/get-field-name.ts +43 -0
  217. package/src/db/adapter/get-id-field.ts +150 -0
  218. package/src/db/adapter/get-model-name.ts +36 -0
  219. package/src/db/adapter/index.ts +656 -0
  220. package/src/db/adapter/types.ts +134 -0
  221. package/src/db/adapter/utils.ts +61 -0
  222. package/src/db/get-tables.ts +304 -0
  223. package/src/db/index.ts +43 -0
  224. package/src/db/plugin.ts +11 -0
  225. package/src/db/schema/account.ts +47 -0
  226. package/src/db/schema/rate-limit.ts +36 -0
  227. package/src/db/schema/session.ts +29 -0
  228. package/src/db/schema/shared.ts +7 -0
  229. package/src/db/schema/user.ts +31 -0
  230. package/src/db/schema/verification.ts +28 -0
  231. package/src/db/type.ts +360 -0
  232. package/src/env/color-depth.ts +172 -0
  233. package/src/env/env-impl.ts +123 -0
  234. package/src/env/index.ts +23 -0
  235. package/src/env/logger.ts +145 -0
  236. package/src/error/codes.ts +72 -0
  237. package/src/error/index.ts +44 -0
  238. package/src/index.ts +1 -0
  239. package/src/instrumentation/api.ts +17 -0
  240. package/src/instrumentation/attributes.ts +22 -0
  241. package/src/instrumentation/index.ts +2 -0
  242. package/src/instrumentation/noop.ts +74 -0
  243. package/src/instrumentation/pure.index.ts +31 -0
  244. package/src/instrumentation/tracer.ts +95 -0
  245. package/src/oauth2/client-credentials-token.ts +126 -0
  246. package/src/oauth2/create-authorization-url.ts +89 -0
  247. package/src/oauth2/index.ts +34 -0
  248. package/src/oauth2/oauth-provider.ts +222 -0
  249. package/src/oauth2/refresh-access-token.ts +157 -0
  250. package/src/oauth2/reject-redirects.ts +70 -0
  251. package/src/oauth2/utils.ts +70 -0
  252. package/src/oauth2/validate-authorization-code.ts +190 -0
  253. package/src/oauth2/verify.ts +408 -0
  254. package/src/social-providers/apple.ts +249 -0
  255. package/src/social-providers/atlassian.ts +133 -0
  256. package/src/social-providers/cognito.ts +281 -0
  257. package/src/social-providers/discord.ts +170 -0
  258. package/src/social-providers/dropbox.ts +112 -0
  259. package/src/social-providers/facebook.ts +288 -0
  260. package/src/social-providers/figma.ts +118 -0
  261. package/src/social-providers/github.ts +184 -0
  262. package/src/social-providers/gitlab.ts +155 -0
  263. package/src/social-providers/google.ts +263 -0
  264. package/src/social-providers/huggingface.ts +119 -0
  265. package/src/social-providers/index.ts +132 -0
  266. package/src/social-providers/kakao.ts +179 -0
  267. package/src/social-providers/kick.ts +109 -0
  268. package/src/social-providers/line.ts +169 -0
  269. package/src/social-providers/linear.ts +121 -0
  270. package/src/social-providers/linkedin.ts +110 -0
  271. package/src/social-providers/microsoft-entra-id.ts +391 -0
  272. package/src/social-providers/naver.ts +113 -0
  273. package/src/social-providers/notion.ts +108 -0
  274. package/src/social-providers/paybin.ts +118 -0
  275. package/src/social-providers/paypal.ts +371 -0
  276. package/src/social-providers/polar.ts +111 -0
  277. package/src/social-providers/railway.ts +100 -0
  278. package/src/social-providers/reddit.ts +126 -0
  279. package/src/social-providers/roblox.ts +112 -0
  280. package/src/social-providers/salesforce.ts +159 -0
  281. package/src/social-providers/slack.ts +112 -0
  282. package/src/social-providers/spotify.ts +94 -0
  283. package/src/social-providers/tiktok.ts +211 -0
  284. package/src/social-providers/twitch.ts +112 -0
  285. package/src/social-providers/twitter.ts +199 -0
  286. package/src/social-providers/vercel.ts +87 -0
  287. package/src/social-providers/vk.ts +125 -0
  288. package/src/social-providers/wechat.ts +220 -0
  289. package/src/social-providers/zoom.ts +230 -0
  290. package/src/types/context.ts +460 -0
  291. package/src/types/cookie.ts +10 -0
  292. package/src/types/helper.ts +27 -0
  293. package/src/types/index.ts +40 -0
  294. package/src/types/init-options.ts +1679 -0
  295. package/src/types/plugin-client.ts +143 -0
  296. package/src/types/plugin.ts +163 -0
  297. package/src/types/secret.ts +8 -0
  298. package/src/utils/async.ts +53 -0
  299. package/src/utils/db.ts +20 -0
  300. package/src/utils/deprecate.ts +21 -0
  301. package/src/utils/error-codes.ts +68 -0
  302. package/src/utils/fetch-metadata.ts +3 -0
  303. package/src/utils/host.ts +416 -0
  304. package/src/utils/id.ts +5 -0
  305. package/src/utils/ip.ts +395 -0
  306. package/src/utils/is-api-error.ts +10 -0
  307. package/src/utils/json.ts +56 -0
  308. package/src/utils/redirect-uri.ts +54 -0
  309. package/src/utils/string.ts +40 -0
  310. package/src/utils/url.ts +77 -0
@@ -0,0 +1,68 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ //#region src/social-providers/linear.d.ts
3
+ interface LinearUser {
4
+ id: string;
5
+ name: string;
6
+ email: string;
7
+ avatarUrl?: string | undefined;
8
+ active: boolean;
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ }
12
+ interface LinearProfile {
13
+ data: {
14
+ viewer: LinearUser;
15
+ };
16
+ }
17
+ interface LinearOptions extends ProviderOptions<LinearUser> {
18
+ clientId: string;
19
+ }
20
+ declare const linear: (options: LinearOptions) => {
21
+ id: "linear";
22
+ name: string;
23
+ createAuthorizationURL({
24
+ state,
25
+ scopes,
26
+ loginHint,
27
+ redirectURI
28
+ }: {
29
+ state: string;
30
+ codeVerifier: string;
31
+ scopes?: string[] | undefined;
32
+ redirectURI: string;
33
+ display?: string | undefined;
34
+ loginHint?: string | undefined;
35
+ }): Promise<URL>;
36
+ validateAuthorizationCode: ({
37
+ code,
38
+ redirectURI
39
+ }: {
40
+ code: string;
41
+ redirectURI: string;
42
+ codeVerifier?: string | undefined;
43
+ deviceId?: string | undefined;
44
+ }) => Promise<OAuth2Tokens>;
45
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
46
+ getUserInfo(token: OAuth2Tokens & {
47
+ user?: {
48
+ name?: {
49
+ firstName?: string;
50
+ lastName?: string;
51
+ };
52
+ email?: string;
53
+ } | undefined;
54
+ }): Promise<{
55
+ user: {
56
+ id: string;
57
+ name?: string;
58
+ email?: string | null;
59
+ image?: string;
60
+ emailVerified: boolean;
61
+ [key: string]: any;
62
+ };
63
+ data: any;
64
+ } | null>;
65
+ options: LinearOptions;
66
+ };
67
+ //#endregion
68
+ export { LinearOptions, LinearProfile, LinearUser, linear };
@@ -0,0 +1,85 @@
1
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
2
+ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
3
+ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
4
+ import { betterFetch } from "@better-fetch/fetch";
5
+ //#region src/social-providers/linear.ts
6
+ const linear = (options) => {
7
+ const tokenEndpoint = "https://api.linear.app/oauth/token";
8
+ return {
9
+ id: "linear",
10
+ name: "Linear",
11
+ createAuthorizationURL({ state, scopes, loginHint, redirectURI }) {
12
+ const _scopes = options.disableDefaultScope ? [] : ["read"];
13
+ if (options.scope) _scopes.push(...options.scope);
14
+ if (scopes) _scopes.push(...scopes);
15
+ return createAuthorizationURL({
16
+ id: "linear",
17
+ options,
18
+ authorizationEndpoint: "https://linear.app/oauth/authorize",
19
+ scopes: _scopes,
20
+ state,
21
+ redirectURI,
22
+ loginHint
23
+ });
24
+ },
25
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
26
+ return validateAuthorizationCode({
27
+ code,
28
+ redirectURI,
29
+ options,
30
+ tokenEndpoint
31
+ });
32
+ },
33
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
34
+ return refreshAccessToken({
35
+ refreshToken,
36
+ options: {
37
+ clientId: options.clientId,
38
+ clientKey: options.clientKey,
39
+ clientSecret: options.clientSecret
40
+ },
41
+ tokenEndpoint
42
+ });
43
+ },
44
+ async getUserInfo(token) {
45
+ if (options.getUserInfo) return options.getUserInfo(token);
46
+ const { data: profile, error } = await betterFetch("https://api.linear.app/graphql", {
47
+ method: "POST",
48
+ headers: {
49
+ "Content-Type": "application/json",
50
+ Authorization: `Bearer ${token.accessToken}`
51
+ },
52
+ body: JSON.stringify({ query: `
53
+ query {
54
+ viewer {
55
+ id
56
+ name
57
+ email
58
+ avatarUrl
59
+ active
60
+ createdAt
61
+ updatedAt
62
+ }
63
+ }
64
+ ` })
65
+ });
66
+ if (error || !profile?.data?.viewer) return null;
67
+ const userData = profile.data.viewer;
68
+ const userMap = await options.mapProfileToUser?.(userData);
69
+ return {
70
+ user: {
71
+ id: profile.data.viewer.id,
72
+ name: profile.data.viewer.name,
73
+ email: profile.data.viewer.email,
74
+ image: profile.data.viewer.avatarUrl,
75
+ emailVerified: false,
76
+ ...userMap
77
+ },
78
+ data: userData
79
+ };
80
+ },
81
+ options
82
+ };
83
+ };
84
+ //#endregion
85
+ export { linear };
@@ -0,0 +1,67 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ //#region src/social-providers/linkedin.d.ts
3
+ interface LinkedInProfile {
4
+ sub: string;
5
+ name: string;
6
+ given_name: string;
7
+ family_name: string;
8
+ picture: string;
9
+ locale: {
10
+ country: string;
11
+ language: string;
12
+ };
13
+ email?: string;
14
+ email_verified?: boolean;
15
+ }
16
+ interface LinkedInOptions extends ProviderOptions<LinkedInProfile> {
17
+ clientId: string;
18
+ }
19
+ declare const linkedin: (options: LinkedInOptions) => {
20
+ id: "linkedin";
21
+ name: string;
22
+ createAuthorizationURL: ({
23
+ state,
24
+ scopes,
25
+ redirectURI,
26
+ loginHint
27
+ }: {
28
+ state: string;
29
+ codeVerifier: string;
30
+ scopes?: string[] | undefined;
31
+ redirectURI: string;
32
+ display?: string | undefined;
33
+ loginHint?: string | undefined;
34
+ }) => Promise<URL>;
35
+ validateAuthorizationCode: ({
36
+ code,
37
+ redirectURI
38
+ }: {
39
+ code: string;
40
+ redirectURI: string;
41
+ codeVerifier?: string | undefined;
42
+ deviceId?: string | undefined;
43
+ }) => Promise<OAuth2Tokens>;
44
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
45
+ getUserInfo(token: OAuth2Tokens & {
46
+ user?: {
47
+ name?: {
48
+ firstName?: string;
49
+ lastName?: string;
50
+ };
51
+ email?: string;
52
+ } | undefined;
53
+ }): Promise<{
54
+ user: {
55
+ id: string;
56
+ name?: string;
57
+ email?: string | null;
58
+ image?: string;
59
+ emailVerified: boolean;
60
+ [key: string]: any;
61
+ };
62
+ data: any;
63
+ } | null>;
64
+ options: LinkedInOptions;
65
+ };
66
+ //#endregion
67
+ export { LinkedInOptions, LinkedInProfile, linkedin };
@@ -0,0 +1,73 @@
1
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
2
+ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
3
+ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
4
+ import { betterFetch } from "@better-fetch/fetch";
5
+ //#region src/social-providers/linkedin.ts
6
+ const linkedin = (options) => {
7
+ const authorizationEndpoint = "https://www.linkedin.com/oauth/v2/authorization";
8
+ const tokenEndpoint = "https://www.linkedin.com/oauth/v2/accessToken";
9
+ return {
10
+ id: "linkedin",
11
+ name: "Linkedin",
12
+ createAuthorizationURL: async ({ state, scopes, redirectURI, loginHint }) => {
13
+ const _scopes = options.disableDefaultScope ? [] : [
14
+ "profile",
15
+ "email",
16
+ "openid"
17
+ ];
18
+ if (options.scope) _scopes.push(...options.scope);
19
+ if (scopes) _scopes.push(...scopes);
20
+ return await createAuthorizationURL({
21
+ id: "linkedin",
22
+ options,
23
+ authorizationEndpoint,
24
+ scopes: _scopes,
25
+ state,
26
+ loginHint,
27
+ redirectURI
28
+ });
29
+ },
30
+ validateAuthorizationCode: async ({ code, redirectURI }) => {
31
+ return await validateAuthorizationCode({
32
+ code,
33
+ redirectURI,
34
+ options,
35
+ tokenEndpoint
36
+ });
37
+ },
38
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
39
+ return refreshAccessToken({
40
+ refreshToken,
41
+ options: {
42
+ clientId: options.clientId,
43
+ clientKey: options.clientKey,
44
+ clientSecret: options.clientSecret
45
+ },
46
+ tokenEndpoint
47
+ });
48
+ },
49
+ async getUserInfo(token) {
50
+ if (options.getUserInfo) return options.getUserInfo(token);
51
+ const { data: profile, error } = await betterFetch("https://api.linkedin.com/v2/userinfo", {
52
+ method: "GET",
53
+ headers: { Authorization: `Bearer ${token.accessToken}` }
54
+ });
55
+ if (error) return null;
56
+ const userMap = await options.mapProfileToUser?.(profile);
57
+ return {
58
+ user: {
59
+ id: profile.sub,
60
+ name: profile.name,
61
+ email: profile.email,
62
+ emailVerified: profile.email_verified ?? false,
63
+ image: profile.picture,
64
+ ...userMap
65
+ },
66
+ data: profile
67
+ };
68
+ },
69
+ options
70
+ };
71
+ };
72
+ //#endregion
73
+ export { linkedin };
@@ -0,0 +1,174 @@
1
+ import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
2
+ //#region src/social-providers/microsoft-entra-id.d.ts
3
+ /**
4
+ * @see [Microsoft Identity Platform - Optional claims reference](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims-reference)
5
+ */
6
+ interface MicrosoftEntraIDProfile extends Record<string, any> {
7
+ /** Identifies the intended recipient of the token */
8
+ aud: string;
9
+ /** Identifies the issuer, or "authorization server" that constructs and returns the token */
10
+ iss: string;
11
+ /** Indicates when the authentication for the token occurred */
12
+ iat: Date;
13
+ /** Records the identity provider that authenticated the subject of the token */
14
+ idp: string;
15
+ /** Identifies the time before which the JWT can't be accepted for processing */
16
+ nbf: Date;
17
+ /** Identifies the expiration time on or after which the JWT can't be accepted for processing */
18
+ exp: Date;
19
+ /** Code hash included in ID tokens when issued with an OAuth 2.0 authorization code */
20
+ c_hash: string;
21
+ /** Access token hash included in ID tokens when issued with an OAuth 2.0 access token */
22
+ at_hash: string;
23
+ /** Internal claim used to record data for token reuse */
24
+ aio: string;
25
+ /** The primary username that represents the user */
26
+ preferred_username: string;
27
+ /** User's email address */
28
+ email?: string;
29
+ /** Human-readable value that identifies the subject of the token */
30
+ name: string;
31
+ /** Matches the parameter included in the original authorize request */
32
+ nonce: string;
33
+ /** User's profile picture */
34
+ picture: string;
35
+ /** Immutable identifier for the user account */
36
+ oid: string;
37
+ /** Set of roles assigned to the user */
38
+ roles: string[];
39
+ /** Internal claim used to revalidate tokens */
40
+ rh: string;
41
+ /** Subject identifier - unique to application ID */
42
+ sub: string;
43
+ /** Tenant ID the user is signing in to */
44
+ tid: string;
45
+ /** Unique identifier for a session */
46
+ sid: string;
47
+ /** Token identifier claim */
48
+ uti: string;
49
+ /** Indicates if user is in at least one group */
50
+ hasgroups: boolean;
51
+ /** User account status in tenant (0 = member, 1 = guest) */
52
+ acct: 0 | 1;
53
+ /** Auth Context IDs */
54
+ acrs: string;
55
+ /** Time when the user last authenticated */
56
+ auth_time: Date;
57
+ /** User's country/region */
58
+ ctry: string;
59
+ /** IP address of requesting client when inside VNET */
60
+ fwd: string;
61
+ /** Group claims */
62
+ groups: string;
63
+ /** Login hint for SSO */
64
+ login_hint: string;
65
+ /** Resource tenant's country/region */
66
+ tenant_ctry: string;
67
+ /** Region of the resource tenant */
68
+ tenant_region_scope: string;
69
+ /** UserPrincipalName */
70
+ upn: string;
71
+ /** User's verified primary email addresses */
72
+ verified_primary_email: string[];
73
+ /** User's verified secondary email addresses */
74
+ verified_secondary_email: string[];
75
+ /** Whether the user's email is verified (optional claim, must be configured in app registration) */
76
+ email_verified?: boolean | undefined;
77
+ /** VNET specifier information */
78
+ vnet: string;
79
+ /** Client Capabilities */
80
+ xms_cc: string;
81
+ /** Whether user's email domain is verified */
82
+ xms_edov: boolean;
83
+ /** Preferred data location for Multi-Geo tenants */
84
+ xms_pdl: string;
85
+ /** User preferred language */
86
+ xms_pl: string;
87
+ /** Tenant preferred language */
88
+ xms_tpl: string;
89
+ /** Zero-touch Deployment ID */
90
+ ztdid: string;
91
+ /** IP Address */
92
+ ipaddr: string;
93
+ /** On-premises Security Identifier */
94
+ onprem_sid: string;
95
+ /** Password Expiration Time */
96
+ pwd_exp: number;
97
+ /** Change Password URL */
98
+ pwd_url: string;
99
+ /** Inside Corporate Network flag */
100
+ in_corp: string;
101
+ /** User's family name/surname */
102
+ family_name: string;
103
+ /** User's given/first name */
104
+ given_name: string;
105
+ }
106
+ interface MicrosoftOptions extends ProviderOptions<MicrosoftEntraIDProfile> {
107
+ clientId: string | string[];
108
+ /**
109
+ * The tenant ID of the Microsoft account
110
+ * @default "common"
111
+ */
112
+ tenantId?: string | undefined;
113
+ /**
114
+ * The authentication authority URL. Use the default "https://login.microsoftonline.com" for standard Entra ID or "https://<tenant-id>.ciamlogin.com" for CIAM scenarios.
115
+ * @default "https://login.microsoftonline.com"
116
+ */
117
+ authority?: string | undefined;
118
+ /**
119
+ * The size of the profile photo
120
+ * @default 48
121
+ */
122
+ profilePhotoSize?: (48 | 64 | 96 | 120 | 240 | 360 | 432 | 504 | 648) | undefined;
123
+ /**
124
+ * Disable profile photo
125
+ */
126
+ disableProfilePhoto?: boolean | undefined;
127
+ }
128
+ declare const microsoft: (options: MicrosoftOptions) => {
129
+ id: "microsoft";
130
+ name: string;
131
+ createAuthorizationURL(data: {
132
+ state: string;
133
+ codeVerifier: string;
134
+ scopes?: string[] | undefined;
135
+ redirectURI: string;
136
+ display?: string | undefined;
137
+ loginHint?: string | undefined;
138
+ }): Promise<URL>;
139
+ validateAuthorizationCode({
140
+ code,
141
+ codeVerifier,
142
+ redirectURI
143
+ }: {
144
+ code: string;
145
+ redirectURI: string;
146
+ codeVerifier?: string | undefined;
147
+ deviceId?: string | undefined;
148
+ }): Promise<OAuth2Tokens>;
149
+ verifyIdToken(token: string, nonce: string | undefined): Promise<boolean>;
150
+ getUserInfo(token: OAuth2Tokens & {
151
+ user?: {
152
+ name?: {
153
+ firstName?: string;
154
+ lastName?: string;
155
+ };
156
+ email?: string;
157
+ } | undefined;
158
+ }): Promise<{
159
+ user: {
160
+ id: string;
161
+ name?: string;
162
+ email?: string | null;
163
+ image?: string;
164
+ emailVerified: boolean;
165
+ [key: string]: any;
166
+ };
167
+ data: any;
168
+ } | null>;
169
+ refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
170
+ options: MicrosoftOptions;
171
+ };
172
+ declare const getMicrosoftPublicKey: (kid: string, tenant: string, authority: string) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
173
+ //#endregion
174
+ export { MicrosoftEntraIDProfile, MicrosoftOptions, getMicrosoftPublicKey, microsoft };
@@ -0,0 +1,152 @@
1
+ import { APIError, BetterAuthError } from "../error/index.mjs";
2
+ import { logger } from "../env/logger.mjs";
3
+ import { getPrimaryClientId } from "../oauth2/utils.mjs";
4
+ import { createAuthorizationURL } from "../oauth2/create-authorization-url.mjs";
5
+ import { refreshAccessToken } from "../oauth2/refresh-access-token.mjs";
6
+ import { validateAuthorizationCode } from "../oauth2/validate-authorization-code.mjs";
7
+ import { base64 } from "@better-auth/utils/base64";
8
+ import { betterFetch } from "@better-fetch/fetch";
9
+ import { decodeJwt, decodeProtectedHeader, importJWK, jwtVerify } from "jose";
10
+ //#region src/social-providers/microsoft-entra-id.ts
11
+ /**
12
+ * Microsoft's fixed tenant id for personal (consumer) Microsoft accounts. Every
13
+ * personal-account token carries it as the `tid` claim, so it distinguishes the
14
+ * consumer account class from work/school tenants.
15
+ * @see https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference
16
+ */
17
+ const MICROSOFT_CONSUMER_TENANT_ID = "9188040d-6c67-4c5b-b112-36a304b66dad";
18
+ const microsoft = (options) => {
19
+ const tenant = options.tenantId || "common";
20
+ let authority = options.authority || "https://login.microsoftonline.com";
21
+ while (authority.endsWith("/")) authority = authority.slice(0, -1);
22
+ const authorizationEndpoint = `${authority}/${tenant}/oauth2/v2.0/authorize`;
23
+ const tokenEndpoint = `${authority}/${tenant}/oauth2/v2.0/token`;
24
+ return {
25
+ id: "microsoft",
26
+ name: "Microsoft EntraID",
27
+ createAuthorizationURL(data) {
28
+ if (!getPrimaryClientId(options.clientId)) {
29
+ logger.error("Client Id is required for Microsoft Entra ID. Make sure to provide it in the options.");
30
+ throw new BetterAuthError("CLIENT_ID_AND_SECRET_REQUIRED");
31
+ }
32
+ const scopes = options.disableDefaultScope ? [] : [
33
+ "openid",
34
+ "profile",
35
+ "email",
36
+ "User.Read",
37
+ "offline_access"
38
+ ];
39
+ if (options.scope) scopes.push(...options.scope);
40
+ if (data.scopes) scopes.push(...data.scopes);
41
+ return createAuthorizationURL({
42
+ id: "microsoft",
43
+ options,
44
+ authorizationEndpoint,
45
+ state: data.state,
46
+ codeVerifier: data.codeVerifier,
47
+ scopes,
48
+ redirectURI: data.redirectURI,
49
+ prompt: options.prompt,
50
+ loginHint: data.loginHint
51
+ });
52
+ },
53
+ validateAuthorizationCode({ code, codeVerifier, redirectURI }) {
54
+ return validateAuthorizationCode({
55
+ code,
56
+ codeVerifier,
57
+ redirectURI,
58
+ options,
59
+ tokenEndpoint
60
+ });
61
+ },
62
+ async verifyIdToken(token, nonce) {
63
+ if (options.disableIdTokenSignIn) return false;
64
+ if (options.verifyIdToken) return options.verifyIdToken(token, nonce);
65
+ try {
66
+ const { kid, alg: jwtAlg } = decodeProtectedHeader(token);
67
+ if (!kid || !jwtAlg) return false;
68
+ const publicKey = await getMicrosoftPublicKey(kid, tenant, authority);
69
+ const verifyOptions = {
70
+ algorithms: [jwtAlg],
71
+ audience: options.clientId,
72
+ maxTokenAge: "1h"
73
+ };
74
+ /**
75
+ * Issuer varies per user's tenant for multi-tenant endpoints, so only validate for specific tenants.
76
+ * @see https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols#endpoints
77
+ */
78
+ if (tenant !== "common" && tenant !== "organizations" && tenant !== "consumers") verifyOptions.issuer = `${authority}/${tenant}/v2.0`;
79
+ const { payload: jwtClaims } = await jwtVerify(token, publicKey, verifyOptions);
80
+ if (nonce && jwtClaims.nonce !== nonce) return false;
81
+ const tid = jwtClaims.tid;
82
+ if (typeof tid !== "string" || jwtClaims.iss !== `${authority}/${tid}/v2.0`) return false;
83
+ if (tenant === "organizations" && tid === MICROSOFT_CONSUMER_TENANT_ID) return false;
84
+ if (tenant === "consumers" && tid !== MICROSOFT_CONSUMER_TENANT_ID) return false;
85
+ return true;
86
+ } catch (error) {
87
+ logger.error("Failed to verify ID token:", error);
88
+ return false;
89
+ }
90
+ },
91
+ async getUserInfo(token) {
92
+ if (options.getUserInfo) return options.getUserInfo(token);
93
+ if (!token.idToken) return null;
94
+ const user = decodeJwt(token.idToken);
95
+ const profilePhotoSize = options.profilePhotoSize || 48;
96
+ await betterFetch(`https://graph.microsoft.com/v1.0/me/photos/${profilePhotoSize}x${profilePhotoSize}/$value`, {
97
+ headers: { Authorization: `Bearer ${token.accessToken}` },
98
+ async onResponse(context) {
99
+ if (options.disableProfilePhoto || !context.response.ok) return;
100
+ try {
101
+ const pictureBuffer = await context.response.clone().arrayBuffer();
102
+ user.picture = `data:image/jpeg;base64, ${base64.encode(pictureBuffer)}`;
103
+ } catch (e) {
104
+ logger.error(e && typeof e === "object" && "name" in e ? e.name : "", e);
105
+ }
106
+ }
107
+ });
108
+ const userMap = await options.mapProfileToUser?.(user);
109
+ const emailVerified = user.email_verified !== void 0 ? user.email_verified : user.email && (user.verified_primary_email?.includes(user.email) || user.verified_secondary_email?.includes(user.email)) ? true : false;
110
+ return {
111
+ user: {
112
+ id: user.sub,
113
+ name: user.name,
114
+ email: user.email,
115
+ image: user.picture,
116
+ emailVerified,
117
+ ...userMap
118
+ },
119
+ data: user
120
+ };
121
+ },
122
+ refreshAccessToken: options.refreshAccessToken ? options.refreshAccessToken : async (refreshToken) => {
123
+ const scopes = options.disableDefaultScope ? [] : [
124
+ "openid",
125
+ "profile",
126
+ "email",
127
+ "User.Read",
128
+ "offline_access"
129
+ ];
130
+ if (options.scope) scopes.push(...options.scope);
131
+ return refreshAccessToken({
132
+ refreshToken,
133
+ options: {
134
+ clientId: options.clientId,
135
+ clientSecret: options.clientSecret
136
+ },
137
+ extraParams: { scope: scopes.join(" ") },
138
+ tokenEndpoint
139
+ });
140
+ },
141
+ options
142
+ };
143
+ };
144
+ const getMicrosoftPublicKey = async (kid, tenant, authority) => {
145
+ const { data } = await betterFetch(`${authority}/${tenant}/discovery/v2.0/keys`);
146
+ if (!data?.keys) throw new APIError("BAD_REQUEST", { message: "Keys not found" });
147
+ const jwk = data.keys.find((key) => key.kid === kid);
148
+ if (!jwk) throw new Error(`JWK with kid ${kid} not found`);
149
+ return await importJWK(jwk, jwk.alg);
150
+ };
151
+ //#endregion
152
+ export { getMicrosoftPublicKey, microsoft };