@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
@@ -0,0 +1,347 @@
1
+ import * as checks from "./checks.js"
2
+ import * as o from "oauth4webapi"
3
+ import {
4
+ OAuthCallbackError,
5
+ OAuthProfileParseError,
6
+ } from "../../../../errors.js"
7
+
8
+ import type {
9
+ Account,
10
+ InternalOptions,
11
+ LoggerInstance,
12
+ Profile,
13
+ RequestInternal,
14
+ TokenSet,
15
+ User,
16
+ } from "../../../../types.js"
17
+ import { type OAuthConfigInternal } from "../../../../providers/index.js"
18
+ import type { Cookie } from "../../../utils/cookie.js"
19
+ import { isOIDCProvider } from "../../../utils/providers.js"
20
+ import { conformInternal, customFetch } from "../../../symbols.js"
21
+ import { decodeJwt } from "jose"
22
+
23
+ function formUrlEncode(token: string) {
24
+ return encodeURIComponent(token).replace(/%20/g, "+")
25
+ }
26
+
27
+ /**
28
+ * Formats client_id and client_secret as an HTTP Basic Authentication header as per the OAuth 2.0
29
+ * specified in RFC6749.
30
+ */
31
+ function clientSecretBasic(clientId: string, clientSecret: string) {
32
+ const username = formUrlEncode(clientId)
33
+ const password = formUrlEncode(clientSecret)
34
+ const credentials = btoa(`${username}:${password}`)
35
+ return `Basic ${credentials}`
36
+ }
37
+
38
+ /**
39
+ * Handles the following OAuth steps.
40
+ * https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
41
+ * https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3
42
+ * https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest
43
+ *
44
+ * @note Although requesting userinfo is not required by the OAuth2.0 spec,
45
+ * we fetch it anyway. This is because we always want a user profile.
46
+ */
47
+ export async function handleOAuth(
48
+ params: RequestInternal["query"],
49
+ cookies: RequestInternal["cookies"],
50
+ options: InternalOptions<"oauth" | "oidc">
51
+ ) {
52
+ const { logger, provider } = options
53
+
54
+ let as: o.AuthorizationServer
55
+
56
+ const { token, userinfo } = provider
57
+ // Falls back to authjs.dev if the user only passed params
58
+ if (
59
+ (!token?.url || token.url.host === "authjs.dev") &&
60
+ (!userinfo?.url || userinfo.url.host === "authjs.dev")
61
+ ) {
62
+ // We assume that issuer is always defined as this has been asserted earlier
63
+
64
+ const issuer = new URL(provider.issuer!)
65
+ const discoveryResponse = await o.discoveryRequest(issuer, {
66
+ [o.allowInsecureRequests]: true,
67
+ [o.customFetch]: provider[customFetch],
68
+ })
69
+ as = await o.processDiscoveryResponse(issuer, discoveryResponse)
70
+
71
+ if (!as.token_endpoint)
72
+ throw new TypeError(
73
+ "TODO: Authorization server did not provide a token endpoint."
74
+ )
75
+
76
+ if (!as.userinfo_endpoint)
77
+ throw new TypeError(
78
+ "TODO: Authorization server did not provide a userinfo endpoint."
79
+ )
80
+ } else {
81
+ as = {
82
+ issuer: provider.issuer ?? "https://authjs.dev", // TODO: review fallback issuer
83
+ token_endpoint: token?.url.toString(),
84
+ userinfo_endpoint: userinfo?.url.toString(),
85
+ }
86
+ }
87
+
88
+ const client: o.Client = {
89
+ client_id: provider.clientId,
90
+ ...provider.client,
91
+ }
92
+
93
+ let clientAuth: o.ClientAuth
94
+
95
+ switch (client.token_endpoint_auth_method) {
96
+ // TODO: in the next breaking major version have undefined be `client_secret_post`
97
+ case undefined:
98
+ case "client_secret_basic":
99
+ // TODO: in the next breaking major version use o.ClientSecretBasic() here
100
+ clientAuth = (_as, _client, _body, headers) => {
101
+ headers.set(
102
+ "authorization",
103
+ clientSecretBasic(provider.clientId, provider.clientSecret!)
104
+ )
105
+ }
106
+ break
107
+ case "client_secret_post":
108
+ clientAuth = o.ClientSecretPost(provider.clientSecret!)
109
+ break
110
+ case "client_secret_jwt":
111
+ clientAuth = o.ClientSecretJwt(provider.clientSecret!)
112
+ break
113
+ case "private_key_jwt":
114
+ clientAuth = o.PrivateKeyJwt(provider.token!.clientPrivateKey!, {
115
+ // TODO: review in the next breaking change
116
+ [o.modifyAssertion](_header, payload) {
117
+ payload.aud = [as.issuer, as.token_endpoint!]
118
+ },
119
+ })
120
+ break
121
+ case "none":
122
+ clientAuth = o.None()
123
+ break
124
+ default:
125
+ throw new Error("unsupported client authentication method")
126
+ }
127
+
128
+ const resCookies: Cookie[] = []
129
+
130
+ const state = await checks.state.use(cookies, resCookies, options)
131
+
132
+ let codeGrantParams: URLSearchParams
133
+ try {
134
+ codeGrantParams = o.validateAuthResponse(
135
+ as,
136
+ client,
137
+ new URLSearchParams(params),
138
+ provider.checks.includes("state") ? state : o.skipStateCheck
139
+ )
140
+ } catch (err) {
141
+ if (err instanceof o.AuthorizationResponseError) {
142
+ const cause = {
143
+ providerId: provider.id,
144
+ ...Object.fromEntries(err.cause.entries()),
145
+ }
146
+ logger.debug("OAuthCallbackError", cause)
147
+ throw new OAuthCallbackError("OAuth Provider returned an error", cause)
148
+ }
149
+ throw err
150
+ }
151
+
152
+ const codeVerifier = await checks.pkce.use(cookies, resCookies, options)
153
+
154
+ let redirect_uri = provider.callbackUrl
155
+ if (!options.isOnRedirectProxy && provider.redirectProxyUrl) {
156
+ redirect_uri = provider.redirectProxyUrl
157
+ }
158
+
159
+ let codeGrantResponse = await o.authorizationCodeGrantRequest(
160
+ as,
161
+ client,
162
+ clientAuth,
163
+ codeGrantParams,
164
+ redirect_uri,
165
+ codeVerifier ?? "decoy",
166
+ {
167
+ // TODO: move away from allowing insecure HTTP requests
168
+ [o.allowInsecureRequests]: true,
169
+ [o.customFetch]: (...args) => {
170
+ if (!provider.checks.includes("pkce")) {
171
+ args[1].body.delete("code_verifier")
172
+ }
173
+ return (provider[customFetch] ?? fetch)(...args)
174
+ },
175
+ }
176
+ )
177
+
178
+ if (provider.token?.conform) {
179
+ codeGrantResponse =
180
+ (await provider.token.conform(codeGrantResponse.clone())) ??
181
+ codeGrantResponse
182
+ }
183
+
184
+ let profile: Profile = {}
185
+
186
+ const requireIdToken = isOIDCProvider(provider)
187
+
188
+ if (provider[conformInternal]) {
189
+ switch (provider.id) {
190
+ case "microsoft-entra-id":
191
+ case "azure-ad": {
192
+ /**
193
+ * These providers return errors in the response body and
194
+ * need the authorization server metadata to be re-processed
195
+ * based on the `id_token`'s `tid` claim.
196
+ * @see: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#error-response-1
197
+ */
198
+ const responseJson = await codeGrantResponse.clone().json()
199
+ if (responseJson.error) {
200
+ const cause = {
201
+ providerId: provider.id,
202
+ ...responseJson,
203
+ }
204
+ throw new OAuthCallbackError(
205
+ `OAuth Provider returned an error: ${responseJson.error}`,
206
+ cause
207
+ )
208
+ }
209
+ const { tid } = decodeJwt(responseJson.id_token)
210
+ if (typeof tid === "string") {
211
+ const tenantRe = /microsoftonline\.com\/(\w+)\/v2\.0/
212
+ const tenantId = as.issuer?.match(tenantRe)?.[1] ?? "common"
213
+ const issuer = new URL(as.issuer.replace(tenantId, tid))
214
+ const discoveryResponse = await o.discoveryRequest(issuer, {
215
+ [o.customFetch]: provider[customFetch],
216
+ })
217
+ as = await o.processDiscoveryResponse(issuer, discoveryResponse)
218
+ }
219
+ break
220
+ }
221
+ default:
222
+ break
223
+ }
224
+ }
225
+ const processedCodeResponse = await o.processAuthorizationCodeResponse(
226
+ as,
227
+ client,
228
+ codeGrantResponse,
229
+ {
230
+ expectedNonce: await checks.nonce.use(cookies, resCookies, options),
231
+ requireIdToken,
232
+ }
233
+ )
234
+
235
+ const tokens: TokenSet & Pick<Account, "expires_at"> = processedCodeResponse
236
+
237
+ if (requireIdToken) {
238
+ const idTokenClaims = o.getValidatedIdTokenClaims(processedCodeResponse)!
239
+ profile = idTokenClaims
240
+
241
+ // Apple sends some of the user information in a `user` parameter as a stringified JSON.
242
+ // It also only does so the first time the user consents to share their information.
243
+ if (provider[conformInternal] && provider.id === "apple") {
244
+ try {
245
+ profile.user = JSON.parse(params?.user)
246
+ } catch {}
247
+ }
248
+
249
+ if (provider.idToken === false) {
250
+ const userinfoResponse = await o.userInfoRequest(
251
+ as,
252
+ client,
253
+ processedCodeResponse.access_token,
254
+ {
255
+ [o.customFetch]: provider[customFetch],
256
+ // TODO: move away from allowing insecure HTTP requests
257
+ [o.allowInsecureRequests]: true,
258
+ }
259
+ )
260
+
261
+ profile = await o.processUserInfoResponse(
262
+ as,
263
+ client,
264
+ idTokenClaims.sub,
265
+ userinfoResponse
266
+ )
267
+ }
268
+ } else {
269
+ if (userinfo?.request) {
270
+ const _profile = await userinfo.request({ tokens, provider })
271
+ if (_profile instanceof Object) profile = _profile
272
+ } else if (userinfo?.url) {
273
+ const userinfoResponse = await o.userInfoRequest(
274
+ as,
275
+ client,
276
+ processedCodeResponse.access_token,
277
+ {
278
+ [o.customFetch]: provider[customFetch],
279
+ // TODO: move away from allowing insecure HTTP requests
280
+ [o.allowInsecureRequests]: true,
281
+ }
282
+ )
283
+ profile = await userinfoResponse.json()
284
+ } else {
285
+ throw new TypeError("No userinfo endpoint configured")
286
+ }
287
+ }
288
+
289
+ if (tokens.expires_in) {
290
+ tokens.expires_at =
291
+ Math.floor(Date.now() / 1000) + Number(tokens.expires_in)
292
+ }
293
+
294
+ const profileResult = await getUserAndAccount(
295
+ profile,
296
+ provider,
297
+ tokens,
298
+ logger
299
+ )
300
+
301
+ return { ...profileResult, profile, cookies: resCookies }
302
+ }
303
+
304
+ /**
305
+ * Returns the user and account that is going to be created in the database.
306
+ * @internal
307
+ */
308
+ export async function getUserAndAccount(
309
+ OAuthProfile: Profile,
310
+ provider: OAuthConfigInternal<any>,
311
+ tokens: TokenSet,
312
+ logger: LoggerInstance
313
+ ) {
314
+ try {
315
+ const userFromProfile = await provider.profile(OAuthProfile, tokens)
316
+ const user = {
317
+ ...userFromProfile,
318
+ // The user's id is intentionally not set based on the profile id, as
319
+ // the user should remain independent of the provider and the profile id
320
+ // is saved on the Account already, as `providerAccountId`.
321
+ id: crypto.randomUUID(),
322
+ email: userFromProfile.email?.toLowerCase(),
323
+ } satisfies User
324
+
325
+ return {
326
+ user,
327
+ account: {
328
+ ...tokens,
329
+ provider: provider.id,
330
+ type: provider.type,
331
+ providerAccountId: userFromProfile.id ?? crypto.randomUUID(),
332
+ },
333
+ }
334
+ } catch (e) {
335
+ // If we didn't get a response either there was a problem with the provider
336
+ // response *or* the user cancelled the action with the provider.
337
+ //
338
+ // Unfortunately, we can't tell which - at least not in a way that works for
339
+ // all providers, so we return an empty object; the user should then be
340
+ // redirected back to the sign up page. We log the error to help developers
341
+ // who might be trying to debug this when configuring a new provider.
342
+ logger.debug("getProfile error details", OAuthProfile)
343
+ logger.error(
344
+ new OAuthProfileParseError(e as Error, { provider: provider.id })
345
+ )
346
+ }
347
+ }
@@ -0,0 +1,258 @@
1
+ import * as o from "oauth4webapi"
2
+ import { InvalidCheck } from "../../../../errors.js"
3
+
4
+ // NOTE: We use the default JWT methods here because they encrypt/decrypt the payload, not just sign it.
5
+ import { decode, encode } from "../../../../jwt.js"
6
+
7
+ import type {
8
+ CookiesOptions,
9
+ InternalOptions,
10
+ RequestInternal,
11
+ User,
12
+ } from "../../../../types.js"
13
+ import type { Cookie } from "../../../utils/cookie.js"
14
+ import type { WebAuthnProviderType } from "../../../../providers/webauthn.js"
15
+
16
+ interface CookiePayload {
17
+ value: string
18
+ }
19
+
20
+ const COOKIE_TTL = 60 * 15 // 15 minutes
21
+
22
+ /** Returns a cookie with a JWT encrypted payload. */
23
+ async function sealCookie(
24
+ name: keyof CookiesOptions,
25
+ payload: string,
26
+ options: InternalOptions<"oauth" | "oidc" | WebAuthnProviderType>
27
+ ): Promise<Cookie> {
28
+ const { cookies, logger } = options
29
+ const cookie = cookies[name]
30
+ const expires = new Date()
31
+ expires.setTime(expires.getTime() + COOKIE_TTL * 1000)
32
+
33
+ logger.debug(`CREATE_${name.toUpperCase()}`, {
34
+ name: cookie.name,
35
+ payload,
36
+ COOKIE_TTL,
37
+ expires,
38
+ })
39
+
40
+ const encoded = await encode({
41
+ ...options.jwt,
42
+ maxAge: COOKIE_TTL,
43
+ token: { value: payload } satisfies CookiePayload,
44
+ salt: cookie.name,
45
+ })
46
+ const cookieOptions = { ...cookie.options, expires }
47
+ return { name: cookie.name, value: encoded, options: cookieOptions }
48
+ }
49
+
50
+ async function parseCookie(
51
+ name: keyof CookiesOptions,
52
+ value: string | undefined,
53
+ options: InternalOptions
54
+ ): Promise<string> {
55
+ try {
56
+ const { logger, cookies, jwt } = options
57
+ logger.debug(`PARSE_${name.toUpperCase()}`, { cookie: value })
58
+
59
+ if (!value) throw new InvalidCheck(`${name} cookie was missing`)
60
+ const parsed = await decode<CookiePayload>({
61
+ ...jwt,
62
+ token: value,
63
+ salt: cookies[name].name,
64
+ })
65
+ if (parsed?.value) return parsed.value
66
+ throw new Error("Invalid cookie")
67
+ } catch (error) {
68
+ throw new InvalidCheck(`${name} value could not be parsed`, {
69
+ cause: error,
70
+ })
71
+ }
72
+ }
73
+
74
+ function clearCookie(
75
+ name: keyof CookiesOptions,
76
+ options: InternalOptions,
77
+ resCookies: Cookie[]
78
+ ) {
79
+ const { logger, cookies } = options
80
+ const cookie = cookies[name]
81
+ logger.debug(`CLEAR_${name.toUpperCase()}`, { cookie })
82
+ resCookies.push({
83
+ name: cookie.name,
84
+ value: "",
85
+ options: { ...cookies[name].options, maxAge: 0 },
86
+ })
87
+ }
88
+
89
+ function useCookie(
90
+ check: "state" | "pkce" | "nonce",
91
+ name: keyof CookiesOptions
92
+ ) {
93
+ return async function (
94
+ cookies: RequestInternal["cookies"],
95
+ resCookies: Cookie[],
96
+ options: InternalOptions<"oidc">
97
+ ) {
98
+ const { provider, logger } = options
99
+ if (!provider?.checks?.includes(check)) return
100
+ const cookieValue = cookies?.[options.cookies[name].name]
101
+ logger.debug(`USE_${name.toUpperCase()}`, { value: cookieValue })
102
+ const parsed = await parseCookie(name, cookieValue, options)
103
+ clearCookie(name, options, resCookies)
104
+ return parsed
105
+ }
106
+ }
107
+
108
+ /**
109
+ * @see https://www.rfc-editor.org/rfc/rfc7636
110
+ * @see https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#pkce
111
+ */
112
+ export const pkce = {
113
+ /** Creates a PKCE code challenge and verifier pair. The verifier in stored in the cookie. */
114
+ async create(options: InternalOptions<"oauth">) {
115
+ const code_verifier = o.generateRandomCodeVerifier()
116
+ const value = await o.calculatePKCECodeChallenge(code_verifier)
117
+ const cookie = await sealCookie("pkceCodeVerifier", code_verifier, options)
118
+ return { cookie, value }
119
+ },
120
+ /**
121
+ * Returns code_verifier if the provider is configured to use PKCE,
122
+ * and clears the container cookie afterwards.
123
+ * An error is thrown if the code_verifier is missing or invalid.
124
+ */
125
+ use: useCookie("pkce", "pkceCodeVerifier"),
126
+ }
127
+
128
+ interface EncodedState {
129
+ origin?: string
130
+ random: string
131
+ }
132
+
133
+ const STATE_MAX_AGE = 60 * 15 // 15 minutes in seconds
134
+ const encodedStateSalt = "encodedState"
135
+
136
+ /**
137
+ * @see https://www.rfc-editor.org/rfc/rfc6749#section-10.12
138
+ * @see https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
139
+ */
140
+ export const state = {
141
+ /** Creates a state cookie with an optionally encoded body. */
142
+ async create(options: InternalOptions<"oauth">, origin?: string) {
143
+ const { provider } = options
144
+ if (!provider.checks.includes("state")) {
145
+ if (origin) {
146
+ throw new InvalidCheck(
147
+ "State data was provided but the provider is not configured to use state"
148
+ )
149
+ }
150
+ return
151
+ }
152
+
153
+ // IDEA: Allow the user to pass data to be stored in the state
154
+ const payload = {
155
+ origin,
156
+ random: o.generateRandomState(),
157
+ } satisfies EncodedState
158
+ const value = await encode({
159
+ secret: options.jwt.secret,
160
+ token: payload,
161
+ salt: encodedStateSalt,
162
+ maxAge: STATE_MAX_AGE,
163
+ })
164
+ const cookie = await sealCookie("state", value, options)
165
+
166
+ return { cookie, value }
167
+ },
168
+ /**
169
+ * Returns state if the provider is configured to use state,
170
+ * and clears the container cookie afterwards.
171
+ * An error is thrown if the state is missing or invalid.
172
+ */
173
+ use: useCookie("state", "state"),
174
+ /** Decodes the state. If it could not be decoded, it throws an error. */
175
+ async decode(state: string, options: InternalOptions) {
176
+ try {
177
+ options.logger.debug("DECODE_STATE", { state })
178
+ const payload = await decode<EncodedState>({
179
+ secret: options.jwt.secret,
180
+ token: state,
181
+ salt: encodedStateSalt,
182
+ })
183
+ if (payload) return payload
184
+ throw new Error("Invalid state")
185
+ } catch (error) {
186
+ throw new InvalidCheck("State could not be decoded", { cause: error })
187
+ }
188
+ },
189
+ }
190
+
191
+ export const nonce = {
192
+ async create(options: InternalOptions<"oidc">) {
193
+ if (!options.provider.checks.includes("nonce")) return
194
+ const value = o.generateRandomNonce()
195
+ const cookie = await sealCookie("nonce", value, options)
196
+ return { cookie, value }
197
+ },
198
+ /**
199
+ * Returns nonce if the provider is configured to use nonce,
200
+ * and clears the container cookie afterwards.
201
+ * An error is thrown if the nonce is missing or invalid.
202
+ * @see https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes
203
+ * @see https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#nonce
204
+ */
205
+ use: useCookie("nonce", "nonce"),
206
+ }
207
+
208
+ const WEBAUTHN_CHALLENGE_MAX_AGE = 60 * 15 // 15 minutes in seconds
209
+
210
+ interface WebAuthnChallengePayload {
211
+ challenge: string
212
+ registerData?: User
213
+ }
214
+
215
+ const webauthnChallengeSalt = "encodedWebauthnChallenge"
216
+ export const webauthnChallenge = {
217
+ async create(
218
+ options: InternalOptions<WebAuthnProviderType>,
219
+ challenge: string,
220
+ registerData?: User
221
+ ) {
222
+ return {
223
+ cookie: await sealCookie(
224
+ "webauthnChallenge",
225
+ await encode({
226
+ secret: options.jwt.secret,
227
+ token: { challenge, registerData } satisfies WebAuthnChallengePayload,
228
+ salt: webauthnChallengeSalt,
229
+ maxAge: WEBAUTHN_CHALLENGE_MAX_AGE,
230
+ }),
231
+ options
232
+ ),
233
+ }
234
+ },
235
+ /** Returns WebAuthn challenge if present. */
236
+ async use(
237
+ options: InternalOptions<WebAuthnProviderType>,
238
+ cookies: RequestInternal["cookies"],
239
+ resCookies: Cookie[]
240
+ ): Promise<WebAuthnChallengePayload> {
241
+ const cookieValue = cookies?.[options.cookies.webauthnChallenge.name]
242
+
243
+ const parsed = await parseCookie("webauthnChallenge", cookieValue, options)
244
+
245
+ const payload = await decode<WebAuthnChallengePayload>({
246
+ secret: options.jwt.secret,
247
+ token: parsed,
248
+ salt: webauthnChallengeSalt,
249
+ })
250
+
251
+ // Clear the WebAuthn challenge cookie after use
252
+ clearCookie("webauthnChallenge", options, resCookies)
253
+
254
+ if (!payload) throw new InvalidCheck("WebAuthn challenge was missing")
255
+
256
+ return payload
257
+ },
258
+ }
@@ -0,0 +1,60 @@
1
+ import { createHash, randomString } from "../../../utils/web.js"
2
+
3
+ import type { AuthAction, InternalOptions } from "../../../../types.js"
4
+ import { MissingCSRF } from "../../../../errors.js"
5
+ interface CreateCSRFTokenParams {
6
+ options: InternalOptions
7
+ cookieValue?: string
8
+ isPost: boolean
9
+ bodyValue?: string
10
+ }
11
+
12
+ /**
13
+ * Ensure CSRF Token cookie is set for any subsequent requests.
14
+ * Used as part of the strategy for mitigation for CSRF tokens.
15
+ *
16
+ * Creates a cookie like 'next-auth.csrf-token' with the value 'token|hash',
17
+ * where 'token' is the CSRF token and 'hash' is a hash made of the token and
18
+ * the secret, and the two values are joined by a pipe '|'. By storing the
19
+ * value and the hash of the value (with the secret used as a salt) we can
20
+ * verify the cookie was set by the server and not by a malicious attacker.
21
+ *
22
+ * For more details, see the following OWASP links:
23
+ * https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#double-submit-cookie
24
+ * https://owasp.org/www-chapter-london/assets/slides/David_Johansson-Double_Defeat_of_Double-Submit_Cookie.pdf
25
+ */
26
+ export async function createCSRFToken({
27
+ options,
28
+ cookieValue,
29
+ isPost,
30
+ bodyValue,
31
+ }: CreateCSRFTokenParams) {
32
+ if (cookieValue) {
33
+ const [csrfToken, csrfTokenHash] = cookieValue.split("|")
34
+
35
+ const expectedCsrfTokenHash = await createHash(
36
+ `${csrfToken}${options.secret}`
37
+ )
38
+
39
+ if (csrfTokenHash === expectedCsrfTokenHash) {
40
+ // If hash matches then we trust the CSRF token value
41
+ // If this is a POST request and the CSRF Token in the POST request matches
42
+ // the cookie we have already verified is the one we have set, then the token is verified!
43
+ const csrfTokenVerified = isPost && csrfToken === bodyValue
44
+
45
+ return { csrfTokenVerified, csrfToken }
46
+ }
47
+ }
48
+
49
+ // New CSRF token
50
+ const csrfToken = randomString(32)
51
+ const csrfTokenHash = await createHash(`${csrfToken}${options.secret}`)
52
+ const cookie = `${csrfToken}|${csrfTokenHash}`
53
+
54
+ return { cookie, csrfToken }
55
+ }
56
+
57
+ export function validateCSRF(action: AuthAction, verified?: boolean) {
58
+ if (verified) return
59
+ throw new MissingCSRF(`CSRF token was missing during an action ${action}`)
60
+ }
@@ -0,0 +1,5 @@
1
+ export { callback } from "./callback/index.js"
2
+ export { session } from "./session.js"
3
+ export { signIn } from "./signin/index.js"
4
+ export { signOut } from "./signout.js"
5
+ export { webAuthnOptions } from "./webauthn-options.js"