@effect-auth/core 0.1.0-alpha.15 → 0.1.0-alpha.18

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