@effect-auth/core 0.1.0-alpha.16 → 0.1.0-alpha.19

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 (637) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +307 -133
  3. package/dist/AbuseProtection.d.ts +100 -0
  4. package/dist/AbuseProtection.d.ts.map +1 -0
  5. package/dist/AbuseProtection.js +71 -0
  6. package/dist/AbuseProtection.js.map +1 -0
  7. package/dist/AccessGrant.d.ts +344 -0
  8. package/dist/AccessGrant.d.ts.map +1 -0
  9. package/dist/AccessGrant.js +687 -0
  10. package/dist/AccessGrant.js.map +1 -0
  11. package/dist/ApiKey.d.ts +0 -12
  12. package/dist/ApiKey.d.ts.map +1 -1
  13. package/dist/ApiKey.js +36 -27
  14. package/dist/ApiKey.js.map +1 -1
  15. package/dist/Assurance.d.ts +415 -0
  16. package/dist/Assurance.d.ts.map +1 -0
  17. package/dist/Assurance.js +764 -0
  18. package/dist/Assurance.js.map +1 -0
  19. package/dist/AtomicPlanExecutor.d.ts +28 -0
  20. package/dist/AtomicPlanExecutor.d.ts.map +1 -0
  21. package/dist/AtomicPlanExecutor.js +5 -0
  22. package/dist/AtomicPlanExecutor.js.map +1 -0
  23. package/dist/AuditLog.d.ts +2314 -52
  24. package/dist/AuditLog.d.ts.map +1 -1
  25. package/dist/AuditLog.js +511 -33
  26. package/dist/AuditLog.js.map +1 -1
  27. package/dist/AuthFlow.d.ts +128 -38
  28. package/dist/AuthFlow.d.ts.map +1 -1
  29. package/dist/AuthFlow.js +611 -263
  30. package/dist/AuthFlow.js.map +1 -1
  31. package/dist/AuthRateLimit.d.ts +96 -0
  32. package/dist/AuthRateLimit.d.ts.map +1 -0
  33. package/dist/AuthRateLimit.js +212 -0
  34. package/dist/AuthRateLimit.js.map +1 -0
  35. package/dist/Challenge.d.ts +0 -3
  36. package/dist/Challenge.d.ts.map +1 -1
  37. package/dist/Challenge.js +1 -4
  38. package/dist/Challenge.js.map +1 -1
  39. package/dist/Client.d.ts +205 -10
  40. package/dist/Client.d.ts.map +1 -1
  41. package/dist/Client.js +397 -16
  42. package/dist/Client.js.map +1 -1
  43. package/dist/CloudflareTurnstile.d.ts +28 -0
  44. package/dist/CloudflareTurnstile.d.ts.map +1 -0
  45. package/dist/CloudflareTurnstile.js +205 -0
  46. package/dist/CloudflareTurnstile.js.map +1 -0
  47. package/dist/Crypto.d.ts +0 -3
  48. package/dist/Crypto.d.ts.map +1 -1
  49. package/dist/Crypto.js +1 -4
  50. package/dist/Crypto.js.map +1 -1
  51. package/dist/DelegatedAccessStorageMigrations.d.ts +7 -0
  52. package/dist/DelegatedAccessStorageMigrations.d.ts.map +1 -0
  53. package/dist/DelegatedAccessStorageMigrations.js +159 -0
  54. package/dist/DelegatedAccessStorageMigrations.js.map +1 -0
  55. package/dist/DevEmail.d.ts +44 -0
  56. package/dist/DevEmail.d.ts.map +1 -0
  57. package/dist/DevEmail.js +115 -0
  58. package/dist/DevEmail.js.map +1 -0
  59. package/dist/DevelopmentSeed.d.ts +47 -0
  60. package/dist/DevelopmentSeed.d.ts.map +1 -0
  61. package/dist/DevelopmentSeed.js +337 -0
  62. package/dist/DevelopmentSeed.js.map +1 -0
  63. package/dist/DisposableEmailDomains.d.ts +19 -0
  64. package/dist/DisposableEmailDomains.d.ts.map +1 -0
  65. package/dist/DisposableEmailDomains.js +85 -0
  66. package/dist/DisposableEmailDomains.js.map +1 -0
  67. package/dist/DomainVerification.d.ts +0 -9
  68. package/dist/DomainVerification.d.ts.map +1 -1
  69. package/dist/DomainVerification.js +36 -22
  70. package/dist/DomainVerification.js.map +1 -1
  71. package/dist/DrizzleBunSqliteStorage.d.ts +18 -0
  72. package/dist/DrizzleBunSqliteStorage.d.ts.map +1 -0
  73. package/dist/DrizzleBunSqliteStorage.js +11 -0
  74. package/dist/DrizzleBunSqliteStorage.js.map +1 -0
  75. package/dist/DrizzleD1SqliteStorage.d.ts +4 -4
  76. package/dist/DrizzleD1SqliteStorage.d.ts.map +1 -1
  77. package/dist/DrizzleD1SqliteStorage.js +5 -5
  78. package/dist/DrizzleD1SqliteStorage.js.map +1 -1
  79. package/dist/DrizzleEffectSqliteStorage.d.ts +13 -4
  80. package/dist/DrizzleEffectSqliteStorage.d.ts.map +1 -1
  81. package/dist/DrizzleEffectSqliteStorage.js +71 -4
  82. package/dist/DrizzleEffectSqliteStorage.js.map +1 -1
  83. package/dist/DrizzleNodeSqliteStorage.d.ts +18 -0
  84. package/dist/DrizzleNodeSqliteStorage.d.ts.map +1 -0
  85. package/dist/DrizzleNodeSqliteStorage.js +11 -0
  86. package/dist/DrizzleNodeSqliteStorage.js.map +1 -0
  87. package/dist/DrizzlePostgresStorage.d.ts +26 -0
  88. package/dist/DrizzlePostgresStorage.d.ts.map +1 -0
  89. package/dist/DrizzlePostgresStorage.js +14 -0
  90. package/dist/DrizzlePostgresStorage.js.map +1 -0
  91. package/dist/EffectQbPostgresDelegatedAccessStorage.d.ts +34 -0
  92. package/dist/EffectQbPostgresDelegatedAccessStorage.d.ts.map +1 -0
  93. package/dist/EffectQbPostgresDelegatedAccessStorage.js +499 -0
  94. package/dist/EffectQbPostgresDelegatedAccessStorage.js.map +1 -0
  95. package/dist/EffectQbPostgresStorage.d.ts +178 -0
  96. package/dist/EffectQbPostgresStorage.d.ts.map +1 -0
  97. package/dist/EffectQbPostgresStorage.js +4637 -0
  98. package/dist/EffectQbPostgresStorage.js.map +1 -0
  99. package/dist/EffectQbSqliteDelegatedAccessStorage.d.ts +112 -0
  100. package/dist/EffectQbSqliteDelegatedAccessStorage.d.ts.map +1 -0
  101. package/dist/EffectQbSqliteDelegatedAccessStorage.js +602 -0
  102. package/dist/EffectQbSqliteDelegatedAccessStorage.js.map +1 -0
  103. package/dist/EffectQbSqliteStorage.d.ts +221 -23
  104. package/dist/EffectQbSqliteStorage.d.ts.map +1 -1
  105. package/dist/EffectQbSqliteStorage.js +2064 -135
  106. package/dist/EffectQbSqliteStorage.js.map +1 -1
  107. package/dist/EmailAuth.d.ts +65 -0
  108. package/dist/EmailAuth.d.ts.map +1 -0
  109. package/dist/EmailAuth.js +171 -0
  110. package/dist/EmailAuth.js.map +1 -0
  111. package/dist/EmailIdentityAuth.d.ts +30 -0
  112. package/dist/EmailIdentityAuth.d.ts.map +1 -0
  113. package/dist/EmailIdentityAuth.js +142 -0
  114. package/dist/EmailIdentityAuth.js.map +1 -0
  115. package/dist/EmailOtp.d.ts +10 -11
  116. package/dist/EmailOtp.d.ts.map +1 -1
  117. package/dist/EmailOtp.js +44 -81
  118. package/dist/EmailOtp.js.map +1 -1
  119. package/dist/EmailRisk.d.ts +48 -0
  120. package/dist/EmailRisk.d.ts.map +1 -0
  121. package/dist/EmailRisk.js +33 -0
  122. package/dist/EmailRisk.js.map +1 -0
  123. package/dist/EmailVerification.d.ts +10 -16
  124. package/dist/EmailVerification.d.ts.map +1 -1
  125. package/dist/EmailVerification.js +85 -42
  126. package/dist/EmailVerification.js.map +1 -1
  127. package/dist/Guard.d.ts +11 -0
  128. package/dist/Guard.d.ts.map +1 -0
  129. package/dist/Guard.js +11 -0
  130. package/dist/Guard.js.map +1 -0
  131. package/dist/HibpPwnedPasswords.d.ts +56 -0
  132. package/dist/HibpPwnedPasswords.d.ts.map +1 -0
  133. package/dist/HibpPwnedPasswords.js +232 -0
  134. package/dist/HibpPwnedPasswords.js.map +1 -0
  135. package/dist/HttpApi/AdminPermissionDefinition.d.ts +4 -0
  136. package/dist/HttpApi/AdminPermissionDefinition.d.ts.map +1 -0
  137. package/dist/HttpApi/AdminPermissionDefinition.js +4 -0
  138. package/dist/HttpApi/AdminPermissionDefinition.js.map +1 -0
  139. package/dist/HttpApi/AdminSecurityTimeline.d.ts +4 -0
  140. package/dist/HttpApi/AdminSecurityTimeline.d.ts.map +1 -0
  141. package/dist/HttpApi/AdminSecurityTimeline.js +4 -0
  142. package/dist/HttpApi/AdminSecurityTimeline.js.map +1 -0
  143. package/dist/HttpApi/AdminSession.d.ts +4 -0
  144. package/dist/HttpApi/AdminSession.d.ts.map +1 -0
  145. package/dist/HttpApi/AdminSession.js +4 -0
  146. package/dist/HttpApi/AdminSession.js.map +1 -0
  147. package/dist/HttpApi/AdminTrustedDevice.d.ts +4 -0
  148. package/dist/HttpApi/AdminTrustedDevice.d.ts.map +1 -0
  149. package/dist/HttpApi/AdminTrustedDevice.js +4 -0
  150. package/dist/HttpApi/AdminTrustedDevice.js.map +1 -0
  151. package/dist/HttpApi/Api.d.ts +939 -884
  152. package/dist/HttpApi/Api.d.ts.map +1 -1
  153. package/dist/HttpApi/Api.js +2254 -940
  154. package/dist/HttpApi/Api.js.map +1 -1
  155. package/dist/HttpApi/ApiKey.d.ts +4 -0
  156. package/dist/HttpApi/ApiKey.d.ts.map +1 -0
  157. package/dist/HttpApi/ApiKey.js +4 -0
  158. package/dist/HttpApi/ApiKey.js.map +1 -0
  159. package/dist/HttpApi/Audit.d.ts +6 -0
  160. package/dist/HttpApi/Audit.d.ts.map +1 -0
  161. package/dist/HttpApi/Audit.js +10 -0
  162. package/dist/HttpApi/Audit.js.map +1 -0
  163. package/dist/HttpApi/ClientApi.d.ts +917 -0
  164. package/dist/HttpApi/ClientApi.d.ts.map +1 -0
  165. package/dist/HttpApi/ClientApi.js +101 -0
  166. package/dist/HttpApi/ClientApi.js.map +1 -0
  167. package/dist/HttpApi/EmailAuth.d.ts +6 -0
  168. package/dist/HttpApi/EmailAuth.d.ts.map +1 -0
  169. package/dist/HttpApi/EmailAuth.js +6 -0
  170. package/dist/HttpApi/EmailAuth.js.map +1 -0
  171. package/dist/HttpApi/EmailGuards.d.ts +115 -0
  172. package/dist/HttpApi/EmailGuards.d.ts.map +1 -0
  173. package/dist/HttpApi/EmailGuards.js +191 -0
  174. package/dist/HttpApi/EmailGuards.js.map +1 -0
  175. package/dist/HttpApi/EmailOtp.d.ts +6 -0
  176. package/dist/HttpApi/EmailOtp.d.ts.map +1 -0
  177. package/dist/HttpApi/EmailOtp.js +6 -0
  178. package/dist/HttpApi/EmailOtp.js.map +1 -0
  179. package/dist/HttpApi/EmailVerification.d.ts +6 -0
  180. package/dist/HttpApi/EmailVerification.d.ts.map +1 -0
  181. package/dist/HttpApi/EmailVerification.js +6 -0
  182. package/dist/HttpApi/EmailVerification.js.map +1 -0
  183. package/dist/HttpApi/Endpoints.d.ts +661 -301
  184. package/dist/HttpApi/Endpoints.d.ts.map +1 -1
  185. package/dist/HttpApi/Endpoints.js +207 -120
  186. package/dist/HttpApi/Endpoints.js.map +1 -1
  187. package/dist/HttpApi/Errors.d.ts +37 -10
  188. package/dist/HttpApi/Errors.d.ts.map +1 -1
  189. package/dist/HttpApi/Errors.js +42 -4
  190. package/dist/HttpApi/Errors.js.map +1 -1
  191. package/dist/HttpApi/Identity.d.ts +6 -0
  192. package/dist/HttpApi/Identity.d.ts.map +1 -0
  193. package/dist/HttpApi/Identity.js +6 -0
  194. package/dist/HttpApi/Identity.js.map +1 -0
  195. package/dist/HttpApi/IdentityGuards.d.ts +31 -0
  196. package/dist/HttpApi/IdentityGuards.d.ts.map +1 -0
  197. package/dist/HttpApi/IdentityGuards.js +33 -0
  198. package/dist/HttpApi/IdentityGuards.js.map +1 -0
  199. package/dist/HttpApi/Jwt.d.ts +4 -0
  200. package/dist/HttpApi/Jwt.d.ts.map +1 -0
  201. package/dist/HttpApi/Jwt.js +4 -0
  202. package/dist/HttpApi/Jwt.js.map +1 -0
  203. package/dist/HttpApi/JwtDiscovery.d.ts +4 -0
  204. package/dist/HttpApi/JwtDiscovery.d.ts.map +1 -0
  205. package/dist/HttpApi/JwtDiscovery.js +4 -0
  206. package/dist/HttpApi/JwtDiscovery.js.map +1 -0
  207. package/dist/HttpApi/LoginApproval.d.ts +5 -0
  208. package/dist/HttpApi/LoginApproval.d.ts.map +1 -0
  209. package/dist/HttpApi/LoginApproval.js +5 -0
  210. package/dist/HttpApi/LoginApproval.js.map +1 -0
  211. package/dist/HttpApi/LoginNotification.d.ts +5 -0
  212. package/dist/HttpApi/LoginNotification.d.ts.map +1 -0
  213. package/dist/HttpApi/LoginNotification.js +5 -0
  214. package/dist/HttpApi/LoginNotification.js.map +1 -0
  215. package/dist/HttpApi/MagicLink.d.ts +6 -0
  216. package/dist/HttpApi/MagicLink.d.ts.map +1 -0
  217. package/dist/HttpApi/MagicLink.js +6 -0
  218. package/dist/HttpApi/MagicLink.js.map +1 -0
  219. package/dist/HttpApi/Mfa.d.ts +5 -0
  220. package/dist/HttpApi/Mfa.d.ts.map +1 -0
  221. package/dist/HttpApi/Mfa.js +5 -0
  222. package/dist/HttpApi/Mfa.js.map +1 -0
  223. package/dist/HttpApi/Middleware.d.ts +26 -0
  224. package/dist/HttpApi/Middleware.d.ts.map +1 -0
  225. package/dist/HttpApi/Middleware.js +13 -0
  226. package/dist/HttpApi/Middleware.js.map +1 -0
  227. package/dist/HttpApi/OAuth.d.ts +4 -0
  228. package/dist/HttpApi/OAuth.d.ts.map +1 -0
  229. package/dist/HttpApi/OAuth.js +4 -0
  230. package/dist/HttpApi/OAuth.js.map +1 -0
  231. package/dist/HttpApi/OAuthDeviceAuthorization.d.ts +106 -0
  232. package/dist/HttpApi/OAuthDeviceAuthorization.d.ts.map +1 -0
  233. package/dist/HttpApi/OAuthDeviceAuthorization.js +415 -0
  234. package/dist/HttpApi/OAuthDeviceAuthorization.js.map +1 -0
  235. package/dist/HttpApi/OAuthProviderAuthorization.d.ts +4 -0
  236. package/dist/HttpApi/OAuthProviderAuthorization.d.ts.map +1 -0
  237. package/dist/HttpApi/OAuthProviderAuthorization.js +4 -0
  238. package/dist/HttpApi/OAuthProviderAuthorization.js.map +1 -0
  239. package/dist/HttpApi/OAuthToken.d.ts +4 -0
  240. package/dist/HttpApi/OAuthToken.d.ts.map +1 -0
  241. package/dist/HttpApi/OAuthToken.js +4 -0
  242. package/dist/HttpApi/OAuthToken.js.map +1 -0
  243. package/dist/HttpApi/OidcDiscovery.d.ts +4 -0
  244. package/dist/HttpApi/OidcDiscovery.d.ts.map +1 -0
  245. package/dist/HttpApi/OidcDiscovery.js +4 -0
  246. package/dist/HttpApi/OidcDiscovery.js.map +1 -0
  247. package/dist/HttpApi/Operations/AdminPermissionDefinition.d.ts +28 -0
  248. package/dist/HttpApi/Operations/AdminPermissionDefinition.d.ts.map +1 -0
  249. package/dist/HttpApi/Operations/AdminPermissionDefinition.js +5 -0
  250. package/dist/HttpApi/Operations/AdminPermissionDefinition.js.map +1 -0
  251. package/dist/HttpApi/Operations/AdminSession.d.ts +16 -0
  252. package/dist/HttpApi/Operations/AdminSession.d.ts.map +1 -0
  253. package/dist/HttpApi/Operations/AdminSession.js +5 -0
  254. package/dist/HttpApi/Operations/AdminSession.js.map +1 -0
  255. package/dist/HttpApi/Operations/ApiKey.d.ts +16 -0
  256. package/dist/HttpApi/Operations/ApiKey.d.ts.map +1 -0
  257. package/dist/HttpApi/Operations/ApiKey.js +5 -0
  258. package/dist/HttpApi/Operations/ApiKey.js.map +1 -0
  259. package/dist/HttpApi/Operations/Discovery.d.ts +19 -0
  260. package/dist/HttpApi/Operations/Discovery.d.ts.map +1 -0
  261. package/dist/HttpApi/Operations/Discovery.js +7 -0
  262. package/dist/HttpApi/Operations/Discovery.js.map +1 -0
  263. package/dist/HttpApi/Operations/EmailAuth.d.ts +12 -0
  264. package/dist/HttpApi/Operations/EmailAuth.d.ts.map +1 -0
  265. package/dist/HttpApi/Operations/EmailAuth.js +5 -0
  266. package/dist/HttpApi/Operations/EmailAuth.js.map +1 -0
  267. package/dist/HttpApi/Operations/EmailOtp.d.ts +14 -0
  268. package/dist/HttpApi/Operations/EmailOtp.d.ts.map +1 -0
  269. package/dist/HttpApi/Operations/EmailOtp.js +5 -0
  270. package/dist/HttpApi/Operations/EmailOtp.js.map +1 -0
  271. package/dist/HttpApi/Operations/EmailVerification.d.ts +14 -0
  272. package/dist/HttpApi/Operations/EmailVerification.d.ts.map +1 -0
  273. package/dist/HttpApi/Operations/EmailVerification.js +5 -0
  274. package/dist/HttpApi/Operations/EmailVerification.js.map +1 -0
  275. package/dist/HttpApi/Operations/HttpOperation.d.ts +4 -0
  276. package/dist/HttpApi/Operations/HttpOperation.d.ts.map +1 -0
  277. package/dist/HttpApi/Operations/HttpOperation.js +2 -0
  278. package/dist/HttpApi/Operations/HttpOperation.js.map +1 -0
  279. package/dist/HttpApi/Operations/Identity.d.ts +22 -0
  280. package/dist/HttpApi/Operations/Identity.d.ts.map +1 -0
  281. package/dist/HttpApi/Operations/Identity.js +5 -0
  282. package/dist/HttpApi/Operations/Identity.js.map +1 -0
  283. package/dist/HttpApi/Operations/Jwt.d.ts +14 -0
  284. package/dist/HttpApi/Operations/Jwt.d.ts.map +1 -0
  285. package/dist/HttpApi/Operations/Jwt.js +5 -0
  286. package/dist/HttpApi/Operations/Jwt.js.map +1 -0
  287. package/dist/HttpApi/Operations/LoginApproval.d.ts +16 -0
  288. package/dist/HttpApi/Operations/LoginApproval.d.ts.map +1 -0
  289. package/dist/HttpApi/Operations/LoginApproval.js +5 -0
  290. package/dist/HttpApi/Operations/LoginApproval.js.map +1 -0
  291. package/dist/HttpApi/Operations/MagicLink.d.ts +14 -0
  292. package/dist/HttpApi/Operations/MagicLink.d.ts.map +1 -0
  293. package/dist/HttpApi/Operations/MagicLink.js +5 -0
  294. package/dist/HttpApi/Operations/MagicLink.js.map +1 -0
  295. package/dist/HttpApi/Operations/Mfa.d.ts +24 -0
  296. package/dist/HttpApi/Operations/Mfa.d.ts.map +1 -0
  297. package/dist/HttpApi/Operations/Mfa.js +5 -0
  298. package/dist/HttpApi/Operations/Mfa.js.map +1 -0
  299. package/dist/HttpApi/Operations/OAuth.d.ts +20 -0
  300. package/dist/HttpApi/Operations/OAuth.d.ts.map +1 -0
  301. package/dist/HttpApi/Operations/OAuth.js +5 -0
  302. package/dist/HttpApi/Operations/OAuth.js.map +1 -0
  303. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts +23 -0
  304. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts.map +1 -0
  305. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js +7 -0
  306. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js.map +1 -0
  307. package/dist/HttpApi/Operations/OAuthProviderAuthorization.d.ts +12 -0
  308. package/dist/HttpApi/Operations/OAuthProviderAuthorization.d.ts.map +1 -0
  309. package/dist/HttpApi/Operations/OAuthProviderAuthorization.js +5 -0
  310. package/dist/HttpApi/Operations/OAuthProviderAuthorization.js.map +1 -0
  311. package/dist/HttpApi/Operations/OAuthToken.d.ts +26 -0
  312. package/dist/HttpApi/Operations/OAuthToken.d.ts.map +1 -0
  313. package/dist/HttpApi/Operations/OAuthToken.js +9 -0
  314. package/dist/HttpApi/Operations/OAuthToken.js.map +1 -0
  315. package/dist/HttpApi/Operations/Passkey.d.ts +22 -0
  316. package/dist/HttpApi/Operations/Passkey.d.ts.map +1 -0
  317. package/dist/HttpApi/Operations/Passkey.js +5 -0
  318. package/dist/HttpApi/Operations/Passkey.js.map +1 -0
  319. package/dist/HttpApi/Operations/Password.d.ts +22 -0
  320. package/dist/HttpApi/Operations/Password.d.ts.map +1 -0
  321. package/dist/HttpApi/Operations/Password.js +5 -0
  322. package/dist/HttpApi/Operations/Password.js.map +1 -0
  323. package/dist/HttpApi/Operations/RecoveryCodes.d.ts +20 -0
  324. package/dist/HttpApi/Operations/RecoveryCodes.d.ts.map +1 -0
  325. package/dist/HttpApi/Operations/RecoveryCodes.js +5 -0
  326. package/dist/HttpApi/Operations/RecoveryCodes.js.map +1 -0
  327. package/dist/HttpApi/Operations/RefreshToken.d.ts +12 -0
  328. package/dist/HttpApi/Operations/RefreshToken.d.ts.map +1 -0
  329. package/dist/HttpApi/Operations/RefreshToken.js +5 -0
  330. package/dist/HttpApi/Operations/RefreshToken.js.map +1 -0
  331. package/dist/HttpApi/Operations/Security.d.ts +12 -0
  332. package/dist/HttpApi/Operations/Security.d.ts.map +1 -0
  333. package/dist/HttpApi/Operations/Security.js +5 -0
  334. package/dist/HttpApi/Operations/Security.js.map +1 -0
  335. package/dist/HttpApi/Operations/SecurityTimeline.d.ts +19 -0
  336. package/dist/HttpApi/Operations/SecurityTimeline.d.ts.map +1 -0
  337. package/dist/HttpApi/Operations/SecurityTimeline.js +7 -0
  338. package/dist/HttpApi/Operations/SecurityTimeline.js.map +1 -0
  339. package/dist/HttpApi/Operations/Session.d.ts +22 -0
  340. package/dist/HttpApi/Operations/Session.d.ts.map +1 -0
  341. package/dist/HttpApi/Operations/Session.js +5 -0
  342. package/dist/HttpApi/Operations/Session.js.map +1 -0
  343. package/dist/HttpApi/Operations/StepUp.d.ts +22 -0
  344. package/dist/HttpApi/Operations/StepUp.d.ts.map +1 -0
  345. package/dist/HttpApi/Operations/StepUp.js +5 -0
  346. package/dist/HttpApi/Operations/StepUp.js.map +1 -0
  347. package/dist/HttpApi/Operations/Totp.d.ts +20 -0
  348. package/dist/HttpApi/Operations/Totp.d.ts.map +1 -0
  349. package/dist/HttpApi/Operations/Totp.js +5 -0
  350. package/dist/HttpApi/Operations/Totp.js.map +1 -0
  351. package/dist/HttpApi/Operations/TrustedDevice.d.ts +23 -0
  352. package/dist/HttpApi/Operations/TrustedDevice.d.ts.map +1 -0
  353. package/dist/HttpApi/Operations/TrustedDevice.js +7 -0
  354. package/dist/HttpApi/Operations/TrustedDevice.js.map +1 -0
  355. package/dist/HttpApi/Operations/index.d.ts +28 -0
  356. package/dist/HttpApi/Operations/index.d.ts.map +1 -0
  357. package/dist/HttpApi/Operations/index.js +28 -0
  358. package/dist/HttpApi/Operations/index.js.map +1 -0
  359. package/dist/HttpApi/Passkey.d.ts +5 -0
  360. package/dist/HttpApi/Passkey.d.ts.map +1 -0
  361. package/dist/HttpApi/Passkey.js +5 -0
  362. package/dist/HttpApi/Passkey.js.map +1 -0
  363. package/dist/HttpApi/Password.d.ts +220 -0
  364. package/dist/HttpApi/Password.d.ts.map +1 -0
  365. package/dist/HttpApi/Password.js +237 -0
  366. package/dist/HttpApi/Password.js.map +1 -0
  367. package/dist/HttpApi/PasswordContract.d.ts +307 -0
  368. package/dist/HttpApi/PasswordContract.d.ts.map +1 -0
  369. package/dist/HttpApi/PasswordContract.js +63 -0
  370. package/dist/HttpApi/PasswordContract.js.map +1 -0
  371. package/dist/HttpApi/PasswordGuards.d.ts +82 -0
  372. package/dist/HttpApi/PasswordGuards.d.ts.map +1 -0
  373. package/dist/HttpApi/PasswordGuards.js +179 -0
  374. package/dist/HttpApi/PasswordGuards.js.map +1 -0
  375. package/dist/HttpApi/RecoveryCodes.d.ts +5 -0
  376. package/dist/HttpApi/RecoveryCodes.d.ts.map +1 -0
  377. package/dist/HttpApi/RecoveryCodes.js +5 -0
  378. package/dist/HttpApi/RecoveryCodes.js.map +1 -0
  379. package/dist/HttpApi/RefreshToken.d.ts +4 -0
  380. package/dist/HttpApi/RefreshToken.d.ts.map +1 -0
  381. package/dist/HttpApi/RefreshToken.js +4 -0
  382. package/dist/HttpApi/RefreshToken.js.map +1 -0
  383. package/dist/HttpApi/RequestGuards.d.ts +42 -0
  384. package/dist/HttpApi/RequestGuards.d.ts.map +1 -0
  385. package/dist/HttpApi/RequestGuards.js +194 -0
  386. package/dist/HttpApi/RequestGuards.js.map +1 -0
  387. package/dist/HttpApi/Schemas.d.ts +399 -84
  388. package/dist/HttpApi/Schemas.d.ts.map +1 -1
  389. package/dist/HttpApi/Schemas.js +225 -27
  390. package/dist/HttpApi/Schemas.js.map +1 -1
  391. package/dist/HttpApi/Security.d.ts +12 -93
  392. package/dist/HttpApi/Security.d.ts.map +1 -1
  393. package/dist/HttpApi/Security.js +65 -356
  394. package/dist/HttpApi/Security.js.map +1 -1
  395. package/dist/HttpApi/SecurityTimeline.d.ts +4 -0
  396. package/dist/HttpApi/SecurityTimeline.d.ts.map +1 -0
  397. package/dist/HttpApi/SecurityTimeline.js +4 -0
  398. package/dist/HttpApi/SecurityTimeline.js.map +1 -0
  399. package/dist/HttpApi/Session.d.ts +5 -0
  400. package/dist/HttpApi/Session.d.ts.map +1 -0
  401. package/dist/HttpApi/Session.js +5 -0
  402. package/dist/HttpApi/Session.js.map +1 -0
  403. package/dist/HttpApi/SessionGuards.d.ts +15 -0
  404. package/dist/HttpApi/SessionGuards.d.ts.map +1 -0
  405. package/dist/HttpApi/SessionGuards.js +37 -0
  406. package/dist/HttpApi/SessionGuards.js.map +1 -0
  407. package/dist/HttpApi/StepUp.d.ts +5 -0
  408. package/dist/HttpApi/StepUp.d.ts.map +1 -0
  409. package/dist/HttpApi/StepUp.js +5 -0
  410. package/dist/HttpApi/StepUp.js.map +1 -0
  411. package/dist/HttpApi/Totp.d.ts +5 -0
  412. package/dist/HttpApi/Totp.d.ts.map +1 -0
  413. package/dist/HttpApi/Totp.js +5 -0
  414. package/dist/HttpApi/Totp.js.map +1 -0
  415. package/dist/HttpApi/Transport.d.ts +4 -6
  416. package/dist/HttpApi/Transport.d.ts.map +1 -1
  417. package/dist/HttpApi/Transport.js +62 -36
  418. package/dist/HttpApi/Transport.js.map +1 -1
  419. package/dist/HttpApi/TrustedDevice.d.ts +4 -0
  420. package/dist/HttpApi/TrustedDevice.d.ts.map +1 -0
  421. package/dist/HttpApi/TrustedDevice.js +4 -0
  422. package/dist/HttpApi/TrustedDevice.js.map +1 -0
  423. package/dist/HttpApi/index.d.ts +11 -3
  424. package/dist/HttpApi/index.d.ts.map +1 -1
  425. package/dist/HttpApi/index.js +10 -2
  426. package/dist/HttpApi/index.js.map +1 -1
  427. package/dist/Identity.d.ts +138 -0
  428. package/dist/Identity.d.ts.map +1 -0
  429. package/dist/Identity.js +105 -0
  430. package/dist/Identity.js.map +1 -0
  431. package/dist/IdentityManagement.d.ts +189 -0
  432. package/dist/IdentityManagement.d.ts.map +1 -0
  433. package/dist/IdentityManagement.js +317 -0
  434. package/dist/IdentityManagement.js.map +1 -0
  435. package/dist/IncidentAction.d.ts +1 -4
  436. package/dist/IncidentAction.d.ts.map +1 -1
  437. package/dist/IncidentAction.js +15 -9
  438. package/dist/IncidentAction.js.map +1 -1
  439. package/dist/Internal.d.ts +2 -0
  440. package/dist/Internal.d.ts.map +1 -1
  441. package/dist/Internal.js +30 -0
  442. package/dist/Internal.js.map +1 -1
  443. package/dist/Invitation.d.ts +362 -0
  444. package/dist/Invitation.d.ts.map +1 -0
  445. package/dist/Invitation.js +633 -0
  446. package/dist/Invitation.js.map +1 -0
  447. package/dist/IpQualityScore.d.ts +38 -0
  448. package/dist/IpQualityScore.d.ts.map +1 -0
  449. package/dist/IpQualityScore.js +215 -0
  450. package/dist/IpQualityScore.js.map +1 -0
  451. package/dist/Jwt.d.ts +8 -29
  452. package/dist/Jwt.d.ts.map +1 -1
  453. package/dist/Jwt.js +67 -56
  454. package/dist/Jwt.js.map +1 -1
  455. package/dist/LoginApproval.d.ts +15 -30
  456. package/dist/LoginApproval.d.ts.map +1 -1
  457. package/dist/LoginApproval.js +47 -41
  458. package/dist/LoginApproval.js.map +1 -1
  459. package/dist/LoginNotification.d.ts +7 -11
  460. package/dist/LoginNotification.d.ts.map +1 -1
  461. package/dist/LoginNotification.js +30 -17
  462. package/dist/LoginNotification.js.map +1 -1
  463. package/dist/LoginRisk.d.ts +11 -13
  464. package/dist/LoginRisk.d.ts.map +1 -1
  465. package/dist/LoginRisk.js +66 -26
  466. package/dist/LoginRisk.js.map +1 -1
  467. package/dist/LoginRiskEnrichment.d.ts +145 -0
  468. package/dist/LoginRiskEnrichment.d.ts.map +1 -0
  469. package/dist/LoginRiskEnrichment.js +220 -0
  470. package/dist/LoginRiskEnrichment.js.map +1 -0
  471. package/dist/MagicLink.d.ts +9 -8
  472. package/dist/MagicLink.d.ts.map +1 -1
  473. package/dist/MagicLink.js +40 -73
  474. package/dist/MagicLink.js.map +1 -1
  475. package/dist/Mailer.d.ts +19 -12
  476. package/dist/Mailer.d.ts.map +1 -1
  477. package/dist/Mailer.js +10 -12
  478. package/dist/Mailer.js.map +1 -1
  479. package/dist/OAuth.d.ts +138 -96
  480. package/dist/OAuth.d.ts.map +1 -1
  481. package/dist/OAuth.js +522 -221
  482. package/dist/OAuth.js.map +1 -1
  483. package/dist/OAuthDeviceAuthorization.d.ts +378 -0
  484. package/dist/OAuthDeviceAuthorization.d.ts.map +1 -0
  485. package/dist/OAuthDeviceAuthorization.js +860 -0
  486. package/dist/OAuthDeviceAuthorization.js.map +1 -0
  487. package/dist/OAuthDeviceClient.d.ts +76 -0
  488. package/dist/OAuthDeviceClient.d.ts.map +1 -0
  489. package/dist/OAuthDeviceClient.js +362 -0
  490. package/dist/OAuthDeviceClient.js.map +1 -0
  491. package/dist/Passkey.d.ts +15 -17
  492. package/dist/Passkey.d.ts.map +1 -1
  493. package/dist/Passkey.js +86 -39
  494. package/dist/Passkey.js.map +1 -1
  495. package/dist/PasskeyBrowser.d.ts +39 -0
  496. package/dist/PasskeyBrowser.d.ts.map +1 -0
  497. package/dist/PasskeyBrowser.js +206 -0
  498. package/dist/PasskeyBrowser.js.map +1 -0
  499. package/dist/PasskeySimpleWebAuthn.d.ts.map +1 -1
  500. package/dist/PasskeySimpleWebAuthn.js +19 -7
  501. package/dist/PasskeySimpleWebAuthn.js.map +1 -1
  502. package/dist/Password.d.ts +71 -37
  503. package/dist/Password.d.ts.map +1 -1
  504. package/dist/Password.js +295 -81
  505. package/dist/Password.js.map +1 -1
  506. package/dist/PasswordRisk.d.ts +63 -0
  507. package/dist/PasswordRisk.d.ts.map +1 -0
  508. package/dist/PasswordRisk.js +37 -0
  509. package/dist/PasswordRisk.js.map +1 -0
  510. package/dist/Permission.d.ts +308 -0
  511. package/dist/Permission.d.ts.map +1 -0
  512. package/dist/Permission.js +827 -0
  513. package/dist/Permission.js.map +1 -0
  514. package/dist/Policy.d.ts +31 -18
  515. package/dist/Policy.d.ts.map +1 -1
  516. package/dist/Policy.js +58 -14
  517. package/dist/Policy.js.map +1 -1
  518. package/dist/PostgresDelegatedAccessStorageMigrations.d.ts +7 -0
  519. package/dist/PostgresDelegatedAccessStorageMigrations.d.ts.map +1 -0
  520. package/dist/PostgresDelegatedAccessStorageMigrations.js +119 -0
  521. package/dist/PostgresDelegatedAccessStorageMigrations.js.map +1 -0
  522. package/dist/PostgresStorageMigrations.d.ts +16 -0
  523. package/dist/PostgresStorageMigrations.d.ts.map +1 -0
  524. package/dist/PostgresStorageMigrations.js +674 -0
  525. package/dist/PostgresStorageMigrations.js.map +1 -0
  526. package/dist/Privacy.d.ts +0 -3
  527. package/dist/Privacy.d.ts.map +1 -1
  528. package/dist/Privacy.js +2 -5
  529. package/dist/Privacy.js.map +1 -1
  530. package/dist/RateLimiter.d.ts +0 -3
  531. package/dist/RateLimiter.d.ts.map +1 -1
  532. package/dist/RateLimiter.js +1 -4
  533. package/dist/RateLimiter.js.map +1 -1
  534. package/dist/RecoveryCode.d.ts +83 -11
  535. package/dist/RecoveryCode.d.ts.map +1 -1
  536. package/dist/RecoveryCode.js +273 -75
  537. package/dist/RecoveryCode.js.map +1 -1
  538. package/dist/RecoveryPolicy.d.ts +81 -0
  539. package/dist/RecoveryPolicy.d.ts.map +1 -0
  540. package/dist/RecoveryPolicy.js +119 -0
  541. package/dist/RecoveryPolicy.js.map +1 -0
  542. package/dist/RefreshToken.d.ts +0 -9
  543. package/dist/RefreshToken.d.ts.map +1 -1
  544. package/dist/RefreshToken.js +31 -22
  545. package/dist/RefreshToken.js.map +1 -1
  546. package/dist/Retention.d.ts +6 -1
  547. package/dist/Retention.d.ts.map +1 -1
  548. package/dist/Retention.js +49 -12
  549. package/dist/Retention.js.map +1 -1
  550. package/dist/SecurityTimeline.d.ts +1 -4
  551. package/dist/SecurityTimeline.d.ts.map +1 -1
  552. package/dist/SecurityTimeline.js +110 -17
  553. package/dist/SecurityTimeline.js.map +1 -1
  554. package/dist/Sessions.d.ts +124 -29
  555. package/dist/Sessions.d.ts.map +1 -1
  556. package/dist/Sessions.js +626 -94
  557. package/dist/Sessions.js.map +1 -1
  558. package/dist/SqliteStorageSchemaData.d.ts +2 -0
  559. package/dist/SqliteStorageSchemaData.d.ts.map +1 -0
  560. package/dist/SqliteStorageSchemaData.js +508 -0
  561. package/dist/SqliteStorageSchemaData.js.map +1 -0
  562. package/dist/StepUp.d.ts +132 -11
  563. package/dist/StepUp.d.ts.map +1 -1
  564. package/dist/StepUp.js +387 -19
  565. package/dist/StepUp.js.map +1 -1
  566. package/dist/Storage.d.ts +89 -23
  567. package/dist/Storage.d.ts.map +1 -1
  568. package/dist/Storage.js +10 -12
  569. package/dist/Storage.js.map +1 -1
  570. package/dist/StorageMigrations.d.ts +7 -1
  571. package/dist/StorageMigrations.d.ts.map +1 -1
  572. package/dist/StorageMigrations.js +256 -0
  573. package/dist/StorageMigrations.js.map +1 -1
  574. package/dist/StorageSchemaGenerator.d.ts +544 -0
  575. package/dist/StorageSchemaGenerator.d.ts.map +1 -0
  576. package/dist/StorageSchemaGenerator.js +1418 -0
  577. package/dist/StorageSchemaGenerator.js.map +1 -0
  578. package/dist/StrongFactor.d.ts +64 -0
  579. package/dist/StrongFactor.d.ts.map +1 -0
  580. package/dist/StrongFactor.js +100 -0
  581. package/dist/StrongFactor.js.map +1 -0
  582. package/dist/Testing.js +2 -2
  583. package/dist/Testing.js.map +1 -1
  584. package/dist/Totp.d.ts +88 -13
  585. package/dist/Totp.d.ts.map +1 -1
  586. package/dist/Totp.js +192 -34
  587. package/dist/Totp.js.map +1 -1
  588. package/dist/TrustedDevice.d.ts +0 -9
  589. package/dist/TrustedDevice.d.ts.map +1 -1
  590. package/dist/TrustedDevice.js +15 -17
  591. package/dist/TrustedDevice.js.map +1 -1
  592. package/dist/WaitUntil.d.ts +0 -3
  593. package/dist/WaitUntil.d.ts.map +1 -1
  594. package/dist/WaitUntil.js +1 -4
  595. package/dist/WaitUntil.js.map +1 -1
  596. package/dist/Webhook.d.ts +42 -12
  597. package/dist/Webhook.d.ts.map +1 -1
  598. package/dist/Webhook.js +165 -26
  599. package/dist/Webhook.js.map +1 -1
  600. package/dist/alchemy/cloudflare/Email.d.ts.map +1 -1
  601. package/dist/alchemy/cloudflare/Email.js +9 -4
  602. package/dist/alchemy/cloudflare/Email.js.map +1 -1
  603. package/dist/cloudflare/Email.js +1 -1
  604. package/dist/cloudflare/Email.js.map +1 -1
  605. package/dist/cloudflare/RequestMetadata.d.ts +49 -0
  606. package/dist/cloudflare/RequestMetadata.d.ts.map +1 -0
  607. package/dist/cloudflare/RequestMetadata.js +71 -0
  608. package/dist/cloudflare/RequestMetadata.js.map +1 -0
  609. package/dist/index.d.ts +0 -35
  610. package/dist/index.d.ts.map +1 -1
  611. package/dist/index.js +0 -35
  612. package/dist/index.js.map +1 -1
  613. package/dist/internal/AuthFlowFinalizer.d.ts +31 -0
  614. package/dist/internal/AuthFlowFinalizer.d.ts.map +1 -0
  615. package/dist/internal/AuthFlowFinalizer.js +182 -0
  616. package/dist/internal/AuthFlowFinalizer.js.map +1 -0
  617. package/migrations/0001_auth_storage.sql +1 -0
  618. package/migrations/0006_auth_totp_factor.sql +1 -0
  619. package/migrations/0024_auth_permission.sql +39 -0
  620. package/migrations/0025_auth_permission_definition.sql +19 -0
  621. package/migrations/0026_auth_user_identity.sql +59 -0
  622. package/migrations/0027_auth_audit_log_storage_order.sql +46 -0
  623. package/migrations/0028_auth_oauth_client_secret_key.sql +39 -0
  624. package/migrations/0029_auth_oauth_device_authorization.sql +28 -0
  625. package/migrations/delegated-access/0001_auth_delegated_access.sql +152 -0
  626. package/migrations/postgres/0001_auth_core.sql +77 -0
  627. package/migrations/postgres/0002_auth_security_oauth.sql +65 -0
  628. package/migrations/postgres/0003_auth_credentials_tokens.sql +43 -0
  629. package/migrations/postgres/0004_auth_security_history.sql +103 -0
  630. package/migrations/postgres/0005_auth_webhooks.sql +29 -0
  631. package/migrations/postgres/0006_auth_domain_timeline.sql +50 -0
  632. package/migrations/postgres/0007_auth_oauth_clients.sql +85 -0
  633. package/migrations/postgres/0008_auth_oauth_tokens.sql +63 -0
  634. package/migrations/postgres/0009_auth_permissions.sql +66 -0
  635. package/migrations/postgres/0010_auth_oauth_device_authorization.sql +50 -0
  636. package/migrations/postgres/delegated-access/0001_auth_delegated_access.sql +112 -0
  637. package/package.json +309 -2
@@ -1,80 +1,53 @@
1
- import { Context, Effect, Encoding, Layer, Option, Redacted, Result } from "effect";
2
- import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http";
1
+ import { Context, Data, Effect, Encoding, Layer, Option, Redacted, Result, } from "effect";
2
+ import { HttpRouter, HttpServerRequest, HttpServerResponse, } from "effect/unstable/http";
3
3
  import { HttpApi, HttpApiBuilder, HttpApiGroup } from "effect/unstable/httpapi";
4
- import { ApiKeyId } from "../ApiKey.js";
5
- import { Jwks } from "../Jwt.js";
4
+ import { BotChallengeVerifier, BotProtectionNoopLive, } from "../AbuseProtection.js";
5
+ import { ApiKeyId, ApiKeyManagement } from "../ApiKey.js";
6
+ import { passkeyEvidence, passwordEvidence, recoveryCodeEvidence, totpEvidence, } from "../Assurance.js";
7
+ import * as Audit from "../AuditLog.js";
6
8
  import { AuthFlow, AuthFlowState, AuthResult, LoginApprovalFinalize, } from "../AuthFlow.js";
9
+ import { AuthRateLimit } from "../AuthRateLimit.js";
10
+ import { EmailAuth } from "../EmailAuth.js";
7
11
  import { EmailOtpLogin } from "../EmailOtp.js";
12
+ import { EmailRiskProviderUnavailableError } from "../EmailRisk.js";
8
13
  import { EmailDeliveryError, EmailVerification, EmailVerificationFlow, EmailVerificationIssueError, } from "../EmailVerification.js";
9
- import { OAuthClientId as makeOAuthClientId } from "../Identifiers.js";
14
+ import { ChallengeId, CredentialId, OAuthClientId as makeOAuthClientId, } from "../Identifiers.js";
15
+ import { IdentityAlreadyExistsError, IdentityConcurrentModificationError, IdentityInactiveError, IdentityIdGenerationError, IdentityManagement, IdentityManagementStorageError, IdentityMutationDeniedError, IdentityNotFoundError, IdentityNotLoginEligibleError, IdentityOwnershipError, IdentityUserNotActiveError, LastLoginIdentityError, } from "../IdentityManagement.js";
10
16
  import { currentUnixMillis } from "../Internal.js";
17
+ import { AuthFlowFinalizer, AuthFlowFinalizerLive, } from "../internal/AuthFlowFinalizer.js";
18
+ import { Jwks, JwtIssuer, JwtRevocation } from "../Jwt.js";
11
19
  import { LoginApproval, LoginApprovalReview } from "../LoginApproval.js";
12
20
  import { LoginNotification } from "../LoginNotification.js";
13
21
  import { MagicLinkLogin } from "../MagicLink.js";
14
- import { OAuthAuthorizationCode, OAuthAuthorizationCodeTokenGrant, OAuthClientCredentialsGrant, OAuthProviderAuthorization, OAuthRefreshToken, OAuthRefreshTokenGrant, OAuthTokenIntrospection, OAuthTokenRevocation, OAuthCodeVerifier as makeOAuthCodeVerifier, } from "../OAuth.js";
15
- import { PasswordLogin, PasswordManagement, PasswordRegistration, PasswordReset, } from "../Password.js";
16
- import { PasskeyCredentialId } from "../Passkey.js";
17
- import { CurrentSession, SessionCookie, Sessions, sessionRequestMetadataKey, upgradeCurrentSession, } from "../Sessions.js";
22
+ import { OAuthAuthorizationCode, OAuthAuthorizationCodeTokenGrant, OAuthAccountUnlinking, OAuthClientCredentialsGrant, OAuthProviderAuthorization, OAuthProviders, OAuthRefreshToken, OAuthRefreshTokenGrant, OAuthTokenIntrospection, OAuthTokenRevocation, OAuthLinkConfirmation, OAuthState, OAuthCodeVerifier as makeOAuthCodeVerifier, } from "../OAuth.js";
23
+ import { oauthDeviceCodeGrantType, OAuthDeviceCode, OAuthDeviceCodeTokenGrant, } from "../OAuthDeviceAuthorization.js";
24
+ import { PasskeyCredentialId, PasskeyCredentialManagement, PasskeyOptions, PasskeyVerification, } from "../Passkey.js";
25
+ import { PasswordHasher } from "../Password.js";
26
+ import { normalizePermissionDefinitionListLimit, PermissionAdministration, } from "../Permission.js";
27
+ import { RecoveryCodeLoginCommitStore, RecoveryCodeManagement, } from "../RecoveryCode.js";
28
+ import { defaultRecoveryRemediationCapabilities, withRecoveryRemediationRequirement, } from "../RecoveryPolicy.js";
29
+ import { RefreshTokenManagement } from "../RefreshToken.js";
18
30
  import { SecurityTimelineStore } from "../SecurityTimeline.js";
19
- import { UserStore } from "../Storage.js";
31
+ import { SessionCookie, Sessions, RecoveryCodeSessionRotation, TotpSessionRotation, sessionRequestMetadataKey, } from "../Sessions.js";
32
+ import { CredentialStore, IdentityStore, UserStore, VerificationStore, } from "../Storage.js";
33
+ import { StrongFactorRemovalPolicy, strongFactor } from "../StrongFactor.js";
34
+ import { TotpFactorManagement, TotpLoginCommitStore } from "../Totp.js";
20
35
  import { TrustedDevice, TrustedDeviceCookie, TrustedDeviceStore, } from "../TrustedDevice.js";
21
- import { adminSecurityTimelineListEndpoint, adminSessionListEndpoint, adminSessionRevokeAllEndpoint, adminSessionRevokeEndpoint, adminTrustedDeviceListEndpoint, adminTrustedDeviceRevokeEndpoint, apiKeyCreateEndpoint, apiKeyListEndpoint, apiKeyRevokeEndpoint, currentSessionEndpoint, emailOtpStartEndpoint, emailOtpVerifyEndpoint, emailVerificationStartEndpoint, emailVerificationVerifyEndpoint, loginApprovalApproveEndpoint, loginApprovalFinalizeEndpoint, loginApprovalStatusEndpoint, loginNotificationReportEndpoint, jwtIntrospectEndpoint, jwtJwksEndpoint, jwtRevokeEndpoint, listSessionsEndpoint, logoutEndpoint, magicLinkStartEndpoint, magicLinkVerifyEndpoint, mfaOptionsEndpoint, oauthAccountUnlinkEndpoint, oauthAuthorizationStartEndpoint, oauthLinkConfirmationConfirmEndpoint, oauthLinkConfirmationInspectEndpoint, oauthLinkConfirmationStartEndpoint, oauthProviderAuthorizeEndpoint, oauthTokenEndpoint, oauthTokenIntrospectionEndpoint, oauthTokenRevocationEndpoint, oidcDiscoveryMetadataEndpoint, passwordChangeEndpoint, passwordResetStartEndpoint, passwordResetVerifyEndpoint, passwordSetEndpoint, passwordSignInEndpoint, passwordSignUpEndpoint, passkeyMfaStartEndpoint, passkeyMfaVerifyEndpoint, recoveryCodeMfaVerifyEndpoint, recoveryCodeMfaVerifyForFlowEndpoint, refreshTokenRefreshEndpoint, refreshSessionEndpoint, revokeOtherSessionsEndpoint, revokeSessionEndpoint, securityTimelineListEndpoint, stepUpOptionsEndpoint, stepUpPasskeyStartEndpoint, stepUpPasskeyVerifyEndpoint, stepUpRecoveryCodeVerifyEndpoint, stepUpTotpVerifyEndpoint, trustedDeviceListEndpoint, trustedDeviceRevokeEndpoint, totpMfaVerifyEndpoint, totpMfaVerifyForFlowEndpoint, } from "./Endpoints.js";
22
- import { AuthBadRequestError, AuthEmailAlreadyRegisteredError, AuthInternalError, AuthInvalidCredentialsError, AuthPolicyDeniedError, AuthRateLimitedError, AuthSchemaErrorMiddleware, AuthSchemaErrorMiddlewareLive, AuthUnauthenticatedError, OAuthAuthorizationEndpointError, OAuthTokenEndpointError, OAuthTokenIntrospectionEndpointError, OAuthTokenRevocationEndpointError, } from "./Errors.js";
36
+ import { EmailAuthHttpApiGroup, EmailOtpHttpApiGroup, EmailVerificationHttpApiGroup, IdentityHttpApiGroup, LoginApprovalHttpApiGroup, MagicLinkHttpApiGroup, MfaHttpApiGroup, PasskeyHttpApiGroup, PasswordHttpApiGroup, RecoveryCodesHttpApiGroup, LoginNotificationHttpApiGroup, SessionHttpApiGroup, StepUpHttpApiGroup, TotpHttpApiGroup, } from "./ClientApi.js";
37
+ import { EmailGuards } from "./EmailGuards.js";
38
+ import { adminSecurityTimelineListEndpoint, adminPermissionDefinitionCreateEndpoint, adminPermissionDefinitionDeleteEndpoint, adminPermissionDefinitionDisableEndpoint, adminPermissionDefinitionEnableEndpoint, adminPermissionDefinitionGetEndpoint, adminPermissionDefinitionListEndpoint, adminPermissionDefinitionUpdateEndpoint, adminSessionListEndpoint, adminSessionRevokeAllEndpoint, adminSessionRevokeEndpoint, adminTrustedDeviceListEndpoint, adminTrustedDeviceRevokeEndpoint, apiKeyCreateEndpoint, apiKeyListEndpoint, apiKeyRevokeEndpoint, jwtIntrospectEndpoint, jwtJwksEndpoint, jwtRevokeEndpoint, oauthAccountUnlinkEndpoint, oauthAuthorizationStartEndpoint, oauthLinkConfirmationConfirmEndpoint, oauthLinkConfirmationInspectEndpoint, oauthLinkConfirmationStartEndpoint, oauthProviderAuthorizeEndpoint, oauthTokenEndpoint, oauthTokenIntrospectionEndpoint, oauthTokenRevocationEndpoint, oidcDiscoveryMetadataEndpoint, refreshTokenRefreshEndpoint, securityTimelineListEndpoint, trustedDeviceListEndpoint, trustedDeviceRevokeEndpoint, } from "./Endpoints.js";
39
+ import { AuthBadRequestError, AuthConflictError, AuthIdentityAlreadyRegisteredError, AuthInternalError, AuthInvalidCredentialsError, AuthNotFoundError, AuthPolicyDeniedError, AuthSchemaErrorMiddleware, AuthSchemaErrorMiddlewareLive, AuthUnauthenticatedError, OAuthAuthorizationEndpointError, OAuthTokenEndpointError, OAuthTokenIntrospectionEndpointError, OAuthTokenRevocationEndpointError, } from "./Errors.js";
40
+ import { IdentityGuards } from "./IdentityGuards.js";
41
+ import { AuthOriginCheckMiddleware, OAuthNoStoreMiddleware, OAuthNoStoreMiddlewareLive, } from "./Middleware.js";
42
+ import { AdminSecurityTimelineHttpOperations, AdminPermissionDefinitionHttpOperations, AdminSessionHttpOperations, AdminTrustedDeviceHttpOperations, ApiKeyHttpOperations, EmailAuthHttpOperations, EmailOtpHttpOperations, EmailVerificationHttpOperations, JwtDiscoveryHttpOperations, JwtHttpOperations, LoginApprovalHttpOperations, MagicLinkHttpOperations, MfaHttpOperations, OAuthHttpOperations, OAuthProviderAuthorizationHttpOperations, OAuthTokenHttpOperations, OAuthTokenIntrospectionHttpOperations, OAuthTokenRevocationHttpOperations, OidcDiscoveryHttpOperations, PasskeyHttpOperations, IdentityHttpOperations, RecoveryCodesHttpOperations, RefreshTokenHttpOperations, LoginNotificationHttpOperations, SecurityTimelineHttpOperations, SessionHttpOperations, StepUpHttpOperations, TotpHttpOperations, TrustedDeviceHttpOperations, } from "./Operations/index.js";
43
+ import { PasswordHttpOperationsLive, passwordGroupHandlers, } from "./Password.js";
44
+ import { requireAuthRateLimit } from "./RequestGuards.js";
23
45
  import { OAuthProviderAuthorizationQuery, OAuthTokenRequestBody, OAuthTokenIntrospectionRequestBody, OAuthTokenIntrospectionResponseBody, OAuthTokenRevocationRequestBody, } from "./Schemas.js";
24
- import { AuthApiRateLimit, AuthApiRateLimitLive, AuthApiRateLimitNoopLive, AuthHttpApiConfig, AuthOriginCheckMiddleware, AuthOriginCheckMiddlewareConfigLive, AuthRateLimitMiddleware, makeAuthRequestMetadata, } from "./Security.js";
46
+ import { AuthOriginCheckMiddlewareConfigLive, customEvidencePolicyHttpFailure, } from "./Security.js";
47
+ import { readOptionalSession, readRequiredSession, requireSession, } from "./SessionGuards.js";
25
48
  import { AuthHttp, LoginApprovalPendingCookie, makeLoginApprovalPendingCookie, } from "./Transport.js";
26
- const canStartRequiredEmailVerification = (result) => result._tag === "RequiresEmailVerification" &&
27
- result.userId !== undefined &&
28
- result.email !== undefined;
29
- const noopAuthApiRateLimit = AuthApiRateLimit.make({
30
- request: () => Effect.void,
31
- passwordSignIn: () => Effect.void,
32
- passwordSignUp: () => Effect.void,
33
- passwordResetStart: () => Effect.void,
34
- emailOtpStart: () => Effect.void,
35
- magicLinkStart: () => Effect.void,
36
- emailVerificationStart: () => Effect.void,
37
- });
38
- export const passwordSignInInput = (payload, trustedDeviceToken, request) => ({
39
- ...payload,
40
- password: Redacted.make(payload.password),
41
- ...(trustedDeviceToken === undefined ? {} : { trustedDeviceToken }),
42
- ...(request === undefined ? {} : { request }),
43
- });
44
- export const passwordSignUpInput = (payload, request) => ({
45
- ...payload,
46
- password: Redacted.make(payload.password),
47
- ...(request === undefined ? {} : { request }),
48
- });
49
- export const passwordResetStartInput = (payload) => {
50
- const { secret, ...input } = payload;
51
- return {
52
- ...input,
53
- ...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
54
- };
55
- };
56
- export const passwordResetVerifyInput = (payload) => ({
57
- challengeId: payload.challengeId,
58
- secret: Redacted.make(payload.secret),
59
- password: Redacted.make(payload.password),
60
- });
61
- export const passwordSetInput = (userId, payload) => ({
62
- userId,
63
- password: Redacted.make(payload.password),
64
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
65
- });
66
- export const passwordChangeInput = (userId, payload) => ({
67
- userId,
68
- currentPassword: Redacted.make(payload.currentPassword),
69
- newPassword: Redacted.make(payload.newPassword),
70
- });
71
- export const emailVerificationStartInput = (payload) => {
72
- const { secret, ...input } = payload;
73
- return {
74
- ...input,
75
- ...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
76
- };
77
- };
49
+ export { AuthClientProtocolApi, EmailAuthHttpApiGroup, EmailOtpHttpApiGroup, EmailVerificationHttpApiGroup, IdentityHttpApiGroup, LoginApprovalHttpApiGroup, MagicLinkHttpApiGroup, MfaHttpApiGroup, PasskeyHttpApiGroup, PasswordHttpApiGroup, RecoveryCodesHttpApiGroup, LoginNotificationHttpApiGroup, SessionHttpApiGroup, StepUpHttpApiGroup, TotpHttpApiGroup, } from "./ClientApi.js";
50
+ export { makePasswordChangeHandler, makePasswordResetStartHandler, makePasswordResetVerifyHandler, makePasswordSetHandler, makePasswordSignInHandler, makePasswordSignUpHandler, passwordChangeInput, passwordSetInput, PasswordHttpApi, PasswordHttpApiGroupLive, PasswordHttpApiLive, PasswordHttpOperationsLive, } from "./Password.js";
78
51
  export const emailVerificationVerifyInput = (payload) => {
79
52
  const { secret, ...input } = payload;
80
53
  return {
@@ -82,36 +55,12 @@ export const emailVerificationVerifyInput = (payload) => {
82
55
  ...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
83
56
  };
84
57
  };
85
- export const emailOtpStartInput = (payload) => {
86
- const { secret, ...input } = payload;
87
- return {
88
- ...input,
89
- ...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
90
- };
91
- };
92
- export const emailOtpVerifyInput = (payload, trustedDeviceToken, request) => ({
93
- challengeId: payload.challengeId,
94
- secret: Redacted.make(payload.secret),
95
- ...(trustedDeviceToken === undefined ? {} : { trustedDeviceToken }),
96
- ...(request === undefined ? {} : { request }),
97
- });
98
- export const magicLinkStartInput = (payload) => {
99
- const { secret, ...input } = payload;
100
- return {
101
- ...input,
102
- ...(secret === undefined ? {} : { secret: Redacted.make(secret) }),
103
- };
104
- };
105
- export const magicLinkVerifyInput = (payload, trustedDeviceToken, request) => ({
106
- challengeId: payload.challengeId,
107
- secret: Redacted.make(payload.secret),
108
- ...(trustedDeviceToken === undefined ? {} : { trustedDeviceToken }),
109
- ...(request === undefined ? {} : { request }),
110
- });
111
58
  export const oauthAuthorizationStartInput = (payload, provider, options = {}) => ({
112
59
  provider,
113
60
  ...(options.ttl === undefined ? {} : { ttl: options.ttl }),
114
- ...(payload.redirectUri === undefined ? {} : { redirectUri: payload.redirectUri }),
61
+ ...(payload.redirectUri === undefined
62
+ ? {}
63
+ : { redirectUri: payload.redirectUri }),
115
64
  ...(payload.scopes === undefined ? {} : { scopes: payload.scopes }),
116
65
  ...(payload.authorizationParams === undefined
117
66
  ? {}
@@ -166,11 +115,15 @@ export const oauthLinkConfirmationStartInput = (payload, options = {}) => Effect
166
115
  });
167
116
  export const oauthLinkConfirmationInspectInput = (payload) => ({
168
117
  challengeId: payload.challengeId,
169
- ...(payload.secret === undefined ? {} : { secret: Redacted.make(payload.secret) }),
118
+ ...(payload.secret === undefined
119
+ ? {}
120
+ : { secret: Redacted.make(payload.secret) }),
170
121
  });
171
122
  export const oauthLinkConfirmationConfirmInput = (payload, currentUserId) => ({
172
123
  challengeId: payload.challengeId,
173
- ...(payload.secret === undefined ? {} : { secret: Redacted.make(payload.secret) }),
124
+ ...(payload.secret === undefined
125
+ ? {}
126
+ : { secret: Redacted.make(payload.secret) }),
174
127
  ...(currentUserId === undefined ? {} : { currentUserId }),
175
128
  ...(payload.expectedProviderId === undefined
176
129
  ? {}
@@ -361,7 +314,9 @@ const oauthClientEndpointAuthentication = (input) => Effect.gen(function* () {
361
314
  if (input.payload.client_secret !== undefined && postAuth === undefined) {
362
315
  return yield* Effect.fail(input.invalidRequest());
363
316
  }
364
- const authentication = Option.isSome(basicAuth) ? basicAuth.value : postAuth;
317
+ const authentication = Option.isSome(basicAuth)
318
+ ? basicAuth.value
319
+ : postAuth;
365
320
  const payloadClientId = oauthTokenGrantString(input.payload.client_id);
366
321
  if (authentication !== undefined &&
367
322
  payloadClientId !== undefined &&
@@ -438,7 +393,9 @@ const oauthTokenIntrospectionResponseHttpBody = (introspection) => {
438
393
  ...(introspection.notBefore === undefined
439
394
  ? {}
440
395
  : { nbf: oauthUnixMillisToSeconds(introspection.notBefore) }),
441
- ...(introspection.subject === undefined ? {} : { sub: introspection.subject }),
396
+ ...(introspection.subject === undefined
397
+ ? {}
398
+ : { sub: introspection.subject }),
442
399
  ...(introspection.audience === undefined
443
400
  ? {}
444
401
  : {
@@ -446,18 +403,51 @@ const oauthTokenIntrospectionResponseHttpBody = (introspection) => {
446
403
  ? [...introspection.audience]
447
404
  : introspection.audience,
448
405
  }),
449
- ...(introspection.issuer === undefined ? {} : { iss: introspection.issuer }),
406
+ ...(introspection.issuer === undefined
407
+ ? {}
408
+ : { iss: introspection.issuer }),
450
409
  ...(introspection.jwtId === undefined ? {} : { jti: introspection.jwtId }),
451
- ...(introspection.extra === undefined ? {} : { extra: introspection.extra }),
410
+ ...(introspection.extra === undefined
411
+ ? {}
412
+ : { extra: introspection.extra }),
452
413
  };
453
414
  };
454
- const oauthRefreshTokenResponse = (input) => Effect.gen(function* () {
455
- if (input.dependencies.refreshTokenGrant === undefined) {
456
- return yield* oauthTokenEndpointError("unsupported_grant_type");
415
+ export class OAuthTokenGrantRegistryDuplicateError extends Data.TaggedError("OAuthTokenGrantRegistryDuplicateError") {
416
+ }
417
+ export class OAuthTokenGrantRegistry extends Context.Service()("auth/HttpApi/OAuthTokenGrantRegistry") {
418
+ }
419
+ (function (OAuthTokenGrantRegistry) {
420
+ OAuthTokenGrantRegistry.make = (registrations) => Effect.gen(function* () {
421
+ const byGrantType = new Map();
422
+ for (const registration of registrations) {
423
+ if (byGrantType.has(registration.grantType)) {
424
+ return yield* new OAuthTokenGrantRegistryDuplicateError({
425
+ grantType: registration.grantType,
426
+ });
427
+ }
428
+ byGrantType.set(registration.grantType, registration);
429
+ }
430
+ return OAuthTokenGrantRegistry.of({
431
+ get: (grantType) => {
432
+ const registration = byGrantType.get(grantType);
433
+ return registration === undefined
434
+ ? Option.none()
435
+ : Option.some(registration);
436
+ },
437
+ });
438
+ });
439
+ })(OAuthTokenGrantRegistry || (OAuthTokenGrantRegistry = {}));
440
+ export const OAuthTokenGrantRegistryLive = (...registrations) => Layer.effect(OAuthTokenGrantRegistry, Effect.gen(function* () {
441
+ const resolved = [];
442
+ for (const registration of registrations) {
443
+ resolved.push(yield* registration);
457
444
  }
445
+ return yield* OAuthTokenGrantRegistry.make(resolved);
446
+ }));
447
+ const oauthRefreshTokenResponse = (input) => Effect.gen(function* () {
458
448
  const refreshToken = oauthTokenGrantString(input.payload.refresh_token);
459
449
  const scope = oauthTokenGrantString(input.payload.scope);
460
- const result = yield* input.dependencies.refreshTokenGrant
450
+ const result = yield* input.grant
461
451
  .exchange({
462
452
  grantType: input.payload.grant_type,
463
453
  ...(refreshToken === undefined
@@ -474,11 +464,8 @@ const oauthRefreshTokenResponse = (input) => Effect.gen(function* () {
474
464
  return oauthTokenResponseHttpBody(result.tokens);
475
465
  });
476
466
  const oauthClientCredentialsTokenResponse = (input) => Effect.gen(function* () {
477
- if (input.dependencies.clientCredentialsGrant === undefined) {
478
- return yield* oauthTokenEndpointError("unsupported_grant_type");
479
- }
480
467
  const scope = oauthTokenGrantString(input.payload.scope);
481
- const result = yield* input.dependencies.clientCredentialsGrant
468
+ const result = yield* input.grant
482
469
  .exchange({
483
470
  grantType: input.payload.grant_type,
484
471
  ...(input.clientId === undefined ? {} : { clientId: input.clientId }),
@@ -491,11 +478,28 @@ const oauthClientCredentialsTokenResponse = (input) => Effect.gen(function* () {
491
478
  }
492
479
  return oauthTokenResponseHttpBody(result.tokens);
493
480
  });
481
+ const oauthDeviceCodeTokenResponse = (input) => Effect.gen(function* () {
482
+ const deviceCode = oauthTokenGrantString(input.payload.device_code);
483
+ const result = yield* input.grant
484
+ .exchange({
485
+ grantType: input.payload.grant_type,
486
+ ...(deviceCode === undefined
487
+ ? {}
488
+ : { deviceCode: Redacted.make(OAuthDeviceCode(deviceCode)) }),
489
+ ...(input.clientId === undefined ? {} : { clientId: input.clientId }),
490
+ clientAuthenticated: input.clientAuthenticated,
491
+ })
492
+ .pipe(Effect.mapError(() => oauthInternalError("Failed to exchange OAuth token")));
493
+ if (!result.valid) {
494
+ return yield* oauthTokenEndpointError(result.reason);
495
+ }
496
+ return oauthTokenResponseHttpBody(result.tokens);
497
+ });
494
498
  const oauthAuthorizationCodeTokenResponse = (input) => Effect.gen(function* () {
495
499
  const code = oauthTokenGrantString(input.payload.code);
496
500
  const codeVerifier = oauthTokenGrantString(input.payload.code_verifier);
497
501
  const redirectUri = oauthTokenGrantString(input.payload.redirect_uri);
498
- const result = yield* input.dependencies.tokenGrant
502
+ const result = yield* input.grant
499
503
  .exchange({
500
504
  grantType: input.payload.grant_type,
501
505
  ...(code === undefined
@@ -505,7 +509,9 @@ const oauthAuthorizationCodeTokenResponse = (input) => Effect.gen(function* () {
505
509
  ...(redirectUri === undefined ? {} : { redirectUri }),
506
510
  ...(codeVerifier === undefined
507
511
  ? {}
508
- : { codeVerifier: Redacted.make(makeOAuthCodeVerifier(codeVerifier)) }),
512
+ : {
513
+ codeVerifier: Redacted.make(makeOAuthCodeVerifier(codeVerifier)),
514
+ }),
509
515
  clientAuthenticated: input.clientAuthenticated,
510
516
  })
511
517
  .pipe(Effect.mapError(() => oauthInternalError("Failed to exchange OAuth token")));
@@ -514,6 +520,22 @@ const oauthAuthorizationCodeTokenResponse = (input) => Effect.gen(function* () {
514
520
  }
515
521
  return oauthTokenResponseHttpBody(result.tokens);
516
522
  });
523
+ export const oauthAuthorizationCodeTokenGrantRegistration = Effect.map(OAuthAuthorizationCodeTokenGrant, (grant) => ({
524
+ grantType: "authorization_code",
525
+ exchange: (input) => oauthAuthorizationCodeTokenResponse({ ...input, grant }),
526
+ }));
527
+ export const oauthRefreshTokenGrantRegistration = Effect.map(OAuthRefreshTokenGrant, (grant) => ({
528
+ grantType: "refresh_token",
529
+ exchange: (input) => oauthRefreshTokenResponse({ ...input, grant }),
530
+ }));
531
+ export const oauthClientCredentialsGrantRegistration = Effect.map(OAuthClientCredentialsGrant, (grant) => ({
532
+ grantType: "client_credentials",
533
+ exchange: (input) => oauthClientCredentialsTokenResponse({ ...input, grant }),
534
+ }));
535
+ export const oauthDeviceCodeTokenGrantRegistration = Effect.map(OAuthDeviceCodeTokenGrant, (grant) => ({
536
+ grantType: oauthDeviceCodeGrantType,
537
+ exchange: (input) => oauthDeviceCodeTokenResponse({ ...input, grant }),
538
+ }));
517
539
  const oauthLinkedAccountHttpBody = (account) => ({
518
540
  accountId: account.id,
519
541
  providerId: account.providerId,
@@ -526,7 +548,9 @@ export const oauthLinkConfirmationConfirmedHttpBody = (confirmed, options = {})
526
548
  reason: confirmed.reason,
527
549
  ...(confirmed.existingAccount === undefined
528
550
  ? {}
529
- : { existingAccount: oauthLinkedAccountHttpBody(confirmed.existingAccount) }),
551
+ : {
552
+ existingAccount: oauthLinkedAccountHttpBody(confirmed.existingAccount),
553
+ }),
530
554
  linked: options.linked === true || confirmed.existingAccount !== undefined,
531
555
  });
532
556
  export const oauthAccountUnlinkResolutionHttpBody = (resolution, options = {}) => {
@@ -573,11 +597,87 @@ export const oauthAccountUnlinkResolutionHttpBody = (resolution, options = {}) =
573
597
  }
574
598
  }
575
599
  };
576
- export const passkeyRegistrationStartInput = (payload, options) => ({
600
+ export class PasskeyHttpConfig extends Context.Service()("auth/http/config/Passkey") {
601
+ }
602
+ (function (PasskeyHttpConfig) {
603
+ PasskeyHttpConfig.make = (config) => PasskeyHttpConfig.of(config);
604
+ })(PasskeyHttpConfig || (PasskeyHttpConfig = {}));
605
+ export const PasskeyHttpConfigLive = (config) => Layer.succeed(PasskeyHttpConfig)(PasskeyHttpConfig.make(config));
606
+ export class TotpHttpConfig extends Context.Service()("auth/http/config/Totp") {
607
+ }
608
+ (function (TotpHttpConfig) {
609
+ TotpHttpConfig.make = (config) => TotpHttpConfig.of(config);
610
+ })(TotpHttpConfig || (TotpHttpConfig = {}));
611
+ export const TotpHttpConfigLive = (config) => Layer.succeed(TotpHttpConfig)(TotpHttpConfig.make(config));
612
+ export const RecoveryCodeHttpConfig = Context.Reference("auth/http/config/RecoveryCode", { defaultValue: () => ({}) });
613
+ export const RecoveryCodeHttpConfigLive = (config = {}) => Layer.succeed(RecoveryCodeHttpConfig)(config);
614
+ export const OAuthHttpConfig = Context.Reference("auth/http/config/OAuth", { defaultValue: () => ({}) });
615
+ export const OAuthHttpConfigLive = (config = {}) => Layer.succeed(OAuthHttpConfig)(config);
616
+ export const OAuthTokenHttpConfig = Context.Reference("auth/http/config/OAuthToken", { defaultValue: () => ({}) });
617
+ export const OAuthTokenHttpConfigLive = (config = {}) => Layer.succeed(OAuthTokenHttpConfig)(config);
618
+ export class RefreshTokenHttpConfig extends Context.Service()("auth/http/config/RefreshToken") {
619
+ }
620
+ (function (RefreshTokenHttpConfig) {
621
+ RefreshTokenHttpConfig.make = (config) => RefreshTokenHttpConfig.of(config);
622
+ })(RefreshTokenHttpConfig || (RefreshTokenHttpConfig = {}));
623
+ export const RefreshTokenHttpConfigLive = (config) => Layer.succeed(RefreshTokenHttpConfig)(RefreshTokenHttpConfig.make(config));
624
+ export const JwtHttpConfig = Context.Reference("auth/http/config/Jwt", { defaultValue: () => ({}) });
625
+ export const JwtHttpConfigLive = (config = {}) => Layer.succeed(JwtHttpConfig)(config);
626
+ export const passkeyRegistrationStartHttpOptions = (config) => ({
627
+ relyingParty: config.relyingParty,
628
+ ...(config.timeout === undefined ? {} : { timeout: config.timeout }),
629
+ ...(config.pubKeyCredParams === undefined
630
+ ? {}
631
+ : { pubKeyCredParams: config.pubKeyCredParams }),
632
+ ...(config.authenticatorSelection === undefined
633
+ ? {}
634
+ : { authenticatorSelection: config.authenticatorSelection }),
635
+ ...(config.attestation === undefined
636
+ ? {}
637
+ : { attestation: config.attestation }),
638
+ });
639
+ export const passkeyAuthenticationStartHttpOptions = (config) => ({
640
+ relyingPartyId: config.relyingParty.id,
641
+ ...(config.timeout === undefined ? {} : { timeout: config.timeout }),
642
+ ...(config.userVerification === undefined
643
+ ? {}
644
+ : { userVerification: config.userVerification }),
645
+ });
646
+ export const passkeyFinishHttpOptions = (config) => ({
647
+ relyingPartyId: config.relyingParty.id,
648
+ expectedOrigin: config.expectedOrigin,
649
+ ...(config.requireUserVerification === undefined
650
+ ? {}
651
+ : { requireUserVerification: config.requireUserVerification }),
652
+ });
653
+ export const passkeyAuthenticationSessionInput = ({ finished, payload, }) => ({
654
+ userId: finished.userId,
655
+ authenticationEvents: [
656
+ passkeyEvidence({
657
+ credentialId: CredentialId(finished.credential.id),
658
+ verifiedAt: finished.credential.lastUsedAt ?? finished.credential.createdAt,
659
+ userVerification: finished.userVerification,
660
+ ...(finished.authenticatorAttachment === undefined
661
+ ? {}
662
+ : { authenticatorAttachment: finished.authenticatorAttachment }),
663
+ ...(finished.backedUp === undefined
664
+ ? {}
665
+ : { backedUp: finished.backedUp }),
666
+ ...(finished.backupEligible === undefined
667
+ ? {}
668
+ : { backupEligible: finished.backupEligible }),
669
+ signCount: finished.signCount,
670
+ ...(finished.aaguid === undefined ? {} : { aaguid: finished.aaguid }),
671
+ }),
672
+ ],
673
+ ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
674
+ });
675
+ const optionalHttpMetadata = (metadata) => (metadata === undefined ? {} : { metadata });
676
+ export const passkeyRegistrationStartInput = (userId, user, options) => ({
577
677
  relyingParty: options.relyingParty,
578
- userId: payload.userId,
579
- userName: payload.userName,
580
- userDisplayName: payload.userDisplayName,
678
+ userId,
679
+ userName: user.userName,
680
+ userDisplayName: user.userDisplayName,
581
681
  ...(options.timeout === undefined ? {} : { timeout: options.timeout }),
582
682
  ...(options.pubKeyCredParams === undefined
583
683
  ? {}
@@ -585,8 +685,10 @@ export const passkeyRegistrationStartInput = (payload, options) => ({
585
685
  ...(options.authenticatorSelection === undefined
586
686
  ? {}
587
687
  : { authenticatorSelection: options.authenticatorSelection }),
588
- ...(options.attestation === undefined ? {} : { attestation: options.attestation }),
589
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
688
+ ...(options.attestation === undefined
689
+ ? {}
690
+ : { attestation: options.attestation }),
691
+ ...optionalHttpMetadata(user.metadata),
590
692
  });
591
693
  export const passkeyAuthenticationStartInput = (payload, options) => ({
592
694
  relyingPartyId: options.relyingPartyId,
@@ -607,16 +709,16 @@ export const passkeyMfaStartInput = (userId, payload, options) => ({
607
709
  flowId: payload.flowId,
608
710
  },
609
711
  });
610
- export const passkeyRegistrationFinishInput = (payload, options) => ({
712
+ export const passkeyRegistrationFinishInput = (userId, payload, user, options) => ({
611
713
  challengeId: payload.challengeId,
612
- userId: payload.userId,
714
+ userId,
613
715
  response: payload.credential,
614
716
  relyingPartyId: options.relyingPartyId,
615
717
  expectedOrigin: options.expectedOrigin,
616
718
  ...(options.requireUserVerification === undefined
617
719
  ? {}
618
720
  : { requireUserVerification: options.requireUserVerification }),
619
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
721
+ ...optionalHttpMetadata(user.metadata),
620
722
  });
621
723
  export const passkeyAuthenticationFinishInput = (payload, options) => ({
622
724
  challengeId: payload.challengeId,
@@ -629,15 +731,18 @@ export const passkeyAuthenticationFinishInput = (payload, options) => ({
629
731
  : { requireUserVerification: options.requireUserVerification }),
630
732
  ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
631
733
  });
632
- export const passkeyMfaVerifyInput = (payload, options) => ({
734
+ export const passkeyMfaVerifyInput = (payload, options, expectedUserId) => ({
633
735
  challengeId: payload.challengeId,
634
736
  response: payload.credential,
635
- ...(payload.userId === undefined ? {} : { userId: payload.userId }),
737
+ ...(expectedUserId === undefined
738
+ ? payload.userId === undefined
739
+ ? {}
740
+ : { userId: payload.userId }
741
+ : { userId: expectedUserId }),
636
742
  relyingPartyId: options.relyingPartyId,
637
743
  expectedOrigin: options.expectedOrigin,
638
- ...(options.requireUserVerification === undefined
639
- ? {}
640
- : { requireUserVerification: options.requireUserVerification }),
744
+ requireUserVerification: true,
745
+ expectedChallengeMetadata: { flowId: payload.flowId },
641
746
  ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
642
747
  });
643
748
  export const passkeyCredentialRevokeInput = (userId, payload) => ({
@@ -650,7 +755,9 @@ const passkeyCredentialInfoHttpBody = (credential) => ({
650
755
  ...(credential.transports === undefined
651
756
  ? {}
652
757
  : { transports: credential.transports }),
653
- ...(credential.backedUp === undefined ? {} : { backedUp: credential.backedUp }),
758
+ ...(credential.backedUp === undefined
759
+ ? {}
760
+ : { backedUp: credential.backedUp }),
654
761
  createdAt: credential.createdAt,
655
762
  ...(credential.lastUsedAt === undefined
656
763
  ? {}
@@ -658,13 +765,17 @@ const passkeyCredentialInfoHttpBody = (credential) => ({
658
765
  ...(credential.revokedAt === undefined
659
766
  ? {}
660
767
  : { revokedAt: credential.revokedAt }),
661
- ...(credential.metadata === undefined ? {} : { metadata: credential.metadata }),
768
+ ...(credential.metadata === undefined
769
+ ? {}
770
+ : { metadata: credential.metadata }),
662
771
  });
663
772
  export const totpEnrollmentStartInput = (userId, payload, options) => ({
664
773
  userId,
665
774
  issuer: options.issuer,
666
775
  accountName: payload.accountName,
667
- ...(options.secretBytes === undefined ? {} : { secretBytes: options.secretBytes }),
776
+ ...(options.secretBytes === undefined
777
+ ? {}
778
+ : { secretBytes: options.secretBytes }),
668
779
  ...(options.algorithm === undefined ? {} : { algorithm: options.algorithm }),
669
780
  ...(options.digits === undefined ? {} : { digits: options.digits }),
670
781
  ...(options.period === undefined ? {} : { period: options.period }),
@@ -694,7 +805,9 @@ const totpFactorInfoHttpBody = (factor) => ({
694
805
  digits: factor.digits,
695
806
  period: factor.period,
696
807
  createdAt: factor.createdAt,
697
- ...(factor.confirmedAt === undefined ? {} : { confirmedAt: factor.confirmedAt }),
808
+ ...(factor.confirmedAt === undefined
809
+ ? {}
810
+ : { confirmedAt: factor.confirmedAt }),
698
811
  ...(factor.lastUsedAt === undefined ? {} : { lastUsedAt: factor.lastUsedAt }),
699
812
  ...(factor.revokedAt === undefined ? {} : { revokedAt: factor.revokedAt }),
700
813
  ...(factor.metadata === undefined ? {} : { metadata: factor.metadata }),
@@ -710,6 +823,9 @@ const totpVerifyResultHttpBody = (result) => ({
710
823
  ? {}
711
824
  : { factor: totpFactorInfoHttpBody(result.factor) }),
712
825
  ...(result.delta === undefined ? {} : { delta: result.delta }),
826
+ ...(result.acceptedCounter === undefined
827
+ ? {}
828
+ : { acceptedCounter: result.acceptedCounter }),
713
829
  });
714
830
  export const recoveryCodeGenerateInput = (userId, payload, options = {}) => ({
715
831
  userId,
@@ -718,6 +834,16 @@ export const recoveryCodeGenerateInput = (userId, payload, options = {}) => ({
718
834
  ...(options.groupSize === undefined ? {} : { groupSize: options.groupSize }),
719
835
  ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
720
836
  });
837
+ export const recoveryCodeRegenerateInput = (userId, payload, options = {}) => ({
838
+ userId,
839
+ ...(options.count === undefined ? {} : { count: options.count }),
840
+ ...(options.length === undefined ? {} : { length: options.length }),
841
+ ...(options.groupSize === undefined ? {} : { groupSize: options.groupSize }),
842
+ ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
843
+ ...(payload.revokeReason === undefined
844
+ ? {}
845
+ : { revokeReason: payload.revokeReason }),
846
+ });
721
847
  export const recoveryCodeVerifyInput = (userId, payload) => ({
722
848
  userId,
723
849
  code: Redacted.make(payload.code),
@@ -796,7 +922,9 @@ const refreshTokenInfoHttpBody = (refreshToken) => ({
796
922
  ...(refreshToken.reuseDetectedAt === undefined
797
923
  ? {}
798
924
  : { reuseDetectedAt: refreshToken.reuseDetectedAt }),
799
- ...(refreshToken.metadata === undefined ? {} : { metadata: refreshToken.metadata }),
925
+ ...(refreshToken.metadata === undefined
926
+ ? {}
927
+ : { metadata: refreshToken.metadata }),
800
928
  });
801
929
  const issuedJwtExpiresAt = (issued) => typeof issued.claims.exp === "number"
802
930
  ? (issued.claims.exp * 1000)
@@ -826,9 +954,15 @@ const jwtKeyInfoHttpBody = (result) => ({
826
954
  keyId: result.key.id,
827
955
  alg: result.key.alg,
828
956
  status: result.key.status,
829
- ...(result.key.createdAt === undefined ? {} : { createdAt: result.key.createdAt }),
830
- ...(result.key.expiresAt === undefined ? {} : { expiresAt: result.key.expiresAt }),
831
- ...(result.key.metadata === undefined ? {} : { metadata: result.key.metadata }),
957
+ ...(result.key.createdAt === undefined
958
+ ? {}
959
+ : { createdAt: result.key.createdAt }),
960
+ ...(result.key.expiresAt === undefined
961
+ ? {}
962
+ : { expiresAt: result.key.expiresAt }),
963
+ ...(result.key.metadata === undefined
964
+ ? {}
965
+ : { metadata: result.key.metadata }),
832
966
  });
833
967
  const jwtIntrospectionHttpBody = (result) => result.active
834
968
  ? {
@@ -837,15 +971,21 @@ const jwtIntrospectionHttpBody = (result) => result.active
837
971
  claims: result.claims,
838
972
  key: jwtKeyInfoHttpBody(result),
839
973
  ...(result.jwtId === undefined ? {} : { jwtId: result.jwtId }),
840
- ...(result.expiresAt === undefined ? {} : { expiresAt: result.expiresAt }),
974
+ ...(result.expiresAt === undefined
975
+ ? {}
976
+ : { expiresAt: result.expiresAt }),
841
977
  revoked: false,
842
978
  }
843
979
  : {
844
980
  active: false,
845
981
  reason: result.reason,
846
982
  ...(result.jwtId === undefined ? {} : { jwtId: result.jwtId }),
847
- ...(result.expiresAt === undefined ? {} : { expiresAt: result.expiresAt }),
848
- ...(result.revokedAt === undefined ? {} : { revokedAt: result.revokedAt }),
983
+ ...(result.expiresAt === undefined
984
+ ? {}
985
+ : { expiresAt: result.expiresAt }),
986
+ ...(result.revokedAt === undefined
987
+ ? {}
988
+ : { revokedAt: result.revokedAt }),
849
989
  ...(result.revokedReason === undefined
850
990
  ? {}
851
991
  : { revokedReason: result.revokedReason }),
@@ -881,6 +1021,10 @@ export const stepUpTotpVerifyInput = (userId, payload, options = {}) => ({
881
1021
  ...(options.window === undefined ? {} : { window: options.window }),
882
1022
  ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
883
1023
  });
1024
+ export const stepUpPasswordVerifyInput = (payload) => ({
1025
+ password: Redacted.make(payload.password),
1026
+ ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
1027
+ });
884
1028
  export const stepUpRecoveryCodeVerifyInput = (userId, payload) => ({
885
1029
  userId,
886
1030
  code: Redacted.make(payload.code),
@@ -899,9 +1043,7 @@ export const stepUpPasskeyVerifyInput = (userId, payload, options) => ({
899
1043
  userId,
900
1044
  relyingPartyId: options.relyingPartyId,
901
1045
  expectedOrigin: options.expectedOrigin,
902
- ...(options.requireUserVerification === undefined
903
- ? {}
904
- : { requireUserVerification: options.requireUserVerification }),
1046
+ requireUserVerification: true,
905
1047
  ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
906
1048
  });
907
1049
  export const loginApprovalApproveInput = (payload) => ({
@@ -928,58 +1070,6 @@ export const loginNotificationReportInput = (payload) => ({
928
1070
  secret: Redacted.make(payload.secret),
929
1071
  });
930
1072
  const webRequestFromHeaders = (headers) => new Request("http://localhost", { headers });
931
- const firstHeaderValue = (value) => {
932
- const first = value?.split(",", 1)[0]?.trim();
933
- return first === "" ? undefined : first;
934
- };
935
- const headerNumber = (value) => {
936
- const parsed = Number(firstHeaderValue(value));
937
- return Number.isFinite(parsed) ? parsed : undefined;
938
- };
939
- const authRequestMetadataOptions = Effect.gen(function* () {
940
- const config = yield* Effect.serviceOption(AuthHttpApiConfig);
941
- return Option.isSome(config) ? (config.value.requestMetadata ?? {}) : {};
942
- });
943
- const loginRequestContextFromRequest = (request, options) => {
944
- if (request === undefined) {
945
- return undefined;
946
- }
947
- const metadata = makeAuthRequestMetadata(request, options);
948
- const trustProxyHeaders = options.trustProxyHeaders ?? false;
949
- const { headers } = request;
950
- const country = trustProxyHeaders
951
- ? firstHeaderValue(headers["cf-ipcountry"])
952
- : undefined;
953
- const region = trustProxyHeaders
954
- ? firstHeaderValue(headers["cf-region"])
955
- : undefined;
956
- const city = trustProxyHeaders
957
- ? firstHeaderValue(headers["cf-ipcity"])
958
- : undefined;
959
- const latitude = trustProxyHeaders
960
- ? headerNumber(headers["cf-iplatitude"])
961
- : undefined;
962
- const longitude = trustProxyHeaders
963
- ? headerNumber(headers["cf-iplongitude"])
964
- : undefined;
965
- const context = {
966
- ...(metadata.ipAddress === undefined
967
- ? {}
968
- : { ip: String(metadata.ipAddress) }),
969
- ...(metadata.userAgent === undefined
970
- ? {}
971
- : { userAgent: metadata.userAgent }),
972
- ...(country === undefined ? {} : { country }),
973
- ...(region === undefined ? {} : { region }),
974
- ...(city === undefined ? {} : { city }),
975
- ...(latitude === undefined ? {} : { latitude }),
976
- ...(longitude === undefined ? {} : { longitude }),
977
- };
978
- return Object.keys(context).length === 0 ? undefined : context;
979
- };
980
- const trustedDeviceTokenFromRequest = (trustedDeviceCookie, request) => trustedDeviceCookie === undefined || request === undefined
981
- ? Effect.succeed(Option.none())
982
- : trustedDeviceCookie.read(new Request("http://localhost", { headers: request.headers }));
983
1073
  const metadataString = (metadata, key) => {
984
1074
  const value = metadata?.[key];
985
1075
  return typeof value === "string" && value.length > 0 ? value : undefined;
@@ -988,14 +1078,18 @@ const emailVerifiedClaims = (claims) => {
988
1078
  const requirements = claims?.requirements?.filter((requirement) => requirement !== "email_verification");
989
1079
  return {
990
1080
  ...claims,
991
- emailVerified: true,
1081
+ verifiedIdentityKinds: claims?.verifiedIdentityKinds?.includes("email")
1082
+ ? claims.verifiedIdentityKinds
1083
+ : [...(claims?.verifiedIdentityKinds ?? []), "email"],
992
1084
  ...(requirements === undefined ? {} : { requirements }),
993
1085
  };
994
1086
  };
995
1087
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
996
1088
  const metadataNumber = (metadata, key) => {
997
1089
  const value = metadata?.[key];
998
- return typeof value === "number" && Number.isFinite(value) ? value : undefined;
1090
+ return typeof value === "number" && Number.isFinite(value)
1091
+ ? value
1092
+ : undefined;
999
1093
  };
1000
1094
  const sessionRequestMetadata = (metadata) => {
1001
1095
  const value = metadata?.[sessionRequestMetadataKey];
@@ -1078,40 +1172,37 @@ export const stepUpAuthenticatedHttpBody = (session) => {
1078
1172
  ? {}
1079
1173
  : { mfaVerifiedAt: session.mfaVerifiedAt }),
1080
1174
  };
1081
- return session.claims === undefined ? body : { ...body, claims: session.claims };
1175
+ return session.claims === undefined
1176
+ ? body
1177
+ : { ...body, claims: session.claims };
1082
1178
  };
1083
- const readOptionalSession = (dependencies, request) => Effect.gen(function* () {
1084
- const tokenOption = yield* dependencies.sessionCookie
1085
- .read(webRequestFromHeaders(request.headers))
1086
- .pipe(Effect.catchTag("SessionValidateError", (error) => error.cause === undefined
1087
- ? Effect.succeed(Option.none())
1088
- : Effect.fail(new AuthInternalError({
1089
- code: "internal_error",
1090
- message: "Failed to validate session",
1091
- }))));
1092
- if (Option.isNone(tokenOption)) {
1093
- return Option.none();
1179
+ const provideHandlerAuthRateLimit = (authRateLimit, handler) => ((...args) => handler(...args).pipe(Effect.provideService(AuthRateLimit, authRateLimit)));
1180
+ const provideRequestGuardServices = (dependencies, handler) => ((...args) => {
1181
+ let effect = handler(...args).pipe(Effect.provideService(AuthRateLimit, dependencies.authRateLimit));
1182
+ if (dependencies.botChallengeVerifier !== undefined) {
1183
+ effect = effect.pipe(Effect.provideService(BotChallengeVerifier, dependencies.botChallengeVerifier));
1094
1184
  }
1095
- return yield* dependencies.sessions.validate(tokenOption.value).pipe(Effect.map(Option.some), Effect.catchTag("SessionValidateError", (error) => error.cause === undefined
1096
- ? Effect.succeed(Option.none())
1097
- : Effect.fail(new AuthInternalError({
1098
- code: "internal_error",
1099
- message: "Failed to validate session",
1100
- }))));
1185
+ if (dependencies.trustedDeviceCookie !== undefined) {
1186
+ effect = effect.pipe(Effect.provideService(TrustedDeviceCookie, dependencies.trustedDeviceCookie));
1187
+ }
1188
+ if (dependencies.identities !== undefined) {
1189
+ effect = effect.pipe(Effect.provideService(IdentityStore, dependencies.identities));
1190
+ }
1191
+ if (dependencies.sessions !== undefined) {
1192
+ effect = effect.pipe(Effect.provideService(Sessions, dependencies.sessions));
1193
+ }
1194
+ if (dependencies.sessionCookie !== undefined) {
1195
+ effect = effect.pipe(Effect.provideService(SessionCookie, dependencies.sessionCookie));
1196
+ }
1197
+ return effect;
1101
1198
  });
1102
- const readRequiredSession = (dependencies, request) => readOptionalSession(dependencies, request).pipe(Effect.flatMap((sessionOption) => Option.isSome(sessionOption)
1103
- ? Effect.succeed(sessionOption.value)
1104
- : Effect.fail(new AuthUnauthenticatedError({
1105
- code: "unauthenticated",
1106
- message: "Unauthenticated",
1107
- }))));
1108
1199
  const upgradeVerifiedEmailSession = (dependencies, request, verified) => Effect.gen(function* () {
1109
1200
  const sessionOption = yield* readOptionalSession(dependencies, request);
1110
1201
  if (Option.isNone(sessionOption)) {
1111
1202
  return;
1112
1203
  }
1113
1204
  const session = sessionOption.value.currentSession;
1114
- if (session.userId !== verified.user.id) {
1205
+ if (session.userId !== verified.identity.userId) {
1115
1206
  return;
1116
1207
  }
1117
1208
  yield* dependencies.sessions
@@ -1127,27 +1218,6 @@ const upgradeVerifiedEmailSession = (dependencies, request, verified) => Effect.
1127
1218
  message: "Failed to update session claims",
1128
1219
  }))));
1129
1220
  });
1130
- const startRequiredEmailVerification = (dependencies, result) => Effect.gen(function* () {
1131
- if (dependencies.emailVerificationFlow === undefined ||
1132
- !canStartRequiredEmailVerification(result)) {
1133
- return result;
1134
- }
1135
- const input = {
1136
- userId: result.userId,
1137
- email: result.email,
1138
- };
1139
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1140
- yield* catchAuthApiRateLimit(authApiRateLimit.emailVerificationStart(input), "Failed to start email verification");
1141
- yield* dependencies.emailVerificationFlow
1142
- .start(input)
1143
- .pipe(Effect.catchTag("EmailVerificationFlowStartError", () => Effect.fail(passwordInternalError("Failed to start email verification"))));
1144
- return result;
1145
- });
1146
- const rateLimited = (retryAfter) => new AuthRateLimitedError({
1147
- code: "rate_limited",
1148
- message: "Too many authentication attempts",
1149
- retryAfter,
1150
- });
1151
1221
  const passwordInternalError = (message) => new AuthInternalError({
1152
1222
  code: "internal_error",
1153
1223
  message,
@@ -1192,7 +1262,8 @@ const oauthInternalError = (message = "Failed to complete OAuth request") => new
1192
1262
  code: "internal_error",
1193
1263
  message,
1194
1264
  });
1195
- const oauthHookHttpError = (error, internalMessage) => error instanceof AuthBadRequestError || error instanceof AuthUnauthenticatedError
1265
+ const oauthHookHttpError = (error, internalMessage) => error instanceof AuthBadRequestError ||
1266
+ error instanceof AuthUnauthenticatedError
1196
1267
  ? error
1197
1268
  : oauthInternalError(internalMessage);
1198
1269
  const oauthLinkConfirmationHttpError = (error, internalMessage) => error.message === "OAuth provider account is already linked to this user" ||
@@ -1211,15 +1282,122 @@ const passkeyBadRequest = (message = "Invalid passkey request") => new AuthBadRe
1211
1282
  code: "bad_request",
1212
1283
  message,
1213
1284
  });
1285
+ const userMetadataString = (user, key) => {
1286
+ const value = user.metadata?.[key];
1287
+ return typeof value === "string" && value.length > 0 ? value : undefined;
1288
+ };
1289
+ export const makePasskeyRegistrationUserResolver = (dependencies) => Effect.fn("auth.http.passkey.registration_user.resolve")(function* (input) {
1290
+ const userOption = yield* dependencies.users
1291
+ .findById(input.currentSession.userId)
1292
+ .pipe(Effect.mapError(() => passkeyInternalError("Failed to load passkey registration user")));
1293
+ if (Option.isNone(userOption)) {
1294
+ return yield* passkeyBadRequest("Passkey registration user not found");
1295
+ }
1296
+ const user = userOption.value;
1297
+ const identities = yield* dependencies.identities
1298
+ .listByUser({ userId: user.id })
1299
+ .pipe(Effect.mapError(() => passkeyInternalError("Failed to load passkey registration identity")));
1300
+ const loginIdentity = identities.find((identity) => identity.isPrimaryLogin) ?? identities[0];
1301
+ if (loginIdentity === undefined) {
1302
+ return yield* passkeyBadRequest("Passkey registration identity not found");
1303
+ }
1304
+ const displayName = userMetadataString(user, "displayName") ??
1305
+ userMetadataString(user, "name") ??
1306
+ loginIdentity.value;
1307
+ return {
1308
+ userName: loginIdentity.value,
1309
+ userDisplayName: displayName,
1310
+ };
1311
+ });
1214
1312
  const passkeyVerificationHttpError = (error) => error.message === "Failed to load passkey credential" ||
1215
1313
  error.message === "Failed to store passkey credential" ||
1216
1314
  error.message === "Failed to update passkey credential" ||
1217
1315
  error.message === "Failed to generate passkey credential record id"
1218
1316
  ? passkeyInternalError()
1219
1317
  : passkeyBadRequest();
1318
+ export const identityHttpError = (error) => {
1319
+ if (error instanceof IdentityMutationDeniedError) {
1320
+ return new AuthPolicyDeniedError({
1321
+ code: "policy_denied",
1322
+ message: "Identity mutation denied",
1323
+ });
1324
+ }
1325
+ if (error instanceof LastLoginIdentityError) {
1326
+ return new AuthPolicyDeniedError({
1327
+ code: "policy_denied",
1328
+ message: "Cannot remove the last login identity",
1329
+ });
1330
+ }
1331
+ if (error instanceof IdentityAlreadyExistsError) {
1332
+ return new AuthIdentityAlreadyRegisteredError({
1333
+ code: "identity_already_registered",
1334
+ message: "Identity is unavailable",
1335
+ });
1336
+ }
1337
+ if (error instanceof IdentityNotFoundError ||
1338
+ error instanceof IdentityOwnershipError ||
1339
+ error instanceof IdentityInactiveError) {
1340
+ return new AuthBadRequestError({
1341
+ code: "bad_request",
1342
+ message: "Invalid identity request",
1343
+ });
1344
+ }
1345
+ if (error instanceof IdentityConcurrentModificationError ||
1346
+ error instanceof IdentityNotLoginEligibleError ||
1347
+ error instanceof IdentityUserNotActiveError) {
1348
+ return new AuthBadRequestError({
1349
+ code: "bad_request",
1350
+ message: "Identity could not be updated",
1351
+ });
1352
+ }
1353
+ if (error instanceof IdentityManagementStorageError ||
1354
+ error instanceof IdentityIdGenerationError) {
1355
+ return new AuthInternalError({
1356
+ code: "internal_error",
1357
+ message: "Failed to complete identity request",
1358
+ });
1359
+ }
1360
+ if (error instanceof EmailRiskProviderUnavailableError) {
1361
+ return new AuthInternalError({
1362
+ code: "internal_error",
1363
+ message: "Failed to complete identity request",
1364
+ });
1365
+ }
1366
+ return new AuthBadRequestError({
1367
+ code: "bad_request",
1368
+ message: "Invalid identity request",
1369
+ });
1370
+ };
1220
1371
  const passkeyCredentialManagementHttpError = (error) => error.message === "Passkey credential not found"
1221
1372
  ? passkeyBadRequest("Invalid passkey credential")
1222
1373
  : passkeyInternalError("Failed to update passkey credentials");
1374
+ const strongFactorRemovalPolicyHttpError = (error) => {
1375
+ switch (error.reason) {
1376
+ case "factor_not_found": {
1377
+ return new AuthBadRequestError({
1378
+ code: "bad_request",
1379
+ message: "Invalid strong factor removal request",
1380
+ });
1381
+ }
1382
+ case "last_strong_factor": {
1383
+ return new AuthPolicyDeniedError({
1384
+ code: "policy_denied",
1385
+ message: "Cannot remove the last active strong factor",
1386
+ });
1387
+ }
1388
+ case "inventory_unavailable": {
1389
+ return new AuthInternalError({
1390
+ code: "internal_error",
1391
+ message: "Failed to check strong factor removal policy",
1392
+ });
1393
+ }
1394
+ }
1395
+ };
1396
+ const requireCanRemoveStrongFactor = (policy, input) => policy === undefined
1397
+ ? Effect.void
1398
+ : policy
1399
+ .requireCanRemove(input)
1400
+ .pipe(Effect.mapError(strongFactorRemovalPolicyHttpError));
1223
1401
  const totpInternalError = (message = "Failed to complete TOTP request") => new AuthInternalError({
1224
1402
  code: "internal_error",
1225
1403
  message,
@@ -1293,7 +1471,9 @@ const jwtBadRequest = (message = "Invalid JWT request") => new AuthBadRequestErr
1293
1471
  code: "bad_request",
1294
1472
  message,
1295
1473
  });
1296
- const jwtRevocationHttpError = (error) => error.message === "JWT ID must not be empty" ? jwtBadRequest() : jwtInternalError();
1474
+ const jwtRevocationHttpError = (error) => error.message === "JWT ID must not be empty"
1475
+ ? jwtBadRequest()
1476
+ : jwtInternalError();
1297
1477
  const mfaInternalError = (message = "Failed to complete MFA request") => new AuthInternalError({
1298
1478
  code: "internal_error",
1299
1479
  message,
@@ -1306,11 +1486,8 @@ const mfaInvalidCredentials = () => new AuthInvalidCredentialsError({
1306
1486
  code: "invalid_credentials",
1307
1487
  message: "Invalid MFA code",
1308
1488
  });
1309
- const mfaPolicyDenied = (reason) => new AuthPolicyDeniedError({
1310
- code: "policy_denied",
1311
- message: reason ?? "MFA policy denied the request",
1312
- });
1313
- const authFlowMfaHttpError = (error) => error._tag === "AuthFlowStateError" ? mfaBadRequest() : mfaInternalError();
1489
+ const authFlowMfaHttpFailure = (error) => customEvidencePolicyHttpFailure(error, "Failed to complete MFA request") ??
1490
+ Effect.fail(error._tag === "AuthFlowStateError" ? mfaBadRequest() : mfaInternalError());
1314
1491
  const stepUpInternalError = (message = "Failed to complete step-up request") => new AuthInternalError({
1315
1492
  code: "internal_error",
1316
1493
  message,
@@ -1327,6 +1504,10 @@ const stepUpPolicyDenied = (message = "Step-up policy denied the request") => ne
1327
1504
  code: "policy_denied",
1328
1505
  message,
1329
1506
  });
1507
+ const stepUpRotationHttpFailure = (error) => {
1508
+ const policyFailure = customEvidencePolicyHttpFailure(error, "Failed to upgrade current session");
1509
+ return policyFailure ?? Effect.fail(stepUpInvalidCredentials());
1510
+ };
1330
1511
  const trustedDeviceSetCookies = (dependencies) => Effect.gen(function* () {
1331
1512
  if (!dependencies.rememberDevice ||
1332
1513
  dependencies.trustedDevice === undefined ||
@@ -1341,144 +1522,37 @@ const trustedDeviceSetCookies = (dependencies) => Effect.gen(function* () {
1341
1522
  .pipe(Effect.mapError(() => passwordInternalError("Failed to remember trusted device")));
1342
1523
  return [cookie];
1343
1524
  });
1344
- const catchAuthApiRateLimit = (effect, internalMessage) => effect.pipe(Effect.catchTag("RateLimitExceededError", (error) => Effect.fail(rateLimited(error.retryAfter))), Effect.catchTag("RateLimitStoreError", () => Effect.fail(passwordInternalError(internalMessage))), Effect.catchTag("PrivacyError", () => Effect.fail(passwordInternalError(internalMessage))));
1345
1525
  export class AdminSessionAuthorization extends Context.Service()("auth/AdminSessionAuthorization") {
1346
1526
  }
1347
- (function (AdminSessionAuthorization) {
1348
- AdminSessionAuthorization.make = (service) => AdminSessionAuthorization.of(service);
1349
- })(AdminSessionAuthorization || (AdminSessionAuthorization = {}));
1527
+ export class AdminPermissionDefinitionAuthorization extends Context.Service()("auth/AdminPermissionDefinitionAuthorization") {
1528
+ }
1350
1529
  export class AdminSecurityTimelineAuthorization extends Context.Service()("auth/AdminSecurityTimelineAuthorization") {
1351
1530
  }
1352
- (function (AdminSecurityTimelineAuthorization) {
1353
- AdminSecurityTimelineAuthorization.make = (service) => AdminSecurityTimelineAuthorization.of(service);
1354
- })(AdminSecurityTimelineAuthorization || (AdminSecurityTimelineAuthorization = {}));
1355
1531
  export class AdminTrustedDeviceAuthorization extends Context.Service()("auth/AdminTrustedDeviceAuthorization") {
1356
1532
  }
1357
- (function (AdminTrustedDeviceAuthorization) {
1358
- AdminTrustedDeviceAuthorization.make = (service) => AdminTrustedDeviceAuthorization.of(service);
1359
- })(AdminTrustedDeviceAuthorization || (AdminTrustedDeviceAuthorization = {}));
1360
1533
  export class OidcDiscoveryMetadata extends Context.Service()("auth/OidcDiscoveryMetadata") {
1361
1534
  }
1362
- (function (OidcDiscoveryMetadata) {
1363
- OidcDiscoveryMetadata.make = (service) => OidcDiscoveryMetadata.of(service);
1364
- })(OidcDiscoveryMetadata || (OidcDiscoveryMetadata = {}));
1365
- export const OidcDiscoveryMetadataLive = (metadata) => Layer.succeed(OidcDiscoveryMetadata, OidcDiscoveryMetadata.make({ load: () => Effect.succeed(metadata) }));
1366
- export const makePasswordSignInHandler = (dependencies) => Effect.fn("auth.http.password.sign_in")(function* ({ payload, request, }) {
1367
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.sign_in");
1368
- const trustedDeviceToken = yield* trustedDeviceTokenFromRequest(dependencies.trustedDeviceCookie, request).pipe(Effect.mapError(() => passwordInternalError("Failed to read trusted device cookie")));
1369
- const requestMetadataOptions = yield* authRequestMetadataOptions;
1370
- const requestContext = loginRequestContextFromRequest(request, requestMetadataOptions);
1371
- const input = passwordSignInInput(payload, Option.isSome(trustedDeviceToken) ? trustedDeviceToken.value : undefined, requestContext);
1372
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1373
- yield* catchAuthApiRateLimit(authApiRateLimit.passwordSignIn(input), "Failed to sign in with password");
1374
- const result = yield* dependencies.password.signIn(input).pipe(Effect.catchTag("StorageError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("PasswordHashError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("TrustedDeviceError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("LoginRiskError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("SessionCreateError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("AuthFlowStateError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("LoginApprovalReviewError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))), Effect.catchTag("LoginApprovalFlowStartError", () => Effect.fail(passwordInternalError("Failed to sign in with password"))));
1375
- yield* startRequiredEmailVerification(dependencies, result);
1376
- return yield* dependencies.authHttp.commitPasswordSignInResult(result);
1377
- });
1378
- export const makePasswordSignUpHandler = (dependencies) => Effect.fn("auth.http.password.sign_up")(function* ({ payload, request, }) {
1379
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.sign_up");
1380
- const requestMetadataOptions = yield* authRequestMetadataOptions;
1381
- const input = passwordSignUpInput(payload, loginRequestContextFromRequest(request, requestMetadataOptions));
1382
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1383
- yield* catchAuthApiRateLimit(authApiRateLimit.passwordSignUp(input), "Failed to sign up with password");
1384
- const result = yield* dependencies.registration.signUp(input).pipe(Effect.catchTag("EmailAlreadyRegisteredError", () => Effect.fail(new AuthEmailAlreadyRegisteredError({
1385
- code: "email_already_registered",
1386
- message: "Email is already registered",
1387
- }))), Effect.catchTag("StorageError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("PasswordHashError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("CryptoError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("TrustedDeviceError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("LoginRiskError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("SessionCreateError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("AuthFlowStateError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("LoginApprovalReviewError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))), Effect.catchTag("LoginApprovalFlowStartError", () => Effect.fail(passwordInternalError("Failed to sign up with password"))));
1388
- yield* startRequiredEmailVerification(dependencies, result);
1389
- return yield* dependencies.authHttp.commitPasswordSignUpResult(result);
1390
- });
1391
- export const makePasswordResetStartHandler = (dependencies) => Effect.fn("auth.http.password.reset_start")(function* ({ payload, }) {
1392
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.reset_start");
1393
- const input = passwordResetStartInput(payload);
1394
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1395
- yield* catchAuthApiRateLimit(authApiRateLimit.passwordResetStart(input), "Failed to start password reset");
1396
- yield* dependencies.passwordReset.start(input).pipe(Effect.mapError(() => new AuthInternalError({
1397
- code: "internal_error",
1398
- message: "Failed to start password reset",
1399
- })));
1400
- return HttpServerResponse.empty({ status: 204 });
1401
- });
1402
- export const makePasswordResetVerifyHandler = (dependencies) => Effect.fn("auth.http.password.reset_verify")(function* ({ payload, }) {
1403
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.reset_verify");
1404
- yield* dependencies.passwordReset
1405
- .verify(passwordResetVerifyInput(payload))
1406
- .pipe(Effect.mapError(() => new AuthBadRequestError({
1407
- code: "bad_request",
1408
- message: "Invalid password reset request",
1409
- })));
1410
- return HttpServerResponse.empty({ status: 204 });
1411
- });
1412
- const passwordManagementError = (error) => error.reason === "internal"
1413
- ? new AuthInternalError({
1414
- code: "internal_error",
1415
- message: "Failed to update password",
1416
- })
1417
- : new AuthBadRequestError({
1418
- code: "bad_request",
1419
- message: "Invalid password update request",
1420
- });
1421
- export const makePasswordSetHandler = (dependencies) => Effect.fn("auth.http.password.set")(function* ({ payload, request, }) {
1422
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.set");
1423
- const current = yield* readRequiredSession(dependencies, request);
1424
- yield* dependencies.passwordManagement
1425
- .set(passwordSetInput(current.currentSession.userId, payload))
1426
- .pipe(Effect.mapError(passwordManagementError));
1427
- return HttpServerResponse.empty({ status: 204 });
1428
- });
1429
- export const makePasswordChangeHandler = (dependencies) => Effect.fn("auth.http.password.change")(function* ({ payload, request, }) {
1430
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "password.change");
1431
- const current = yield* readRequiredSession(dependencies, request);
1432
- yield* dependencies.passwordManagement
1433
- .change(passwordChangeInput(current.currentSession.userId, payload))
1434
- .pipe(Effect.mapError(passwordManagementError));
1435
- return HttpServerResponse.empty({ status: 204 });
1436
- });
1437
- export const makeCurrentSessionHandler = (dependencies) => Effect.fn("auth.http.session.current")(function* ({ request, }) {
1535
+ export const OidcDiscoveryMetadataLive = (metadata) => Layer.succeed(OidcDiscoveryMetadata, OidcDiscoveryMetadata.of({ load: () => Effect.succeed(metadata) }));
1536
+ export const makeCurrentSessionHandler = (dependencies) => Effect.fn("auth.http.session.current")(function* (handlerRequest) {
1537
+ const { request } = handlerRequest;
1438
1538
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.current");
1539
+ const session = yield* readRequiredSession(dependencies, request);
1540
+ return yield* dependencies.authHttp.commitCurrentSession(session);
1541
+ });
1542
+ export const makeRefreshSessionHandler = (dependencies) => Effect.fn("auth.http.session.refresh")(function* ({ request, }) {
1543
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.refresh");
1439
1544
  const tokenOption = yield* dependencies.sessionCookie
1440
1545
  .read(webRequestFromHeaders(request.headers))
1441
- .pipe(Effect.mapError((error) => error.cause === undefined
1442
- ? new AuthUnauthenticatedError({
1443
- code: "unauthenticated",
1444
- message: "Unauthenticated",
1445
- })
1446
- : new AuthInternalError({
1447
- code: "internal_error",
1448
- message: "Failed to validate session",
1449
- })));
1450
- if (Option.isNone(tokenOption)) {
1451
- return yield* new AuthUnauthenticatedError({
1452
- code: "unauthenticated",
1453
- message: "Unauthenticated",
1454
- });
1455
- }
1456
- const session = yield* dependencies.sessions
1457
- .validate(tokenOption.value)
1458
- .pipe(Effect.mapError((error) => error.cause === undefined
1459
- ? new AuthUnauthenticatedError({
1460
- code: "unauthenticated",
1461
- message: "Unauthenticated",
1462
- })
1463
- : new AuthInternalError({
1464
- code: "internal_error",
1465
- message: "Failed to validate session",
1466
- })));
1467
- return yield* dependencies.authHttp.commitCurrentSession(session);
1468
- });
1469
- export const makeRefreshSessionHandler = (dependencies) => Effect.fn("auth.http.session.refresh")(function* ({ request, }) {
1470
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.refresh");
1471
- const tokenOption = yield* dependencies.sessionCookie
1472
- .read(webRequestFromHeaders(request.headers))
1473
- .pipe(Effect.mapError((error) => error.cause === undefined
1474
- ? new AuthUnauthenticatedError({
1475
- code: "unauthenticated",
1476
- message: "Unauthenticated",
1477
- })
1478
- : new AuthInternalError({
1479
- code: "internal_error",
1480
- message: "Failed to validate session",
1481
- })));
1546
+ .pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to validate session") ??
1547
+ Effect.fail(error.cause === undefined
1548
+ ? new AuthUnauthenticatedError({
1549
+ code: "unauthenticated",
1550
+ message: "Unauthenticated",
1551
+ })
1552
+ : new AuthInternalError({
1553
+ code: "internal_error",
1554
+ message: "Failed to validate session",
1555
+ }))));
1482
1556
  if (Option.isNone(tokenOption)) {
1483
1557
  return yield* new AuthUnauthenticatedError({
1484
1558
  code: "unauthenticated",
@@ -1487,51 +1561,36 @@ export const makeRefreshSessionHandler = (dependencies) => Effect.fn("auth.http.
1487
1561
  }
1488
1562
  const session = yield* dependencies.sessions
1489
1563
  .refresh(tokenOption.value)
1490
- .pipe(Effect.mapError((error) => error.cause === undefined
1491
- ? new AuthUnauthenticatedError({
1492
- code: "unauthenticated",
1493
- message: "Unauthenticated",
1494
- })
1495
- : new AuthInternalError({
1496
- code: "internal_error",
1497
- message: "Failed to refresh session",
1498
- })));
1564
+ .pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to refresh session") ??
1565
+ Effect.fail(error.cause === undefined
1566
+ ? new AuthUnauthenticatedError({
1567
+ code: "unauthenticated",
1568
+ message: "Unauthenticated",
1569
+ })
1570
+ : new AuthInternalError({
1571
+ code: "internal_error",
1572
+ message: "Failed to refresh session",
1573
+ }))));
1499
1574
  return yield* dependencies.authHttp.commitSessionRefreshed(session);
1500
1575
  });
1501
1576
  export const makeLogoutHandler = (dependencies) => Effect.fn("auth.http.session.logout")(function* ({ request, }) {
1502
1577
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.logout");
1503
- const tokenOption = yield* dependencies.sessionCookie
1504
- .read(webRequestFromHeaders(request.headers))
1505
- .pipe(Effect.catchTag("SessionValidateError", (error) => error.cause === undefined
1506
- ? Effect.succeed(Option.none())
1507
- : Effect.fail(new AuthInternalError({
1578
+ const sessionOption = yield* readOptionalSession(dependencies, request);
1579
+ if (Option.isSome(sessionOption)) {
1580
+ yield* dependencies.sessions
1581
+ .revoke({
1582
+ sessionId: sessionOption.value.currentSession.sessionId,
1583
+ reason: "logout",
1584
+ })
1585
+ .pipe(Effect.mapError(() => new AuthInternalError({
1508
1586
  code: "internal_error",
1509
- message: "Failed to validate session",
1510
- }))));
1511
- if (Option.isSome(tokenOption)) {
1512
- const sessionOption = yield* dependencies.sessions
1513
- .validate(tokenOption.value)
1514
- .pipe(Effect.map(Option.some), Effect.catchTag("SessionValidateError", (error) => error.cause === undefined
1515
- ? Effect.succeed(Option.none())
1516
- : Effect.fail(new AuthInternalError({
1517
- code: "internal_error",
1518
- message: "Failed to validate session",
1519
- }))));
1520
- if (Option.isSome(sessionOption)) {
1521
- yield* dependencies.sessions
1522
- .revoke({
1523
- sessionId: sessionOption.value.currentSession.sessionId,
1524
- reason: "logout",
1525
- })
1526
- .pipe(Effect.mapError(() => new AuthInternalError({
1527
- code: "internal_error",
1528
- message: "Failed to revoke session",
1529
- })));
1530
- }
1587
+ message: "Failed to revoke session",
1588
+ })));
1531
1589
  }
1532
1590
  return yield* dependencies.authHttp.commitSessionCleared();
1533
1591
  });
1534
- export const makeListSessionsHandler = (dependencies) => Effect.fn("auth.http.session.list")(function* ({ request, }) {
1592
+ export const makeListSessionsHandler = (dependencies) => Effect.fn("auth.http.session.list")(function* (handlerRequest) {
1593
+ const { request } = handlerRequest;
1535
1594
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.list");
1536
1595
  const current = yield* readRequiredSession(dependencies, request);
1537
1596
  const sessions = yield* dependencies.sessions
@@ -1544,7 +1603,8 @@ export const makeListSessionsHandler = (dependencies) => Effect.fn("auth.http.se
1544
1603
  sessions: sessions.map((session) => activeSessionBody(session, current.currentSession.sessionId)),
1545
1604
  };
1546
1605
  });
1547
- export const makeRevokeSessionHandler = (dependencies) => Effect.fn("auth.http.session.revoke")(function* ({ payload, request, }) {
1606
+ export const makeRevokeSessionHandler = (dependencies) => Effect.fn("auth.http.session.revoke")(function* (handlerRequest) {
1607
+ const { payload, request } = handlerRequest;
1548
1608
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.revoke");
1549
1609
  const current = yield* readRequiredSession(dependencies, request);
1550
1610
  yield* dependencies.sessions
@@ -1561,7 +1621,8 @@ export const makeRevokeSessionHandler = (dependencies) => Effect.fn("auth.http.s
1561
1621
  ? yield* dependencies.authHttp.commitSessionCleared()
1562
1622
  : HttpServerResponse.empty({ status: 204 });
1563
1623
  });
1564
- export const makeRevokeOtherSessionsHandler = (dependencies) => Effect.fn("auth.http.session.revoke_others")(function* ({ request, }) {
1624
+ export const makeRevokeOtherSessionsHandler = (dependencies) => Effect.fn("auth.http.session.revoke_others")(function* (handlerRequest) {
1625
+ const { request } = handlerRequest;
1565
1626
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "session.revoke_others");
1566
1627
  const current = yield* readRequiredSession(dependencies, request);
1567
1628
  yield* dependencies.sessions
@@ -1576,7 +1637,8 @@ export const makeRevokeOtherSessionsHandler = (dependencies) => Effect.fn("auth.
1576
1637
  })));
1577
1638
  return HttpServerResponse.empty({ status: 204 });
1578
1639
  });
1579
- export const makeAdminSessionListHandler = (dependencies) => Effect.fn("auth.http.admin_session.list")(function* ({ query, request, }) {
1640
+ export const makeAdminSessionListHandler = (dependencies) => Effect.fn("auth.http.admin_session.list")(function* (handlerRequest) {
1641
+ const { query, request } = handlerRequest;
1580
1642
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_session.list");
1581
1643
  const current = yield* readRequiredSession(dependencies, request);
1582
1644
  yield* dependencies.authorization.authorize({
@@ -1593,7 +1655,8 @@ export const makeAdminSessionListHandler = (dependencies) => Effect.fn("auth.htt
1593
1655
  })));
1594
1656
  return { sessions: sessions.map(adminSessionHttpBody) };
1595
1657
  });
1596
- export const makeAdminSessionRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke")(function* ({ payload, request, }) {
1658
+ export const makeAdminSessionRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke")(function* (handlerRequest) {
1659
+ const { payload, request } = handlerRequest;
1597
1660
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_session.revoke");
1598
1661
  const current = yield* readRequiredSession(dependencies, request);
1599
1662
  yield* dependencies.authorization.authorize({
@@ -1615,7 +1678,8 @@ export const makeAdminSessionRevokeHandler = (dependencies) => Effect.fn("auth.h
1615
1678
  })));
1616
1679
  return HttpServerResponse.empty({ status: 204 });
1617
1680
  });
1618
- export const makeAdminSessionRevokeAllHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke_all")(function* ({ payload, request, }) {
1681
+ export const makeAdminSessionRevokeAllHandler = (dependencies) => Effect.fn("auth.http.admin_session.revoke_all")(function* (handlerRequest) {
1682
+ const { payload, request } = handlerRequest;
1619
1683
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_session.revoke_all");
1620
1684
  const current = yield* readRequiredSession(dependencies, request);
1621
1685
  yield* dependencies.authorization.authorize({
@@ -1630,6 +1694,213 @@ export const makeAdminSessionRevokeAllHandler = (dependencies) => Effect.fn("aut
1630
1694
  })));
1631
1695
  return HttpServerResponse.empty({ status: 204 });
1632
1696
  });
1697
+ export const adminPermissionDefinitionHttpBody = (definition) => ({
1698
+ id: definition.id,
1699
+ ...(definition.description === undefined
1700
+ ? {}
1701
+ : { description: definition.description }),
1702
+ ...(definition.scopeType === undefined
1703
+ ? {}
1704
+ : { scopeType: definition.scopeType }),
1705
+ createdAt: definition.createdAt,
1706
+ updatedAt: definition.updatedAt,
1707
+ ...(definition.disabledAt === undefined
1708
+ ? {}
1709
+ : { disabledAt: definition.disabledAt }),
1710
+ ...(definition.deletedAt === undefined
1711
+ ? {}
1712
+ : { deletedAt: definition.deletedAt }),
1713
+ });
1714
+ const adminPermissionDefinitionHttpError = (error) => {
1715
+ switch (error.reason) {
1716
+ case "storage": {
1717
+ return new AuthInternalError({
1718
+ code: "internal_error",
1719
+ message: "Failed to complete permission definition request",
1720
+ });
1721
+ }
1722
+ case "not_found": {
1723
+ return new AuthNotFoundError({
1724
+ code: "not_found",
1725
+ message: "Permission definition not found",
1726
+ });
1727
+ }
1728
+ case "already_exists":
1729
+ case "concurrent_modification":
1730
+ case "deleted":
1731
+ case "inactive": {
1732
+ return new AuthConflictError({
1733
+ code: "conflict",
1734
+ message: "Permission definition conflicts with its current state",
1735
+ });
1736
+ }
1737
+ case "invalid_input": {
1738
+ return new AuthBadRequestError({
1739
+ code: "bad_request",
1740
+ message: "Invalid permission definition request",
1741
+ });
1742
+ }
1743
+ }
1744
+ };
1745
+ export const adminPermissionDefinitionCreateOperation = Effect.fn("auth.http.admin_permission_definition.create")(function* (handlerRequest) {
1746
+ const { payload, request } = handlerRequest;
1747
+ const administration = yield* PermissionAdministration;
1748
+ const authorization = yield* AdminPermissionDefinitionAuthorization;
1749
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.create");
1750
+ const current = yield* requireSession(request);
1751
+ yield* authorization.authorize({
1752
+ currentSession: current.currentSession,
1753
+ action: "create",
1754
+ request,
1755
+ permissionId: payload.id,
1756
+ ...(payload.scopeType === undefined
1757
+ ? {}
1758
+ : { scopeType: payload.scopeType }),
1759
+ });
1760
+ const definition = yield* administration
1761
+ .createPermissionDefinition(payload)
1762
+ .pipe(Effect.mapError(adminPermissionDefinitionHttpError));
1763
+ yield* Audit.emit({
1764
+ type: "auth.permission_definition.created",
1765
+ actor: Audit.AuditActor.user({
1766
+ userId: current.currentSession.userId,
1767
+ sessionId: current.currentSession.sessionId,
1768
+ }),
1769
+ permissionId: definition.id,
1770
+ ...(definition.scopeType === undefined
1771
+ ? {}
1772
+ : { scopeType: definition.scopeType }),
1773
+ occurredAt: definition.updatedAt,
1774
+ });
1775
+ return adminPermissionDefinitionHttpBody(definition);
1776
+ });
1777
+ export const adminPermissionDefinitionGetOperation = Effect.fn("auth.http.admin_permission_definition.get")(function* (handlerRequest) {
1778
+ const { query, request } = handlerRequest;
1779
+ const administration = yield* PermissionAdministration;
1780
+ const authorization = yield* AdminPermissionDefinitionAuthorization;
1781
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.get");
1782
+ const current = yield* requireSession(request);
1783
+ yield* authorization.authorize({
1784
+ currentSession: current.currentSession,
1785
+ action: "get",
1786
+ request,
1787
+ permissionId: query.id,
1788
+ });
1789
+ const definition = yield* administration
1790
+ .getPermissionDefinition(query.id)
1791
+ .pipe(Effect.mapError(adminPermissionDefinitionHttpError));
1792
+ if (Option.isNone(definition)) {
1793
+ return yield* new AuthNotFoundError({
1794
+ code: "not_found",
1795
+ message: "Permission definition not found",
1796
+ });
1797
+ }
1798
+ return adminPermissionDefinitionHttpBody(definition.value);
1799
+ });
1800
+ export const adminPermissionDefinitionListOperation = Effect.fn("auth.http.admin_permission_definition.list")(function* (handlerRequest) {
1801
+ const { query, request } = handlerRequest;
1802
+ const administration = yield* PermissionAdministration;
1803
+ const authorization = yield* AdminPermissionDefinitionAuthorization;
1804
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.list");
1805
+ const current = yield* requireSession(request);
1806
+ yield* authorization.authorize({
1807
+ currentSession: current.currentSession,
1808
+ action: "list",
1809
+ request,
1810
+ });
1811
+ const limit = normalizePermissionDefinitionListLimit(query.limit);
1812
+ const definitions = yield* administration
1813
+ .listPermissionDefinitions({ ...query, limit })
1814
+ .pipe(Effect.mapError(adminPermissionDefinitionHttpError));
1815
+ const nextAfter = definitions.length === limit ? definitions.at(-1)?.id : undefined;
1816
+ return {
1817
+ definitions: definitions.map(adminPermissionDefinitionHttpBody),
1818
+ ...(nextAfter === undefined ? {} : { nextAfter }),
1819
+ };
1820
+ });
1821
+ export const adminPermissionDefinitionUpdateOperation = Effect.fn("auth.http.admin_permission_definition.update")(function* (handlerRequest) {
1822
+ const { payload, request } = handlerRequest;
1823
+ const administration = yield* PermissionAdministration;
1824
+ const authorization = yield* AdminPermissionDefinitionAuthorization;
1825
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_permission_definition.update");
1826
+ const current = yield* requireSession(request);
1827
+ yield* authorization.authorize({
1828
+ currentSession: current.currentSession,
1829
+ action: "update",
1830
+ request,
1831
+ permissionId: payload.id,
1832
+ ...(payload.scopeType === undefined
1833
+ ? {}
1834
+ : { scopeType: payload.scopeType }),
1835
+ });
1836
+ const definition = yield* administration
1837
+ .updatePermissionDefinition(payload)
1838
+ .pipe(Effect.mapError(adminPermissionDefinitionHttpError));
1839
+ yield* Audit.emit({
1840
+ type: "auth.permission_definition.updated",
1841
+ actor: Audit.AuditActor.user({
1842
+ userId: current.currentSession.userId,
1843
+ sessionId: current.currentSession.sessionId,
1844
+ }),
1845
+ permissionId: definition.id,
1846
+ ...(definition.scopeType === undefined
1847
+ ? {}
1848
+ : { scopeType: definition.scopeType }),
1849
+ changedFields: [
1850
+ ...(payload.description === undefined ? [] : ["description"]),
1851
+ ...(payload.scopeType === undefined ? [] : ["scopeType"]),
1852
+ ],
1853
+ occurredAt: definition.updatedAt,
1854
+ });
1855
+ return adminPermissionDefinitionHttpBody(definition);
1856
+ });
1857
+ const runAdminPermissionDefinitionMutation = Effect.fn("auth.http.admin_permission_definition.mutate")(function* (action, handlerRequest) {
1858
+ const { payload, request } = handlerRequest;
1859
+ const administration = yield* PermissionAdministration;
1860
+ const authorization = yield* AdminPermissionDefinitionAuthorization;
1861
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", `admin_permission_definition.${action}`);
1862
+ const current = yield* requireSession(request);
1863
+ yield* authorization.authorize({
1864
+ currentSession: current.currentSession,
1865
+ action,
1866
+ request,
1867
+ permissionId: payload.id,
1868
+ });
1869
+ const mutation = action === "disable"
1870
+ ? administration.disablePermissionDefinition(payload)
1871
+ : action === "enable"
1872
+ ? administration.enablePermissionDefinition(payload)
1873
+ : administration.deletePermissionDefinition(payload);
1874
+ const definition = yield* mutation.pipe(Effect.mapError(adminPermissionDefinitionHttpError));
1875
+ const actor = Audit.AuditActor.user({
1876
+ userId: current.currentSession.userId,
1877
+ sessionId: current.currentSession.sessionId,
1878
+ });
1879
+ const common = {
1880
+ actor,
1881
+ permissionId: definition.id,
1882
+ ...(definition.scopeType === undefined
1883
+ ? {}
1884
+ : { scopeType: definition.scopeType }),
1885
+ occurredAt: definition.updatedAt,
1886
+ };
1887
+ const event = action === "disable"
1888
+ ? { type: "auth.permission_definition.disabled", ...common }
1889
+ : action === "enable"
1890
+ ? { type: "auth.permission_definition.enabled", ...common }
1891
+ : { type: "auth.permission_definition.deleted", ...common };
1892
+ yield* Audit.emit(event);
1893
+ return adminPermissionDefinitionHttpBody(definition);
1894
+ });
1895
+ export const adminPermissionDefinitionDisableOperation = Effect.fn("auth.http.admin_permission_definition.disable")(function* (handlerRequest) {
1896
+ return yield* runAdminPermissionDefinitionMutation("disable", handlerRequest);
1897
+ });
1898
+ export const adminPermissionDefinitionEnableOperation = Effect.fn("auth.http.admin_permission_definition.enable")(function* (handlerRequest) {
1899
+ return yield* runAdminPermissionDefinitionMutation("enable", handlerRequest);
1900
+ });
1901
+ export const adminPermissionDefinitionDeleteOperation = Effect.fn("auth.http.admin_permission_definition.delete")(function* (handlerRequest) {
1902
+ return yield* runAdminPermissionDefinitionMutation("delete", handlerRequest);
1903
+ });
1633
1904
  export const makeLoginNotificationReportHandler = (dependencies) => Effect.fn("auth.http.security.login_notification.report")(function* ({ payload, }) {
1634
1905
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "security.login_notification.report");
1635
1906
  if (dependencies.loginNotification === undefined) {
@@ -1645,33 +1916,48 @@ export const makeLoginNotificationReportHandler = (dependencies) => Effect.fn("a
1645
1916
  })));
1646
1917
  return HttpServerResponse.empty({ status: 204 });
1647
1918
  });
1648
- const securityTimelineActorHttpBody = (actor) => actor.type === "anonymous"
1649
- ? { type: "anonymous" }
1650
- : {
1651
- type: "user",
1652
- ...(actor.sessionId === undefined ? {} : { sessionId: actor.sessionId }),
1653
- };
1919
+ const securityTimelineActorHttpBody = (actor) => {
1920
+ switch (actor.type) {
1921
+ case "anonymous": {
1922
+ return { type: "anonymous" };
1923
+ }
1924
+ case "user": {
1925
+ return {
1926
+ type: "user",
1927
+ ...(actor.sessionId === undefined
1928
+ ? {}
1929
+ : { sessionId: actor.sessionId }),
1930
+ };
1931
+ }
1932
+ case "custom": {
1933
+ return undefined;
1934
+ }
1935
+ }
1936
+ };
1654
1937
  const securityTimelineRequestHttpBody = (request) => ({
1655
1938
  ...(request.ipHash === undefined ? {} : { ipHash: request.ipHash }),
1656
1939
  ...(request.userAgentHash === undefined
1657
1940
  ? {}
1658
1941
  : { userAgentHash: request.userAgentHash }),
1659
1942
  });
1660
- export const securityTimelineEventHttpBody = (event) => ({
1661
- eventId: event.id,
1662
- type: event.type,
1663
- category: event.category,
1664
- severity: event.severity,
1665
- occurredAt: event.occurredAt,
1666
- summary: event.summary,
1667
- ...(event.actor === undefined
1668
- ? {}
1669
- : { actor: securityTimelineActorHttpBody(event.actor) }),
1670
- ...(event.request === undefined
1671
- ? {}
1672
- : { request: securityTimelineRequestHttpBody(event.request) }),
1673
- ...(event.metadata === undefined ? {} : { metadata: event.metadata }),
1674
- });
1943
+ export const securityTimelineEventHttpBody = (event) => {
1944
+ const actor = event.actor === undefined
1945
+ ? undefined
1946
+ : securityTimelineActorHttpBody(event.actor);
1947
+ return {
1948
+ eventId: event.id,
1949
+ type: event.type,
1950
+ category: event.category,
1951
+ severity: event.severity,
1952
+ occurredAt: event.occurredAt,
1953
+ summary: event.summary,
1954
+ ...(actor === undefined ? {} : { actor }),
1955
+ ...(event.request === undefined
1956
+ ? {}
1957
+ : { request: securityTimelineRequestHttpBody(event.request) }),
1958
+ ...(event.metadata === undefined ? {} : { metadata: event.metadata }),
1959
+ };
1960
+ };
1675
1961
  const securityTimelineListInput = (query, userId) => ({
1676
1962
  userId,
1677
1963
  ...(query.limit === undefined ? {} : { limit: query.limit }),
@@ -1682,7 +1968,8 @@ const securityTimelineListInput = (query, userId) => ({
1682
1968
  ...(query.categories === undefined ? {} : { categories: query.categories }),
1683
1969
  });
1684
1970
  const adminSecurityTimelineListInput = (query) => securityTimelineListInput(query, query.userId);
1685
- export const makeSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.security_timeline.list")(function* ({ query, request, }) {
1971
+ export const makeSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.security_timeline.list")(function* (handlerRequest) {
1972
+ const { query, request } = handlerRequest;
1686
1973
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "security_timeline.list");
1687
1974
  const current = yield* readRequiredSession(dependencies, request);
1688
1975
  const events = yield* dependencies.securityTimeline
@@ -1693,7 +1980,8 @@ export const makeSecurityTimelineListHandler = (dependencies) => Effect.fn("auth
1693
1980
  })));
1694
1981
  return { events: events.map(securityTimelineEventHttpBody) };
1695
1982
  });
1696
- export const makeAdminSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.admin_security_timeline.list")(function* ({ query, request, }) {
1983
+ export const makeAdminSecurityTimelineListHandler = (dependencies) => Effect.fn("auth.http.admin_security_timeline.list")(function* (handlerRequest) {
1984
+ const { query, request } = handlerRequest;
1697
1985
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_security_timeline.list");
1698
1986
  const current = yield* readRequiredSession(dependencies, request);
1699
1987
  yield* dependencies.authorization.authorize({
@@ -1716,7 +2004,8 @@ export const trustedDeviceHttpBody = (device) => ({
1716
2004
  expiresAt: device.expiresAt,
1717
2005
  ...(device.metadata === undefined ? {} : { metadata: device.metadata }),
1718
2006
  });
1719
- export const makeTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.trusted_device.list")(function* ({ request, }) {
2007
+ export const makeTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.trusted_device.list")(function* (handlerRequest) {
2008
+ const { request } = handlerRequest;
1720
2009
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "trusted_device.list");
1721
2010
  const current = yield* readRequiredSession(dependencies, request);
1722
2011
  const now = yield* currentUnixMillis;
@@ -1728,7 +2017,8 @@ export const makeTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.ht
1728
2017
  })));
1729
2018
  return { devices: devices.map(trustedDeviceHttpBody) };
1730
2019
  });
1731
- export const makeTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.trusted_device.revoke")(function* ({ payload, request, }) {
2020
+ export const makeTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.trusted_device.revoke")(function* (handlerRequest) {
2021
+ const { payload, request } = handlerRequest;
1732
2022
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "trusted_device.revoke");
1733
2023
  const current = yield* readRequiredSession(dependencies, request);
1734
2024
  yield* dependencies.trustedDevices
@@ -1742,7 +2032,8 @@ export const makeTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.
1742
2032
  })));
1743
2033
  return HttpServerResponse.empty({ status: 204 });
1744
2034
  });
1745
- export const makeAdminTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.list")(function* ({ query, request, }) {
2035
+ export const makeAdminTrustedDeviceListHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.list")(function* (handlerRequest) {
2036
+ const { query, request } = handlerRequest;
1746
2037
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_trusted_device.list");
1747
2038
  const current = yield* readRequiredSession(dependencies, request);
1748
2039
  yield* dependencies.authorization.authorize({
@@ -1760,7 +2051,8 @@ export const makeAdminTrustedDeviceListHandler = (dependencies) => Effect.fn("au
1760
2051
  })));
1761
2052
  return { devices: devices.map(trustedDeviceHttpBody) };
1762
2053
  });
1763
- export const makeAdminTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.revoke")(function* ({ payload, request, }) {
2054
+ export const makeAdminTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("auth.http.admin_trusted_device.revoke")(function* (handlerRequest) {
2055
+ const { payload, request } = handlerRequest;
1764
2056
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "admin_trusted_device.revoke");
1765
2057
  const current = yield* readRequiredSession(dependencies, request);
1766
2058
  yield* dependencies.authorization.authorize({
@@ -1781,12 +2073,10 @@ export const makeAdminTrustedDeviceRevokeHandler = (dependencies) => Effect.fn("
1781
2073
  })));
1782
2074
  return HttpServerResponse.empty({ status: 204 });
1783
2075
  });
1784
- export const makeEmailVerificationStartHandler = (dependencies) => Effect.fn("auth.http.email_verification.start")(function* ({ payload, }) {
2076
+ export const makeEmailVerificationStartHandler = (dependencies) => Effect.fn("auth.http.email_verification.start")(function* (handlerRequest) {
1785
2077
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email_verification.start");
1786
- const input = emailVerificationStartInput(payload);
1787
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1788
- yield* catchAuthApiRateLimit(authApiRateLimit.emailVerificationStart(input), "Failed to start email verification");
1789
- yield* dependencies.emailVerificationFlow.start(input).pipe(Effect.catchTag("EmailVerificationFlowStartError", (error) => Effect.fail(error.cause instanceof EmailVerificationIssueError
2078
+ const guarded = yield* EmailGuards.emailVerification.start(handlerRequest);
2079
+ yield* dependencies.emailVerificationFlow.start(guarded.input).pipe(Effect.catchTag("EmailVerificationFlowStartError", (error) => Effect.fail(error.cause instanceof EmailVerificationIssueError
1790
2080
  ? new AuthBadRequestError({
1791
2081
  code: "bad_request",
1792
2082
  message: "Invalid email verification request",
@@ -1813,55 +2103,65 @@ export const makeEmailVerificationVerifyHandler = (dependencies) => Effect.fn("a
1813
2103
  yield* upgradeVerifiedEmailSession(dependencies, request, verified);
1814
2104
  return HttpServerResponse.empty({ status: 204 });
1815
2105
  });
1816
- export const makeEmailOtpStartHandler = (dependencies) => Effect.fn("auth.http.email_otp.start")(function* ({ payload, }) {
2106
+ export const makeEmailOtpStartHandler = (dependencies) => Effect.fn("auth.http.email_otp.start")(function* (handlerRequest) {
2107
+ const { payload } = handlerRequest;
1817
2108
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email_otp.start");
1818
- const input = emailOtpStartInput(payload);
1819
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1820
- yield* catchAuthApiRateLimit(authApiRateLimit.emailOtpStart(input), "Failed to start email OTP");
1821
- return yield* dependencies.emailOtp.start(input).pipe(Effect.mapError(() => new AuthInternalError({
2109
+ const guarded = yield* EmailGuards.emailOtp.start(handlerRequest);
2110
+ const started = yield* dependencies.emailOtp.start(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
1822
2111
  code: "internal_error",
1823
2112
  message: "Failed to start email OTP",
1824
2113
  })));
2114
+ return {
2115
+ challengeId: started.challengeId,
2116
+ identity: payload.identity,
2117
+ expiresAt: started.expiresAt,
2118
+ };
1825
2119
  });
1826
- export const makeEmailOtpVerifyHandler = (dependencies) => Effect.fn("auth.http.email_otp.verify")(function* ({ payload, request, }) {
2120
+ export const makeEmailOtpVerifyHandler = (dependencies) => Effect.fn("auth.http.email_otp.verify")(function* (handlerRequest) {
1827
2121
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email_otp.verify");
1828
- const trustedDeviceToken = yield* trustedDeviceTokenFromRequest(dependencies.trustedDeviceCookie, request).pipe(Effect.mapError(() => passwordInternalError("Failed to read trusted device cookie")));
1829
- const requestMetadataOptions = yield* authRequestMetadataOptions;
1830
- const requestContext = loginRequestContextFromRequest(request, requestMetadataOptions);
1831
- const result = yield* dependencies.emailOtp
1832
- .verify(emailOtpVerifyInput(payload, Option.isSome(trustedDeviceToken)
1833
- ? trustedDeviceToken.value
1834
- : undefined, requestContext))
1835
- .pipe(Effect.mapError(() => new AuthInternalError({
2122
+ const guarded = yield* EmailGuards.emailOtp.verify(handlerRequest);
2123
+ const result = yield* dependencies.emailOtp.verify(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
1836
2124
  code: "internal_error",
1837
2125
  message: "Failed to verify email OTP",
1838
2126
  })));
1839
2127
  return yield* dependencies.authHttp.commitEmailOtpVerifyResult(result);
1840
2128
  });
1841
- export const makeMagicLinkStartHandler = (dependencies) => Effect.fn("auth.http.magic_link.start")(function* ({ payload, }) {
2129
+ export const makeEmailAuthStartHandler = (dependencies) => Effect.fn("auth.http.email.start")(function* (handlerRequest) {
2130
+ const { payload } = handlerRequest;
2131
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "email.start");
2132
+ const guarded = yield* EmailGuards.emailAuth.start(handlerRequest);
2133
+ const started = yield* dependencies.emailAuth.start(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
2134
+ code: "internal_error",
2135
+ message: "Failed to start email authentication",
2136
+ })));
2137
+ return {
2138
+ identity: payload.identity,
2139
+ emailOtp: {
2140
+ challengeId: started.emailOtp.challengeId,
2141
+ expiresAt: started.emailOtp.expiresAt,
2142
+ },
2143
+ magicLink: {
2144
+ expiresAt: started.magicLink.expiresAt,
2145
+ },
2146
+ };
2147
+ });
2148
+ export const makeMagicLinkStartHandler = (dependencies) => Effect.fn("auth.http.magic_link.start")(function* (handlerRequest) {
2149
+ const { payload } = handlerRequest;
1842
2150
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "magic_link.start");
1843
- const input = magicLinkStartInput(payload);
1844
- const authApiRateLimit = dependencies.authApiRateLimit ?? noopAuthApiRateLimit;
1845
- yield* catchAuthApiRateLimit(authApiRateLimit.magicLinkStart(input), "Failed to start magic link");
1846
- const started = yield* dependencies.magicLink.start(input).pipe(Effect.mapError(() => new AuthInternalError({
2151
+ const guarded = yield* EmailGuards.magicLink.start(handlerRequest);
2152
+ const started = yield* dependencies.magicLink.start(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
1847
2153
  code: "internal_error",
1848
2154
  message: "Failed to start magic link",
1849
2155
  })));
1850
2156
  return {
1851
- email: started.email,
2157
+ identity: payload.identity,
1852
2158
  expiresAt: started.expiresAt,
1853
2159
  };
1854
2160
  });
1855
- export const makeMagicLinkVerifyHandler = (dependencies) => Effect.fn("auth.http.magic_link.verify")(function* ({ payload, request, }) {
2161
+ export const makeMagicLinkVerifyHandler = (dependencies) => Effect.fn("auth.http.magic_link.verify")(function* (handlerRequest) {
1856
2162
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "magic_link.verify");
1857
- const trustedDeviceToken = yield* trustedDeviceTokenFromRequest(dependencies.trustedDeviceCookie, request).pipe(Effect.mapError(() => passwordInternalError("Failed to read trusted device cookie")));
1858
- const requestMetadataOptions = yield* authRequestMetadataOptions;
1859
- const requestContext = loginRequestContextFromRequest(request, requestMetadataOptions);
1860
- const result = yield* dependencies.magicLink
1861
- .verify(magicLinkVerifyInput(payload, Option.isSome(trustedDeviceToken)
1862
- ? trustedDeviceToken.value
1863
- : undefined, requestContext))
1864
- .pipe(Effect.mapError(() => new AuthInternalError({
2163
+ const guarded = yield* EmailGuards.magicLink.verify(handlerRequest);
2164
+ const result = yield* dependencies.magicLink.verify(guarded.input).pipe(Effect.mapError(() => new AuthInternalError({
1865
2165
  code: "internal_error",
1866
2166
  message: "Failed to verify magic link",
1867
2167
  })));
@@ -1869,7 +2169,9 @@ export const makeMagicLinkVerifyHandler = (dependencies) => Effect.fn("auth.http
1869
2169
  });
1870
2170
  export const makeOAuthAuthorizationStartHandler = (dependencies) => Effect.fn("auth.http.oauth.authorization_start")(function* ({ payload, }) {
1871
2171
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.authorization_start");
1872
- const provider = yield* dependencies.oauthProviders.get(payload.providerId).pipe(Effect.mapError(() => oauthInternalError("Failed to load OAuth provider")));
2172
+ const provider = yield* dependencies.oauthProviders
2173
+ .get(payload.providerId)
2174
+ .pipe(Effect.mapError(() => oauthInternalError("Failed to load OAuth provider")));
1873
2175
  if (Option.isNone(provider)) {
1874
2176
  return yield* oauthBadRequest("Unknown OAuth provider");
1875
2177
  }
@@ -1877,7 +2179,9 @@ export const makeOAuthAuthorizationStartHandler = (dependencies) => Effect.fn("a
1877
2179
  .start(oauthAuthorizationStartInput(payload, provider.value, dependencies))
1878
2180
  .pipe(Effect.mapError(() => oauthInternalError("Failed to start OAuth authorization")));
1879
2181
  if (dependencies.storeCodeVerifier !== undefined) {
1880
- yield* dependencies.storeCodeVerifier({ payload, started }).pipe(Effect.mapError(() => oauthInternalError("Failed to store OAuth verifier")));
2182
+ yield* dependencies
2183
+ .storeCodeVerifier({ payload, started })
2184
+ .pipe(Effect.mapError(() => oauthInternalError("Failed to store OAuth verifier")));
1881
2185
  }
1882
2186
  return oauthAuthorizationStartedHttpBody(started);
1883
2187
  });
@@ -1915,9 +2219,13 @@ export const makeOAuthProviderAuthorizationHandler = (dependencies) => Effect.fn
1915
2219
  }
1916
2220
  return yield* oauthAuthorizationEndpointError(result.reason, result.errorDescription);
1917
2221
  });
1918
- export const makeOAuthAuthorizationCodeTokenHandler = (dependencies) => Effect.fn("auth.http.oauth.token")(function* ({ request, }) {
2222
+ export const makeOAuthTokenHandler = (dependencies) => Effect.fn("auth.http.oauth.token")(function* ({ request, }) {
1919
2223
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.token");
1920
2224
  const payload = yield* oauthTokenRequestBody(request);
2225
+ const registration = dependencies.registry.get(payload.grant_type);
2226
+ if (Option.isNone(registration)) {
2227
+ return yield* oauthTokenEndpointError("unsupported_grant_type");
2228
+ }
1921
2229
  const { clientId, clientAuthenticated } = yield* oauthClientEndpointAuthentication({
1922
2230
  request,
1923
2231
  payload,
@@ -1925,24 +2233,7 @@ export const makeOAuthAuthorizationCodeTokenHandler = (dependencies) => Effect.f
1925
2233
  invalidRequest: () => oauthTokenEndpointError("invalid_request"),
1926
2234
  invalidClient: () => oauthTokenEndpointError("invalid_client"),
1927
2235
  });
1928
- if (payload.grant_type === "refresh_token") {
1929
- return yield* oauthRefreshTokenResponse({
1930
- dependencies,
1931
- payload,
1932
- ...(clientId === undefined ? {} : { clientId }),
1933
- clientAuthenticated,
1934
- });
1935
- }
1936
- if (payload.grant_type === "client_credentials") {
1937
- return yield* oauthClientCredentialsTokenResponse({
1938
- dependencies,
1939
- payload,
1940
- ...(clientId === undefined ? {} : { clientId }),
1941
- clientAuthenticated,
1942
- });
1943
- }
1944
- return yield* oauthAuthorizationCodeTokenResponse({
1945
- dependencies,
2236
+ return yield* registration.value.exchange({
1946
2237
  payload,
1947
2238
  ...(clientId === undefined ? {} : { clientId }),
1948
2239
  clientAuthenticated,
@@ -1998,22 +2289,15 @@ export const makeOAuthTokenIntrospectionHandler = (dependencies) => Effect.fn("a
1998
2289
  }
1999
2290
  return oauthTokenIntrospectionResponseHttpBody(result.introspection);
2000
2291
  });
2001
- const makeOAuthTokenRevocationNotConfiguredHandler = () => Effect.fn("auth.http.oauth.revoke_not_configured")(function* ({ request, }) {
2002
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.revoke");
2003
- yield* oauthTokenRevocationRequestBody(request);
2004
- return yield* oauthTokenRevocationEndpointError("invalid_request");
2005
- });
2006
- const makeOAuthTokenIntrospectionNotConfiguredHandler = () => Effect.fn("auth.http.oauth.introspect_not_configured")(function* ({ request, }) {
2007
- yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.introspect");
2008
- yield* oauthTokenIntrospectionRequestBody(request);
2009
- return yield* oauthTokenIntrospectionEndpointError("invalid_request");
2010
- });
2011
- export const makeOAuthAccountUnlinkHandler = (dependencies) => Effect.fn("auth.http.oauth.account_unlink")(function* ({ payload, request, }) {
2292
+ export const makeOAuthAccountUnlinkHandler = (dependencies) => Effect.fn("auth.http.oauth.account_unlink")(function* (handlerRequest) {
2293
+ const { payload, request } = handlerRequest;
2012
2294
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.account_unlink");
2013
2295
  const session = yield* readRequiredSession(dependencies, request);
2014
2296
  const stepUpSatisfied = dependencies.stepUpSatisfied === undefined
2015
2297
  ? undefined
2016
- : yield* dependencies.stepUpSatisfied({ payload, request, session }).pipe(Effect.mapError(() => oauthInternalError("Failed to evaluate OAuth unlink step-up")));
2298
+ : yield* dependencies
2299
+ .stepUpSatisfied({ payload, request, session })
2300
+ .pipe(Effect.mapError(() => oauthInternalError("Failed to evaluate OAuth unlink step-up")));
2017
2301
  const decision = yield* dependencies.oauthAccountUnlinking
2018
2302
  .resolve({
2019
2303
  userId: session.currentSession.userId,
@@ -2038,16 +2322,22 @@ export const makeOAuthLinkConfirmationStartHandler = (dependencies) => Effect.fn
2038
2322
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.link_confirmation_start");
2039
2323
  const baseInput = dependencies.startInput === undefined
2040
2324
  ? yield* oauthLinkConfirmationStartInput(payload, dependencies)
2041
- : yield* dependencies.startInput({ payload, request }).pipe(Effect.mapError((error) => oauthHookHttpError(error, "Failed to resolve OAuth link confirmation input")));
2325
+ : yield* dependencies
2326
+ .startInput({ payload, request })
2327
+ .pipe(Effect.mapError((error) => oauthHookHttpError(error, "Failed to resolve OAuth link confirmation input")));
2042
2328
  const input = {
2043
2329
  ...baseInput,
2044
2330
  ...(baseInput.ttl === undefined && dependencies.ttl !== undefined
2045
2331
  ? { ttl: dependencies.ttl }
2046
2332
  : {}),
2047
2333
  };
2048
- const started = yield* dependencies.oauthLinkConfirmation.start(input).pipe(Effect.mapError((error) => oauthLinkConfirmationHttpError(error, "Failed to start OAuth link confirmation")));
2334
+ const started = yield* dependencies.oauthLinkConfirmation
2335
+ .start(input)
2336
+ .pipe(Effect.mapError((error) => oauthLinkConfirmationHttpError(error, "Failed to start OAuth link confirmation")));
2049
2337
  if (dependencies.onStarted !== undefined) {
2050
- yield* dependencies.onStarted({ payload, request, started }).pipe(Effect.mapError(() => oauthInternalError("Failed to deliver OAuth link confirmation")));
2338
+ yield* dependencies
2339
+ .onStarted({ payload, request, started })
2340
+ .pipe(Effect.mapError(() => oauthInternalError("Failed to deliver OAuth link confirmation")));
2051
2341
  }
2052
2342
  return oauthLinkConfirmationStartedHttpBody(started);
2053
2343
  });
@@ -2062,38 +2352,62 @@ export const makeOAuthLinkConfirmationConfirmHandler = (dependencies) => Effect.
2062
2352
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oauth.link_confirmation_confirm");
2063
2353
  const currentUserId = dependencies.currentUserId === undefined
2064
2354
  ? undefined
2065
- : yield* dependencies.currentUserId({ payload, request }).pipe(Effect.mapError((error) => oauthHookHttpError(error, "Failed to resolve current OAuth user")));
2355
+ : yield* dependencies
2356
+ .currentUserId({ payload, request })
2357
+ .pipe(Effect.mapError((error) => oauthHookHttpError(error, "Failed to resolve current OAuth user")));
2066
2358
  const confirmed = yield* dependencies.oauthLinkConfirmation
2067
2359
  .confirm(oauthLinkConfirmationConfirmInput(payload, currentUserId))
2068
2360
  .pipe(Effect.mapError((error) => oauthLinkConfirmationHttpError(error, "Failed to confirm OAuth link confirmation")));
2069
2361
  if (dependencies.linkAfterConfirm !== undefined) {
2070
- yield* dependencies.linkAfterConfirm({ payload, request, confirmed }).pipe(Effect.mapError(() => oauthInternalError("Failed to link OAuth account")));
2362
+ yield* dependencies
2363
+ .linkAfterConfirm({ payload, request, confirmed })
2364
+ .pipe(Effect.mapError(() => oauthInternalError("Failed to link OAuth account")));
2071
2365
  }
2072
2366
  return oauthLinkConfirmationConfirmedHttpBody(confirmed, {
2073
2367
  linked: dependencies.linkAfterConfirm !== undefined,
2074
2368
  });
2075
2369
  });
2076
- export const makePasskeyRegistrationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_start")(function* ({ payload, }) {
2370
+ export const makePasskeyRegistrationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_start")(function* (handlerRequest) {
2371
+ const { request } = handlerRequest;
2077
2372
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.registration_start");
2373
+ const current = yield* readRequiredSession(dependencies, request);
2374
+ yield* requireAuthRateLimit("auth.passkey.registration_start", handlerRequest, current.currentSession.userId);
2375
+ const user = yield* dependencies.resolveUser({
2376
+ currentSession: current.currentSession,
2377
+ actor: current.actor,
2378
+ request,
2379
+ });
2078
2380
  return yield* dependencies.passkeyOptions
2079
- .startRegistration(passkeyRegistrationStartInput(payload, dependencies))
2381
+ .startRegistration(passkeyRegistrationStartInput(current.currentSession.userId, user, dependencies))
2080
2382
  .pipe(Effect.mapError(() => passkeyInternalError("Failed to start passkey registration")));
2081
2383
  });
2082
- export const makePasskeyRegistrationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_finish")(function* ({ payload, }) {
2384
+ export const makePasskeyRegistrationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.registration_finish")(function* (handlerRequest) {
2385
+ const { payload, request } = handlerRequest;
2083
2386
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.registration_finish");
2387
+ const current = yield* readRequiredSession(dependencies, request);
2388
+ yield* requireAuthRateLimit("auth.passkey.registration_finish", handlerRequest, current.currentSession.userId);
2389
+ const user = yield* dependencies.resolveUser({
2390
+ currentSession: current.currentSession,
2391
+ actor: current.actor,
2392
+ request,
2393
+ });
2084
2394
  const finished = yield* dependencies.passkeyVerification
2085
- .finishRegistration(passkeyRegistrationFinishInput(payload, dependencies))
2395
+ .finishRegistration(passkeyRegistrationFinishInput(current.currentSession.userId, payload, user, dependencies))
2086
2396
  .pipe(Effect.mapError(passkeyVerificationHttpError));
2087
2397
  return { credentialId: finished.credential.credentialId };
2088
2398
  });
2089
- export const makePasskeyAuthenticationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_start")(function* ({ payload, }) {
2399
+ export const makePasskeyAuthenticationStartHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_start")(function* (handlerRequest) {
2400
+ const { payload } = handlerRequest;
2090
2401
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.authentication_start");
2402
+ yield* requireAuthRateLimit("auth.passkey.authentication_start", handlerRequest);
2091
2403
  return yield* dependencies.passkeyOptions
2092
2404
  .startAuthentication(passkeyAuthenticationStartInput(payload, dependencies))
2093
2405
  .pipe(Effect.mapError(() => passkeyInternalError("Failed to start passkey authentication")));
2094
2406
  });
2095
- export const makePasskeyAuthenticationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_finish")(function* ({ payload, request, }) {
2407
+ export const makePasskeyAuthenticationFinishHandler = (dependencies) => Effect.fn("auth.http.passkey.authentication_finish")(function* (handlerRequest) {
2408
+ const { payload, request } = handlerRequest;
2096
2409
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.authentication_finish");
2410
+ yield* requireAuthRateLimit("auth.passkey.authentication_finish", handlerRequest);
2097
2411
  const finished = yield* dependencies.passkeyVerification
2098
2412
  .finishAuthentication(passkeyAuthenticationFinishInput(payload, dependencies))
2099
2413
  .pipe(Effect.mapError(passkeyVerificationHttpError));
@@ -2106,9 +2420,58 @@ export const makePasskeyAuthenticationFinishHandler = (dependencies) => Effect.f
2106
2420
  .pipe(Effect.mapError(() => passkeyInternalError("Failed to create passkey session")));
2107
2421
  return yield* dependencies.authHttp.commitAuthenticatedSession(session);
2108
2422
  });
2109
- export const makePasskeyCredentialListHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_list")(function* ({ request, }) {
2423
+ const identityInfoHttpBody = (identity) => ({ ...identity });
2424
+ const withIdentitySession = (dependencies, request, operation, handlerRequest, run) => Effect.gen(function* () {
2425
+ const session = yield* readRequiredSession(dependencies, request);
2426
+ yield* requireAuthRateLimit(operation, handlerRequest, session.currentSession.userId);
2427
+ return yield* run(session).pipe(Effect.mapError(identityHttpError));
2428
+ });
2429
+ export const makeIdentityAvailabilityHandler = (dependencies) => (handlerRequest) => Effect.gen(function* () {
2430
+ const guarded = yield* IdentityGuards.availability(handlerRequest);
2431
+ const available = yield* dependencies.identityManagement
2432
+ .availability(guarded.input)
2433
+ .pipe(Effect.mapError(identityHttpError));
2434
+ return { available };
2435
+ });
2436
+ export const makeIdentityListHandler = (dependencies) => (handlerRequest) => withIdentitySession(dependencies, handlerRequest.request, "auth.identity.list", handlerRequest, (session) => dependencies.identityManagement
2437
+ .list(session.currentSession.userId)
2438
+ .pipe(Effect.map((identities) => ({
2439
+ identities: identities.map(identityInfoHttpBody),
2440
+ }))));
2441
+ const identityMutationHandler = (dependencies, operation, handlerRequest, run) => withIdentitySession(dependencies, handlerRequest.request, operation, handlerRequest, (session) => run(session, handlerRequest.payload));
2442
+ export const makeIdentityAddHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.add", request, (session, payload) => dependencies.identityManagement
2443
+ .add({
2444
+ ...payload,
2445
+ userId: session.currentSession.userId,
2446
+ currentSession: session,
2447
+ })
2448
+ .pipe(Effect.map(identityInfoHttpBody)));
2449
+ export const makeIdentityReplaceHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.replace", request, (session, payload) => dependencies.identityManagement
2450
+ .replace({
2451
+ ...payload,
2452
+ userId: session.currentSession.userId,
2453
+ currentSession: session,
2454
+ })
2455
+ .pipe(Effect.map(identityInfoHttpBody)));
2456
+ export const makeIdentityRevokeHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.revoke", request, (session, payload) => dependencies.identityManagement
2457
+ .revoke({
2458
+ ...payload,
2459
+ userId: session.currentSession.userId,
2460
+ currentSession: session,
2461
+ })
2462
+ .pipe(Effect.map(identityInfoHttpBody)));
2463
+ export const makeIdentityPrimaryHandler = (dependencies) => (request) => identityMutationHandler(dependencies, "auth.identity.set_primary", request, (session, payload) => dependencies.identityManagement
2464
+ .setPrimary({
2465
+ ...payload,
2466
+ userId: session.currentSession.userId,
2467
+ currentSession: session,
2468
+ })
2469
+ .pipe(Effect.map(identityInfoHttpBody)));
2470
+ export const makePasskeyCredentialListHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_list")(function* (handlerRequest) {
2471
+ const { request } = handlerRequest;
2110
2472
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.credential_list");
2111
2473
  const current = yield* readRequiredSession(dependencies, request);
2474
+ yield* requireAuthRateLimit("auth.passkey.credentials.list", handlerRequest, current.currentSession.userId);
2112
2475
  const credentials = yield* dependencies.passkeyCredentialManagement
2113
2476
  .listForUser({ userId: current.currentSession.userId })
2114
2477
  .pipe(Effect.mapError(() => passkeyInternalError("Failed to list passkey credentials")));
@@ -2116,87 +2479,130 @@ export const makePasskeyCredentialListHandler = (dependencies) => Effect.fn("aut
2116
2479
  credentials: credentials.map(passkeyCredentialInfoHttpBody),
2117
2480
  };
2118
2481
  });
2119
- export const makePasskeyCredentialRevokeHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_revoke")(function* ({ payload, request, }) {
2482
+ export const makePasskeyCredentialRevokeHandler = (dependencies) => Effect.fn("auth.http.passkey.credential_revoke")(function* (handlerRequest) {
2483
+ const { payload, request } = handlerRequest;
2120
2484
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "passkey.credential_revoke");
2121
2485
  const current = yield* readRequiredSession(dependencies, request);
2486
+ yield* requireAuthRateLimit("auth.passkey.credentials.revoke", handlerRequest, current.currentSession.userId);
2487
+ yield* requireCanRemoveStrongFactor(dependencies.strongFactorRemovalPolicy, {
2488
+ userId: current.currentSession.userId,
2489
+ factor: strongFactor("passkey", PasskeyCredentialId(payload.credentialId)),
2490
+ });
2122
2491
  yield* dependencies.passkeyCredentialManagement
2123
2492
  .revokeForUser(passkeyCredentialRevokeInput(current.currentSession.userId, payload))
2124
2493
  .pipe(Effect.mapError(passkeyCredentialManagementHttpError));
2125
2494
  return HttpServerResponse.empty({ status: 204 });
2126
2495
  });
2127
- export const makeTotpEnrollmentStartHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_start")(function* ({ payload, request, }) {
2496
+ export const makeTotpEnrollmentStartHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_start")(function* (handlerRequest) {
2497
+ const { payload, request } = handlerRequest;
2128
2498
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.enrollment_start");
2129
2499
  const current = yield* readRequiredSession(dependencies, request);
2500
+ yield* requireAuthRateLimit("auth.totp.enrollment_start", handlerRequest, current.currentSession.userId);
2130
2501
  const started = yield* dependencies.totpFactorManagement
2131
2502
  .startEnrollment(totpEnrollmentStartInput(current.currentSession.userId, payload, dependencies))
2132
2503
  .pipe(Effect.mapError(totpFactorManagementHttpError));
2133
2504
  return totpEnrollmentStartedHttpBody(started);
2134
2505
  });
2135
- export const makeTotpEnrollmentConfirmHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_confirm")(function* ({ payload, request, }) {
2506
+ export const makeTotpEnrollmentConfirmHandler = (dependencies) => Effect.fn("auth.http.totp.enrollment_confirm")(function* (handlerRequest) {
2507
+ const { payload, request } = handlerRequest;
2136
2508
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.enrollment_confirm");
2137
2509
  const current = yield* readRequiredSession(dependencies, request);
2510
+ yield* requireAuthRateLimit("auth.totp.enrollment_confirm", handlerRequest, current.currentSession.userId);
2138
2511
  const confirmed = yield* dependencies.totpFactorManagement
2139
2512
  .confirmEnrollment(totpEnrollmentConfirmInput(current.currentSession.userId, payload, dependencies))
2140
2513
  .pipe(Effect.mapError(totpFactorManagementHttpError));
2141
2514
  return totpFactorInfoHttpBody(confirmed);
2142
2515
  });
2143
- export const makeTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.totp.verify")(function* ({ payload, request, }) {
2516
+ export const makeTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.totp.verify")(function* (handlerRequest) {
2517
+ const { payload, request } = handlerRequest;
2144
2518
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.verify");
2145
2519
  const current = yield* readRequiredSession(dependencies, request);
2520
+ yield* requireAuthRateLimit("auth.totp.verify", handlerRequest, current.currentSession.userId);
2146
2521
  const result = yield* dependencies.totpFactorManagement
2147
2522
  .verifyForUser(totpVerifyInput(current.currentSession.userId, payload, dependencies))
2148
2523
  .pipe(Effect.mapError(() => totpInternalError("Failed to verify TOTP factor")));
2149
2524
  return totpVerifyResultHttpBody(result);
2150
2525
  });
2151
- export const makeTotpFactorListHandler = (dependencies) => Effect.fn("auth.http.totp.factor_list")(function* ({ request, }) {
2526
+ export const makeTotpFactorListHandler = (dependencies) => Effect.fn("auth.http.totp.factor_list")(function* (handlerRequest) {
2527
+ const { request } = handlerRequest;
2152
2528
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.factor_list");
2153
2529
  const current = yield* readRequiredSession(dependencies, request);
2530
+ yield* requireAuthRateLimit("auth.totp.factors.list", handlerRequest, current.currentSession.userId);
2154
2531
  const factors = yield* dependencies.totpFactorManagement
2155
2532
  .listForUser({ userId: current.currentSession.userId })
2156
2533
  .pipe(Effect.mapError(() => totpInternalError("Failed to list TOTP factors")));
2157
2534
  return { factors: factors.map(totpFactorInfoHttpBody) };
2158
2535
  });
2159
- export const makeTotpFactorRevokeHandler = (dependencies) => Effect.fn("auth.http.totp.factor_revoke")(function* ({ payload, request, }) {
2536
+ export const makeTotpFactorRevokeHandler = (dependencies) => Effect.fn("auth.http.totp.factor_revoke")(function* (handlerRequest) {
2537
+ const { payload, request } = handlerRequest;
2160
2538
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "totp.factor_revoke");
2161
2539
  const current = yield* readRequiredSession(dependencies, request);
2540
+ yield* requireAuthRateLimit("auth.totp.factors.revoke", handlerRequest, current.currentSession.userId);
2541
+ yield* requireCanRemoveStrongFactor(dependencies.strongFactorRemovalPolicy, {
2542
+ userId: current.currentSession.userId,
2543
+ factor: strongFactor("totp", payload.factorId),
2544
+ });
2162
2545
  yield* dependencies.totpFactorManagement
2163
2546
  .revokeForUser(totpFactorRevokeInput(current.currentSession.userId, payload))
2164
2547
  .pipe(Effect.mapError(totpFactorManagementHttpError));
2165
2548
  return HttpServerResponse.empty({ status: 204 });
2166
2549
  });
2167
- export const makeRecoveryCodeGenerateHandler = (dependencies) => Effect.fn("auth.http.recovery_code.generate")(function* ({ payload, request, }) {
2550
+ export const makeRecoveryCodeGenerateHandler = (dependencies) => Effect.fn("auth.http.recovery_code.generate")(function* (handlerRequest) {
2551
+ const { payload, request } = handlerRequest;
2168
2552
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.generate");
2169
2553
  const current = yield* readRequiredSession(dependencies, request);
2554
+ yield* requireAuthRateLimit("auth.recovery_code.generate", handlerRequest, current.currentSession.userId);
2170
2555
  const generated = yield* dependencies.recoveryCodeManagement
2171
2556
  .generateForUser(recoveryCodeGenerateInput(current.currentSession.userId, payload, dependencies))
2172
2557
  .pipe(Effect.mapError(recoveryCodeManagementHttpError));
2173
2558
  return recoveryCodesGeneratedHttpBody(generated);
2174
2559
  });
2175
- export const makeRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.recovery_code.verify")(function* ({ payload, request, }) {
2560
+ export const makeRecoveryCodeRegenerateHandler = (dependencies) => Effect.fn("auth.http.recovery_code.regenerate")(function* (handlerRequest) {
2561
+ const { payload, request } = handlerRequest;
2562
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.regenerate");
2563
+ const current = yield* readRequiredSession(dependencies, request);
2564
+ yield* requireAuthRateLimit("auth.recovery_code.regenerate", handlerRequest, current.currentSession.userId);
2565
+ const generated = yield* dependencies.recoveryCodeManagement
2566
+ .regenerateForUser(recoveryCodeRegenerateInput(current.currentSession.userId, payload, dependencies))
2567
+ .pipe(Effect.mapError(recoveryCodeManagementHttpError));
2568
+ return recoveryCodesGeneratedHttpBody(generated);
2569
+ });
2570
+ export const makeRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.recovery_code.verify")(function* (handlerRequest) {
2571
+ const { payload, request } = handlerRequest;
2176
2572
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.verify");
2177
2573
  const current = yield* readRequiredSession(dependencies, request);
2574
+ yield* requireAuthRateLimit("auth.recovery_code.verify", handlerRequest, current.currentSession.userId);
2178
2575
  const result = yield* dependencies.recoveryCodeManagement
2179
2576
  .verifyForUser(recoveryCodeVerifyInput(current.currentSession.userId, payload))
2180
2577
  .pipe(Effect.mapError(() => recoveryCodeInternalError("Failed to verify recovery code")));
2181
2578
  return recoveryCodeVerifyResultHttpBody(result);
2182
2579
  });
2183
- export const makeRecoveryCodeListHandler = (dependencies) => Effect.fn("auth.http.recovery_code.list")(function* ({ request, }) {
2580
+ export const makeRecoveryCodeListHandler = (dependencies) => Effect.fn("auth.http.recovery_code.list")(function* (handlerRequest) {
2581
+ const { request } = handlerRequest;
2184
2582
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.list");
2185
2583
  const current = yield* readRequiredSession(dependencies, request);
2584
+ yield* requireAuthRateLimit("auth.recovery_code.list", handlerRequest, current.currentSession.userId);
2186
2585
  const codes = yield* dependencies.recoveryCodeManagement
2187
2586
  .listForUser({ userId: current.currentSession.userId })
2188
2587
  .pipe(Effect.mapError(() => recoveryCodeInternalError("Failed to list recovery codes")));
2189
2588
  return { codes: codes.map(recoveryCodeInfoHttpBody) };
2190
2589
  });
2191
- export const makeRecoveryCodeRevokeHandler = (dependencies) => Effect.fn("auth.http.recovery_code.revoke")(function* ({ payload, request, }) {
2590
+ export const makeRecoveryCodeRevokeHandler = (dependencies) => Effect.fn("auth.http.recovery_code.revoke")(function* (handlerRequest) {
2591
+ const { payload, request } = handlerRequest;
2192
2592
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "recovery_code.revoke");
2193
2593
  const current = yield* readRequiredSession(dependencies, request);
2594
+ yield* requireAuthRateLimit("auth.recovery_code.revoke", handlerRequest, current.currentSession.userId);
2595
+ yield* requireCanRemoveStrongFactor(dependencies.strongFactorRemovalPolicy, {
2596
+ userId: current.currentSession.userId,
2597
+ factor: strongFactor("recovery-code", payload.codeId),
2598
+ });
2194
2599
  yield* dependencies.recoveryCodeManagement
2195
2600
  .revokeForUser(recoveryCodeRevokeInput(current.currentSession.userId, payload))
2196
2601
  .pipe(Effect.mapError(recoveryCodeManagementHttpError));
2197
2602
  return HttpServerResponse.empty({ status: 204 });
2198
2603
  });
2199
- export const makeApiKeyCreateHandler = (dependencies) => Effect.fn("auth.http.api_key.create")(function* ({ payload, request, }) {
2604
+ export const makeApiKeyCreateHandler = (dependencies) => Effect.fn("auth.http.api_key.create")(function* (handlerRequest) {
2605
+ const { payload, request } = handlerRequest;
2200
2606
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "api_key.create");
2201
2607
  const current = yield* readRequiredSession(dependencies, request);
2202
2608
  const created = yield* dependencies.apiKeyManagement
@@ -2204,7 +2610,8 @@ export const makeApiKeyCreateHandler = (dependencies) => Effect.fn("auth.http.ap
2204
2610
  .pipe(Effect.mapError(apiKeyManagementHttpError));
2205
2611
  return apiKeyCreatedHttpBody(created);
2206
2612
  });
2207
- export const makeApiKeyListHandler = (dependencies) => Effect.fn("auth.http.api_key.list")(function* ({ request, }) {
2613
+ export const makeApiKeyListHandler = (dependencies) => Effect.fn("auth.http.api_key.list")(function* (handlerRequest) {
2614
+ const { request } = handlerRequest;
2208
2615
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "api_key.list");
2209
2616
  const current = yield* readRequiredSession(dependencies, request);
2210
2617
  const keys = yield* dependencies.apiKeyManagement
@@ -2212,7 +2619,8 @@ export const makeApiKeyListHandler = (dependencies) => Effect.fn("auth.http.api_
2212
2619
  .pipe(Effect.mapError(() => apiKeyInternalError("Failed to list API keys")));
2213
2620
  return { keys: keys.map(apiKeyInfoHttpBody) };
2214
2621
  });
2215
- export const makeApiKeyRevokeHandler = (dependencies) => Effect.fn("auth.http.api_key.revoke")(function* ({ payload, request, }) {
2622
+ export const makeApiKeyRevokeHandler = (dependencies) => Effect.fn("auth.http.api_key.revoke")(function* (handlerRequest) {
2623
+ const { payload, request } = handlerRequest;
2216
2624
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "api_key.revoke");
2217
2625
  const current = yield* readRequiredSession(dependencies, request);
2218
2626
  yield* dependencies.apiKeyManagement
@@ -2257,7 +2665,7 @@ export const makeJwtIntrospectHandler = (dependencies) => Effect.fn("auth.http.j
2257
2665
  .pipe(Effect.mapError(() => jwtInternalError("Failed to introspect JWT access token")));
2258
2666
  return jwtIntrospectionHttpBody(result);
2259
2667
  });
2260
- export const makeJwtRevokeHandler = (dependencies) => Effect.fn("auth.http.jwt.revoke")(function* ({ payload }) {
2668
+ export const makeJwtRevokeHandler = (dependencies) => Effect.fn("auth.http.jwt.revoke")(function* ({ payload, }) {
2261
2669
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "jwt.revoke");
2262
2670
  yield* dependencies.jwtRevocation
2263
2671
  .revokeJwtId(jwtRevokeInput(payload))
@@ -2266,20 +2674,28 @@ export const makeJwtRevokeHandler = (dependencies) => Effect.fn("auth.http.jwt.r
2266
2674
  });
2267
2675
  export const makeJwtJwksHandler = (dependencies) => Effect.fn("auth.http.jwt.jwks")(function* (_) {
2268
2676
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "jwt.jwks");
2269
- const document = yield* dependencies.jwks.document().pipe(Effect.mapError(() => jwtInternalError("Failed to load JWT JWKS document")));
2677
+ const document = yield* dependencies.jwks
2678
+ .document()
2679
+ .pipe(Effect.mapError(() => jwtInternalError("Failed to load JWT JWKS document")));
2270
2680
  return jwtJwksHttpBody(document);
2271
2681
  });
2272
2682
  export const makeOidcDiscoveryMetadataHandler = (dependencies) => Effect.fn("auth.http.oidc.discovery_metadata")(function* (_) {
2273
2683
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "oidc.discovery_metadata");
2274
- return yield* dependencies.metadata.load().pipe(Effect.mapError(() => jwtInternalError("Failed to load OIDC discovery metadata")));
2684
+ return yield* dependencies.metadata
2685
+ .load()
2686
+ .pipe(Effect.mapError(() => jwtInternalError("Failed to load OIDC discovery metadata")));
2275
2687
  });
2276
- export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.options")(function* ({ payload, }) {
2688
+ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.options")(function* (handlerRequest) {
2689
+ const { payload } = handlerRequest;
2277
2690
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.options");
2691
+ yield* requireAuthRateLimit("auth.mfa.options", handlerRequest);
2278
2692
  const pending = yield* dependencies.authFlowState
2279
2693
  .inspect(payload.flowId)
2280
2694
  .pipe(Effect.mapError(() => mfaBadRequest()));
2695
+ const allowed = new Set(pending.factors?.map((factor) => factor.type));
2281
2696
  const factors = [];
2282
- if (dependencies.totpFactorManagement !== undefined) {
2697
+ if (allowed.has("totp") &&
2698
+ dependencies.totpFactorManagement !== undefined) {
2283
2699
  const totpFactors = yield* dependencies.totpFactorManagement
2284
2700
  .listForUser({ userId: pending.userId })
2285
2701
  .pipe(Effect.mapError(() => mfaInternalError("Failed to list MFA options")));
@@ -2287,7 +2703,8 @@ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.
2287
2703
  factors.push({ type: "totp" });
2288
2704
  }
2289
2705
  }
2290
- if (dependencies.recoveryCodeManagement !== undefined) {
2706
+ if (allowed.has("backup-code") &&
2707
+ dependencies.recoveryCodeManagement !== undefined) {
2291
2708
  const recoveryCodes = yield* dependencies.recoveryCodeManagement
2292
2709
  .listForUser({ userId: pending.userId })
2293
2710
  .pipe(Effect.mapError(() => mfaInternalError("Failed to list MFA options")));
@@ -2295,7 +2712,8 @@ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.
2295
2712
  factors.push({ type: "backup-code" });
2296
2713
  }
2297
2714
  }
2298
- if (dependencies.passkeyCredentialManagement !== undefined) {
2715
+ if (allowed.has("passkey") &&
2716
+ dependencies.passkeyCredentialManagement !== undefined) {
2299
2717
  const credentials = yield* dependencies.passkeyCredentialManagement
2300
2718
  .listForUser({ userId: pending.userId })
2301
2719
  .pipe(Effect.mapError(() => mfaInternalError("Failed to list MFA options")));
@@ -2305,12 +2723,29 @@ export const makeMfaOptionsHandler = (dependencies) => Effect.fn("auth.http.mfa.
2305
2723
  }
2306
2724
  return { factors };
2307
2725
  });
2308
- export const makeTotpMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify")(function* ({ payload, }) {
2726
+ const inspectMfaFlowForFactor = (authFlowState, flowId, factorType) => Effect.gen(function* () {
2727
+ const pending = yield* authFlowState
2728
+ .inspect(flowId)
2729
+ .pipe(Effect.mapError(() => mfaBadRequest()));
2730
+ if (pending.factors?.some((factor) => factor.type === factorType) !== true) {
2731
+ return yield* mfaBadRequest();
2732
+ }
2733
+ return pending;
2734
+ });
2735
+ export const makeTotpMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify")(function* (handlerRequest) {
2736
+ const { payload } = handlerRequest;
2309
2737
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.totp_verify");
2738
+ yield* requireAuthRateLimit("auth.mfa.totp_verify", handlerRequest);
2739
+ const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "totp");
2740
+ if (pending.userId !== payload.userId) {
2741
+ return yield* mfaInvalidCredentials();
2742
+ }
2310
2743
  const verified = yield* dependencies.totpFactorManagement
2311
2744
  .verifyForUser(totpMfaVerifyInput(payload, dependencies))
2312
2745
  .pipe(Effect.mapError(() => mfaInternalError("Failed to verify TOTP MFA factor")));
2313
- if (!verified.valid) {
2746
+ if (!verified.valid ||
2747
+ verified.factor === undefined ||
2748
+ verified.acceptedCounter === undefined) {
2314
2749
  return yield* mfaInvalidCredentials();
2315
2750
  }
2316
2751
  const result = yield* dependencies.authFlow
@@ -2318,44 +2753,98 @@ export const makeTotpMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.m
2318
2753
  flowId: payload.flowId,
2319
2754
  userId: payload.userId,
2320
2755
  method: "totp",
2321
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
2756
+ evidence: totpEvidence({
2757
+ factorId: verified.factor.id,
2758
+ acceptedCounter: verified.acceptedCounter,
2759
+ verifiedAt: yield* currentUnixMillis,
2760
+ }),
2322
2761
  })
2323
- .pipe(Effect.mapError(authFlowMfaHttpError));
2324
- if (result._tag === "PolicyDenied") {
2325
- return yield* mfaPolicyDenied(result.reason);
2326
- }
2327
- return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
2762
+ .pipe(Effect.catch(authFlowMfaHttpFailure));
2763
+ return yield* dependencies.authHttp.commitMfaResult(result);
2328
2764
  });
2329
- export const makeTotpMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify_for_flow")(function* ({ payload, }) {
2765
+ export const makeTotpMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.totp_verify_for_flow")(function* (handlerRequest) {
2766
+ const { payload } = handlerRequest;
2330
2767
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.totp_verify_for_flow");
2331
- const pending = yield* dependencies.authFlowState
2332
- .inspect(payload.flowId)
2333
- .pipe(Effect.mapError(() => mfaBadRequest()));
2768
+ yield* requireAuthRateLimit("auth.mfa.totp_verify_for_flow", handlerRequest);
2769
+ const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "totp");
2770
+ const user = yield* dependencies.users
2771
+ .findById(pending.userId)
2772
+ .pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA user")));
2773
+ if (Option.isNone(user) || user.value.disabledAt !== undefined) {
2774
+ return yield* mfaInvalidCredentials();
2775
+ }
2776
+ const verification = yield* dependencies.verificationStore
2777
+ .findById(ChallengeId(payload.flowId))
2778
+ .pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA flow")));
2779
+ if (Option.isNone(verification)) {
2780
+ return yield* mfaBadRequest();
2781
+ }
2334
2782
  const verified = yield* dependencies.totpFactorManagement
2335
- .verifyForUser(totpMfaVerifyForFlowInput(pending.userId, payload, dependencies))
2783
+ .identifyForUser(totpMfaVerifyForFlowInput(pending.userId, payload, dependencies))
2336
2784
  .pipe(Effect.mapError(() => mfaInternalError("Failed to verify TOTP MFA factor")));
2337
- if (!verified.valid) {
2785
+ if (!verified.valid ||
2786
+ verified.factor === undefined ||
2787
+ verified.acceptedCounter === undefined) {
2338
2788
  return yield* mfaInvalidCredentials();
2339
2789
  }
2790
+ if (dependencies.authFlow.prepareMfa === undefined) {
2791
+ return yield* mfaInternalError("Atomic TOTP login is not configured");
2792
+ }
2793
+ const verifiedAt = yield* currentUnixMillis;
2340
2794
  const result = yield* dependencies.authFlow
2341
- .completeMfa({
2795
+ .prepareMfa({
2342
2796
  flowId: payload.flowId,
2343
2797
  userId: pending.userId,
2344
2798
  method: "totp",
2345
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
2799
+ evidence: totpEvidence({
2800
+ factorId: verified.factor.id,
2801
+ acceptedCounter: verified.acceptedCounter,
2802
+ verifiedAt,
2803
+ }),
2346
2804
  })
2347
- .pipe(Effect.mapError(authFlowMfaHttpError));
2805
+ .pipe(Effect.catch(authFlowMfaHttpFailure));
2348
2806
  if (result._tag === "PolicyDenied") {
2349
- return yield* mfaPolicyDenied(result.reason);
2807
+ return yield* dependencies.authHttp.commitMfaResult(result);
2808
+ }
2809
+ const committedAt = yield* currentUnixMillis;
2810
+ const committed = yield* dependencies.totpLoginCommitStore
2811
+ .commit({
2812
+ verification: verification.value,
2813
+ factorId: verified.factor.id,
2814
+ userId: pending.userId,
2815
+ counter: verified.acceptedCounter,
2816
+ consumedAt: committedAt,
2817
+ lastUsedAt: committedAt,
2818
+ ...(payload.metadata === undefined
2819
+ ? {}
2820
+ : { factorMetadata: payload.metadata }),
2821
+ ...(result._tag === "PreparedAuthenticated"
2822
+ ? { session: result.prepared.row }
2823
+ : { continuation: "login-approval" }),
2824
+ })
2825
+ .pipe(Effect.catch(() => Effect.succeed(false)));
2826
+ if (!committed) {
2827
+ return yield* mfaInvalidCredentials();
2350
2828
  }
2351
- return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
2829
+ if (result._tag === "PreparedLoginApproval") {
2830
+ const approval = yield* result.complete.pipe(Effect.catch(authFlowMfaHttpFailure));
2831
+ return yield* dependencies.authHttp.commitMfaResult(approval);
2832
+ }
2833
+ yield* result.notify;
2834
+ return yield* dependencies.authHttp.commitAuthenticatedSession(result.prepared.session);
2352
2835
  });
2353
- export const makeRecoveryCodeMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify")(function* ({ payload, }) {
2836
+ export const makeRecoveryCodeMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify")(function* (handlerRequest) {
2837
+ const { payload } = handlerRequest;
2354
2838
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.recovery_code_verify");
2839
+ yield* requireAuthRateLimit("auth.mfa.recovery_code_verify", handlerRequest);
2840
+ const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "backup-code");
2841
+ if (pending.userId !== payload.userId) {
2842
+ return yield* mfaInvalidCredentials();
2843
+ }
2355
2844
  const verified = yield* dependencies.recoveryCodeManagement
2356
2845
  .verifyForUser(recoveryCodeMfaVerifyInput(payload))
2357
2846
  .pipe(Effect.mapError(() => mfaInternalError("Failed to verify recovery code MFA factor")));
2358
- if (!verified.valid) {
2847
+ if (!verified.valid || verified.code === undefined) {
2359
2848
  return yield* mfaInvalidCredentials();
2360
2849
  }
2361
2850
  const result = yield* dependencies.authFlow
@@ -2363,71 +2852,159 @@ export const makeRecoveryCodeMfaVerifyHandler = (dependencies) => Effect.fn("aut
2363
2852
  flowId: payload.flowId,
2364
2853
  userId: payload.userId,
2365
2854
  method: "backup-code",
2366
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
2855
+ evidence: recoveryCodeEvidence({
2856
+ codeId: verified.code.id,
2857
+ verifiedAt: yield* currentUnixMillis,
2858
+ }),
2367
2859
  })
2368
- .pipe(Effect.mapError(authFlowMfaHttpError));
2369
- if (result._tag === "PolicyDenied") {
2370
- return yield* mfaPolicyDenied(result.reason);
2371
- }
2372
- return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
2860
+ .pipe(Effect.catch(authFlowMfaHttpFailure));
2861
+ return yield* dependencies.authHttp.commitMfaResult(result);
2373
2862
  });
2374
- export const makeRecoveryCodeMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify_for_flow")(function* ({ payload, }) {
2863
+ export const makeRecoveryCodeMfaVerifyForFlowHandler = (dependencies) => Effect.fn("auth.http.mfa.recovery_code_verify_for_flow")(function* (handlerRequest) {
2864
+ const { payload } = handlerRequest;
2375
2865
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.recovery_code_verify_for_flow");
2376
- const pending = yield* dependencies.authFlowState
2377
- .inspect(payload.flowId)
2378
- .pipe(Effect.mapError(() => mfaBadRequest()));
2866
+ yield* requireAuthRateLimit("auth.mfa.recovery_code_verify_for_flow", handlerRequest);
2867
+ const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "backup-code");
2868
+ const user = yield* dependencies.users
2869
+ .findById(pending.userId)
2870
+ .pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA user")));
2871
+ if (Option.isNone(user) || user.value.disabledAt !== undefined) {
2872
+ return yield* mfaInvalidCredentials();
2873
+ }
2874
+ const verification = yield* dependencies.verificationStore
2875
+ .findById(ChallengeId(payload.flowId))
2876
+ .pipe(Effect.mapError(() => mfaInternalError("Failed to load pending MFA flow")));
2877
+ if (Option.isNone(verification)) {
2878
+ return yield* mfaBadRequest();
2879
+ }
2379
2880
  const verified = yield* dependencies.recoveryCodeManagement
2380
- .verifyForUser(recoveryCodeMfaVerifyForFlowInput(pending.userId, payload))
2881
+ .identifyForUser(recoveryCodeMfaVerifyForFlowInput(pending.userId, payload))
2381
2882
  .pipe(Effect.mapError(() => mfaInternalError("Failed to verify recovery code MFA factor")));
2382
- if (!verified.valid) {
2883
+ if (!verified.valid || verified.code === undefined) {
2383
2884
  return yield* mfaInvalidCredentials();
2384
2885
  }
2886
+ if (dependencies.authFlow.prepareMfa === undefined) {
2887
+ return yield* mfaInternalError("Atomic recovery-code login is not configured");
2888
+ }
2889
+ const verifiedAt = yield* currentUnixMillis;
2385
2890
  const result = yield* dependencies.authFlow
2386
- .completeMfa({
2891
+ .prepareMfa({
2387
2892
  flowId: payload.flowId,
2388
2893
  userId: pending.userId,
2389
2894
  method: "backup-code",
2390
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
2895
+ evidence: recoveryCodeEvidence({
2896
+ codeId: verified.code.id,
2897
+ verifiedAt,
2898
+ }),
2391
2899
  })
2392
- .pipe(Effect.mapError(authFlowMfaHttpError));
2900
+ .pipe(Effect.catch(authFlowMfaHttpFailure));
2393
2901
  if (result._tag === "PolicyDenied") {
2394
- return yield* mfaPolicyDenied(result.reason);
2902
+ return yield* dependencies.authHttp.commitMfaResult(result);
2903
+ }
2904
+ const committedAt = yield* currentUnixMillis;
2905
+ const committed = yield* dependencies.recoveryCodeLoginCommitStore
2906
+ .commit({
2907
+ verification: verification.value,
2908
+ codeId: verified.code.id,
2909
+ userId: pending.userId,
2910
+ consumedAt: committedAt,
2911
+ usedAt: committedAt,
2912
+ ...(payload.metadata === undefined
2913
+ ? {}
2914
+ : { codeMetadata: payload.metadata }),
2915
+ ...(result._tag === "PreparedAuthenticated"
2916
+ ? { session: result.prepared.row }
2917
+ : { continuation: "login-approval" }),
2918
+ })
2919
+ .pipe(Effect.catch(() => Effect.succeed(false)));
2920
+ if (!committed) {
2921
+ return yield* mfaInvalidCredentials();
2395
2922
  }
2396
- return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
2923
+ if (result._tag === "PreparedLoginApproval") {
2924
+ const approval = yield* result.complete.pipe(Effect.catch(authFlowMfaHttpFailure));
2925
+ return yield* dependencies.authHttp.commitMfaResult(approval);
2926
+ }
2927
+ yield* result.notify;
2928
+ return yield* dependencies.authHttp.commitAuthenticatedSession(result.prepared.session);
2397
2929
  });
2398
- export const makePasskeyMfaStartHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_start")(function* ({ payload, }) {
2930
+ export const makePasskeyMfaStartHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_start")(function* (handlerRequest) {
2931
+ const { payload } = handlerRequest;
2399
2932
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.passkey_start");
2933
+ yield* requireAuthRateLimit("auth.mfa.passkey_start", handlerRequest);
2400
2934
  const pending = yield* dependencies.authFlowState
2401
2935
  .inspect(payload.flowId)
2402
2936
  .pipe(Effect.mapError(() => mfaBadRequest()));
2937
+ if (pending.factors?.some((factor) => factor.type === "passkey") !== true) {
2938
+ return yield* mfaBadRequest();
2939
+ }
2403
2940
  return yield* dependencies.passkeyOptions
2404
2941
  .startAuthentication(passkeyMfaStartInput(pending.userId, payload, dependencies))
2405
2942
  .pipe(Effect.mapError(() => passkeyInternalError("Failed to start passkey MFA authentication")));
2406
2943
  });
2407
- export const makePasskeyMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_verify")(function* ({ payload, }) {
2944
+ export const makePasskeyMfaVerifyHandler = (dependencies) => Effect.fn("auth.http.mfa.passkey_verify")(function* (handlerRequest) {
2945
+ const { payload } = handlerRequest;
2408
2946
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "mfa.passkey_verify");
2947
+ yield* requireAuthRateLimit("auth.mfa.passkey_verify", handlerRequest);
2948
+ const pending = yield* inspectMfaFlowForFactor(dependencies.authFlowState, payload.flowId, "passkey");
2409
2949
  const finished = yield* dependencies.passkeyVerification
2410
- .finishAuthentication(passkeyMfaVerifyInput(payload, dependencies))
2950
+ .finishAuthentication(passkeyMfaVerifyInput(payload, dependencies, pending.userId))
2411
2951
  .pipe(Effect.mapError(passkeyVerificationHttpError));
2952
+ if (finished.userVerification !== "verified") {
2953
+ return yield* mfaBadRequest();
2954
+ }
2412
2955
  const result = yield* dependencies.authFlow
2413
2956
  .completeMfa({
2414
2957
  flowId: payload.flowId,
2415
2958
  userId: finished.userId,
2416
2959
  method: "passkey",
2417
- ...(payload.metadata === undefined ? {} : { metadata: payload.metadata }),
2960
+ evidence: passkeyEvidence({
2961
+ credentialId: CredentialId(finished.credential.id),
2962
+ verifiedAt: yield* currentUnixMillis,
2963
+ userVerification: finished.userVerification,
2964
+ ...(finished.authenticatorAttachment === undefined
2965
+ ? {}
2966
+ : { authenticatorAttachment: finished.authenticatorAttachment }),
2967
+ ...(finished.backedUp === undefined
2968
+ ? {}
2969
+ : { backedUp: finished.backedUp }),
2970
+ ...(finished.backupEligible === undefined
2971
+ ? {}
2972
+ : { backupEligible: finished.backupEligible }),
2973
+ signCount: finished.signCount,
2974
+ ...(finished.aaguid === undefined ? {} : { aaguid: finished.aaguid }),
2975
+ }),
2418
2976
  })
2419
- .pipe(Effect.mapError(authFlowMfaHttpError));
2420
- if (result._tag === "PolicyDenied") {
2421
- return yield* mfaPolicyDenied(result.reason);
2422
- }
2423
- return yield* dependencies.authHttp.commitAuthenticatedSession(result.session);
2424
- });
2425
- const upgradeStepUpSession = (dependencies, current, method) => upgradeCurrentSession({ method, reason: "step_up" }).pipe(Effect.provideService(CurrentSession, CurrentSession.make(current.currentSession)), Effect.provideService(Sessions, dependencies.sessions), Effect.map(stepUpAuthenticatedHttpBody), Effect.mapError(() => stepUpInternalError("Failed to upgrade current session")));
2426
- export const makeStepUpOptionsHandler = (dependencies) => Effect.fn("auth.http.step_up.options")(function* ({ request, }) {
2977
+ .pipe(Effect.catch(authFlowMfaHttpFailure));
2978
+ return yield* dependencies.authHttp.commitMfaResult(result);
2979
+ });
2980
+ const upgradeStepUpSession = (dependencies, current, evidence, claims) => dependencies.sessions
2981
+ .assureAndRotate({
2982
+ token: current.issued.token,
2983
+ evidence,
2984
+ claims,
2985
+ reason: "step_up",
2986
+ })
2987
+ .pipe(Effect.flatMap((issued) => dependencies.sessionCookie.commit(issued).pipe(Effect.flatMap((cookie) => HttpServerResponse.json(stepUpAuthenticatedHttpBody(issued), {
2988
+ status: 200,
2989
+ headers: { "set-cookie": cookie },
2990
+ })))), Effect.mapError(() => stepUpInternalError("Failed to upgrade current session")));
2991
+ const reauthenticateStepUpSession = (dependencies, current, evidence) => upgradeStepUpSession(dependencies, current, evidence);
2992
+ export const makeStepUpOptionsHandler = (dependencies) => Effect.fn("auth.http.step_up.options")(function* (handlerRequest) {
2993
+ const { request } = handlerRequest;
2427
2994
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.options");
2428
2995
  const current = yield* readRequiredSession(dependencies, request);
2996
+ yield* requireAuthRateLimit("auth.step_up.options", handlerRequest, current.currentSession.userId);
2429
2997
  const { userId } = current.currentSession;
2430
2998
  const factors = [];
2999
+ if (dependencies.credentials !== undefined) {
3000
+ const passwordCredential = yield* dependencies.credentials
3001
+ .findPasswordByUserId(userId)
3002
+ .pipe(Effect.mapError(() => stepUpInternalError("Failed to list step-up options")));
3003
+ if (Option.isSome(passwordCredential) &&
3004
+ passwordCredential.value.revokedAt === undefined) {
3005
+ factors.push({ type: "password" });
3006
+ }
3007
+ }
2431
3008
  if (dependencies.totpFactorManagement !== undefined) {
2432
3009
  const totpFactors = yield* dependencies.totpFactorManagement
2433
3010
  .listForUser({ userId })
@@ -2454,90 +3031,234 @@ export const makeStepUpOptionsHandler = (dependencies) => Effect.fn("auth.http.s
2454
3031
  }
2455
3032
  return { factors };
2456
3033
  });
2457
- export const makeStepUpTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.totp_verify")(function* ({ payload, request, }) {
3034
+ export const makeStepUpTotpVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.totp_verify")(function* (handlerRequest) {
3035
+ const { payload, request } = handlerRequest;
2458
3036
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.totp_verify");
2459
3037
  const current = yield* readRequiredSession(dependencies, request);
3038
+ yield* requireAuthRateLimit("auth.step_up.totp_verify", handlerRequest, current.currentSession.userId);
2460
3039
  const verified = yield* dependencies.totpFactorManagement
2461
- .verifyForUser(stepUpTotpVerifyInput(current.currentSession.userId, payload, dependencies))
3040
+ .identifyForUser(stepUpTotpVerifyInput(current.currentSession.userId, payload, dependencies))
2462
3041
  .pipe(Effect.mapError(() => stepUpInternalError("Failed to verify TOTP step-up factor")));
2463
3042
  if (!verified.valid) {
2464
3043
  return yield* stepUpInvalidCredentials();
2465
3044
  }
2466
- return yield* upgradeStepUpSession(dependencies, current, "totp");
3045
+ if (verified.factor === undefined ||
3046
+ verified.acceptedCounter === undefined) {
3047
+ return yield* stepUpInvalidCredentials();
3048
+ }
3049
+ const issued = yield* dependencies.totpSessionRotation
3050
+ .acceptAndRotate({
3051
+ token: current.issued.token,
3052
+ factorId: verified.factor.id,
3053
+ userId: current.currentSession.userId,
3054
+ acceptedCounter: verified.acceptedCounter,
3055
+ expectedAuthenticationEvents: current.currentSession.authenticationEvents,
3056
+ ...(payload.metadata === undefined
3057
+ ? {}
3058
+ : { factorMetadata: payload.metadata }),
3059
+ evidence: totpEvidence({
3060
+ factorId: verified.factor.id,
3061
+ acceptedCounter: verified.acceptedCounter,
3062
+ verifiedAt: yield* currentUnixMillis,
3063
+ }),
3064
+ reason: "step_up",
3065
+ })
3066
+ .pipe(Effect.catch(stepUpRotationHttpFailure));
3067
+ const cookie = yield* dependencies.sessionCookie
3068
+ .commit(issued)
3069
+ .pipe(Effect.mapError(() => stepUpInternalError("Failed to commit upgraded session")));
3070
+ return yield* HttpServerResponse.json(stepUpAuthenticatedHttpBody(issued), {
3071
+ status: 200,
3072
+ headers: { "set-cookie": cookie },
3073
+ }).pipe(Effect.mapError(() => stepUpInternalError("Failed to encode upgraded session")));
3074
+ });
3075
+ export const makeStepUpPasswordVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.password_verify")(function* (handlerRequest) {
3076
+ const { payload, request } = handlerRequest;
3077
+ yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.password_verify");
3078
+ const current = yield* readRequiredSession(dependencies, request);
3079
+ yield* requireAuthRateLimit("auth.step_up.password_verify", handlerRequest, current.currentSession.userId);
3080
+ const input = stepUpPasswordVerifyInput(payload);
3081
+ const credential = yield* dependencies.credentials
3082
+ .findPasswordByUserId(current.currentSession.userId)
3083
+ .pipe(Effect.mapError(() => stepUpInternalError("Failed to verify password step-up factor")));
3084
+ if (Option.isNone(credential) || credential.value.revokedAt !== undefined) {
3085
+ return yield* stepUpInvalidCredentials();
3086
+ }
3087
+ const verified = yield* dependencies.hasher
3088
+ .verify({ hash: credential.value.passwordHash, password: input.password })
3089
+ .pipe(Effect.mapError(() => stepUpInternalError("Failed to verify password step-up factor")));
3090
+ if (!verified) {
3091
+ return yield* stepUpInvalidCredentials();
3092
+ }
3093
+ return yield* reauthenticateStepUpSession(dependencies, current, passwordEvidence({
3094
+ credentialId: credential.value.id,
3095
+ verifiedAt: yield* currentUnixMillis,
3096
+ }));
2467
3097
  });
2468
- export const makeStepUpRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.recovery_code_verify")(function* ({ payload, request, }) {
3098
+ export const makeStepUpRecoveryCodeVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.recovery_code_verify")(function* (handlerRequest) {
3099
+ const { payload, request } = handlerRequest;
2469
3100
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.recovery_code_verify");
2470
3101
  const current = yield* readRequiredSession(dependencies, request);
3102
+ yield* requireAuthRateLimit("auth.step_up.recovery_code_verify", handlerRequest, current.currentSession.userId);
2471
3103
  const verified = yield* dependencies.recoveryCodeManagement
2472
- .verifyForUser(stepUpRecoveryCodeVerifyInput(current.currentSession.userId, payload))
3104
+ .identifyForUser(stepUpRecoveryCodeVerifyInput(current.currentSession.userId, payload))
2473
3105
  .pipe(Effect.mapError(() => stepUpInternalError("Failed to verify recovery-code step-up factor")));
2474
3106
  if (!verified.valid) {
2475
3107
  return yield* stepUpInvalidCredentials();
2476
3108
  }
2477
- return yield* upgradeStepUpSession(dependencies, current, "backup_code");
2478
- });
2479
- export const makeStepUpPasskeyStartHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_start")(function* ({ payload, request, }) {
3109
+ if (verified.code === undefined) {
3110
+ return yield* stepUpInvalidCredentials();
3111
+ }
3112
+ const evidence = recoveryCodeEvidence({
3113
+ codeId: verified.code.id,
3114
+ verifiedAt: yield* currentUnixMillis,
3115
+ });
3116
+ const issued = yield* dependencies.recoveryCodeSessionRotation
3117
+ .consumeAndRotate({
3118
+ token: current.issued.token,
3119
+ codeId: verified.code.id,
3120
+ userId: current.currentSession.userId,
3121
+ expectedAuthenticationEvents: current.currentSession.authenticationEvents,
3122
+ evidence,
3123
+ claims: withRecoveryRemediationRequirement(current.currentSession.claims, defaultRecoveryRemediationCapabilities),
3124
+ reason: "recovery_code_step_up",
3125
+ })
3126
+ .pipe(Effect.catch(stepUpRotationHttpFailure));
3127
+ const cookie = yield* dependencies.sessionCookie
3128
+ .commit(issued)
3129
+ .pipe(Effect.mapError(() => stepUpInternalError("Failed to commit recovery session")));
3130
+ return yield* HttpServerResponse.json(stepUpAuthenticatedHttpBody(issued), {
3131
+ status: 200,
3132
+ headers: { "set-cookie": cookie },
3133
+ }).pipe(Effect.mapError(() => stepUpInternalError("Failed to encode recovery session")));
3134
+ });
3135
+ export const makeStepUpPasskeyStartHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_start")(function* (handlerRequest) {
3136
+ const { payload, request } = handlerRequest;
2480
3137
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.passkey_start");
2481
3138
  const current = yield* readRequiredSession(dependencies, request);
3139
+ yield* requireAuthRateLimit("auth.step_up.passkey_start", handlerRequest, current.currentSession.userId);
2482
3140
  return yield* dependencies.passkeyOptions
2483
3141
  .startAuthentication(stepUpPasskeyStartInput(current.currentSession.userId, payload, dependencies))
2484
3142
  .pipe(Effect.mapError((error) => error.cause === undefined
2485
3143
  ? stepUpBadRequest()
2486
3144
  : stepUpInternalError("Failed to start passkey step-up")));
2487
3145
  });
2488
- export const makeStepUpPasskeyVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_verify")(function* ({ payload, request, }) {
3146
+ export const makeStepUpPasskeyVerifyHandler = (dependencies) => Effect.fn("auth.http.step_up.passkey_verify")(function* (handlerRequest) {
3147
+ const { payload, request } = handlerRequest;
2489
3148
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "step_up.passkey_verify");
2490
3149
  const current = yield* readRequiredSession(dependencies, request);
3150
+ yield* requireAuthRateLimit("auth.step_up.passkey_verify", handlerRequest, current.currentSession.userId);
2491
3151
  const finished = yield* dependencies.passkeyVerification
2492
3152
  .finishAuthentication(stepUpPasskeyVerifyInput(current.currentSession.userId, payload, dependencies))
2493
3153
  .pipe(Effect.mapError(passkeyVerificationHttpError));
3154
+ if (finished.userVerification !== "verified") {
3155
+ return yield* stepUpPolicyDenied("Passkey user verification was not confirmed");
3156
+ }
2494
3157
  if (finished.userId !== current.currentSession.userId) {
2495
3158
  return yield* stepUpPolicyDenied("Passkey belongs to a different user");
2496
3159
  }
2497
- return yield* upgradeStepUpSession(dependencies, current, "passkey");
3160
+ return yield* upgradeStepUpSession(dependencies, current, passkeyEvidence({
3161
+ credentialId: CredentialId(finished.credential.id),
3162
+ verifiedAt: yield* currentUnixMillis,
3163
+ userVerification: finished.userVerification,
3164
+ ...(finished.authenticatorAttachment === undefined
3165
+ ? {}
3166
+ : { authenticatorAttachment: finished.authenticatorAttachment }),
3167
+ ...(finished.backedUp === undefined
3168
+ ? {}
3169
+ : { backedUp: finished.backedUp }),
3170
+ ...(finished.backupEligible === undefined
3171
+ ? {}
3172
+ : { backupEligible: finished.backupEligible }),
3173
+ signCount: finished.signCount,
3174
+ ...(finished.aaguid === undefined ? {} : { aaguid: finished.aaguid }),
3175
+ }));
2498
3176
  });
2499
- export const makeLoginApprovalApproveHandler = (dependencies) => Effect.fn("auth.http.login_approval.approve")(function* ({ payload, request, }) {
3177
+ export const makeLoginApprovalApproveHandler = (dependencies) =>
3178
+ // oxlint-disable-next-line eslint/complexity -- approval preflight intentionally validates every binding before either one-time state is consumed.
3179
+ Effect.fn("auth.http.login_approval.approve")(function* ({ payload, request, }) {
2500
3180
  yield* Effect.annotateCurrentSpan("auth.http.endpoint", "login_approval.approve");
2501
3181
  const input = loginApprovalApproveInput(payload);
2502
- const approval = yield* dependencies.loginApproval
2503
- .verify(input.approval)
3182
+ const inspectedApproval = yield* dependencies.loginApproval
3183
+ .inspect(input.approval)
2504
3184
  .pipe(Effect.mapError(() => loginApprovalBadRequest()));
2505
- const approvedFlowId = metadataString(approval.metadata, "flowId");
3185
+ const approvedFlowId = metadataString(inspectedApproval.metadata, "flowId");
2506
3186
  if (approvedFlowId !== input.flowId) {
2507
3187
  return yield* loginApprovalBadRequest();
2508
3188
  }
2509
- if (approval.sessionBinding === "none") {
3189
+ if (inspectedApproval.sessionBinding === "none") {
2510
3190
  return yield* loginApprovalNoSessionBindingDenied();
2511
3191
  }
2512
- const sameDeviceSecret = approval.sameDeviceRequired
3192
+ const sameDeviceSecret = inspectedApproval.sameDeviceRequired
2513
3193
  ? yield* dependencies.loginApprovalPendingCookie
2514
3194
  .read(new Request("http://localhost", { headers: request.headers }))
2515
3195
  .pipe(Effect.flatMap((secret) => Option.isSome(secret)
2516
3196
  ? Effect.succeed(secret.value)
2517
3197
  : Effect.fail(loginApprovalSameDeviceDenied())))
2518
3198
  : undefined;
3199
+ const inspectedFlow = yield* dependencies.authFlowState
3200
+ .inspect(input.flowId, sameDeviceSecret)
3201
+ .pipe(Effect.mapError(() => inspectedApproval.sameDeviceRequired
3202
+ ? loginApprovalSameDeviceDenied()
3203
+ : loginApprovalBadRequest()));
3204
+ if (inspectedFlow.userId !== inspectedApproval.userId) {
3205
+ return yield* loginApprovalBadRequest();
3206
+ }
3207
+ const identity = inspectedApproval.markIdentityVerified === true
3208
+ ? inspectedApproval.identityId === undefined
3209
+ ? Option.none()
3210
+ : yield* dependencies.identities
3211
+ .findById(inspectedApproval.identityId)
3212
+ .pipe(Effect.mapError(() => passwordInternalError("Failed to load identity for verification")))
3213
+ : Option.none();
3214
+ if (inspectedApproval.markIdentityVerified === true &&
3215
+ (Option.isNone(identity) ||
3216
+ identity.value.userId !== inspectedApproval.userId)) {
3217
+ return yield* loginApprovalBadRequest();
3218
+ }
3219
+ const approval = yield* dependencies.loginApproval
3220
+ .verify(input.approval)
3221
+ .pipe(Effect.mapError(() => loginApprovalBadRequest()));
3222
+ if (metadataString(approval.metadata, "flowId") !== input.flowId ||
3223
+ approval.userId !== inspectedApproval.userId ||
3224
+ approval.sessionBinding !== inspectedApproval.sessionBinding ||
3225
+ approval.sameDeviceRequired !== inspectedApproval.sameDeviceRequired ||
3226
+ approval.markIdentityVerified !==
3227
+ inspectedApproval.markIdentityVerified ||
3228
+ approval.identityId !== inspectedApproval.identityId) {
3229
+ return yield* loginApprovalBadRequest();
3230
+ }
2519
3231
  const consumed = yield* dependencies.authFlowState
2520
3232
  .consume(input.flowId, sameDeviceSecret)
2521
3233
  .pipe(Effect.mapError(() => approval.sameDeviceRequired
2522
3234
  ? loginApprovalSameDeviceDenied()
2523
3235
  : loginApprovalBadRequest()));
2524
- if (consumed.userId !== approval.userId) {
3236
+ if (consumed.userId !== approval.userId ||
3237
+ consumed.userId !== inspectedFlow.userId) {
2525
3238
  return yield* loginApprovalBadRequest();
2526
3239
  }
2527
- if (approval.markEmailVerified === true) {
2528
- const updated = yield* dependencies.users
2529
- .markEmailVerified({
2530
- userId: approval.userId,
2531
- updatedAt: yield* currentUnixMillis,
2532
- })
2533
- .pipe(Effect.mapError(() => passwordInternalError("Failed to mark email verified")));
3240
+ if (approval.markIdentityVerified === true) {
3241
+ if (approval.identityId === undefined || Option.isNone(identity)) {
3242
+ return yield* loginApprovalBadRequest();
3243
+ }
3244
+ const updated = yield* dependencies.identities
3245
+ .markVerified({
3246
+ id: approval.identityId,
3247
+ expectedNormalizedValue: identity.value.normalizedValue,
3248
+ verifiedAt: yield* currentUnixMillis,
3249
+ })
3250
+ .pipe(Effect.mapError(() => passwordInternalError("Failed to mark identity verified")));
2534
3251
  if (Option.isNone(updated)) {
2535
3252
  return yield* loginApprovalBadRequest();
2536
3253
  }
2537
3254
  }
2538
- const result = yield* dependencies.authFlow
2539
- .complete(consumed)
2540
- .pipe(Effect.mapError(() => passwordInternalError("Failed to complete login approval")));
3255
+ const result = yield* dependencies
3256
+ .finalizeAuthFlow(consumed)
3257
+ .pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to complete login approval") ??
3258
+ Effect.fail(passwordInternalError("Failed to complete login approval"))));
3259
+ if (result._tag === "PolicyDenied") {
3260
+ return yield* loginApprovalPolicyDenied();
3261
+ }
2541
3262
  const setCookies = yield* trustedDeviceSetCookies({
2542
3263
  trustedDevice: dependencies.trustedDevice,
2543
3264
  trustedDeviceCookie: dependencies.trustedDeviceCookie,
@@ -2586,9 +3307,10 @@ export const makeLoginApprovalFinalizeHandler = (dependencies) => Effect.fn("aut
2586
3307
  ? { sameDeviceSecret: sameDeviceSecret.value }
2587
3308
  : {}),
2588
3309
  })
2589
- .pipe(Effect.mapError((error) => error._tag === "AuthFlowStateError"
2590
- ? loginApprovalSameDeviceDenied()
2591
- : passwordInternalError("Failed to finalize login approval")));
3310
+ .pipe(Effect.catch((error) => customEvidencePolicyHttpFailure(error, "Failed to finalize login approval") ??
3311
+ Effect.fail(error._tag === "AuthFlowStateError"
3312
+ ? loginApprovalSameDeviceDenied()
3313
+ : passwordInternalError("Failed to finalize login approval"))));
2592
3314
  if (result._tag === "PolicyDenied") {
2593
3315
  return yield* loginApprovalPolicyDenied(result.reason);
2594
3316
  }
@@ -2600,427 +3322,1019 @@ export const makeLoginApprovalFinalizeHandler = (dependencies) => Effect.fn("aut
2600
3322
  });
2601
3323
  return yield* dependencies.authHttp.commitAuthenticatedSession(result.session, { setCookies });
2602
3324
  });
2603
- export class PasswordApi extends HttpApiGroup.make("password")
2604
- .add(passwordSignInEndpoint.middleware(AuthRateLimitMiddleware), passwordSignUpEndpoint.middleware(AuthRateLimitMiddleware), passwordResetStartEndpoint.middleware(AuthRateLimitMiddleware), passwordResetVerifyEndpoint.middleware(AuthRateLimitMiddleware), passwordSetEndpoint.middleware(AuthOriginCheckMiddleware), passwordChangeEndpoint.middleware(AuthOriginCheckMiddleware))
2605
- .prefix("/auth/password")
2606
- .middleware(AuthSchemaErrorMiddleware)
2607
- .middleware(AuthOriginCheckMiddleware) {
2608
- }
2609
- export class SessionApi extends HttpApiGroup.make("session")
2610
- .add(currentSessionEndpoint, refreshSessionEndpoint.middleware(AuthOriginCheckMiddleware), logoutEndpoint.middleware(AuthOriginCheckMiddleware), listSessionsEndpoint, revokeSessionEndpoint.middleware(AuthOriginCheckMiddleware), revokeOtherSessionsEndpoint.middleware(AuthOriginCheckMiddleware))
2611
- .prefix("/auth") {
2612
- }
2613
- export class AdminSessionApi extends HttpApiGroup.make("adminSession")
3325
+ export const SessionHttpOperationsLive = Layer.effect(SessionHttpOperations, Effect.gen(function* () {
3326
+ const sessions = yield* Sessions;
3327
+ const sessionCookie = yield* SessionCookie;
3328
+ const authHttp = yield* AuthHttp;
3329
+ return SessionHttpOperations.of({
3330
+ current: makeCurrentSessionHandler({ sessions, sessionCookie, authHttp }),
3331
+ refresh: makeRefreshSessionHandler({ sessions, sessionCookie, authHttp }),
3332
+ logout: makeLogoutHandler({ sessions, sessionCookie, authHttp }),
3333
+ list: makeListSessionsHandler({ sessions, sessionCookie }),
3334
+ revoke: makeRevokeSessionHandler({ sessions, sessionCookie, authHttp }),
3335
+ revokeOthers: makeRevokeOtherSessionsHandler({ sessions, sessionCookie }),
3336
+ });
3337
+ }));
3338
+ export const EmailVerificationHttpOperationsLive = Layer.effect(EmailVerificationHttpOperations, Effect.gen(function* () {
3339
+ const emailVerificationFlow = yield* EmailVerificationFlow;
3340
+ const emailVerification = yield* EmailVerification;
3341
+ const identities = yield* IdentityStore;
3342
+ const sessions = yield* Sessions;
3343
+ const sessionCookie = yield* SessionCookie;
3344
+ const authRateLimit = yield* AuthRateLimit;
3345
+ const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
3346
+ const guardServices = {
3347
+ authRateLimit,
3348
+ identities,
3349
+ ...(Option.isSome(botChallengeVerifier)
3350
+ ? { botChallengeVerifier: botChallengeVerifier.value }
3351
+ : {}),
3352
+ };
3353
+ return EmailVerificationHttpOperations.of({
3354
+ start: provideRequestGuardServices(guardServices, makeEmailVerificationStartHandler({
3355
+ emailVerificationFlow,
3356
+ })),
3357
+ verify: makeEmailVerificationVerifyHandler({
3358
+ emailVerification,
3359
+ sessions,
3360
+ sessionCookie,
3361
+ }),
3362
+ });
3363
+ }));
3364
+ export const EmailOtpHttpOperationsLive = Layer.effect(EmailOtpHttpOperations, Effect.gen(function* () {
3365
+ const emailOtp = yield* EmailOtpLogin;
3366
+ const authHttp = yield* AuthHttp;
3367
+ const authRateLimit = yield* AuthRateLimit;
3368
+ const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
3369
+ const cookie = yield* Effect.serviceOption(TrustedDeviceCookie);
3370
+ const guardServices = {
3371
+ authRateLimit,
3372
+ ...(Option.isSome(botChallengeVerifier)
3373
+ ? { botChallengeVerifier: botChallengeVerifier.value }
3374
+ : {}),
3375
+ ...(Option.isSome(cookie) ? { trustedDeviceCookie: cookie.value } : {}),
3376
+ };
3377
+ return EmailOtpHttpOperations.of({
3378
+ start: provideRequestGuardServices(guardServices, makeEmailOtpStartHandler({ emailOtp })),
3379
+ verify: provideRequestGuardServices(guardServices, makeEmailOtpVerifyHandler({
3380
+ emailOtp,
3381
+ authHttp,
3382
+ })),
3383
+ });
3384
+ }));
3385
+ export const EmailAuthHttpOperationsLive = Layer.effect(EmailAuthHttpOperations, Effect.gen(function* () {
3386
+ const emailAuth = yield* EmailAuth;
3387
+ const authRateLimit = yield* AuthRateLimit;
3388
+ const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
3389
+ const guardServices = {
3390
+ authRateLimit,
3391
+ ...(Option.isSome(botChallengeVerifier)
3392
+ ? { botChallengeVerifier: botChallengeVerifier.value }
3393
+ : {}),
3394
+ };
3395
+ return EmailAuthHttpOperations.of({
3396
+ start: provideRequestGuardServices(guardServices, makeEmailAuthStartHandler({ emailAuth })),
3397
+ });
3398
+ }));
3399
+ export const MagicLinkHttpOperationsLive = Layer.effect(MagicLinkHttpOperations, Effect.gen(function* () {
3400
+ const magicLink = yield* MagicLinkLogin;
3401
+ const authHttp = yield* AuthHttp;
3402
+ const authRateLimit = yield* AuthRateLimit;
3403
+ const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
3404
+ const cookie = yield* Effect.serviceOption(TrustedDeviceCookie);
3405
+ const guardServices = {
3406
+ authRateLimit,
3407
+ ...(Option.isSome(botChallengeVerifier)
3408
+ ? { botChallengeVerifier: botChallengeVerifier.value }
3409
+ : {}),
3410
+ ...(Option.isSome(cookie) ? { trustedDeviceCookie: cookie.value } : {}),
3411
+ };
3412
+ return MagicLinkHttpOperations.of({
3413
+ start: provideRequestGuardServices(guardServices, makeMagicLinkStartHandler({ magicLink })),
3414
+ verify: provideRequestGuardServices(guardServices, makeMagicLinkVerifyHandler({
3415
+ magicLink,
3416
+ authHttp,
3417
+ })),
3418
+ });
3419
+ }));
3420
+ export const PasskeyHttpOperationsLive = Layer.effect(PasskeyHttpOperations, Effect.gen(function* () {
3421
+ const authRateLimit = yield* AuthRateLimit;
3422
+ const config = yield* PasskeyHttpConfig;
3423
+ const passkeyOptions = yield* PasskeyOptions;
3424
+ const passkeyVerification = yield* PasskeyVerification;
3425
+ const passkeyCredentialManagement = yield* PasskeyCredentialManagement;
3426
+ const sessions = yield* Sessions;
3427
+ const sessionCookie = yield* SessionCookie;
3428
+ const authHttp = yield* AuthHttp;
3429
+ const users = yield* UserStore;
3430
+ const identities = yield* IdentityStore;
3431
+ const policy = yield* Effect.serviceOption(StrongFactorRemovalPolicy);
3432
+ const resolveUser = makePasskeyRegistrationUserResolver({
3433
+ users,
3434
+ identities,
3435
+ });
3436
+ return PasskeyHttpOperations.of({
3437
+ registerStart: provideHandlerAuthRateLimit(authRateLimit, makePasskeyRegistrationStartHandler({
3438
+ passkeyOptions,
3439
+ sessions,
3440
+ sessionCookie,
3441
+ resolveUser,
3442
+ ...passkeyRegistrationStartHttpOptions(config),
3443
+ })),
3444
+ registerFinish: provideHandlerAuthRateLimit(authRateLimit, makePasskeyRegistrationFinishHandler({
3445
+ passkeyVerification,
3446
+ sessions,
3447
+ sessionCookie,
3448
+ resolveUser,
3449
+ ...passkeyFinishHttpOptions(config),
3450
+ })),
3451
+ authenticateStart: provideHandlerAuthRateLimit(authRateLimit, makePasskeyAuthenticationStartHandler({
3452
+ passkeyOptions,
3453
+ ...passkeyAuthenticationStartHttpOptions(config),
3454
+ })),
3455
+ authenticateFinish: provideHandlerAuthRateLimit(authRateLimit, makePasskeyAuthenticationFinishHandler({
3456
+ passkeyVerification,
3457
+ sessions,
3458
+ authHttp,
3459
+ makeSessionInput: passkeyAuthenticationSessionInput,
3460
+ ...passkeyFinishHttpOptions(config),
3461
+ })),
3462
+ listCredentials: provideHandlerAuthRateLimit(authRateLimit, makePasskeyCredentialListHandler({
3463
+ passkeyCredentialManagement,
3464
+ sessions,
3465
+ sessionCookie,
3466
+ })),
3467
+ revokeCredential: provideHandlerAuthRateLimit(authRateLimit, makePasskeyCredentialRevokeHandler({
3468
+ passkeyCredentialManagement,
3469
+ sessions,
3470
+ sessionCookie,
3471
+ ...(Option.isSome(policy)
3472
+ ? { strongFactorRemovalPolicy: policy.value }
3473
+ : {}),
3474
+ })),
3475
+ });
3476
+ }));
3477
+ export const IdentityHttpOperationsLive = Layer.effect(IdentityHttpOperations, Effect.gen(function* () {
3478
+ const authRateLimit = yield* AuthRateLimit;
3479
+ const botChallengeVerifier = yield* Effect.serviceOption(BotChallengeVerifier);
3480
+ const identityManagement = yield* IdentityManagement;
3481
+ const sessions = yield* Sessions;
3482
+ const sessionCookie = yield* SessionCookie;
3483
+ const dependencies = {
3484
+ identityManagement,
3485
+ sessions,
3486
+ sessionCookie,
3487
+ };
3488
+ const availabilityGuardServices = {
3489
+ authRateLimit,
3490
+ sessions,
3491
+ sessionCookie,
3492
+ ...(Option.isSome(botChallengeVerifier)
3493
+ ? { botChallengeVerifier: botChallengeVerifier.value }
3494
+ : {}),
3495
+ };
3496
+ return IdentityHttpOperations.of({
3497
+ availability: provideRequestGuardServices(availabilityGuardServices, makeIdentityAvailabilityHandler(dependencies)),
3498
+ list: provideHandlerAuthRateLimit(authRateLimit, makeIdentityListHandler(dependencies)),
3499
+ add: provideHandlerAuthRateLimit(authRateLimit, makeIdentityAddHandler(dependencies)),
3500
+ replace: provideHandlerAuthRateLimit(authRateLimit, makeIdentityReplaceHandler(dependencies)),
3501
+ revoke: provideHandlerAuthRateLimit(authRateLimit, makeIdentityRevokeHandler(dependencies)),
3502
+ primary: provideHandlerAuthRateLimit(authRateLimit, makeIdentityPrimaryHandler(dependencies)),
3503
+ });
3504
+ }));
3505
+ export const TotpHttpOperationsLive = Layer.effect(TotpHttpOperations, Effect.gen(function* () {
3506
+ const authRateLimit = yield* AuthRateLimit;
3507
+ const config = yield* TotpHttpConfig;
3508
+ const totpFactorManagement = yield* TotpFactorManagement;
3509
+ const sessions = yield* Sessions;
3510
+ const sessionCookie = yield* SessionCookie;
3511
+ const policy = yield* Effect.serviceOption(StrongFactorRemovalPolicy);
3512
+ return TotpHttpOperations.of({
3513
+ startEnrollment: provideHandlerAuthRateLimit(authRateLimit, makeTotpEnrollmentStartHandler({
3514
+ totpFactorManagement,
3515
+ sessions,
3516
+ sessionCookie,
3517
+ ...config,
3518
+ })),
3519
+ confirmEnrollment: provideHandlerAuthRateLimit(authRateLimit, makeTotpEnrollmentConfirmHandler({
3520
+ totpFactorManagement,
3521
+ sessions,
3522
+ sessionCookie,
3523
+ ...config,
3524
+ })),
3525
+ verify: provideHandlerAuthRateLimit(authRateLimit, makeTotpVerifyHandler({
3526
+ totpFactorManagement,
3527
+ sessions,
3528
+ sessionCookie,
3529
+ ...config,
3530
+ })),
3531
+ listFactors: provideHandlerAuthRateLimit(authRateLimit, makeTotpFactorListHandler({
3532
+ totpFactorManagement,
3533
+ sessions,
3534
+ sessionCookie,
3535
+ })),
3536
+ revokeFactor: provideHandlerAuthRateLimit(authRateLimit, makeTotpFactorRevokeHandler({
3537
+ totpFactorManagement,
3538
+ sessions,
3539
+ sessionCookie,
3540
+ ...(Option.isSome(policy)
3541
+ ? { strongFactorRemovalPolicy: policy.value }
3542
+ : {}),
3543
+ })),
3544
+ });
3545
+ }));
3546
+ export const RecoveryCodesHttpOperationsLive = Layer.effect(RecoveryCodesHttpOperations, Effect.gen(function* () {
3547
+ const authRateLimit = yield* AuthRateLimit;
3548
+ const config = yield* RecoveryCodeHttpConfig;
3549
+ const recoveryCodeManagement = yield* RecoveryCodeManagement;
3550
+ const sessions = yield* Sessions;
3551
+ const sessionCookie = yield* SessionCookie;
3552
+ const policy = yield* Effect.serviceOption(StrongFactorRemovalPolicy);
3553
+ return RecoveryCodesHttpOperations.of({
3554
+ generate: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeGenerateHandler({
3555
+ recoveryCodeManagement,
3556
+ sessions,
3557
+ sessionCookie,
3558
+ ...config,
3559
+ })),
3560
+ regenerate: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeRegenerateHandler({
3561
+ recoveryCodeManagement,
3562
+ sessions,
3563
+ sessionCookie,
3564
+ ...config,
3565
+ })),
3566
+ verify: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeVerifyHandler({
3567
+ recoveryCodeManagement,
3568
+ sessions,
3569
+ sessionCookie,
3570
+ })),
3571
+ list: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeListHandler({
3572
+ recoveryCodeManagement,
3573
+ sessions,
3574
+ sessionCookie,
3575
+ })),
3576
+ revoke: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeRevokeHandler({
3577
+ recoveryCodeManagement,
3578
+ sessions,
3579
+ sessionCookie,
3580
+ ...(Option.isSome(policy)
3581
+ ? { strongFactorRemovalPolicy: policy.value }
3582
+ : {}),
3583
+ })),
3584
+ });
3585
+ }));
3586
+ export const MfaHttpOperationsLive = Layer.effect(MfaHttpOperations, Effect.gen(function* () {
3587
+ const authRateLimit = yield* AuthRateLimit;
3588
+ const passkeyConfig = yield* PasskeyHttpConfig;
3589
+ const totpConfig = yield* TotpHttpConfig;
3590
+ const authFlowState = yield* AuthFlowState;
3591
+ const authFlow = yield* AuthFlow;
3592
+ const authHttp = yield* AuthHttp;
3593
+ const totpFactorManagement = yield* TotpFactorManagement;
3594
+ const recoveryCodeManagement = yield* RecoveryCodeManagement;
3595
+ const verificationStore = yield* VerificationStore;
3596
+ const recoveryCodeLoginCommitStore = yield* RecoveryCodeLoginCommitStore;
3597
+ const totpLoginCommitStore = yield* TotpLoginCommitStore;
3598
+ const users = yield* UserStore;
3599
+ const passkeyCredentialManagement = yield* PasskeyCredentialManagement;
3600
+ const passkeyOptions = yield* PasskeyOptions;
3601
+ const passkeyVerification = yield* PasskeyVerification;
3602
+ return MfaHttpOperations.of({
3603
+ options: provideHandlerAuthRateLimit(authRateLimit, makeMfaOptionsHandler({
3604
+ authFlowState,
3605
+ totpFactorManagement,
3606
+ recoveryCodeManagement,
3607
+ passkeyCredentialManagement,
3608
+ })),
3609
+ verifyTotp: provideHandlerAuthRateLimit(authRateLimit, makeTotpMfaVerifyHandler({
3610
+ totpFactorManagement,
3611
+ authFlowState,
3612
+ authFlow,
3613
+ authHttp,
3614
+ ...totpConfig,
3615
+ })),
3616
+ verifyTotpForFlow: provideHandlerAuthRateLimit(authRateLimit, makeTotpMfaVerifyForFlowHandler({
3617
+ totpFactorManagement,
3618
+ authFlowState,
3619
+ authFlow,
3620
+ authHttp,
3621
+ verificationStore,
3622
+ totpLoginCommitStore,
3623
+ users,
3624
+ ...totpConfig,
3625
+ })),
3626
+ verifyRecoveryCode: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeMfaVerifyHandler({
3627
+ recoveryCodeManagement,
3628
+ authFlowState,
3629
+ authFlow,
3630
+ authHttp,
3631
+ })),
3632
+ verifyRecoveryCodeForFlow: provideHandlerAuthRateLimit(authRateLimit, makeRecoveryCodeMfaVerifyForFlowHandler({
3633
+ recoveryCodeManagement,
3634
+ authFlowState,
3635
+ authFlow,
3636
+ authHttp,
3637
+ verificationStore,
3638
+ recoveryCodeLoginCommitStore,
3639
+ users,
3640
+ })),
3641
+ startPasskey: provideHandlerAuthRateLimit(authRateLimit, makePasskeyMfaStartHandler({
3642
+ passkeyOptions,
3643
+ authFlowState,
3644
+ ...passkeyAuthenticationStartHttpOptions(passkeyConfig),
3645
+ })),
3646
+ verifyPasskey: provideHandlerAuthRateLimit(authRateLimit, makePasskeyMfaVerifyHandler({
3647
+ passkeyVerification,
3648
+ authFlowState,
3649
+ authFlow,
3650
+ authHttp,
3651
+ ...passkeyFinishHttpOptions(passkeyConfig),
3652
+ })),
3653
+ });
3654
+ }));
3655
+ export const StepUpHttpOperationsLive = Layer.effect(StepUpHttpOperations, Effect.gen(function* () {
3656
+ const authRateLimit = yield* AuthRateLimit;
3657
+ const passkeyConfig = yield* PasskeyHttpConfig;
3658
+ const totpConfig = yield* TotpHttpConfig;
3659
+ const sessions = yield* Sessions;
3660
+ const sessionCookie = yield* SessionCookie;
3661
+ const credentials = yield* CredentialStore;
3662
+ const hasher = yield* PasswordHasher;
3663
+ const totpFactorManagement = yield* TotpFactorManagement;
3664
+ const recoveryCodeManagement = yield* RecoveryCodeManagement;
3665
+ const recoveryCodeSessionRotation = yield* RecoveryCodeSessionRotation;
3666
+ const totpSessionRotation = yield* TotpSessionRotation;
3667
+ const passkeyCredentialManagement = yield* PasskeyCredentialManagement;
3668
+ const passkeyOptions = yield* PasskeyOptions;
3669
+ const passkeyVerification = yield* PasskeyVerification;
3670
+ return StepUpHttpOperations.of({
3671
+ options: provideHandlerAuthRateLimit(authRateLimit, makeStepUpOptionsHandler({
3672
+ sessions,
3673
+ sessionCookie,
3674
+ credentials,
3675
+ totpFactorManagement,
3676
+ recoveryCodeManagement,
3677
+ passkeyCredentialManagement,
3678
+ })),
3679
+ verifyTotp: provideHandlerAuthRateLimit(authRateLimit, makeStepUpTotpVerifyHandler({
3680
+ totpFactorManagement,
3681
+ sessions,
3682
+ sessionCookie,
3683
+ totpSessionRotation,
3684
+ ...totpConfig,
3685
+ })),
3686
+ verifyPassword: provideHandlerAuthRateLimit(authRateLimit, makeStepUpPasswordVerifyHandler({
3687
+ credentials,
3688
+ hasher,
3689
+ sessions,
3690
+ sessionCookie,
3691
+ })),
3692
+ verifyRecoveryCode: provideHandlerAuthRateLimit(authRateLimit, makeStepUpRecoveryCodeVerifyHandler({
3693
+ recoveryCodeManagement,
3694
+ recoveryCodeSessionRotation,
3695
+ sessions,
3696
+ sessionCookie,
3697
+ })),
3698
+ startPasskey: provideHandlerAuthRateLimit(authRateLimit, makeStepUpPasskeyStartHandler({
3699
+ passkeyOptions,
3700
+ sessions,
3701
+ sessionCookie,
3702
+ ...passkeyAuthenticationStartHttpOptions(passkeyConfig),
3703
+ })),
3704
+ verifyPasskey: provideHandlerAuthRateLimit(authRateLimit, makeStepUpPasskeyVerifyHandler({
3705
+ passkeyVerification,
3706
+ sessions,
3707
+ sessionCookie,
3708
+ ...passkeyFinishHttpOptions(passkeyConfig),
3709
+ })),
3710
+ });
3711
+ }));
3712
+ export const AdminSessionHttpOperationsLive = Layer.effect(AdminSessionHttpOperations, Effect.gen(function* () {
3713
+ const sessions = yield* Sessions;
3714
+ const sessionCookie = yield* SessionCookie;
3715
+ const authorization = yield* AdminSessionAuthorization;
3716
+ return AdminSessionHttpOperations.of({
3717
+ list: makeAdminSessionListHandler({
3718
+ sessions,
3719
+ sessionCookie,
3720
+ authorization,
3721
+ }),
3722
+ revoke: makeAdminSessionRevokeHandler({
3723
+ sessions,
3724
+ sessionCookie,
3725
+ authorization,
3726
+ }),
3727
+ revokeAll: makeAdminSessionRevokeAllHandler({
3728
+ sessions,
3729
+ sessionCookie,
3730
+ authorization,
3731
+ }),
3732
+ });
3733
+ }));
3734
+ export const AdminPermissionDefinitionHttpOperationsLive = Layer.succeed(AdminPermissionDefinitionHttpOperations, AdminPermissionDefinitionHttpOperations.of({
3735
+ create: adminPermissionDefinitionCreateOperation,
3736
+ get: adminPermissionDefinitionGetOperation,
3737
+ list: adminPermissionDefinitionListOperation,
3738
+ update: adminPermissionDefinitionUpdateOperation,
3739
+ disable: adminPermissionDefinitionDisableOperation,
3740
+ enable: adminPermissionDefinitionEnableOperation,
3741
+ delete: adminPermissionDefinitionDeleteOperation,
3742
+ }));
3743
+ export const LoginNotificationHttpOperationsLive = Layer.effect(LoginNotificationHttpOperations, Effect.gen(function* () {
3744
+ const loginNotification = yield* Effect.serviceOption(LoginNotification);
3745
+ return LoginNotificationHttpOperations.of({
3746
+ reportLogin: makeLoginNotificationReportHandler(Option.isSome(loginNotification)
3747
+ ? { loginNotification: loginNotification.value }
3748
+ : {}),
3749
+ });
3750
+ }));
3751
+ export const SecurityTimelineHttpOperationsLive = Layer.effect(SecurityTimelineHttpOperations, Effect.gen(function* () {
3752
+ const sessions = yield* Sessions;
3753
+ const sessionCookie = yield* SessionCookie;
3754
+ const securityTimeline = yield* SecurityTimelineStore;
3755
+ return SecurityTimelineHttpOperations.of({
3756
+ list: makeSecurityTimelineListHandler({
3757
+ sessions,
3758
+ sessionCookie,
3759
+ securityTimeline,
3760
+ }),
3761
+ });
3762
+ }));
3763
+ export const AdminSecurityTimelineHttpOperationsLive = Layer.effect(AdminSecurityTimelineHttpOperations, Effect.gen(function* () {
3764
+ const sessions = yield* Sessions;
3765
+ const sessionCookie = yield* SessionCookie;
3766
+ const securityTimeline = yield* SecurityTimelineStore;
3767
+ const authorization = yield* AdminSecurityTimelineAuthorization;
3768
+ return AdminSecurityTimelineHttpOperations.of({
3769
+ list: makeAdminSecurityTimelineListHandler({
3770
+ sessions,
3771
+ sessionCookie,
3772
+ securityTimeline,
3773
+ authorization,
3774
+ }),
3775
+ });
3776
+ }));
3777
+ export const TrustedDeviceHttpOperationsLive = Layer.effect(TrustedDeviceHttpOperations, Effect.gen(function* () {
3778
+ const sessions = yield* Sessions;
3779
+ const sessionCookie = yield* SessionCookie;
3780
+ const trustedDevices = yield* TrustedDeviceStore;
3781
+ return TrustedDeviceHttpOperations.of({
3782
+ list: makeTrustedDeviceListHandler({
3783
+ sessions,
3784
+ sessionCookie,
3785
+ trustedDevices,
3786
+ }),
3787
+ revoke: makeTrustedDeviceRevokeHandler({
3788
+ sessions,
3789
+ sessionCookie,
3790
+ trustedDevices,
3791
+ }),
3792
+ });
3793
+ }));
3794
+ export const AdminTrustedDeviceHttpOperationsLive = Layer.effect(AdminTrustedDeviceHttpOperations, Effect.gen(function* () {
3795
+ const sessions = yield* Sessions;
3796
+ const sessionCookie = yield* SessionCookie;
3797
+ const trustedDevices = yield* TrustedDeviceStore;
3798
+ const authorization = yield* AdminTrustedDeviceAuthorization;
3799
+ return AdminTrustedDeviceHttpOperations.of({
3800
+ list: makeAdminTrustedDeviceListHandler({
3801
+ sessions,
3802
+ sessionCookie,
3803
+ trustedDevices,
3804
+ authorization,
3805
+ }),
3806
+ revoke: makeAdminTrustedDeviceRevokeHandler({
3807
+ sessions,
3808
+ sessionCookie,
3809
+ trustedDevices,
3810
+ authorization,
3811
+ }),
3812
+ });
3813
+ }));
3814
+ export const OAuthHttpOperationsLive = Layer.effect(OAuthHttpOperations, Effect.gen(function* () {
3815
+ const oauthProviders = yield* OAuthProviders;
3816
+ const oauthState = yield* OAuthState;
3817
+ const oauthAccountUnlinking = yield* OAuthAccountUnlinking;
3818
+ const oauthLinkConfirmation = yield* OAuthLinkConfirmation;
3819
+ const sessions = yield* Sessions;
3820
+ const sessionCookie = yield* SessionCookie;
3821
+ const config = yield* OAuthHttpConfig;
3822
+ return OAuthHttpOperations.of({
3823
+ authorizationStart: makeOAuthAuthorizationStartHandler({
3824
+ oauthProviders,
3825
+ oauthState,
3826
+ ...config,
3827
+ }),
3828
+ accountUnlink: makeOAuthAccountUnlinkHandler({
3829
+ oauthAccountUnlinking,
3830
+ sessions,
3831
+ sessionCookie,
3832
+ ...config,
3833
+ }),
3834
+ linkConfirmationStart: makeOAuthLinkConfirmationStartHandler({
3835
+ oauthLinkConfirmation,
3836
+ ...config,
3837
+ }),
3838
+ linkConfirmationInspect: makeOAuthLinkConfirmationInspectHandler({
3839
+ oauthLinkConfirmation,
3840
+ }),
3841
+ linkConfirmationConfirm: makeOAuthLinkConfirmationConfirmHandler({
3842
+ oauthLinkConfirmation,
3843
+ ...config,
3844
+ }),
3845
+ });
3846
+ }));
3847
+ export const OAuthProviderAuthorizationHttpOperationsLive = Layer.effect(OAuthProviderAuthorizationHttpOperations, Effect.gen(function* () {
3848
+ const authorization = yield* OAuthProviderAuthorization;
3849
+ return OAuthProviderAuthorizationHttpOperations.of({
3850
+ authorize: makeOAuthProviderAuthorizationHandler({ authorization }),
3851
+ });
3852
+ }));
3853
+ export const OAuthTokenHttpOperationsLive = Layer.effect(OAuthTokenHttpOperations, Effect.gen(function* () {
3854
+ const registry = yield* OAuthTokenGrantRegistry;
3855
+ const config = yield* OAuthTokenHttpConfig;
3856
+ return OAuthTokenHttpOperations.of({
3857
+ token: makeOAuthTokenHandler({ registry, ...config }),
3858
+ });
3859
+ }));
3860
+ export const OAuthTokenIntrospectionHttpOperationsLive = Layer.effect(OAuthTokenIntrospectionHttpOperations, Effect.gen(function* () {
3861
+ const tokenIntrospection = yield* OAuthTokenIntrospection;
3862
+ const config = yield* OAuthTokenHttpConfig;
3863
+ return OAuthTokenIntrospectionHttpOperations.of({
3864
+ introspect: makeOAuthTokenIntrospectionHandler({
3865
+ tokenIntrospection,
3866
+ ...config,
3867
+ }),
3868
+ });
3869
+ }));
3870
+ export const OAuthTokenRevocationHttpOperationsLive = Layer.effect(OAuthTokenRevocationHttpOperations, Effect.gen(function* () {
3871
+ const tokenRevocation = yield* OAuthTokenRevocation;
3872
+ const config = yield* OAuthTokenHttpConfig;
3873
+ return OAuthTokenRevocationHttpOperations.of({
3874
+ revoke: makeOAuthTokenRevocationHandler({ tokenRevocation, ...config }),
3875
+ });
3876
+ }));
3877
+ export const LoginApprovalHttpOperationsLive = Layer.effect(LoginApprovalHttpOperations, Effect.gen(function* () {
3878
+ const loginApproval = yield* LoginApproval;
3879
+ const authFlowState = yield* AuthFlowState;
3880
+ const authFlowFinalizer = yield* AuthFlowFinalizer;
3881
+ const identities = yield* IdentityStore;
3882
+ const authHttp = yield* AuthHttp;
3883
+ const loginApprovalReview = yield* Effect.serviceOption(LoginApprovalReview);
3884
+ const loginApprovalFinalize = yield* Effect.serviceOption(LoginApprovalFinalize);
3885
+ const pendingCookie = yield* Effect.serviceOption(LoginApprovalPendingCookie);
3886
+ const trustedDevice = yield* Effect.serviceOption(TrustedDevice);
3887
+ const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
3888
+ const loginApprovalPendingCookie = Option.isSome(pendingCookie)
3889
+ ? pendingCookie.value
3890
+ : makeLoginApprovalPendingCookie();
3891
+ return LoginApprovalHttpOperations.of({
3892
+ approve: makeLoginApprovalApproveHandler({
3893
+ loginApproval,
3894
+ authFlowState,
3895
+ finalizeAuthFlow: authFlowFinalizer.complete,
3896
+ identities,
3897
+ authHttp,
3898
+ loginApprovalPendingCookie,
3899
+ ...(Option.isSome(trustedDevice)
3900
+ ? { trustedDevice: trustedDevice.value }
3901
+ : {}),
3902
+ ...(Option.isSome(trustedDeviceCookie)
3903
+ ? { trustedDeviceCookie: trustedDeviceCookie.value }
3904
+ : {}),
3905
+ }),
3906
+ status: makeLoginApprovalStatusHandler(Option.isSome(loginApprovalReview)
3907
+ ? { loginApprovalReview: loginApprovalReview.value }
3908
+ : {}),
3909
+ finalize: makeLoginApprovalFinalizeHandler({
3910
+ authHttp,
3911
+ loginApprovalPendingCookie,
3912
+ ...(Option.isSome(loginApprovalFinalize)
3913
+ ? { loginApprovalFinalize: loginApprovalFinalize.value }
3914
+ : {}),
3915
+ ...(Option.isSome(trustedDevice)
3916
+ ? { trustedDevice: trustedDevice.value }
3917
+ : {}),
3918
+ ...(Option.isSome(trustedDeviceCookie)
3919
+ ? { trustedDeviceCookie: trustedDeviceCookie.value }
3920
+ : {}),
3921
+ }),
3922
+ });
3923
+ })).pipe(Layer.provide(AuthFlowFinalizerLive));
3924
+ export const ApiKeyHttpOperationsLive = Layer.effect(ApiKeyHttpOperations, Effect.gen(function* () {
3925
+ const apiKeyManagement = yield* ApiKeyManagement;
3926
+ const sessions = yield* Sessions;
3927
+ const sessionCookie = yield* SessionCookie;
3928
+ const dependencies = { apiKeyManagement, sessions, sessionCookie };
3929
+ return ApiKeyHttpOperations.of({
3930
+ create: makeApiKeyCreateHandler(dependencies),
3931
+ list: makeApiKeyListHandler(dependencies),
3932
+ revoke: makeApiKeyRevokeHandler(dependencies),
3933
+ });
3934
+ }));
3935
+ export const RefreshTokenHttpOperationsLive = Layer.effect(RefreshTokenHttpOperations, Effect.gen(function* () {
3936
+ const refreshTokenManagement = yield* RefreshTokenManagement;
3937
+ const jwtIssuer = yield* JwtIssuer;
3938
+ const config = yield* RefreshTokenHttpConfig;
3939
+ return RefreshTokenHttpOperations.of({
3940
+ refresh: makeRefreshTokenRefreshHandler({
3941
+ refreshTokenManagement,
3942
+ jwtIssuer,
3943
+ ...config,
3944
+ }),
3945
+ });
3946
+ }));
3947
+ export const JwtHttpOperationsLive = Layer.effect(JwtHttpOperations, Effect.gen(function* () {
3948
+ const jwtRevocation = yield* JwtRevocation;
3949
+ const config = yield* JwtHttpConfig;
3950
+ return JwtHttpOperations.of({
3951
+ introspect: makeJwtIntrospectHandler({ jwtRevocation, ...config }),
3952
+ revoke: makeJwtRevokeHandler({ jwtRevocation }),
3953
+ });
3954
+ }));
3955
+ export const JwtDiscoveryHttpOperationsLive = Layer.effect(JwtDiscoveryHttpOperations, Effect.gen(function* () {
3956
+ const jwks = yield* Jwks;
3957
+ return JwtDiscoveryHttpOperations.of({
3958
+ jwks: makeJwtJwksHandler({ jwks }),
3959
+ });
3960
+ }));
3961
+ export const OidcDiscoveryHttpOperationsLive = Layer.effect(OidcDiscoveryHttpOperations, Effect.gen(function* () {
3962
+ const metadata = yield* OidcDiscoveryMetadata;
3963
+ return OidcDiscoveryHttpOperations.of({
3964
+ openidConfiguration: makeOidcDiscoveryMetadataHandler({ metadata }),
3965
+ });
3966
+ }));
3967
+ export class AdminSessionHttpApiGroup extends HttpApiGroup.make("adminSession")
2614
3968
  .add(adminSessionListEndpoint, adminSessionRevokeEndpoint, adminSessionRevokeAllEndpoint)
2615
3969
  .prefix("/auth/admin/sessions")
2616
3970
  .middleware(AuthSchemaErrorMiddleware)
2617
3971
  .middleware(AuthOriginCheckMiddleware) {
2618
3972
  }
2619
- export class AdminSessionHttpApi extends HttpApi.make("AdminSessionHttpApi").add(AdminSessionApi) {
3973
+ export class AdminSessionHttpApi extends HttpApi.make("AdminSessionHttpApi").add(AdminSessionHttpApiGroup) {
2620
3974
  }
2621
- export class EmailVerificationApi extends HttpApiGroup.make("emailVerification")
2622
- .add(emailVerificationStartEndpoint.middleware(AuthRateLimitMiddleware), emailVerificationVerifyEndpoint)
2623
- .prefix("/auth/email-verification")
3975
+ export class AdminPermissionDefinitionHttpApiGroup extends HttpApiGroup.make("adminPermissionDefinition")
3976
+ .add(adminPermissionDefinitionCreateEndpoint, adminPermissionDefinitionGetEndpoint, adminPermissionDefinitionListEndpoint, adminPermissionDefinitionUpdateEndpoint, adminPermissionDefinitionDisableEndpoint, adminPermissionDefinitionEnableEndpoint, adminPermissionDefinitionDeleteEndpoint)
3977
+ .prefix("/auth/admin")
2624
3978
  .middleware(AuthSchemaErrorMiddleware)
2625
3979
  .middleware(AuthOriginCheckMiddleware) {
2626
3980
  }
2627
- export class EmailOtpApi extends HttpApiGroup.make("emailOtp")
2628
- .add(emailOtpStartEndpoint.middleware(AuthRateLimitMiddleware), emailOtpVerifyEndpoint.middleware(AuthRateLimitMiddleware))
2629
- .prefix("/auth/email-otp")
2630
- .middleware(AuthSchemaErrorMiddleware)
2631
- .middleware(AuthOriginCheckMiddleware) {
3981
+ export class AdminPermissionDefinitionHttpApi extends HttpApi.make("AdminPermissionDefinitionHttpApi").add(AdminPermissionDefinitionHttpApiGroup) {
2632
3982
  }
2633
- export class MagicLinkApi extends HttpApiGroup.make("magicLink")
2634
- .add(magicLinkStartEndpoint.middleware(AuthRateLimitMiddleware), magicLinkVerifyEndpoint.middleware(AuthRateLimitMiddleware))
2635
- .prefix("/auth/magic-link")
2636
- .middleware(AuthSchemaErrorMiddleware)
2637
- .middleware(AuthOriginCheckMiddleware) {
3983
+ export class EmailAuthHttpApi extends HttpApi.make("EmailAuthHttpApi").add(EmailAuthHttpApiGroup) {
3984
+ }
3985
+ export class PasskeyHttpApi extends HttpApi.make("PasskeyHttpApi").add(PasskeyHttpApiGroup) {
2638
3986
  }
2639
- export class OAuthApi extends HttpApiGroup.make("oauth")
3987
+ export class IdentityHttpApi extends HttpApi.make("IdentityHttpApi").add(IdentityHttpApiGroup) {
3988
+ }
3989
+ export class TotpHttpApi extends HttpApi.make("TotpHttpApi").add(TotpHttpApiGroup) {
3990
+ }
3991
+ export class RecoveryCodesHttpApi extends HttpApi.make("RecoveryCodesHttpApi").add(RecoveryCodesHttpApiGroup) {
3992
+ }
3993
+ export class OAuthHttpApiGroup extends HttpApiGroup.make("oauth")
2640
3994
  .add(oauthAuthorizationStartEndpoint, oauthAccountUnlinkEndpoint, oauthLinkConfirmationStartEndpoint, oauthLinkConfirmationInspectEndpoint, oauthLinkConfirmationConfirmEndpoint)
2641
3995
  .prefix("/auth/oauth")
2642
3996
  .middleware(AuthSchemaErrorMiddleware)
2643
3997
  .middleware(AuthOriginCheckMiddleware) {
2644
3998
  }
2645
- export class OAuthTokenApi extends HttpApiGroup.make("oauthToken")
2646
- .add(oauthTokenEndpoint, oauthTokenIntrospectionEndpoint, oauthTokenRevocationEndpoint)
3999
+ export class OAuthHttpApi extends HttpApi.make("OAuthHttpApi").add(OAuthHttpApiGroup) {
4000
+ }
4001
+ export class OAuthTokenHttpApiGroup extends HttpApiGroup.make("oauthToken")
4002
+ .add(oauthTokenEndpoint.middleware(OAuthNoStoreMiddleware))
2647
4003
  .prefix("/auth/oauth")
2648
4004
  .middleware(AuthSchemaErrorMiddleware) {
2649
4005
  }
2650
- export class OAuthTokenHttpApi extends HttpApi.make("OAuthTokenHttpApi").add(OAuthTokenApi) {
4006
+ export class OAuthTokenHttpApi extends HttpApi.make("OAuthTokenHttpApi").add(OAuthTokenHttpApiGroup) {
2651
4007
  }
2652
- export class OAuthProviderAuthorizationApi extends HttpApiGroup.make("oauthProviderAuthorization")
2653
- .add(oauthProviderAuthorizeEndpoint)
4008
+ export class OAuthTokenIntrospectionHttpApiGroup extends HttpApiGroup.make("oauthTokenIntrospection")
4009
+ .add(oauthTokenIntrospectionEndpoint)
2654
4010
  .prefix("/auth/oauth")
2655
4011
  .middleware(AuthSchemaErrorMiddleware) {
2656
4012
  }
2657
- export class OAuthProviderAuthorizationHttpApi extends HttpApi.make("OAuthProviderAuthorizationHttpApi").add(OAuthProviderAuthorizationApi) {
4013
+ export class OAuthTokenIntrospectionHttpApi extends HttpApi.make("OAuthTokenIntrospectionHttpApi").add(OAuthTokenIntrospectionHttpApiGroup) {
2658
4014
  }
2659
- export class LoginApprovalApi extends HttpApiGroup.make("loginApproval")
2660
- .add(loginApprovalApproveEndpoint, loginApprovalStatusEndpoint, loginApprovalFinalizeEndpoint)
2661
- .prefix("/auth/login-approval")
2662
- .middleware(AuthSchemaErrorMiddleware)
2663
- .middleware(AuthOriginCheckMiddleware) {
4015
+ export class OAuthTokenRevocationHttpApiGroup extends HttpApiGroup.make("oauthTokenRevocation")
4016
+ .add(oauthTokenRevocationEndpoint)
4017
+ .prefix("/auth/oauth")
4018
+ .middleware(AuthSchemaErrorMiddleware) {
2664
4019
  }
2665
- export class MfaApi extends HttpApiGroup.make("mfa")
2666
- .add(mfaOptionsEndpoint, totpMfaVerifyEndpoint, totpMfaVerifyForFlowEndpoint, recoveryCodeMfaVerifyEndpoint, recoveryCodeMfaVerifyForFlowEndpoint, passkeyMfaStartEndpoint, passkeyMfaVerifyEndpoint)
2667
- .prefix("/auth/mfa")
2668
- .middleware(AuthSchemaErrorMiddleware)
2669
- .middleware(AuthOriginCheckMiddleware) {
4020
+ export class OAuthTokenRevocationHttpApi extends HttpApi.make("OAuthTokenRevocationHttpApi").add(OAuthTokenRevocationHttpApiGroup) {
2670
4021
  }
2671
- export class StepUpApi extends HttpApiGroup.make("stepUp")
2672
- .add(stepUpOptionsEndpoint, stepUpTotpVerifyEndpoint, stepUpRecoveryCodeVerifyEndpoint, stepUpPasskeyStartEndpoint, stepUpPasskeyVerifyEndpoint)
2673
- .prefix("/auth/step-up")
2674
- .middleware(AuthSchemaErrorMiddleware)
2675
- .middleware(AuthOriginCheckMiddleware) {
4022
+ export class OAuthProviderAuthorizationHttpApiGroup extends HttpApiGroup.make("oauthProviderAuthorization")
4023
+ .add(oauthProviderAuthorizeEndpoint)
4024
+ .prefix("/auth/oauth")
4025
+ .middleware(AuthSchemaErrorMiddleware) {
4026
+ }
4027
+ export class OAuthProviderAuthorizationHttpApi extends HttpApi.make("OAuthProviderAuthorizationHttpApi").add(OAuthProviderAuthorizationHttpApiGroup) {
4028
+ }
4029
+ export class MfaHttpApi extends HttpApi.make("MfaHttpApi").add(MfaHttpApiGroup) {
4030
+ }
4031
+ export class StepUpHttpApi extends HttpApi.make("StepUpHttpApi").add(StepUpHttpApiGroup) {
2676
4032
  }
2677
- export class ApiKeyApi extends HttpApiGroup.make("apiKey")
4033
+ export class ApiKeyHttpApiGroup extends HttpApiGroup.make("apiKey")
2678
4034
  .add(apiKeyCreateEndpoint, apiKeyListEndpoint, apiKeyRevokeEndpoint)
2679
4035
  .prefix("/auth/api-keys")
2680
4036
  .middleware(AuthSchemaErrorMiddleware)
2681
4037
  .middleware(AuthOriginCheckMiddleware) {
2682
4038
  }
2683
- export class RefreshTokenApi extends HttpApiGroup.make("refreshToken")
4039
+ export class ApiKeyHttpApi extends HttpApi.make("ApiKeyHttpApi").add(ApiKeyHttpApiGroup) {
4040
+ }
4041
+ export class RefreshTokenHttpApiGroup extends HttpApiGroup.make("refreshToken")
2684
4042
  .add(refreshTokenRefreshEndpoint)
2685
4043
  .prefix("/auth/token")
2686
4044
  .middleware(AuthSchemaErrorMiddleware) {
2687
4045
  }
2688
- export class JwtApi extends HttpApiGroup.make("jwt")
4046
+ export class RefreshTokenHttpApi extends HttpApi.make("RefreshTokenHttpApi").add(RefreshTokenHttpApiGroup) {
4047
+ }
4048
+ export class JwtHttpApiGroup extends HttpApiGroup.make("jwt")
2689
4049
  .add(jwtIntrospectEndpoint, jwtRevokeEndpoint)
2690
4050
  .prefix("/auth/jwt")
2691
4051
  .middleware(AuthSchemaErrorMiddleware) {
2692
4052
  }
2693
- export class JwtDiscoveryApi extends HttpApiGroup.make("jwtDiscovery")
4053
+ export class JwtHttpApi extends HttpApi.make("JwtHttpApi").add(JwtHttpApiGroup) {
4054
+ }
4055
+ export class JwtDiscoveryHttpApiGroup extends HttpApiGroup.make("jwtDiscovery")
2694
4056
  .add(jwtJwksEndpoint)
2695
4057
  .prefix("/.well-known")
2696
4058
  .middleware(AuthSchemaErrorMiddleware) {
2697
4059
  }
2698
- export class JwtDiscoveryHttpApi extends HttpApi.make("JwtDiscoveryHttpApi").add(JwtDiscoveryApi) {
4060
+ export class JwtDiscoveryHttpApi extends HttpApi.make("JwtDiscoveryHttpApi").add(JwtDiscoveryHttpApiGroup) {
2699
4061
  }
2700
- export class OidcDiscoveryApi extends HttpApiGroup.make("oidcDiscovery")
4062
+ export class OidcDiscoveryHttpApiGroup extends HttpApiGroup.make("oidcDiscovery")
2701
4063
  .add(oidcDiscoveryMetadataEndpoint)
2702
4064
  .prefix("/.well-known")
2703
4065
  .middleware(AuthSchemaErrorMiddleware) {
2704
4066
  }
2705
- export class OidcDiscoveryHttpApi extends HttpApi.make("OidcDiscoveryHttpApi").add(OidcDiscoveryApi) {
2706
- }
2707
- export class SecurityApi extends HttpApiGroup.make("security")
2708
- .add(loginNotificationReportEndpoint)
2709
- .prefix("/auth/security")
2710
- .middleware(AuthSchemaErrorMiddleware)
2711
- .middleware(AuthOriginCheckMiddleware) {
4067
+ export class OidcDiscoveryHttpApi extends HttpApi.make("OidcDiscoveryHttpApi").add(OidcDiscoveryHttpApiGroup) {
2712
4068
  }
2713
- export class SecurityTimelineApi extends HttpApiGroup.make("securityTimeline")
4069
+ export class SecurityTimelineHttpApiGroup extends HttpApiGroup.make("securityTimeline")
2714
4070
  .add(securityTimelineListEndpoint)
2715
4071
  .prefix("/auth/security")
2716
4072
  .middleware(AuthSchemaErrorMiddleware)
2717
4073
  .middleware(AuthOriginCheckMiddleware) {
2718
4074
  }
2719
- export class SecurityTimelineHttpApi extends HttpApi.make("SecurityTimelineHttpApi")
2720
- .add(SecurityTimelineApi) {
4075
+ export class SecurityTimelineHttpApi extends HttpApi.make("SecurityTimelineHttpApi").add(SecurityTimelineHttpApiGroup) {
2721
4076
  }
2722
- export class AdminSecurityTimelineApi extends HttpApiGroup.make("adminSecurityTimeline")
4077
+ export class AdminSecurityTimelineHttpApiGroup extends HttpApiGroup.make("adminSecurityTimeline")
2723
4078
  .add(adminSecurityTimelineListEndpoint)
2724
4079
  .prefix("/auth/admin/security")
2725
4080
  .middleware(AuthSchemaErrorMiddleware)
2726
4081
  .middleware(AuthOriginCheckMiddleware) {
2727
4082
  }
2728
- export class AdminSecurityTimelineHttpApi extends HttpApi.make("AdminSecurityTimelineHttpApi").add(AdminSecurityTimelineApi) {
4083
+ export class AdminSecurityTimelineHttpApi extends HttpApi.make("AdminSecurityTimelineHttpApi").add(AdminSecurityTimelineHttpApiGroup) {
2729
4084
  }
2730
- export class TrustedDeviceApi extends HttpApiGroup.make("trustedDevice")
4085
+ export class TrustedDeviceHttpApiGroup extends HttpApiGroup.make("trustedDevice")
2731
4086
  .add(trustedDeviceListEndpoint, trustedDeviceRevokeEndpoint)
2732
4087
  .prefix("/auth/trusted-devices")
2733
4088
  .middleware(AuthSchemaErrorMiddleware)
2734
4089
  .middleware(AuthOriginCheckMiddleware) {
2735
4090
  }
2736
- export class TrustedDeviceHttpApi extends HttpApi.make("TrustedDeviceHttpApi")
2737
- .add(TrustedDeviceApi) {
4091
+ export class TrustedDeviceHttpApi extends HttpApi.make("TrustedDeviceHttpApi").add(TrustedDeviceHttpApiGroup) {
2738
4092
  }
2739
- export class AdminTrustedDeviceApi extends HttpApiGroup.make("adminTrustedDevice")
4093
+ export class AdminTrustedDeviceHttpApiGroup extends HttpApiGroup.make("adminTrustedDevice")
2740
4094
  .add(adminTrustedDeviceListEndpoint, adminTrustedDeviceRevokeEndpoint)
2741
4095
  .prefix("/auth/admin/trusted-devices")
2742
4096
  .middleware(AuthSchemaErrorMiddleware)
2743
4097
  .middleware(AuthOriginCheckMiddleware) {
2744
4098
  }
2745
- export class AdminTrustedDeviceHttpApi extends HttpApi.make("AdminTrustedDeviceHttpApi").add(AdminTrustedDeviceApi) {
4099
+ export class AdminTrustedDeviceHttpApi extends HttpApi.make("AdminTrustedDeviceHttpApi").add(AdminTrustedDeviceHttpApiGroup) {
2746
4100
  }
2747
- export class AuthApi extends HttpApi.make("AuthApi")
2748
- .add(PasswordApi)
2749
- .add(SessionApi)
2750
- .add(EmailVerificationApi)
2751
- .add(EmailOtpApi)
2752
- .add(MagicLinkApi)
2753
- .add(LoginApprovalApi)
2754
- .add(SecurityApi) {
4101
+ export class CoreAuthHttpApi extends HttpApi.make("AuthApi")
4102
+ .add(PasswordHttpApiGroup)
4103
+ .add(SessionHttpApiGroup)
4104
+ .add(EmailVerificationHttpApiGroup)
4105
+ .add(EmailOtpHttpApiGroup)
4106
+ .add(MagicLinkHttpApiGroup)
4107
+ .add(LoginApprovalHttpApiGroup)
4108
+ .add(LoginNotificationHttpApiGroup) {
2755
4109
  }
2756
- export const PasswordApiLive = HttpApiBuilder.group(AuthApi, "password", Effect.fn("auth.http.password.group")(function* (handlers) {
2757
- const password = yield* PasswordLogin;
2758
- const registration = yield* PasswordRegistration;
2759
- const passwordReset = yield* PasswordReset;
2760
- const passwordManagement = yield* PasswordManagement;
2761
- const authHttp = yield* AuthHttp;
2762
- const emailVerificationFlow = yield* EmailVerificationFlow;
2763
- const sessions = yield* Sessions;
2764
- const sessionCookie = yield* SessionCookie;
2765
- const authApiRateLimit = yield* AuthApiRateLimit;
2766
- const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
4110
+ export const CoreAuthPasswordGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "password", passwordGroupHandlers);
4111
+ export const CoreAuthSessionGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "session", Effect.fn("auth.http.session.group")(function* (handlers) {
4112
+ const operations = yield* SessionHttpOperations;
2767
4113
  return handlers
2768
- .handle("signIn", makePasswordSignInHandler({
2769
- password,
2770
- authHttp,
2771
- emailVerificationFlow,
2772
- authApiRateLimit,
2773
- ...(Option.isSome(trustedDeviceCookie)
2774
- ? { trustedDeviceCookie: trustedDeviceCookie.value }
2775
- : {}),
2776
- }))
2777
- .handle("signUp", makePasswordSignUpHandler({
2778
- registration,
2779
- authHttp,
2780
- emailVerificationFlow,
2781
- authApiRateLimit,
2782
- }))
2783
- .handle("resetStart", makePasswordResetStartHandler({
2784
- passwordReset,
2785
- authApiRateLimit,
2786
- }))
2787
- .handle("resetVerify", makePasswordResetVerifyHandler({
2788
- passwordReset,
2789
- }))
2790
- .handle("set", makePasswordSetHandler({
2791
- passwordManagement,
2792
- sessions,
2793
- sessionCookie,
2794
- }))
2795
- .handle("change", makePasswordChangeHandler({
2796
- passwordManagement,
2797
- sessions,
2798
- sessionCookie,
2799
- }));
4114
+ .handle("current", operations.current)
4115
+ .handle("refresh", operations.refresh)
4116
+ .handle("logout", operations.logout)
4117
+ .handle("list", operations.list)
4118
+ .handle("revoke", operations.revoke)
4119
+ .handle("revokeOthers", operations.revokeOthers);
2800
4120
  }));
2801
- export const SessionApiLive = HttpApiBuilder.group(AuthApi, "session", Effect.fn("auth.http.session.group")(function* (handlers) {
2802
- const sessions = yield* Sessions;
2803
- const sessionCookie = yield* SessionCookie;
2804
- const authHttp = yield* AuthHttp;
4121
+ export const CoreAuthEmailVerificationGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "emailVerification", Effect.fn("auth.http.email_verification.group")(function* (handlers) {
4122
+ const operations = yield* EmailVerificationHttpOperations;
2805
4123
  return handlers
2806
- .handle("current", makeCurrentSessionHandler({ sessions, sessionCookie, authHttp }))
2807
- .handle("refresh", makeRefreshSessionHandler({ sessions, sessionCookie, authHttp }))
2808
- .handle("logout", makeLogoutHandler({ sessions, sessionCookie, authHttp }))
2809
- .handle("list", makeListSessionsHandler({ sessions, sessionCookie }))
2810
- .handle("revoke", makeRevokeSessionHandler({ sessions, sessionCookie, authHttp }))
2811
- .handle("revokeOthers", makeRevokeOtherSessionsHandler({ sessions, sessionCookie }));
4124
+ .handle("start", operations.start)
4125
+ .handle("verify", operations.verify);
2812
4126
  }));
2813
- export const AdminSessionApiLive = HttpApiBuilder.group(AdminSessionHttpApi, "adminSession", Effect.fn("auth.http.admin_session.group")(function* (handlers) {
2814
- const sessions = yield* Sessions;
2815
- const sessionCookie = yield* SessionCookie;
2816
- const authorization = yield* AdminSessionAuthorization;
4127
+ export const CoreAuthEmailOtpGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "emailOtp", Effect.fn("auth.http.email_otp.group")(function* (handlers) {
4128
+ const operations = yield* EmailOtpHttpOperations;
2817
4129
  return handlers
2818
- .handle("list", makeAdminSessionListHandler({ sessions, sessionCookie, authorization }))
2819
- .handle("revoke", makeAdminSessionRevokeHandler({ sessions, sessionCookie, authorization }))
2820
- .handle("revokeAll", makeAdminSessionRevokeAllHandler({
2821
- sessions,
2822
- sessionCookie,
2823
- authorization,
2824
- }));
4130
+ .handle("start", operations.start)
4131
+ .handle("verify", operations.verify);
2825
4132
  }));
2826
- export const AdminSessionHttpApiLive = HttpApiBuilder.layer(AdminSessionHttpApi).pipe(Layer.provide(AdminSessionApiLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2827
- export const EmailVerificationApiLive = HttpApiBuilder.group(AuthApi, "emailVerification", Effect.fn("auth.http.email_verification.group")(function* (handlers) {
2828
- const emailVerificationFlow = yield* EmailVerificationFlow;
2829
- const emailVerification = yield* EmailVerification;
2830
- const sessions = yield* Sessions;
2831
- const sessionCookie = yield* SessionCookie;
2832
- const authApiRateLimit = yield* AuthApiRateLimit;
4133
+ export const EmailAuthHttpApiGroupLive = HttpApiBuilder.group(EmailAuthHttpApi, "emailAuth", Effect.fn("auth.http.email.group")(function* (handlers) {
4134
+ const operations = yield* EmailAuthHttpOperations;
4135
+ return handlers.handle("start", operations.start);
4136
+ }));
4137
+ export const CoreAuthMagicLinkGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "magicLink", Effect.fn("auth.http.magic_link.group")(function* (handlers) {
4138
+ const operations = yield* MagicLinkHttpOperations;
2833
4139
  return handlers
2834
- .handle("start", makeEmailVerificationStartHandler({
2835
- emailVerificationFlow,
2836
- authApiRateLimit,
2837
- }))
2838
- .handle("verify", makeEmailVerificationVerifyHandler({
2839
- emailVerification,
2840
- sessions,
2841
- sessionCookie,
2842
- }));
4140
+ .handle("start", operations.start)
4141
+ .handle("verify", operations.verify);
2843
4142
  }));
2844
- export const EmailOtpApiLive = HttpApiBuilder.group(AuthApi, "emailOtp", Effect.fn("auth.http.email_otp.group")(function* (handlers) {
2845
- const emailOtp = yield* EmailOtpLogin;
2846
- const authHttp = yield* AuthHttp;
2847
- const authApiRateLimit = yield* AuthApiRateLimit;
2848
- const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
4143
+ export const PasskeyHttpApiGroupLive = HttpApiBuilder.group(PasskeyHttpApi, "passkey", Effect.fn("auth.http.passkey.group")(function* (handlers) {
4144
+ const operations = yield* PasskeyHttpOperations;
2849
4145
  return handlers
2850
- .handle("start", makeEmailOtpStartHandler({ emailOtp, authApiRateLimit }))
2851
- .handle("verify", makeEmailOtpVerifyHandler({
2852
- emailOtp,
2853
- authHttp,
2854
- ...(Option.isSome(trustedDeviceCookie)
2855
- ? { trustedDeviceCookie: trustedDeviceCookie.value }
2856
- : {}),
2857
- }));
4146
+ .handle("registerStart", operations.registerStart)
4147
+ .handle("registerFinish", operations.registerFinish)
4148
+ .handle("authenticateStart", operations.authenticateStart)
4149
+ .handle("authenticateFinish", operations.authenticateFinish)
4150
+ .handle("listCredentials", operations.listCredentials)
4151
+ .handle("revokeCredential", operations.revokeCredential);
2858
4152
  }));
2859
- export const MagicLinkApiLive = HttpApiBuilder.group(AuthApi, "magicLink", Effect.fn("auth.http.magic_link.group")(function* (handlers) {
2860
- const magicLink = yield* MagicLinkLogin;
2861
- const authHttp = yield* AuthHttp;
2862
- const authApiRateLimit = yield* AuthApiRateLimit;
2863
- const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
4153
+ export const IdentityHttpApiGroupLive = HttpApiBuilder.group(IdentityHttpApi, "identity", Effect.fn("auth.http.identity.group")(function* (handlers) {
4154
+ const operations = yield* IdentityHttpOperations;
2864
4155
  return handlers
2865
- .handle("start", makeMagicLinkStartHandler({ magicLink, authApiRateLimit }))
2866
- .handle("verify", makeMagicLinkVerifyHandler({
2867
- magicLink,
2868
- authHttp,
2869
- ...(Option.isSome(trustedDeviceCookie)
2870
- ? { trustedDeviceCookie: trustedDeviceCookie.value }
2871
- : {}),
2872
- }));
4156
+ .handle("availability", operations.availability)
4157
+ .handle("list", operations.list)
4158
+ .handle("add", operations.add)
4159
+ .handle("replace", operations.replace)
4160
+ .handle("revoke", operations.revoke)
4161
+ .handle("primary", operations.primary);
2873
4162
  }));
2874
- export const LoginApprovalApiLive = HttpApiBuilder.group(AuthApi, "loginApproval", Effect.fn("auth.http.login_approval.group")(function* (handlers) {
2875
- const loginApproval = yield* LoginApproval;
2876
- const authFlowState = yield* AuthFlowState;
2877
- const authFlow = yield* AuthFlow;
2878
- const users = yield* UserStore;
2879
- const authHttp = yield* AuthHttp;
2880
- const loginApprovalReview = yield* Effect.serviceOption(LoginApprovalReview);
2881
- const loginApprovalFinalize = yield* Effect.serviceOption(LoginApprovalFinalize);
2882
- const pendingCookieOption = yield* Effect.serviceOption(LoginApprovalPendingCookie);
2883
- const trustedDevice = yield* Effect.serviceOption(TrustedDevice);
2884
- const trustedDeviceCookie = yield* Effect.serviceOption(TrustedDeviceCookie);
2885
- const loginApprovalPendingCookie = Option.isSome(pendingCookieOption)
2886
- ? pendingCookieOption.value
2887
- : makeLoginApprovalPendingCookie();
4163
+ export const TotpHttpApiGroupLive = HttpApiBuilder.group(TotpHttpApi, "totp", Effect.fn("auth.http.totp.group")(function* (handlers) {
4164
+ const operations = yield* TotpHttpOperations;
2888
4165
  return handlers
2889
- .handle("approve", makeLoginApprovalApproveHandler({
2890
- loginApproval,
2891
- authFlowState,
2892
- authFlow,
2893
- users,
2894
- authHttp,
2895
- loginApprovalPendingCookie,
2896
- ...(Option.isSome(trustedDevice)
2897
- ? { trustedDevice: trustedDevice.value }
2898
- : {}),
2899
- ...(Option.isSome(trustedDeviceCookie)
2900
- ? { trustedDeviceCookie: trustedDeviceCookie.value }
2901
- : {}),
2902
- }))
2903
- .handle("status", makeLoginApprovalStatusHandler(Option.isSome(loginApprovalReview)
2904
- ? { loginApprovalReview: loginApprovalReview.value }
2905
- : {}))
2906
- .handle("finalize", makeLoginApprovalFinalizeHandler({
2907
- authHttp,
2908
- loginApprovalPendingCookie,
2909
- ...(Option.isSome(loginApprovalFinalize)
2910
- ? { loginApprovalFinalize: loginApprovalFinalize.value }
2911
- : {}),
2912
- ...(Option.isSome(trustedDevice)
2913
- ? { trustedDevice: trustedDevice.value }
2914
- : {}),
2915
- ...(Option.isSome(trustedDeviceCookie)
2916
- ? { trustedDeviceCookie: trustedDeviceCookie.value }
2917
- : {}),
2918
- }));
4166
+ .handle("startEnrollment", operations.startEnrollment)
4167
+ .handle("confirmEnrollment", operations.confirmEnrollment)
4168
+ .handle("verify", operations.verify)
4169
+ .handle("listFactors", operations.listFactors)
4170
+ .handle("revokeFactor", operations.revokeFactor);
2919
4171
  }));
2920
- export const SecurityApiLive = HttpApiBuilder.group(AuthApi, "security", Effect.fn("auth.http.security.group")(function* (handlers) {
2921
- const loginNotification = yield* Effect.serviceOption(LoginNotification);
2922
- return handlers.handle("reportLogin", makeLoginNotificationReportHandler(Option.isSome(loginNotification)
2923
- ? { loginNotification: loginNotification.value }
2924
- : {}));
4172
+ export const RecoveryCodesHttpApiGroupLive = HttpApiBuilder.group(RecoveryCodesHttpApi, "recoveryCodes", Effect.fn("auth.http.recovery_codes.group")(function* (handlers) {
4173
+ const operations = yield* RecoveryCodesHttpOperations;
4174
+ return handlers
4175
+ .handle("generateRecoveryCodes", operations.generate)
4176
+ .handle("regenerateRecoveryCodes", operations.regenerate)
4177
+ .handle("verifyRecoveryCode", operations.verify)
4178
+ .handle("listRecoveryCodes", operations.list)
4179
+ .handle("revokeRecoveryCode", operations.revoke);
2925
4180
  }));
2926
- export const SecurityTimelineApiLive = HttpApiBuilder.group(SecurityTimelineHttpApi, "securityTimeline", Effect.fn("auth.http.security_timeline.group")(function* (handlers) {
2927
- const sessions = yield* Sessions;
2928
- const sessionCookie = yield* SessionCookie;
2929
- const securityTimeline = yield* SecurityTimelineStore;
2930
- return handlers.handle("list", makeSecurityTimelineListHandler({
2931
- sessions,
2932
- sessionCookie,
2933
- securityTimeline,
2934
- }));
4181
+ export const MfaHttpApiGroupLive = HttpApiBuilder.group(MfaHttpApi, "mfa", Effect.fn("auth.http.mfa.group")(function* (handlers) {
4182
+ const operations = yield* MfaHttpOperations;
4183
+ return handlers
4184
+ .handle("options", operations.options)
4185
+ .handle("verifyTotp", operations.verifyTotp)
4186
+ .handle("verifyTotpForFlow", operations.verifyTotpForFlow)
4187
+ .handle("verifyRecoveryCode", operations.verifyRecoveryCode)
4188
+ .handle("verifyRecoveryCodeForFlow", operations.verifyRecoveryCodeForFlow)
4189
+ .handle("startPasskey", operations.startPasskey)
4190
+ .handle("verifyPasskey", operations.verifyPasskey);
2935
4191
  }));
2936
- export const SecurityTimelineHttpApiLive = HttpApiBuilder.layer(SecurityTimelineHttpApi).pipe(Layer.provide(SecurityTimelineApiLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2937
- export const OAuthProviderAuthorizationApiLive = HttpApiBuilder.group(OAuthProviderAuthorizationHttpApi, "oauthProviderAuthorization", Effect.fn("auth.http.oauth_provider_authorization.group")(function* (handlers) {
2938
- const authorization = yield* OAuthProviderAuthorization;
2939
- return handlers.handle("authorize", makeOAuthProviderAuthorizationHandler({ authorization }));
4192
+ export const StepUpHttpApiGroupLive = HttpApiBuilder.group(StepUpHttpApi, "stepUp", Effect.fn("auth.http.step_up.group")(function* (handlers) {
4193
+ const operations = yield* StepUpHttpOperations;
4194
+ return handlers
4195
+ .handle("options", operations.options)
4196
+ .handle("verifyTotp", operations.verifyTotp)
4197
+ .handle("verifyPassword", operations.verifyPassword)
4198
+ .handle("verifyRecoveryCode", operations.verifyRecoveryCode)
4199
+ .handle("startPasskey", operations.startPasskey)
4200
+ .handle("verifyPasskey", operations.verifyPasskey);
2940
4201
  }));
2941
- export const OAuthProviderAuthorizationHttpApiLive = HttpApiBuilder.layer(OAuthProviderAuthorizationHttpApi).pipe(Layer.provide(OAuthProviderAuthorizationApiLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2942
- export const OAuthTokenApiLive = HttpApiBuilder.group(OAuthTokenHttpApi, "oauthToken", Effect.fn("auth.http.oauth_token.group")(function* (handlers) {
2943
- const tokenGrant = yield* OAuthAuthorizationCodeTokenGrant;
2944
- const refreshTokenGrant = yield* Effect.serviceOption(OAuthRefreshTokenGrant);
2945
- const clientCredentialsGrant = yield* Effect.serviceOption(OAuthClientCredentialsGrant);
2946
- const tokenIntrospection = yield* Effect.serviceOption(OAuthTokenIntrospection);
2947
- const tokenRevocation = yield* Effect.serviceOption(OAuthTokenRevocation);
4202
+ export const OAuthHttpApiGroupLive = HttpApiBuilder.group(OAuthHttpApi, "oauth", Effect.fn("auth.http.oauth.group")(function* (handlers) {
4203
+ const operations = yield* OAuthHttpOperations;
2948
4204
  return handlers
2949
- .handle("token", makeOAuthAuthorizationCodeTokenHandler({
2950
- tokenGrant,
2951
- ...(Option.isNone(refreshTokenGrant)
2952
- ? {}
2953
- : { refreshTokenGrant: refreshTokenGrant.value }),
2954
- ...(Option.isNone(clientCredentialsGrant)
2955
- ? {}
2956
- : { clientCredentialsGrant: clientCredentialsGrant.value }),
2957
- }))
2958
- .handle("introspect", Option.isNone(tokenIntrospection)
2959
- ? makeOAuthTokenIntrospectionNotConfiguredHandler()
2960
- : makeOAuthTokenIntrospectionHandler({
2961
- tokenIntrospection: tokenIntrospection.value,
2962
- }))
2963
- .handle("revoke", Option.isNone(tokenRevocation)
2964
- ? makeOAuthTokenRevocationNotConfiguredHandler()
2965
- : makeOAuthTokenRevocationHandler({
2966
- tokenRevocation: tokenRevocation.value,
2967
- }));
4205
+ .handle("startAuthorization", operations.authorizationStart)
4206
+ .handle("unlinkAccount", operations.accountUnlink)
4207
+ .handle("startLinkConfirmation", operations.linkConfirmationStart)
4208
+ .handle("inspectLinkConfirmation", operations.linkConfirmationInspect)
4209
+ .handle("confirmLinkConfirmation", operations.linkConfirmationConfirm);
2968
4210
  }));
2969
- export const OAuthTokenHttpApiLive = HttpApiBuilder.layer(OAuthTokenHttpApi).pipe(Layer.provide(OAuthTokenApiLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2970
- export const JwtDiscoveryApiLive = HttpApiBuilder.group(JwtDiscoveryHttpApi, "jwtDiscovery", Effect.fn("auth.http.jwt_discovery.group")(function* (handlers) {
2971
- const jwks = yield* Jwks;
2972
- return handlers.handle("jwks", makeJwtJwksHandler({ jwks }));
4211
+ export const OAuthHttpApiLive = HttpApiBuilder.layer(OAuthHttpApi).pipe(Layer.provide(OAuthHttpApiGroupLive), Layer.provide(OAuthHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4212
+ export const ApiKeyHttpApiGroupLive = HttpApiBuilder.group(ApiKeyHttpApi, "apiKey", Effect.fn("auth.http.api_key.group")(function* (handlers) {
4213
+ const operations = yield* ApiKeyHttpOperations;
4214
+ return handlers
4215
+ .handle("createApiKey", operations.create)
4216
+ .handle("listApiKeys", operations.list)
4217
+ .handle("revokeApiKey", operations.revoke);
2973
4218
  }));
2974
- export const JwtDiscoveryHttpApiLive = HttpApiBuilder.layer(JwtDiscoveryHttpApi).pipe(Layer.provide(JwtDiscoveryApiLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2975
- export const OidcDiscoveryApiLive = HttpApiBuilder.group(OidcDiscoveryHttpApi, "oidcDiscovery", Effect.fn("auth.http.oidc_discovery.group")(function* (handlers) {
2976
- const metadata = yield* OidcDiscoveryMetadata;
2977
- return handlers.handle("openidConfiguration", makeOidcDiscoveryMetadataHandler({ metadata }));
4219
+ export const ApiKeyHttpApiLive = HttpApiBuilder.layer(ApiKeyHttpApi).pipe(Layer.provide(ApiKeyHttpApiGroupLive), Layer.provide(ApiKeyHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4220
+ export const RefreshTokenHttpApiGroupLive = HttpApiBuilder.group(RefreshTokenHttpApi, "refreshToken", Effect.fn("auth.http.refresh_token.group")(function* (handlers) {
4221
+ const operations = yield* RefreshTokenHttpOperations;
4222
+ return handlers.handle("refresh", operations.refresh);
2978
4223
  }));
2979
- export const OidcDiscoveryHttpApiLive = HttpApiBuilder.layer(OidcDiscoveryHttpApi).pipe(Layer.provide(OidcDiscoveryApiLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2980
- export const AdminSecurityTimelineApiLive = HttpApiBuilder.group(AdminSecurityTimelineHttpApi, "adminSecurityTimeline", Effect.fn("auth.http.admin_security_timeline.group")(function* (handlers) {
2981
- const sessions = yield* Sessions;
2982
- const sessionCookie = yield* SessionCookie;
2983
- const securityTimeline = yield* SecurityTimelineStore;
2984
- const authorization = yield* AdminSecurityTimelineAuthorization;
2985
- return handlers.handle("list", makeAdminSecurityTimelineListHandler({
2986
- sessions,
2987
- sessionCookie,
2988
- securityTimeline,
2989
- authorization,
2990
- }));
4224
+ export const RefreshTokenHttpApiLive = HttpApiBuilder.layer(RefreshTokenHttpApi).pipe(Layer.provide(RefreshTokenHttpApiGroupLive), Layer.provide(RefreshTokenHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4225
+ export const JwtHttpApiGroupLive = HttpApiBuilder.group(JwtHttpApi, "jwt", Effect.fn("auth.http.jwt.group")(function* (handlers) {
4226
+ const operations = yield* JwtHttpOperations;
4227
+ return handlers
4228
+ .handle("introspect", operations.introspect)
4229
+ .handle("revoke", operations.revoke);
2991
4230
  }));
2992
- export const AdminSecurityTimelineHttpApiLive = HttpApiBuilder.layer(AdminSecurityTimelineHttpApi).pipe(Layer.provide(AdminSecurityTimelineApiLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
2993
- export const TrustedDeviceApiLive = HttpApiBuilder.group(TrustedDeviceHttpApi, "trustedDevice", Effect.fn("auth.http.trusted_device.group")(function* (handlers) {
2994
- const sessions = yield* Sessions;
2995
- const sessionCookie = yield* SessionCookie;
2996
- const trustedDevices = yield* TrustedDeviceStore;
4231
+ export const JwtHttpApiLive = HttpApiBuilder.layer(JwtHttpApi).pipe(Layer.provide(JwtHttpApiGroupLive), Layer.provide(JwtHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4232
+ export const AdminSessionHttpApiGroupLive = HttpApiBuilder.group(AdminSessionHttpApi, "adminSession", Effect.fn("auth.http.admin_session.group")(function* (handlers) {
4233
+ const operations = yield* AdminSessionHttpOperations;
2997
4234
  return handlers
2998
- .handle("list", makeTrustedDeviceListHandler({ sessions, sessionCookie, trustedDevices }))
2999
- .handle("revoke", makeTrustedDeviceRevokeHandler({ sessions, sessionCookie, trustedDevices }));
4235
+ .handle("list", operations.list)
4236
+ .handle("revoke", operations.revoke)
4237
+ .handle("revokeAll", operations.revokeAll);
3000
4238
  }));
3001
- export const TrustedDeviceHttpApiLive = HttpApiBuilder.layer(TrustedDeviceHttpApi).pipe(Layer.provide(TrustedDeviceApiLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
3002
- export const AdminTrustedDeviceApiLive = HttpApiBuilder.group(AdminTrustedDeviceHttpApi, "adminTrustedDevice", Effect.fn("auth.http.admin_trusted_device.group")(function* (handlers) {
3003
- const sessions = yield* Sessions;
3004
- const sessionCookie = yield* SessionCookie;
3005
- const trustedDevices = yield* TrustedDeviceStore;
3006
- const authorization = yield* AdminTrustedDeviceAuthorization;
4239
+ export const AdminSessionHttpApiLive = HttpApiBuilder.layer(AdminSessionHttpApi).pipe(Layer.provide(AdminSessionHttpApiGroupLive), Layer.provide(AdminSessionHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4240
+ export const AdminPermissionDefinitionHttpApiGroupLive = HttpApiBuilder.group(AdminPermissionDefinitionHttpApi, "adminPermissionDefinition", Effect.fn("auth.http.admin_permission_definition.group")(function* (handlers) {
4241
+ const operations = yield* AdminPermissionDefinitionHttpOperations;
4242
+ // The standalone API installs a router middleware that provides these
4243
+ // operation requirements for every request.
4244
+ const create = operations.create;
4245
+ const get = operations.get;
4246
+ const list = operations.list;
4247
+ const update = operations.update;
4248
+ const disable = operations.disable;
4249
+ const enable = operations.enable;
4250
+ const remove = operations.delete;
3007
4251
  return handlers
3008
- .handle("list", makeAdminTrustedDeviceListHandler({
3009
- sessions,
3010
- sessionCookie,
3011
- trustedDevices,
3012
- authorization,
3013
- }))
3014
- .handle("revoke", makeAdminTrustedDeviceRevokeHandler({
3015
- sessions,
3016
- sessionCookie,
3017
- trustedDevices,
3018
- authorization,
3019
- }));
4252
+ .handle("create", create)
4253
+ .handle("get", get)
4254
+ .handle("list", list)
4255
+ .handle("update", update)
4256
+ .handle("disable", disable)
4257
+ .handle("enable", enable)
4258
+ .handle("delete", remove);
4259
+ }));
4260
+ export const AdminPermissionDefinitionHttpRequirementsLive = HttpRouter.middleware()(Effect.gen(function* () {
4261
+ const context = yield* Effect.context();
4262
+ return (httpEffect) => httpEffect.pipe(Effect.provide(context));
4263
+ }), { global: true });
4264
+ export const AdminPermissionDefinitionHttpApiLive = Layer.merge(HttpApiBuilder.layer(AdminPermissionDefinitionHttpApi).pipe(Layer.provide(AdminPermissionDefinitionHttpApiGroupLive), Layer.provide(AdminPermissionDefinitionHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive)), AdminPermissionDefinitionHttpRequirementsLive);
4265
+ export const EmailAuthHttpApiLive = HttpApiBuilder.layer(EmailAuthHttpApi).pipe(Layer.provide(EmailAuthHttpApiGroupLive), Layer.provide(EmailAuthHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4266
+ export const PasskeyHttpApiLive = HttpApiBuilder.layer(PasskeyHttpApi).pipe(Layer.provide(PasskeyHttpApiGroupLive), Layer.provide(PasskeyHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4267
+ export const IdentityHttpApiLive = HttpApiBuilder.layer(IdentityHttpApi).pipe(Layer.provide(IdentityHttpApiGroupLive), Layer.provide(IdentityHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4268
+ export const TotpHttpApiLive = HttpApiBuilder.layer(TotpHttpApi).pipe(Layer.provide(TotpHttpApiGroupLive), Layer.provide(TotpHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4269
+ export const RecoveryCodesHttpApiLive = HttpApiBuilder.layer(RecoveryCodesHttpApi).pipe(Layer.provide(RecoveryCodesHttpApiGroupLive), Layer.provide(RecoveryCodesHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4270
+ export const MfaHttpApiLive = HttpApiBuilder.layer(MfaHttpApi).pipe(Layer.provide(MfaHttpApiGroupLive), Layer.provide(MfaHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4271
+ export const StepUpHttpApiLive = HttpApiBuilder.layer(StepUpHttpApi).pipe(Layer.provide(StepUpHttpApiGroupLive), Layer.provide(StepUpHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4272
+ export const CoreAuthLoginApprovalGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "loginApproval", Effect.fn("auth.http.login_approval.group")(function* (handlers) {
4273
+ const operations = yield* LoginApprovalHttpOperations;
4274
+ return handlers
4275
+ .handle("approve", operations.approve)
4276
+ .handle("status", operations.status)
4277
+ .handle("finalize", operations.finalize);
4278
+ }));
4279
+ export const CoreAuthLoginNotificationGroupLive = HttpApiBuilder.group(CoreAuthHttpApi, "security", Effect.fn("auth.http.security.group")(function* (handlers) {
4280
+ const operations = yield* LoginNotificationHttpOperations;
4281
+ return handlers.handle("reportLogin", operations.reportLogin);
4282
+ }));
4283
+ export const SecurityTimelineHttpApiGroupLive = HttpApiBuilder.group(SecurityTimelineHttpApi, "securityTimeline", Effect.fn("auth.http.security_timeline.group")(function* (handlers) {
4284
+ const operations = yield* SecurityTimelineHttpOperations;
4285
+ return handlers.handle("list", operations.list);
4286
+ }));
4287
+ export const SecurityTimelineHttpApiLive = HttpApiBuilder.layer(SecurityTimelineHttpApi).pipe(Layer.provide(SecurityTimelineHttpApiGroupLive), Layer.provide(SecurityTimelineHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4288
+ export const OAuthProviderAuthorizationHttpApiGroupLive = HttpApiBuilder.group(OAuthProviderAuthorizationHttpApi, "oauthProviderAuthorization", Effect.fn("auth.http.oauth_provider_authorization.group")(function* (handlers) {
4289
+ const operations = yield* OAuthProviderAuthorizationHttpOperations;
4290
+ return handlers.handle("authorize", operations.authorize);
4291
+ }));
4292
+ export const OAuthProviderAuthorizationHttpApiLive = HttpApiBuilder.layer(OAuthProviderAuthorizationHttpApi).pipe(Layer.provide(OAuthProviderAuthorizationHttpApiGroupLive), Layer.provide(OAuthProviderAuthorizationHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4293
+ export const OAuthTokenHttpApiGroupLive = HttpApiBuilder.group(OAuthTokenHttpApi, "oauthToken", Effect.fn("auth.http.oauth_token.group")(function* (handlers) {
4294
+ const operations = yield* OAuthTokenHttpOperations;
4295
+ return handlers.handle("token", operations.token);
4296
+ }));
4297
+ export const OAuthTokenHttpApiLive = HttpApiBuilder.layer(OAuthTokenHttpApi).pipe(Layer.provide(OAuthTokenHttpApiGroupLive), Layer.provide(OAuthTokenHttpOperationsLive), Layer.provide(OAuthNoStoreMiddlewareLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4298
+ export const OAuthTokenIntrospectionHttpApiGroupLive = HttpApiBuilder.group(OAuthTokenIntrospectionHttpApi, "oauthTokenIntrospection", Effect.fn("auth.http.oauth_token_introspection.group")(function* (handlers) {
4299
+ const operations = yield* OAuthTokenIntrospectionHttpOperations;
4300
+ return handlers.handle("introspect", operations.introspect);
4301
+ }));
4302
+ export const OAuthTokenIntrospectionHttpApiLive = HttpApiBuilder.layer(OAuthTokenIntrospectionHttpApi).pipe(Layer.provide(OAuthTokenIntrospectionHttpApiGroupLive), Layer.provide(OAuthTokenIntrospectionHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4303
+ export const OAuthTokenRevocationHttpApiGroupLive = HttpApiBuilder.group(OAuthTokenRevocationHttpApi, "oauthTokenRevocation", Effect.fn("auth.http.oauth_token_revocation.group")(function* (handlers) {
4304
+ const operations = yield* OAuthTokenRevocationHttpOperations;
4305
+ return handlers.handle("revoke", operations.revoke);
4306
+ }));
4307
+ export const OAuthTokenRevocationHttpApiLive = HttpApiBuilder.layer(OAuthTokenRevocationHttpApi).pipe(Layer.provide(OAuthTokenRevocationHttpApiGroupLive), Layer.provide(OAuthTokenRevocationHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4308
+ export const JwtDiscoveryHttpApiGroupLive = HttpApiBuilder.group(JwtDiscoveryHttpApi, "jwtDiscovery", Effect.fn("auth.http.jwt_discovery.group")(function* (handlers) {
4309
+ const operations = yield* JwtDiscoveryHttpOperations;
4310
+ return handlers.handle("jwks", operations.jwks);
4311
+ }));
4312
+ export const JwtDiscoveryHttpApiLive = HttpApiBuilder.layer(JwtDiscoveryHttpApi).pipe(Layer.provide(JwtDiscoveryHttpApiGroupLive), Layer.provide(JwtDiscoveryHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4313
+ export const OidcDiscoveryHttpApiGroupLive = HttpApiBuilder.group(OidcDiscoveryHttpApi, "oidcDiscovery", Effect.fn("auth.http.oidc_discovery.group")(function* (handlers) {
4314
+ const operations = yield* OidcDiscoveryHttpOperations;
4315
+ return handlers.handle("openidConfiguration", operations.openidConfiguration);
4316
+ }));
4317
+ export const OidcDiscoveryHttpApiLive = HttpApiBuilder.layer(OidcDiscoveryHttpApi).pipe(Layer.provide(OidcDiscoveryHttpApiGroupLive), Layer.provide(OidcDiscoveryHttpOperationsLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4318
+ export const AdminSecurityTimelineHttpApiGroupLive = HttpApiBuilder.group(AdminSecurityTimelineHttpApi, "adminSecurityTimeline", Effect.fn("auth.http.admin_security_timeline.group")(function* (handlers) {
4319
+ const operations = yield* AdminSecurityTimelineHttpOperations;
4320
+ return handlers.handle("list", operations.list);
4321
+ }));
4322
+ export const AdminSecurityTimelineHttpApiLive = HttpApiBuilder.layer(AdminSecurityTimelineHttpApi).pipe(Layer.provide(AdminSecurityTimelineHttpApiGroupLive), Layer.provide(AdminSecurityTimelineHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4323
+ export const TrustedDeviceHttpApiGroupLive = HttpApiBuilder.group(TrustedDeviceHttpApi, "trustedDevice", Effect.fn("auth.http.trusted_device.group")(function* (handlers) {
4324
+ const operations = yield* TrustedDeviceHttpOperations;
4325
+ return handlers
4326
+ .handle("list", operations.list)
4327
+ .handle("revoke", operations.revoke);
4328
+ }));
4329
+ export const TrustedDeviceHttpApiLive = HttpApiBuilder.layer(TrustedDeviceHttpApi).pipe(Layer.provide(TrustedDeviceHttpApiGroupLive), Layer.provide(TrustedDeviceHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4330
+ export const AdminTrustedDeviceHttpApiGroupLive = HttpApiBuilder.group(AdminTrustedDeviceHttpApi, "adminTrustedDevice", Effect.fn("auth.http.admin_trusted_device.group")(function* (handlers) {
4331
+ const operations = yield* AdminTrustedDeviceHttpOperations;
4332
+ return handlers
4333
+ .handle("list", operations.list)
4334
+ .handle("revoke", operations.revoke);
3020
4335
  }));
3021
- export const AdminTrustedDeviceHttpApiLive = HttpApiBuilder.layer(AdminTrustedDeviceHttpApi).pipe(Layer.provide(AdminTrustedDeviceApiLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
3022
- const AuthHttpApiBaseLive = HttpApiBuilder.layer(AuthApi).pipe(Layer.provide(PasswordApiLive), Layer.provide(SessionApiLive), Layer.provide(EmailVerificationApiLive), Layer.provide(EmailOtpApiLive), Layer.provide(MagicLinkApiLive), Layer.provide(LoginApprovalApiLive), Layer.provide(SecurityApiLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
3023
- export const AuthHttpApiBareLive = AuthHttpApiBaseLive.pipe(Layer.provide(AuthApiRateLimitNoopLive));
3024
- export const AuthHttpApiLive = AuthHttpApiBaseLive.pipe(Layer.provide(AuthApiRateLimitLive));
4336
+ export const AdminTrustedDeviceHttpApiLive = HttpApiBuilder.layer(AdminTrustedDeviceHttpApi).pipe(Layer.provide(AdminTrustedDeviceHttpApiGroupLive), Layer.provide(AdminTrustedDeviceHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4337
+ const CoreAuthHttpApiBaseLive = HttpApiBuilder.layer(CoreAuthHttpApi).pipe(Layer.provide(CoreAuthPasswordGroupLive), Layer.provide(CoreAuthSessionGroupLive), Layer.provide(CoreAuthEmailVerificationGroupLive), Layer.provide(CoreAuthEmailOtpGroupLive), Layer.provide(CoreAuthMagicLinkGroupLive), Layer.provide(CoreAuthLoginApprovalGroupLive), Layer.provide(CoreAuthLoginNotificationGroupLive), Layer.provide(PasswordHttpOperationsLive), Layer.provide(SessionHttpOperationsLive), Layer.provide(EmailVerificationHttpOperationsLive), Layer.provide(EmailOtpHttpOperationsLive), Layer.provide(MagicLinkHttpOperationsLive), Layer.provide(LoginApprovalHttpOperationsLive), Layer.provide(LoginNotificationHttpOperationsLive), Layer.provide(AuthOriginCheckMiddlewareConfigLive), Layer.provide(AuthSchemaErrorMiddlewareLive));
4338
+ export const CoreAuthHttpApiLive = CoreAuthHttpApiBaseLive.pipe(Layer.provide(BotProtectionNoopLive));
3025
4339
  export { AuthResult };
3026
4340
  //# sourceMappingURL=Api.js.map