@mulverse/mulguard-core 1.0.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 (600) hide show
  1. package/README.md +24 -0
  2. package/adapters.d.ts +522 -0
  3. package/adapters.d.ts.map +1 -0
  4. package/adapters.js +170 -0
  5. package/errors.d.ts +429 -0
  6. package/errors.d.ts.map +1 -0
  7. package/errors.js +473 -0
  8. package/index.d.ts +547 -0
  9. package/index.d.ts.map +1 -0
  10. package/index.js +142 -0
  11. package/jwt.d.ts +132 -0
  12. package/jwt.d.ts.map +1 -0
  13. package/jwt.js +123 -0
  14. package/lib/actions/callback/handle-login.d.ts +35 -0
  15. package/lib/actions/callback/handle-login.d.ts.map +1 -0
  16. package/lib/actions/callback/handle-login.js +275 -0
  17. package/lib/actions/callback/index.d.ts +5 -0
  18. package/lib/actions/callback/index.d.ts.map +1 -0
  19. package/lib/actions/callback/index.js +409 -0
  20. package/lib/actions/callback/oauth/callback.d.ts +36 -0
  21. package/lib/actions/callback/oauth/callback.d.ts.map +1 -0
  22. package/lib/actions/callback/oauth/callback.js +248 -0
  23. package/lib/actions/callback/oauth/checks.d.ts +70 -0
  24. package/lib/actions/callback/oauth/checks.d.ts.map +1 -0
  25. package/lib/actions/callback/oauth/checks.js +188 -0
  26. package/lib/actions/callback/oauth/csrf-token.d.ts +33 -0
  27. package/lib/actions/callback/oauth/csrf-token.d.ts.map +1 -0
  28. package/lib/actions/callback/oauth/csrf-token.js +39 -0
  29. package/lib/actions/index.d.ts +6 -0
  30. package/lib/actions/index.d.ts.map +1 -0
  31. package/lib/actions/index.js +5 -0
  32. package/lib/actions/session.d.ts +5 -0
  33. package/lib/actions/session.d.ts.map +1 -0
  34. package/lib/actions/session.js +127 -0
  35. package/lib/actions/signin/authorization-url.d.ts +12 -0
  36. package/lib/actions/signin/authorization-url.d.ts.map +1 -0
  37. package/lib/actions/signin/authorization-url.js +94 -0
  38. package/lib/actions/signin/index.d.ts +4 -0
  39. package/lib/actions/signin/index.d.ts.map +1 -0
  40. package/lib/actions/signin/index.js +22 -0
  41. package/lib/actions/signin/send-token.d.ts +10 -0
  42. package/lib/actions/signin/send-token.d.ts.map +1 -0
  43. package/lib/actions/signin/send-token.js +98 -0
  44. package/lib/actions/signout.d.ts +11 -0
  45. package/lib/actions/signout.d.ts.map +1 -0
  46. package/lib/actions/signout.js +30 -0
  47. package/lib/actions/webauthn-options.d.ts +8 -0
  48. package/lib/actions/webauthn-options.d.ts.map +1 -0
  49. package/lib/actions/webauthn-options.js +60 -0
  50. package/lib/index.d.ts +2 -0
  51. package/lib/index.d.ts.map +1 -0
  52. package/lib/index.js +70 -0
  53. package/lib/init.d.ts +25 -0
  54. package/lib/init.d.ts.map +1 -0
  55. package/lib/init.js +172 -0
  56. package/lib/pages/error.d.ts +17 -0
  57. package/lib/pages/error.d.ts.map +1 -0
  58. package/lib/pages/error.js +40 -0
  59. package/lib/pages/index.d.ts +42 -0
  60. package/lib/pages/index.d.ts.map +1 -0
  61. package/lib/pages/index.js +136 -0
  62. package/lib/pages/signin.d.ts +10 -0
  63. package/lib/pages/signin.d.ts.map +1 -0
  64. package/lib/pages/signin.js +75 -0
  65. package/lib/pages/signout.d.ts +8 -0
  66. package/lib/pages/signout.d.ts.map +1 -0
  67. package/lib/pages/signout.js +17 -0
  68. package/lib/pages/styles.d.ts +3 -0
  69. package/lib/pages/styles.d.ts.map +1 -0
  70. package/lib/pages/styles.js +381 -0
  71. package/lib/pages/verify-request.d.ts +8 -0
  72. package/lib/pages/verify-request.d.ts.map +1 -0
  73. package/lib/pages/verify-request.js +11 -0
  74. package/lib/symbols.d.ts +50 -0
  75. package/lib/symbols.d.ts.map +1 -0
  76. package/lib/symbols.js +57 -0
  77. package/lib/utils/actions.d.ts +3 -0
  78. package/lib/utils/actions.d.ts.map +1 -0
  79. package/lib/utils/actions.js +14 -0
  80. package/lib/utils/assert.d.ts +14 -0
  81. package/lib/utils/assert.d.ts.map +1 -0
  82. package/lib/utils/assert.js +168 -0
  83. package/lib/utils/callback-url.d.ts +17 -0
  84. package/lib/utils/callback-url.d.ts.map +1 -0
  85. package/lib/utils/callback-url.js +27 -0
  86. package/lib/utils/cookie.d.ts +111 -0
  87. package/lib/utils/cookie.d.ts.map +1 -0
  88. package/lib/utils/cookie.js +205 -0
  89. package/lib/utils/date.d.ts +7 -0
  90. package/lib/utils/date.d.ts.map +1 -0
  91. package/lib/utils/date.js +8 -0
  92. package/lib/utils/email.d.ts +20 -0
  93. package/lib/utils/email.d.ts.map +1 -0
  94. package/lib/utils/email.js +57 -0
  95. package/lib/utils/env.d.ts +9 -0
  96. package/lib/utils/env.d.ts.map +1 -0
  97. package/lib/utils/env.js +96 -0
  98. package/lib/utils/logger.d.ts +18 -0
  99. package/lib/utils/logger.d.ts.map +1 -0
  100. package/lib/utils/logger.js +50 -0
  101. package/lib/utils/merge.d.ts +3 -0
  102. package/lib/utils/merge.d.ts.map +1 -0
  103. package/lib/utils/merge.js +23 -0
  104. package/lib/utils/providers.d.ts +19 -0
  105. package/lib/utils/providers.d.ts.map +1 -0
  106. package/lib/utils/providers.js +149 -0
  107. package/lib/utils/session.d.ts +7 -0
  108. package/lib/utils/session.d.ts.map +1 -0
  109. package/lib/utils/session.js +29 -0
  110. package/lib/utils/web.d.ts +10 -0
  111. package/lib/utils/web.d.ts.map +1 -0
  112. package/lib/utils/web.js +109 -0
  113. package/lib/utils/webauthn-client.d.ts +30 -0
  114. package/lib/utils/webauthn-client.d.ts.map +1 -0
  115. package/lib/utils/webauthn-client.js +197 -0
  116. package/lib/utils/webauthn-utils.d.ts +81 -0
  117. package/lib/utils/webauthn-utils.d.ts.map +1 -0
  118. package/lib/utils/webauthn-utils.js +343 -0
  119. package/lib/vendored/cookie.d.ts +120 -0
  120. package/lib/vendored/cookie.d.ts.map +1 -0
  121. package/lib/vendored/cookie.js +237 -0
  122. package/package.json +118 -0
  123. package/providers/42-school.d.ts +240 -0
  124. package/providers/42-school.d.ts.map +1 -0
  125. package/providers/42-school.js +78 -0
  126. package/providers/apple.d.ts +149 -0
  127. package/providers/apple.d.ts.map +1 -0
  128. package/providers/apple.js +104 -0
  129. package/providers/asgardeo.d.ts +102 -0
  130. package/providers/asgardeo.d.ts.map +1 -0
  131. package/providers/asgardeo.js +93 -0
  132. package/providers/atlassian.d.ts +94 -0
  133. package/providers/atlassian.d.ts.map +1 -0
  134. package/providers/atlassian.js +84 -0
  135. package/providers/auth0.d.ts +116 -0
  136. package/providers/auth0.d.ts.map +1 -0
  137. package/providers/auth0.js +49 -0
  138. package/providers/authentik.d.ts +90 -0
  139. package/providers/authentik.d.ts.map +1 -0
  140. package/providers/authentik.js +65 -0
  141. package/providers/azure-ad-b2c.d.ts +104 -0
  142. package/providers/azure-ad-b2c.d.ts.map +1 -0
  143. package/providers/azure-ad-b2c.js +100 -0
  144. package/providers/azure-ad.d.ts +19 -0
  145. package/providers/azure-ad.d.ts.map +1 -0
  146. package/providers/azure-ad.js +23 -0
  147. package/providers/azure-devops.d.ts +128 -0
  148. package/providers/azure-devops.d.ts.map +1 -0
  149. package/providers/azure-devops.js +158 -0
  150. package/providers/bankid-no.d.ts +134 -0
  151. package/providers/bankid-no.d.ts.map +1 -0
  152. package/providers/bankid-no.js +65 -0
  153. package/providers/battlenet.d.ts +85 -0
  154. package/providers/battlenet.d.ts.map +1 -0
  155. package/providers/battlenet.js +81 -0
  156. package/providers/beyondidentity.d.ts +77 -0
  157. package/providers/beyondidentity.d.ts.map +1 -0
  158. package/providers/beyondidentity.js +84 -0
  159. package/providers/bitbucket.d.ts +89 -0
  160. package/providers/bitbucket.d.ts.map +1 -0
  161. package/providers/bitbucket.js +92 -0
  162. package/providers/box.d.ts +63 -0
  163. package/providers/box.d.ts.map +1 -0
  164. package/providers/box.js +73 -0
  165. package/providers/boxyhq-saml.d.ts +121 -0
  166. package/providers/boxyhq-saml.d.ts.map +1 -0
  167. package/providers/boxyhq-saml.js +127 -0
  168. package/providers/bungie.d.ts +167 -0
  169. package/providers/bungie.d.ts.map +1 -0
  170. package/providers/bungie.js +174 -0
  171. package/providers/click-up.d.ts +75 -0
  172. package/providers/click-up.d.ts.map +1 -0
  173. package/providers/click-up.js +89 -0
  174. package/providers/cognito.d.ts +81 -0
  175. package/providers/cognito.d.ts.map +1 -0
  176. package/providers/cognito.js +73 -0
  177. package/providers/coinbase.d.ts +69 -0
  178. package/providers/coinbase.d.ts.map +1 -0
  179. package/providers/coinbase.js +78 -0
  180. package/providers/concept2.d.ts +81 -0
  181. package/providers/concept2.d.ts.map +1 -0
  182. package/providers/concept2.js +86 -0
  183. package/providers/credentials.d.ts +132 -0
  184. package/providers/credentials.d.ts.map +1 -0
  185. package/providers/credentials.js +74 -0
  186. package/providers/descope.d.ts +91 -0
  187. package/providers/descope.d.ts.map +1 -0
  188. package/providers/descope.js +78 -0
  189. package/providers/discord.d.ts +139 -0
  190. package/providers/discord.d.ts.map +1 -0
  191. package/providers/discord.js +86 -0
  192. package/providers/dribbble.d.ts +88 -0
  193. package/providers/dribbble.d.ts.map +1 -0
  194. package/providers/dribbble.js +85 -0
  195. package/providers/dropbox.d.ts +65 -0
  196. package/providers/dropbox.d.ts.map +1 -0
  197. package/providers/dropbox.js +88 -0
  198. package/providers/duende-identity-server6.d.ts +91 -0
  199. package/providers/duende-identity-server6.d.ts.map +1 -0
  200. package/providers/duende-identity-server6.js +80 -0
  201. package/providers/email.d.ts +41 -0
  202. package/providers/email.d.ts.map +1 -0
  203. package/providers/email.js +18 -0
  204. package/providers/eventbrite.d.ts +78 -0
  205. package/providers/eventbrite.d.ts.map +1 -0
  206. package/providers/eventbrite.js +88 -0
  207. package/providers/eveonline.d.ts +94 -0
  208. package/providers/eveonline.d.ts.map +1 -0
  209. package/providers/eveonline.js +92 -0
  210. package/providers/facebook.d.ts +84 -0
  211. package/providers/facebook.d.ts.map +1 -0
  212. package/providers/facebook.js +93 -0
  213. package/providers/faceit.d.ts +64 -0
  214. package/providers/faceit.d.ts.map +1 -0
  215. package/providers/faceit.js +74 -0
  216. package/providers/figma.d.ts +75 -0
  217. package/providers/figma.d.ts.map +1 -0
  218. package/providers/figma.js +81 -0
  219. package/providers/forwardemail.d.ts +4 -0
  220. package/providers/forwardemail.d.ts.map +1 -0
  221. package/providers/forwardemail.js +32 -0
  222. package/providers/foursquare.d.ts +71 -0
  223. package/providers/foursquare.d.ts.map +1 -0
  224. package/providers/foursquare.js +91 -0
  225. package/providers/freshbooks.d.ts +66 -0
  226. package/providers/freshbooks.d.ts.map +1 -0
  227. package/providers/freshbooks.js +76 -0
  228. package/providers/frontegg.d.ts +95 -0
  229. package/providers/frontegg.d.ts.map +1 -0
  230. package/providers/frontegg.js +88 -0
  231. package/providers/fusionauth.d.ts +279 -0
  232. package/providers/fusionauth.d.ts.map +1 -0
  233. package/providers/fusionauth.js +292 -0
  234. package/providers/github.d.ts +127 -0
  235. package/providers/github.d.ts.map +1 -0
  236. package/providers/github.js +115 -0
  237. package/providers/gitlab.d.ts +115 -0
  238. package/providers/gitlab.d.ts.map +1 -0
  239. package/providers/gitlab.js +75 -0
  240. package/providers/google.d.ts +138 -0
  241. package/providers/google.d.ts.map +1 -0
  242. package/providers/google.js +119 -0
  243. package/providers/hubspot.d.ts +76 -0
  244. package/providers/hubspot.d.ts.map +1 -0
  245. package/providers/hubspot.js +93 -0
  246. package/providers/huggingface.d.ts +216 -0
  247. package/providers/huggingface.d.ts.map +1 -0
  248. package/providers/huggingface.js +101 -0
  249. package/providers/identity-server4.d.ts +69 -0
  250. package/providers/identity-server4.d.ts.map +1 -0
  251. package/providers/identity-server4.js +64 -0
  252. package/providers/index.d.ts +61 -0
  253. package/providers/index.d.ts.map +1 -0
  254. package/providers/index.js +3 -0
  255. package/providers/instagram.d.ts +74 -0
  256. package/providers/instagram.d.ts.map +1 -0
  257. package/providers/instagram.js +87 -0
  258. package/providers/kakao.d.ts +148 -0
  259. package/providers/kakao.d.ts.map +1 -0
  260. package/providers/kakao.js +103 -0
  261. package/providers/keycloak.d.ts +100 -0
  262. package/providers/keycloak.d.ts.map +1 -0
  263. package/providers/keycloak.js +73 -0
  264. package/providers/kinde.d.ts +73 -0
  265. package/providers/kinde.d.ts.map +1 -0
  266. package/providers/kinde.js +51 -0
  267. package/providers/line.d.ts +83 -0
  268. package/providers/line.d.ts.map +1 -0
  269. package/providers/line.js +73 -0
  270. package/providers/linkedin.d.ts +77 -0
  271. package/providers/linkedin.d.ts.map +1 -0
  272. package/providers/linkedin.js +65 -0
  273. package/providers/logto.d.ts +98 -0
  274. package/providers/logto.d.ts.map +1 -0
  275. package/providers/logto.js +81 -0
  276. package/providers/loops.d.ts +40 -0
  277. package/providers/loops.d.ts.map +1 -0
  278. package/providers/loops.js +59 -0
  279. package/providers/mailchimp.d.ts +66 -0
  280. package/providers/mailchimp.d.ts.map +1 -0
  281. package/providers/mailchimp.js +76 -0
  282. package/providers/mailgun.d.ts +55 -0
  283. package/providers/mailgun.d.ts.map +1 -0
  284. package/providers/mailgun.js +74 -0
  285. package/providers/mailru.d.ts +63 -0
  286. package/providers/mailru.d.ts.map +1 -0
  287. package/providers/mailru.js +61 -0
  288. package/providers/mastodon.d.ts +90 -0
  289. package/providers/mastodon.d.ts.map +1 -0
  290. package/providers/mastodon.js +75 -0
  291. package/providers/mattermost.d.ts +132 -0
  292. package/providers/mattermost.d.ts.map +1 -0
  293. package/providers/mattermost.js +83 -0
  294. package/providers/medium.d.ts +68 -0
  295. package/providers/medium.d.ts.map +1 -0
  296. package/providers/medium.js +84 -0
  297. package/providers/microsoft-entra-id.d.ts +428 -0
  298. package/providers/microsoft-entra-id.d.ts.map +1 -0
  299. package/providers/microsoft-entra-id.js +156 -0
  300. package/providers/naver.d.ts +80 -0
  301. package/providers/naver.d.ts.map +1 -0
  302. package/providers/naver.js +79 -0
  303. package/providers/netlify.d.ts +66 -0
  304. package/providers/netlify.d.ts.map +1 -0
  305. package/providers/netlify.js +85 -0
  306. package/providers/netsuite.d.ts +189 -0
  307. package/providers/netsuite.d.ts.map +1 -0
  308. package/providers/netsuite.js +170 -0
  309. package/providers/nextcloud.d.ts +150 -0
  310. package/providers/nextcloud.d.ts.map +1 -0
  311. package/providers/nextcloud.js +99 -0
  312. package/providers/nodemailer.d.ts +27 -0
  313. package/providers/nodemailer.d.ts.map +1 -0
  314. package/providers/nodemailer.js +34 -0
  315. package/providers/notion.d.ts +99 -0
  316. package/providers/notion.d.ts.map +1 -0
  317. package/providers/notion.js +110 -0
  318. package/providers/oauth.d.ts +188 -0
  319. package/providers/oauth.d.ts.map +1 -0
  320. package/providers/oauth.js +1 -0
  321. package/providers/okta.d.ts +99 -0
  322. package/providers/okta.d.ts.map +1 -0
  323. package/providers/okta.js +63 -0
  324. package/providers/onelogin.d.ts +65 -0
  325. package/providers/onelogin.d.ts.map +1 -0
  326. package/providers/onelogin.js +61 -0
  327. package/providers/ory-hydra.d.ts +79 -0
  328. package/providers/ory-hydra.d.ts.map +1 -0
  329. package/providers/ory-hydra.js +67 -0
  330. package/providers/osso.d.ts +79 -0
  331. package/providers/osso.d.ts.map +1 -0
  332. package/providers/osso.js +77 -0
  333. package/providers/osu.d.ts +116 -0
  334. package/providers/osu.d.ts.map +1 -0
  335. package/providers/osu.js +75 -0
  336. package/providers/passage.d.ts +88 -0
  337. package/providers/passage.d.ts.map +1 -0
  338. package/providers/passage.js +75 -0
  339. package/providers/passkey.d.ts +65 -0
  340. package/providers/passkey.d.ts.map +1 -0
  341. package/providers/passkey.js +87 -0
  342. package/providers/patreon.d.ts +73 -0
  343. package/providers/patreon.d.ts.map +1 -0
  344. package/providers/patreon.js +77 -0
  345. package/providers/ping-id.d.ts +57 -0
  346. package/providers/ping-id.d.ts.map +1 -0
  347. package/providers/ping-id.js +40 -0
  348. package/providers/pinterest.d.ts +79 -0
  349. package/providers/pinterest.d.ts.map +1 -0
  350. package/providers/pinterest.js +85 -0
  351. package/providers/pipedrive.d.ts +99 -0
  352. package/providers/pipedrive.d.ts.map +1 -0
  353. package/providers/pipedrive.js +71 -0
  354. package/providers/postmark.d.ts +4 -0
  355. package/providers/postmark.d.ts.map +1 -0
  356. package/providers/postmark.js +36 -0
  357. package/providers/provider-types.d.ts +3 -0
  358. package/providers/provider-types.d.ts.map +1 -0
  359. package/providers/provider-types.js +1 -0
  360. package/providers/reddit.d.ts +88 -0
  361. package/providers/reddit.d.ts.map +1 -0
  362. package/providers/reddit.js +90 -0
  363. package/providers/resend.d.ts +4 -0
  364. package/providers/resend.d.ts.map +1 -0
  365. package/providers/resend.js +32 -0
  366. package/providers/roblox.d.ts +67 -0
  367. package/providers/roblox.d.ts.map +1 -0
  368. package/providers/roblox.js +53 -0
  369. package/providers/salesforce.d.ts +59 -0
  370. package/providers/salesforce.d.ts.map +1 -0
  371. package/providers/salesforce.js +52 -0
  372. package/providers/sendgrid.d.ts +4 -0
  373. package/providers/sendgrid.d.ts.map +1 -0
  374. package/providers/sendgrid.js +35 -0
  375. package/providers/simplelogin.d.ts +87 -0
  376. package/providers/simplelogin.d.ts.map +1 -0
  377. package/providers/simplelogin.js +83 -0
  378. package/providers/slack.d.ts +102 -0
  379. package/providers/slack.d.ts.map +1 -0
  380. package/providers/slack.js +69 -0
  381. package/providers/spotify.d.ts +75 -0
  382. package/providers/spotify.d.ts.map +1 -0
  383. package/providers/spotify.js +73 -0
  384. package/providers/strava.d.ts +68 -0
  385. package/providers/strava.d.ts.map +1 -0
  386. package/providers/strava.js +80 -0
  387. package/providers/threads.d.ts +108 -0
  388. package/providers/threads.d.ts.map +1 -0
  389. package/providers/threads.js +89 -0
  390. package/providers/tiktok.d.ts +248 -0
  391. package/providers/tiktok.d.ts.map +1 -0
  392. package/providers/tiktok.js +195 -0
  393. package/providers/todoist.d.ts +76 -0
  394. package/providers/todoist.d.ts.map +1 -0
  395. package/providers/todoist.js +97 -0
  396. package/providers/trakt.d.ts +93 -0
  397. package/providers/trakt.d.ts.map +1 -0
  398. package/providers/trakt.js +91 -0
  399. package/providers/twitch.d.ts +71 -0
  400. package/providers/twitch.d.ts.map +1 -0
  401. package/providers/twitch.js +96 -0
  402. package/providers/twitter.d.ts +183 -0
  403. package/providers/twitter.d.ts.map +1 -0
  404. package/providers/twitter.js +100 -0
  405. package/providers/united-effects.d.ts +80 -0
  406. package/providers/united-effects.d.ts.map +1 -0
  407. package/providers/united-effects.js +72 -0
  408. package/providers/vipps.d.ts +71 -0
  409. package/providers/vipps.d.ts.map +1 -0
  410. package/providers/vipps.js +33 -0
  411. package/providers/vk.d.ts +334 -0
  412. package/providers/vk.d.ts.map +1 -0
  413. package/providers/vk.js +103 -0
  414. package/providers/webauthn.d.ts +148 -0
  415. package/providers/webauthn.d.ts.map +1 -0
  416. package/providers/webauthn.js +128 -0
  417. package/providers/webex.d.ts +78 -0
  418. package/providers/webex.d.ts.map +1 -0
  419. package/providers/webex.js +73 -0
  420. package/providers/wechat.d.ts +78 -0
  421. package/providers/wechat.d.ts.map +1 -0
  422. package/providers/wechat.js +105 -0
  423. package/providers/wikimedia.d.ts +99 -0
  424. package/providers/wikimedia.d.ts.map +1 -0
  425. package/providers/wikimedia.js +90 -0
  426. package/providers/wordpress.d.ts +65 -0
  427. package/providers/wordpress.d.ts.map +1 -0
  428. package/providers/wordpress.js +71 -0
  429. package/providers/workos.d.ts +154 -0
  430. package/providers/workos.d.ts.map +1 -0
  431. package/providers/workos.js +143 -0
  432. package/providers/yandex.d.ts +131 -0
  433. package/providers/yandex.d.ts.map +1 -0
  434. package/providers/yandex.js +80 -0
  435. package/providers/zitadel.d.ts +117 -0
  436. package/providers/zitadel.d.ts.map +1 -0
  437. package/providers/zitadel.js +95 -0
  438. package/providers/zoho.d.ts +63 -0
  439. package/providers/zoho.d.ts.map +1 -0
  440. package/providers/zoho.js +79 -0
  441. package/providers/zoom.d.ts +93 -0
  442. package/providers/zoom.d.ts.map +1 -0
  443. package/providers/zoom.js +82 -0
  444. package/src/adapters/server-actions-helpers.ts +126 -0
  445. package/src/adapters.ts +603 -0
  446. package/src/errors.ts +551 -0
  447. package/src/index.ts +689 -0
  448. package/src/jwt.ts +283 -0
  449. package/src/lib/actions/callback/handle-login.ts +334 -0
  450. package/src/lib/actions/callback/index.ts +554 -0
  451. package/src/lib/actions/callback/oauth/callback.ts +347 -0
  452. package/src/lib/actions/callback/oauth/checks.ts +258 -0
  453. package/src/lib/actions/callback/oauth/csrf-token.ts +60 -0
  454. package/src/lib/actions/index.ts +5 -0
  455. package/src/lib/actions/session.ts +167 -0
  456. package/src/lib/actions/signin/authorization-url.ts +123 -0
  457. package/src/lib/actions/signin/index.ts +37 -0
  458. package/src/lib/actions/signin/send-token.ts +124 -0
  459. package/src/lib/actions/signout.ts +38 -0
  460. package/src/lib/actions/webauthn-options.ts +100 -0
  461. package/src/lib/index.ts +97 -0
  462. package/src/lib/init.ts +236 -0
  463. package/src/lib/pages/error.tsx +106 -0
  464. package/src/lib/pages/index.ts +181 -0
  465. package/src/lib/pages/signin.tsx +255 -0
  466. package/src/lib/pages/signout.tsx +49 -0
  467. package/src/lib/pages/styles.css +377 -0
  468. package/src/lib/pages/styles.ts +381 -0
  469. package/src/lib/pages/verify-request.tsx +36 -0
  470. package/src/lib/symbols.ts +60 -0
  471. package/src/lib/utils/actions.ts +17 -0
  472. package/src/lib/utils/assert.ts +259 -0
  473. package/src/lib/utils/callback-url.ts +42 -0
  474. package/src/lib/utils/cookie.ts +248 -0
  475. package/src/lib/utils/date.ts +8 -0
  476. package/src/lib/utils/email.ts +65 -0
  477. package/src/lib/utils/env.ts +113 -0
  478. package/src/lib/utils/logger.ts +75 -0
  479. package/src/lib/utils/merge.ts +30 -0
  480. package/src/lib/utils/providers.ts +203 -0
  481. package/src/lib/utils/session.ts +41 -0
  482. package/src/lib/utils/web.ts +151 -0
  483. package/src/lib/utils/webauthn-client.js +229 -0
  484. package/src/lib/utils/webauthn-utils.ts +531 -0
  485. package/src/lib/vendored/cookie.ts +383 -0
  486. package/src/providers/42-school.ts +256 -0
  487. package/src/providers/apple.ts +206 -0
  488. package/src/providers/asgardeo.ts +118 -0
  489. package/src/providers/atlassian.ts +120 -0
  490. package/src/providers/auth0.ts +127 -0
  491. package/src/providers/authentik.ts +100 -0
  492. package/src/providers/azure-ad-b2c.ts +124 -0
  493. package/src/providers/azure-ad.ts +30 -0
  494. package/src/providers/azure-devops.ts +184 -0
  495. package/src/providers/bankid-no.ts +161 -0
  496. package/src/providers/battlenet.ts +107 -0
  497. package/src/providers/beyondidentity.ts +102 -0
  498. package/src/providers/bitbucket.ts +122 -0
  499. package/src/providers/box.ts +87 -0
  500. package/src/providers/boxyhq-saml.ts +148 -0
  501. package/src/providers/bungie.ts +192 -0
  502. package/src/providers/click-up.ts +104 -0
  503. package/src/providers/cognito.ts +94 -0
  504. package/src/providers/coinbase.ts +93 -0
  505. package/src/providers/concept2.ts +108 -0
  506. package/src/providers/credentials.ts +157 -0
  507. package/src/providers/descope.ts +105 -0
  508. package/src/providers/discord.ts +176 -0
  509. package/src/providers/dribbble.ts +122 -0
  510. package/src/providers/dropbox.ts +102 -0
  511. package/src/providers/duende-identity-server6.ts +101 -0
  512. package/src/providers/email.ts +60 -0
  513. package/src/providers/eventbrite.ts +105 -0
  514. package/src/providers/eveonline.ts +117 -0
  515. package/src/providers/facebook.ts +119 -0
  516. package/src/providers/faceit.ts +90 -0
  517. package/src/providers/figma.ts +105 -0
  518. package/src/providers/forwardemail.ts +37 -0
  519. package/src/providers/foursquare.ts +105 -0
  520. package/src/providers/freshbooks.ts +90 -0
  521. package/src/providers/frontegg.ts +111 -0
  522. package/src/providers/fusionauth.ts +336 -0
  523. package/src/providers/github.ts +187 -0
  524. package/src/providers/gitlab.ts +140 -0
  525. package/src/providers/google.ts +152 -0
  526. package/src/providers/hubspot.ts +117 -0
  527. package/src/providers/huggingface.ts +234 -0
  528. package/src/providers/identity-server4.ts +78 -0
  529. package/src/providers/index.ts +115 -0
  530. package/src/providers/instagram.ts +103 -0
  531. package/src/providers/kakao.ts +184 -0
  532. package/src/providers/keycloak.ts +111 -0
  533. package/src/providers/kinde.ts +85 -0
  534. package/src/providers/line.ts +99 -0
  535. package/src/providers/linkedin.ts +91 -0
  536. package/src/providers/logto.ts +122 -0
  537. package/src/providers/loops.ts +79 -0
  538. package/src/providers/mailchimp.ts +90 -0
  539. package/src/providers/mailgun.ts +98 -0
  540. package/src/providers/mailru.ts +75 -0
  541. package/src/providers/mastodon.ts +112 -0
  542. package/src/providers/mattermost.ts +154 -0
  543. package/src/providers/medium.ts +89 -0
  544. package/src/providers/microsoft-entra-id.ts +497 -0
  545. package/src/providers/naver.ts +102 -0
  546. package/src/providers/netlify.ts +90 -0
  547. package/src/providers/netsuite.ts +225 -0
  548. package/src/providers/nextcloud.ts +207 -0
  549. package/src/providers/nodemailer.ts +84 -0
  550. package/src/providers/notion.ts +166 -0
  551. package/src/providers/oauth.ts +310 -0
  552. package/src/providers/okta.ts +111 -0
  553. package/src/providers/onelogin.ts +75 -0
  554. package/src/providers/ory-hydra.ts +93 -0
  555. package/src/providers/osso.ts +91 -0
  556. package/src/providers/osu.ts +138 -0
  557. package/src/providers/passage.ts +103 -0
  558. package/src/providers/passkey.ts +94 -0
  559. package/src/providers/patreon.ts +98 -0
  560. package/src/providers/ping-id.ts +68 -0
  561. package/src/providers/pinterest.ts +106 -0
  562. package/src/providers/pipedrive.ts +120 -0
  563. package/src/providers/postmark.ts +38 -0
  564. package/src/providers/provider-types.ts +107 -0
  565. package/src/providers/reddit.ts +104 -0
  566. package/src/providers/resend.ts +35 -0
  567. package/src/providers/roblox.ts +94 -0
  568. package/src/providers/salesforce.ts +73 -0
  569. package/src/providers/sendgrid.ts +36 -0
  570. package/src/providers/simplelogin.ts +107 -0
  571. package/src/providers/slack.ts +115 -0
  572. package/src/providers/spotify.ts +99 -0
  573. package/src/providers/strava.ts +101 -0
  574. package/src/providers/threads.ts +135 -0
  575. package/src/providers/tiktok.ts +319 -0
  576. package/src/providers/todoist.ts +122 -0
  577. package/src/providers/trakt.ts +120 -0
  578. package/src/providers/twitch.ts +121 -0
  579. package/src/providers/twitter.ts +207 -0
  580. package/src/providers/united-effects.ts +89 -0
  581. package/src/providers/vipps.ts +86 -0
  582. package/src/providers/vk.ts +401 -0
  583. package/src/providers/webauthn.ts +296 -0
  584. package/src/providers/webex.ts +102 -0
  585. package/src/providers/wechat.ts +141 -0
  586. package/src/providers/wikimedia.ts +258 -0
  587. package/src/providers/wordpress.ts +86 -0
  588. package/src/providers/workos.ts +180 -0
  589. package/src/providers/yandex.ts +159 -0
  590. package/src/providers/zitadel.ts +128 -0
  591. package/src/providers/zoho.ts +84 -0
  592. package/src/providers/zoom.ts +119 -0
  593. package/src/types.ts +430 -0
  594. package/src/warnings.ts +21 -0
  595. package/types.d.ts +309 -0
  596. package/types.d.ts.map +1 -0
  597. package/types.js +53 -0
  598. package/warnings.d.ts +17 -0
  599. package/warnings.d.ts.map +1 -0
  600. package/warnings.js +1 -0
package/src/jwt.ts ADDED
@@ -0,0 +1,283 @@
1
+ /**
2
+ *
3
+ *
4
+ * This module contains functions and types
5
+ * to encode and decode {@link https://authjs.dev/concepts/session-strategies#jwt-session JWT}s
6
+ * issued and used by Auth.js.
7
+ *
8
+ * The JWT issued by Auth.js is _encrypted by default_, using the _A256CBC-HS512_ algorithm ({@link https://www.rfc-editor.org/rfc/rfc7518.html#section-5.2.5 JWE}).
9
+ * It uses the `AUTH_SECRET` environment variable or the passed `secret` property to derive a suitable encryption key.
10
+ *
11
+ * :::info Note
12
+ * Auth.js JWTs are meant to be used by the same app that issued them.
13
+ * If you need JWT authentication for your third-party API, you should rely on your Identity Provider instead.
14
+ * :::
15
+ *
16
+ * ## Installation
17
+ *
18
+ * ```bash npm2yarn
19
+ * npm install @auth/core
20
+ * ```
21
+ *
22
+ * You can then import this submodule from `@auth/core/jwt`.
23
+ *
24
+ * ## Usage
25
+ *
26
+ * :::warning Warning
27
+ * This module *will* be refactored/changed. We do not recommend relying on it right now.
28
+ * :::
29
+ *
30
+ *
31
+ * ## Resources
32
+ *
33
+ * - [What is a JWT session strategy](https://authjs.dev/concepts/session-strategies#jwt-session)
34
+ * - [RFC7519 - JSON Web Token (JWT)](https://www.rfc-editor.org/rfc/rfc7519)
35
+ *
36
+ * @module jwt
37
+ */
38
+
39
+ import { hkdf } from "@panva/hkdf"
40
+ import { EncryptJWT, base64url, calculateJwkThumbprint, jwtDecrypt } from "jose"
41
+ import { defaultCookies, SessionStore } from "./lib/utils/cookie.js"
42
+ import { Awaitable } from "./types.js"
43
+ import type { LoggerInstance } from "./lib/utils/logger.js"
44
+ import { MissingSecret } from "./errors.js"
45
+ import * as cookie from "./lib/vendored/cookie.js"
46
+
47
+ const { parse: parseCookie } = cookie
48
+ const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60 // 30 days
49
+
50
+ const now = () => (Date.now() / 1000) | 0
51
+
52
+ const alg = "dir"
53
+ const enc = "A256CBC-HS512"
54
+ type Digest = Parameters<typeof calculateJwkThumbprint>[1]
55
+
56
+ /** Issues a JWT. By default, the JWT is encrypted using "A256CBC-HS512". */
57
+ export async function encode<Payload = JWT>(params: JWTEncodeParams<Payload>) {
58
+ const { token = {}, secret, maxAge = DEFAULT_MAX_AGE, salt } = params
59
+ const secrets = Array.isArray(secret) ? secret : [secret]
60
+ const encryptionSecret = await getDerivedEncryptionKey(enc, secrets[0], salt)
61
+
62
+ const thumbprint = await calculateJwkThumbprint(
63
+ { kty: "oct", k: base64url.encode(encryptionSecret) },
64
+ `sha${encryptionSecret.byteLength << 3}` as Digest
65
+ )
66
+ // @ts-expect-error `jose` allows any object as payload.
67
+ return await new EncryptJWT(token)
68
+ .setProtectedHeader({ alg, enc, kid: thumbprint })
69
+ .setIssuedAt()
70
+ .setExpirationTime(now() + maxAge)
71
+ .setJti(crypto.randomUUID())
72
+ .encrypt(encryptionSecret)
73
+ }
74
+
75
+ /** Decodes an Auth.js issued JWT. */
76
+ export async function decode<Payload = JWT>(
77
+ params: JWTDecodeParams
78
+ ): Promise<Payload | null> {
79
+ const { token, secret, salt } = params
80
+ const secrets = Array.isArray(secret) ? secret : [secret]
81
+ if (!token) return null
82
+ const { payload } = await jwtDecrypt(
83
+ token,
84
+ async ({ kid, enc }) => {
85
+ for (const secret of secrets) {
86
+ const encryptionSecret = await getDerivedEncryptionKey(
87
+ enc,
88
+ secret,
89
+ salt
90
+ )
91
+ if (kid === undefined) return encryptionSecret
92
+
93
+ const thumbprint = await calculateJwkThumbprint(
94
+ { kty: "oct", k: base64url.encode(encryptionSecret) },
95
+ `sha${encryptionSecret.byteLength << 3}` as Digest
96
+ )
97
+ if (kid === thumbprint) return encryptionSecret
98
+ }
99
+
100
+ throw new Error("no matching decryption secret")
101
+ },
102
+ {
103
+ clockTolerance: 15,
104
+ keyManagementAlgorithms: [alg],
105
+ contentEncryptionAlgorithms: [enc, "A256GCM"],
106
+ }
107
+ )
108
+ return payload as Payload
109
+ }
110
+
111
+ type GetTokenParamsBase = {
112
+ secret?: JWTDecodeParams["secret"]
113
+ salt?: JWTDecodeParams["salt"]
114
+ }
115
+
116
+ export interface GetTokenParams<R extends boolean = false>
117
+ extends GetTokenParamsBase {
118
+ /** The request containing the JWT either in the cookies or in the `Authorization` header. */
119
+ req: Request | { headers: Headers | Record<string, string> }
120
+ /**
121
+ * Use secure prefix for cookie name, unless URL in `NEXTAUTH_URL` is http://
122
+ * or not set (e.g. development or test instance) case use unprefixed name
123
+ */
124
+ secureCookie?: boolean
125
+ /** If the JWT is in the cookie, what name `getToken()` should look for. */
126
+ cookieName?: string
127
+ /**
128
+ * `getToken()` will return the raw JWT if this is set to `true`
129
+ *
130
+ * @default false
131
+ */
132
+ raw?: R
133
+ decode?: JWTOptions["decode"]
134
+ logger?: LoggerInstance | Console
135
+ }
136
+
137
+ /**
138
+ * Takes an Auth.js request (`req`) and returns either the Auth.js issued JWT's payload,
139
+ * or the raw JWT string. We look for the JWT in the either the cookies, or the `Authorization` header.
140
+ */
141
+ export async function getToken<R extends boolean = false>(
142
+ params: GetTokenParams<R>
143
+ ): Promise<R extends true ? string : JWT | null>
144
+ export async function getToken(
145
+ params: GetTokenParams
146
+ ): Promise<string | JWT | null> {
147
+ const {
148
+ secureCookie,
149
+ cookieName = defaultCookies(secureCookie ?? false).sessionToken.name,
150
+ decode: _decode = decode,
151
+ salt = cookieName,
152
+ secret,
153
+ logger = console,
154
+ raw,
155
+ req,
156
+ } = params
157
+
158
+ if (!req) throw new Error("Must pass `req` to JWT getToken()")
159
+
160
+ const headers =
161
+ req.headers instanceof Headers ? req.headers : new Headers(req.headers)
162
+
163
+ const sessionStore = new SessionStore(
164
+ { name: cookieName, options: { secure: secureCookie } },
165
+ parseCookie(headers.get("cookie") ?? ""),
166
+ logger
167
+ )
168
+
169
+ let token = sessionStore.value
170
+
171
+ const authorizationHeader = headers.get("authorization")
172
+
173
+ if (!token && authorizationHeader?.split(" ")[0] === "Bearer") {
174
+ const urlEncodedToken = authorizationHeader.split(" ")[1]
175
+ token = decodeURIComponent(urlEncodedToken)
176
+ }
177
+
178
+ if (!token) return null
179
+
180
+ if (raw) return token
181
+
182
+ if (!secret)
183
+ throw new MissingSecret("Must pass `secret` if not set to JWT getToken()")
184
+
185
+ try {
186
+ return await _decode({ token, secret, salt })
187
+ } catch {
188
+ return null
189
+ }
190
+ }
191
+
192
+ async function getDerivedEncryptionKey(
193
+ enc: string,
194
+ keyMaterial: Parameters<typeof hkdf>[1],
195
+ salt: Parameters<typeof hkdf>[2]
196
+ ) {
197
+ let length: number
198
+ switch (enc) {
199
+ case "A256CBC-HS512":
200
+ length = 64
201
+ break
202
+ case "A256GCM":
203
+ length = 32
204
+ break
205
+ default:
206
+ throw new Error("Unsupported JWT Content Encryption Algorithm")
207
+ }
208
+ return await hkdf(
209
+ "sha256",
210
+ keyMaterial,
211
+ salt,
212
+ `Auth.js Generated Encryption Key (${salt})`,
213
+ length
214
+ )
215
+ }
216
+
217
+ export interface DefaultJWT extends Record<string, unknown> {
218
+ name?: string | null
219
+ email?: string | null
220
+ picture?: string | null
221
+ sub?: string
222
+ iat?: number
223
+ exp?: number
224
+ jti?: string
225
+ }
226
+
227
+ /**
228
+ * Returned by the `jwt` callback when using JWT sessions
229
+ *
230
+ * [`jwt` callback](https://authjs.dev/reference/core/types#jwt)
231
+ */
232
+ export interface JWT extends Record<string, unknown>, DefaultJWT {}
233
+
234
+ export interface JWTEncodeParams<Payload = JWT> {
235
+ /**
236
+ * The maximum age of the Auth.js issued JWT in seconds.
237
+ *
238
+ * @default 30 * 24 * 60 * 60 // 30 days
239
+ */
240
+ maxAge?: number
241
+ /** Used in combination with `secret`, to derive the encryption secret for JWTs. */
242
+ salt: string
243
+ /** Used in combination with `salt`, to derive the encryption secret for JWTs. */
244
+ secret: string | string[]
245
+ /** The JWT payload. */
246
+ token?: Payload
247
+ }
248
+
249
+ export interface JWTDecodeParams {
250
+ /** Used in combination with `secret`, to derive the encryption secret for JWTs. */
251
+ salt: string
252
+ /**
253
+ * Used in combination with `salt`, to derive the encryption secret for JWTs.
254
+ *
255
+ * @note
256
+ * You can also pass an array of secrets, in which case the first secret that successfully
257
+ * decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
258
+ * The newer secret should be added to the start of the array, which will be used for all new sessions.
259
+ */
260
+ secret: string | string[]
261
+ /** The Auth.js issued JWT to be decoded */
262
+ token?: string
263
+ }
264
+
265
+ export interface JWTOptions {
266
+ /**
267
+ * The secret used to encode/decode the Auth.js issued JWT.
268
+ * It can be an array of secrets, in which case the first secret that successfully
269
+ * decrypts the JWT will be used. This is useful for rotating secrets without invalidating existing sessions.
270
+ * @internal
271
+ */
272
+ secret: string | string[]
273
+ /**
274
+ * The maximum age of the Auth.js issued JWT in seconds.
275
+ *
276
+ * @default 30 * 24 * 60 * 60 // 30 days
277
+ */
278
+ maxAge: number
279
+ /** Override this method to control the Auth.js issued JWT encoding. */
280
+ encode: (params: JWTEncodeParams) => Awaitable<string>
281
+ /** Override this method to control the Auth.js issued JWT decoding. */
282
+ decode: (params: JWTDecodeParams) => Awaitable<JWT | null>
283
+ }
@@ -0,0 +1,334 @@
1
+ import { AccountNotLinked, OAuthAccountNotLinked } from "../../../errors.js"
2
+ import { fromDate } from "../../utils/date.js"
3
+
4
+ import type {
5
+ AdapterAccount,
6
+ AdapterSession,
7
+ AdapterUser,
8
+ } from "../../../adapters.js"
9
+ import type { Account, InternalOptions, User } from "../../../types.js"
10
+ import type { JWT } from "../../../jwt.js"
11
+ import type { OAuthConfig } from "../../../providers/index.js"
12
+ import type { SessionToken } from "../../utils/cookie.js"
13
+
14
+ /**
15
+ * This function handles the complex flow of signing users in, and either creating,
16
+ * linking (or not linking) accounts depending on if the user is currently logged
17
+ * in, if they have account already and the authentication mechanism they are using.
18
+ *
19
+ * It prevents insecure behaviour, such as linking OAuth accounts unless a user is
20
+ * signed in and authenticated with an existing valid account.
21
+ *
22
+ * All verification (e.g. OAuth flows or email address verification flows) are
23
+ * done prior to this handler being called to avoid additional complexity in this
24
+ * handler.
25
+ */
26
+ export async function handleLoginOrRegister(
27
+ sessionToken: SessionToken,
28
+ _profile: User | AdapterUser | { email: string },
29
+ _account: AdapterAccount | Account | null,
30
+ options: InternalOptions
31
+ ) {
32
+ // Input validation
33
+ if (!_account?.providerAccountId || !_account.type)
34
+ throw new Error("Missing or invalid provider account")
35
+ if (!["email", "oauth", "oidc", "webauthn"].includes(_account.type))
36
+ throw new Error("Provider not supported")
37
+
38
+ const {
39
+ adapter,
40
+ jwt,
41
+ events,
42
+ session: { strategy: sessionStrategy, generateSessionToken },
43
+ } = options
44
+
45
+ // If no adapter is configured then we don't have a database and cannot
46
+ // persist data; in this mode we just return a dummy session object.
47
+ if (!adapter) {
48
+ return { user: _profile as User, account: _account as Account }
49
+ }
50
+
51
+ const profile = _profile as AdapterUser
52
+ let account = _account as AdapterAccount
53
+
54
+ const {
55
+ createUser,
56
+ updateUser,
57
+ getUser,
58
+ getUserByAccount,
59
+ getUserByEmail,
60
+ linkAccount,
61
+ createSession,
62
+ getSessionAndUser,
63
+ deleteSession,
64
+ } = adapter
65
+
66
+ let session: AdapterSession | JWT | null = null
67
+ let user: AdapterUser | null = null
68
+ let isNewUser = false
69
+
70
+ const useJwtSession = sessionStrategy === "jwt"
71
+
72
+ if (sessionToken) {
73
+ if (useJwtSession) {
74
+ try {
75
+ const salt = options.cookies.sessionToken.name
76
+ session = await jwt.decode({ ...jwt, token: sessionToken, salt })
77
+ if (session && "sub" in session && session.sub) {
78
+ user = await getUser(session.sub)
79
+ }
80
+ } catch {
81
+ // If session can't be verified, treat as no session
82
+ }
83
+ } else {
84
+ const userAndSession = await getSessionAndUser(sessionToken)
85
+ if (userAndSession) {
86
+ session = userAndSession.session
87
+ user = userAndSession.user
88
+ }
89
+ }
90
+ }
91
+
92
+ if (account.type === "email") {
93
+ // If signing in with an email, check if an account with the same email address exists already
94
+ const userByEmail = await getUserByEmail(profile.email)
95
+ if (userByEmail) {
96
+ // If they are not already signed in as the same user, this flow will
97
+ // sign them out of the current session and sign them in as the new user
98
+ if (user?.id !== userByEmail.id && !useJwtSession && sessionToken) {
99
+ // Delete existing session if they are currently signed in as another user.
100
+ // This will switch user accounts for the session in cases where the user was
101
+ // already logged in with a different account.
102
+ await deleteSession(sessionToken)
103
+ }
104
+
105
+ // Update emailVerified property on the user object
106
+ user = await updateUser({
107
+ id: userByEmail.id,
108
+ emailVerified: new Date(),
109
+ })
110
+ await events.updateUser?.({ user })
111
+ } else {
112
+ // Create user account if there isn't one for the email address already
113
+ user = await createUser({ ...profile, emailVerified: new Date() })
114
+ await events.createUser?.({ user })
115
+ isNewUser = true
116
+ }
117
+
118
+ // Create new session
119
+ session = useJwtSession
120
+ ? {}
121
+ : await createSession({
122
+ sessionToken: generateSessionToken(),
123
+ userId: user.id,
124
+ expires: fromDate(options.session.maxAge),
125
+ })
126
+
127
+ return { session, user, isNewUser }
128
+ } else if (account.type === "webauthn") {
129
+ // Check if the account exists
130
+ const userByAccount = await getUserByAccount({
131
+ providerAccountId: account.providerAccountId,
132
+ provider: account.provider,
133
+ })
134
+ if (userByAccount) {
135
+ if (user) {
136
+ // If the user is already signed in with this account, we don't need to do anything
137
+ if (userByAccount.id === user.id) {
138
+ const currentAccount: AdapterAccount = { ...account, userId: user.id }
139
+ return { session, user, isNewUser, account: currentAccount }
140
+ }
141
+ // If the user is currently signed in, but the new account they are signing in
142
+ // with is already associated with another user, then we cannot link them
143
+ // and need to return an error.
144
+ throw new AccountNotLinked(
145
+ "The account is already associated with another user",
146
+ { provider: account.provider }
147
+ )
148
+ }
149
+ // If there is no active session, but the account being signed in with is already
150
+ // associated with a valid user then create session to sign the user in.
151
+ session = useJwtSession
152
+ ? {}
153
+ : await createSession({
154
+ sessionToken: generateSessionToken(),
155
+ userId: userByAccount.id,
156
+ expires: fromDate(options.session.maxAge),
157
+ })
158
+
159
+ const currentAccount: AdapterAccount = {
160
+ ...account,
161
+ userId: userByAccount.id,
162
+ }
163
+ return {
164
+ session,
165
+ user: userByAccount,
166
+ isNewUser,
167
+ account: currentAccount,
168
+ }
169
+ } else {
170
+ // If the account doesn't exist, we'll create it
171
+ if (user) {
172
+ // If the user is already signed in and the account isn't already associated
173
+ // with another user account then we can go ahead and link the accounts safely.
174
+ await linkAccount({ ...account, userId: user.id })
175
+ await events.linkAccount?.({ user, account, profile })
176
+
177
+ // As they are already signed in, we don't need to do anything after linking them
178
+ const currentAccount: AdapterAccount = { ...account, userId: user.id }
179
+ return { session, user, isNewUser, account: currentAccount }
180
+ }
181
+
182
+ // If the user is not signed in and it looks like a new account then we
183
+ // check there also isn't an user account already associated with the same
184
+ // email address as the one in the request.
185
+ const userByEmail = profile.email
186
+ ? await getUserByEmail(profile.email)
187
+ : null
188
+ if (userByEmail) {
189
+ // We don't trust user-provided email addresses, so we don't want to link accounts
190
+ // if the email address associated with the new account is already associated with
191
+ // an existing account.
192
+ throw new AccountNotLinked(
193
+ "Another account already exists with the same e-mail address",
194
+ { provider: account.provider }
195
+ )
196
+ } else {
197
+ // If the current user is not logged in and the profile isn't linked to any user
198
+ // accounts (by email or provider account id)...
199
+ //
200
+ // If no account matching the same [provider].id or .email exists, we can
201
+ // create a new account for the user, link it to the OAuth account and
202
+ // create a new session for them so they are signed in with it.
203
+ user = await createUser({ ...profile })
204
+ }
205
+ await events.createUser?.({ user })
206
+
207
+ await linkAccount({ ...account, userId: user.id })
208
+ await events.linkAccount?.({ user, account, profile })
209
+
210
+ session = useJwtSession
211
+ ? {}
212
+ : await createSession({
213
+ sessionToken: generateSessionToken(),
214
+ userId: user.id,
215
+ expires: fromDate(options.session.maxAge),
216
+ })
217
+
218
+ const currentAccount: AdapterAccount = { ...account, userId: user.id }
219
+ return { session, user, isNewUser: true, account: currentAccount }
220
+ }
221
+ }
222
+
223
+ // If signing in with OAuth account, check to see if the account exists already
224
+ const userByAccount = await getUserByAccount({
225
+ providerAccountId: account.providerAccountId,
226
+ provider: account.provider,
227
+ })
228
+ if (userByAccount) {
229
+ if (user) {
230
+ // If the user is already signed in with this account, we don't need to do anything
231
+ if (userByAccount.id === user.id) {
232
+ return { session, user, isNewUser }
233
+ }
234
+ // If the user is currently signed in, but the new account they are signing in
235
+ // with is already associated with another user, then we cannot link them
236
+ // and need to return an error.
237
+ throw new OAuthAccountNotLinked(
238
+ "The account is already associated with another user",
239
+ { provider: account.provider }
240
+ )
241
+ }
242
+ // If there is no active session, but the account being signed in with is already
243
+ // associated with a valid user then create session to sign the user in.
244
+ session = useJwtSession
245
+ ? {}
246
+ : await createSession({
247
+ sessionToken: generateSessionToken(),
248
+ userId: userByAccount.id,
249
+ expires: fromDate(options.session.maxAge),
250
+ })
251
+
252
+ return { session, user: userByAccount, isNewUser }
253
+ } else {
254
+ const { provider: p } = options as InternalOptions<"oauth" | "oidc">
255
+ const { type, provider, providerAccountId, userId, ...tokenSet } = account
256
+ const defaults = { providerAccountId, provider, type, userId }
257
+ account = Object.assign(p.account(tokenSet) ?? {}, defaults)
258
+
259
+ if (user) {
260
+ // If the user is already signed in and the OAuth account isn't already associated
261
+ // with another user account then we can go ahead and link the accounts safely.
262
+ await linkAccount({ ...account, userId: user.id })
263
+ await events.linkAccount?.({ user, account, profile })
264
+
265
+ // As they are already signed in, we don't need to do anything after linking them
266
+ return { session, user, isNewUser }
267
+ }
268
+
269
+ // If the user is not signed in and it looks like a new OAuth account then we
270
+ // check there also isn't an user account already associated with the same
271
+ // email address as the one in the OAuth profile.
272
+ //
273
+ // This step is often overlooked in OAuth implementations, but covers the following cases:
274
+ //
275
+ // 1. It makes it harder for someone to accidentally create two accounts.
276
+ // e.g. by signin in with email, then again with an oauth account connected to the same email.
277
+ // 2. It makes it harder to hijack a user account using a 3rd party OAuth account.
278
+ // e.g. by creating an oauth account then changing the email address associated with it.
279
+ //
280
+ // It's quite common for services to automatically link accounts in this case, but it's
281
+ // better practice to require the user to sign in *then* link accounts to be sure
282
+ // someone is not exploiting a problem with a third party OAuth service.
283
+ //
284
+ // OAuth providers should require email address verification to prevent this, but in
285
+ // practice that is not always the case; this helps protect against that.
286
+ const userByEmail = profile.email
287
+ ? await getUserByEmail(profile.email)
288
+ : null
289
+ if (userByEmail) {
290
+ const provider = options.provider as OAuthConfig<any>
291
+ if (provider?.allowDangerousEmailAccountLinking) {
292
+ // If you trust the oauth provider to correctly verify email addresses, you can opt-in to
293
+ // account linking even when the user is not signed-in.
294
+ user = userByEmail
295
+ isNewUser = false
296
+ } else {
297
+ // We end up here when we don't have an account with the same [provider].id *BUT*
298
+ // we do already have an account with the same email address as the one in the
299
+ // OAuth profile the user has just tried to sign in with.
300
+ //
301
+ // We don't want to have two accounts with the same email address, and we don't
302
+ // want to link them in case it's not safe to do so, so instead we prompt the user
303
+ // to sign in via email to verify their identity and then link the accounts.
304
+ throw new OAuthAccountNotLinked(
305
+ "Another account already exists with the same e-mail address",
306
+ { provider: account.provider }
307
+ )
308
+ }
309
+ } else {
310
+ // If the current user is not logged in and the profile isn't linked to any user
311
+ // accounts (by email or provider account id)...
312
+ //
313
+ // If no account matching the same [provider].id or .email exists, we can
314
+ // create a new account for the user, link it to the OAuth account and
315
+ // create a new session for them so they are signed in with it.
316
+ user = await createUser({ ...profile, emailVerified: null })
317
+ isNewUser = true
318
+ }
319
+ await events.createUser?.({ user })
320
+
321
+ await linkAccount({ ...account, userId: user.id })
322
+ await events.linkAccount?.({ user, account, profile })
323
+
324
+ session = useJwtSession
325
+ ? {}
326
+ : await createSession({
327
+ sessionToken: generateSessionToken(),
328
+ userId: user.id,
329
+ expires: fromDate(options.session.maxAge),
330
+ })
331
+
332
+ return { session, user, isNewUser }
333
+ }
334
+ }