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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (637) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +307 -133
  3. package/dist/AbuseProtection.d.ts +100 -0
  4. package/dist/AbuseProtection.d.ts.map +1 -0
  5. package/dist/AbuseProtection.js +71 -0
  6. package/dist/AbuseProtection.js.map +1 -0
  7. package/dist/AccessGrant.d.ts +344 -0
  8. package/dist/AccessGrant.d.ts.map +1 -0
  9. package/dist/AccessGrant.js +687 -0
  10. package/dist/AccessGrant.js.map +1 -0
  11. package/dist/ApiKey.d.ts +0 -12
  12. package/dist/ApiKey.d.ts.map +1 -1
  13. package/dist/ApiKey.js +36 -27
  14. package/dist/ApiKey.js.map +1 -1
  15. package/dist/Assurance.d.ts +415 -0
  16. package/dist/Assurance.d.ts.map +1 -0
  17. package/dist/Assurance.js +764 -0
  18. package/dist/Assurance.js.map +1 -0
  19. package/dist/AtomicPlanExecutor.d.ts +28 -0
  20. package/dist/AtomicPlanExecutor.d.ts.map +1 -0
  21. package/dist/AtomicPlanExecutor.js +5 -0
  22. package/dist/AtomicPlanExecutor.js.map +1 -0
  23. package/dist/AuditLog.d.ts +2314 -52
  24. package/dist/AuditLog.d.ts.map +1 -1
  25. package/dist/AuditLog.js +511 -33
  26. package/dist/AuditLog.js.map +1 -1
  27. package/dist/AuthFlow.d.ts +128 -38
  28. package/dist/AuthFlow.d.ts.map +1 -1
  29. package/dist/AuthFlow.js +611 -263
  30. package/dist/AuthFlow.js.map +1 -1
  31. package/dist/AuthRateLimit.d.ts +96 -0
  32. package/dist/AuthRateLimit.d.ts.map +1 -0
  33. package/dist/AuthRateLimit.js +212 -0
  34. package/dist/AuthRateLimit.js.map +1 -0
  35. package/dist/Challenge.d.ts +0 -3
  36. package/dist/Challenge.d.ts.map +1 -1
  37. package/dist/Challenge.js +1 -4
  38. package/dist/Challenge.js.map +1 -1
  39. package/dist/Client.d.ts +205 -10
  40. package/dist/Client.d.ts.map +1 -1
  41. package/dist/Client.js +397 -16
  42. package/dist/Client.js.map +1 -1
  43. package/dist/CloudflareTurnstile.d.ts +28 -0
  44. package/dist/CloudflareTurnstile.d.ts.map +1 -0
  45. package/dist/CloudflareTurnstile.js +205 -0
  46. package/dist/CloudflareTurnstile.js.map +1 -0
  47. package/dist/Crypto.d.ts +0 -3
  48. package/dist/Crypto.d.ts.map +1 -1
  49. package/dist/Crypto.js +1 -4
  50. package/dist/Crypto.js.map +1 -1
  51. package/dist/DelegatedAccessStorageMigrations.d.ts +7 -0
  52. package/dist/DelegatedAccessStorageMigrations.d.ts.map +1 -0
  53. package/dist/DelegatedAccessStorageMigrations.js +159 -0
  54. package/dist/DelegatedAccessStorageMigrations.js.map +1 -0
  55. package/dist/DevEmail.d.ts +44 -0
  56. package/dist/DevEmail.d.ts.map +1 -0
  57. package/dist/DevEmail.js +115 -0
  58. package/dist/DevEmail.js.map +1 -0
  59. package/dist/DevelopmentSeed.d.ts +47 -0
  60. package/dist/DevelopmentSeed.d.ts.map +1 -0
  61. package/dist/DevelopmentSeed.js +337 -0
  62. package/dist/DevelopmentSeed.js.map +1 -0
  63. package/dist/DisposableEmailDomains.d.ts +19 -0
  64. package/dist/DisposableEmailDomains.d.ts.map +1 -0
  65. package/dist/DisposableEmailDomains.js +85 -0
  66. package/dist/DisposableEmailDomains.js.map +1 -0
  67. package/dist/DomainVerification.d.ts +0 -9
  68. package/dist/DomainVerification.d.ts.map +1 -1
  69. package/dist/DomainVerification.js +36 -22
  70. package/dist/DomainVerification.js.map +1 -1
  71. package/dist/DrizzleBunSqliteStorage.d.ts +18 -0
  72. package/dist/DrizzleBunSqliteStorage.d.ts.map +1 -0
  73. package/dist/DrizzleBunSqliteStorage.js +11 -0
  74. package/dist/DrizzleBunSqliteStorage.js.map +1 -0
  75. package/dist/DrizzleD1SqliteStorage.d.ts +4 -4
  76. package/dist/DrizzleD1SqliteStorage.d.ts.map +1 -1
  77. package/dist/DrizzleD1SqliteStorage.js +5 -5
  78. package/dist/DrizzleD1SqliteStorage.js.map +1 -1
  79. package/dist/DrizzleEffectSqliteStorage.d.ts +13 -4
  80. package/dist/DrizzleEffectSqliteStorage.d.ts.map +1 -1
  81. package/dist/DrizzleEffectSqliteStorage.js +71 -4
  82. package/dist/DrizzleEffectSqliteStorage.js.map +1 -1
  83. package/dist/DrizzleNodeSqliteStorage.d.ts +18 -0
  84. package/dist/DrizzleNodeSqliteStorage.d.ts.map +1 -0
  85. package/dist/DrizzleNodeSqliteStorage.js +11 -0
  86. package/dist/DrizzleNodeSqliteStorage.js.map +1 -0
  87. package/dist/DrizzlePostgresStorage.d.ts +26 -0
  88. package/dist/DrizzlePostgresStorage.d.ts.map +1 -0
  89. package/dist/DrizzlePostgresStorage.js +14 -0
  90. package/dist/DrizzlePostgresStorage.js.map +1 -0
  91. package/dist/EffectQbPostgresDelegatedAccessStorage.d.ts +34 -0
  92. package/dist/EffectQbPostgresDelegatedAccessStorage.d.ts.map +1 -0
  93. package/dist/EffectQbPostgresDelegatedAccessStorage.js +499 -0
  94. package/dist/EffectQbPostgresDelegatedAccessStorage.js.map +1 -0
  95. package/dist/EffectQbPostgresStorage.d.ts +178 -0
  96. package/dist/EffectQbPostgresStorage.d.ts.map +1 -0
  97. package/dist/EffectQbPostgresStorage.js +4637 -0
  98. package/dist/EffectQbPostgresStorage.js.map +1 -0
  99. package/dist/EffectQbSqliteDelegatedAccessStorage.d.ts +112 -0
  100. package/dist/EffectQbSqliteDelegatedAccessStorage.d.ts.map +1 -0
  101. package/dist/EffectQbSqliteDelegatedAccessStorage.js +602 -0
  102. package/dist/EffectQbSqliteDelegatedAccessStorage.js.map +1 -0
  103. package/dist/EffectQbSqliteStorage.d.ts +221 -23
  104. package/dist/EffectQbSqliteStorage.d.ts.map +1 -1
  105. package/dist/EffectQbSqliteStorage.js +2064 -135
  106. package/dist/EffectQbSqliteStorage.js.map +1 -1
  107. package/dist/EmailAuth.d.ts +65 -0
  108. package/dist/EmailAuth.d.ts.map +1 -0
  109. package/dist/EmailAuth.js +171 -0
  110. package/dist/EmailAuth.js.map +1 -0
  111. package/dist/EmailIdentityAuth.d.ts +30 -0
  112. package/dist/EmailIdentityAuth.d.ts.map +1 -0
  113. package/dist/EmailIdentityAuth.js +142 -0
  114. package/dist/EmailIdentityAuth.js.map +1 -0
  115. package/dist/EmailOtp.d.ts +10 -11
  116. package/dist/EmailOtp.d.ts.map +1 -1
  117. package/dist/EmailOtp.js +44 -81
  118. package/dist/EmailOtp.js.map +1 -1
  119. package/dist/EmailRisk.d.ts +48 -0
  120. package/dist/EmailRisk.d.ts.map +1 -0
  121. package/dist/EmailRisk.js +33 -0
  122. package/dist/EmailRisk.js.map +1 -0
  123. package/dist/EmailVerification.d.ts +10 -16
  124. package/dist/EmailVerification.d.ts.map +1 -1
  125. package/dist/EmailVerification.js +85 -42
  126. package/dist/EmailVerification.js.map +1 -1
  127. package/dist/Guard.d.ts +11 -0
  128. package/dist/Guard.d.ts.map +1 -0
  129. package/dist/Guard.js +11 -0
  130. package/dist/Guard.js.map +1 -0
  131. package/dist/HibpPwnedPasswords.d.ts +56 -0
  132. package/dist/HibpPwnedPasswords.d.ts.map +1 -0
  133. package/dist/HibpPwnedPasswords.js +232 -0
  134. package/dist/HibpPwnedPasswords.js.map +1 -0
  135. package/dist/HttpApi/AdminPermissionDefinition.d.ts +4 -0
  136. package/dist/HttpApi/AdminPermissionDefinition.d.ts.map +1 -0
  137. package/dist/HttpApi/AdminPermissionDefinition.js +4 -0
  138. package/dist/HttpApi/AdminPermissionDefinition.js.map +1 -0
  139. package/dist/HttpApi/AdminSecurityTimeline.d.ts +4 -0
  140. package/dist/HttpApi/AdminSecurityTimeline.d.ts.map +1 -0
  141. package/dist/HttpApi/AdminSecurityTimeline.js +4 -0
  142. package/dist/HttpApi/AdminSecurityTimeline.js.map +1 -0
  143. package/dist/HttpApi/AdminSession.d.ts +4 -0
  144. package/dist/HttpApi/AdminSession.d.ts.map +1 -0
  145. package/dist/HttpApi/AdminSession.js +4 -0
  146. package/dist/HttpApi/AdminSession.js.map +1 -0
  147. package/dist/HttpApi/AdminTrustedDevice.d.ts +4 -0
  148. package/dist/HttpApi/AdminTrustedDevice.d.ts.map +1 -0
  149. package/dist/HttpApi/AdminTrustedDevice.js +4 -0
  150. package/dist/HttpApi/AdminTrustedDevice.js.map +1 -0
  151. package/dist/HttpApi/Api.d.ts +939 -884
  152. package/dist/HttpApi/Api.d.ts.map +1 -1
  153. package/dist/HttpApi/Api.js +2254 -940
  154. package/dist/HttpApi/Api.js.map +1 -1
  155. package/dist/HttpApi/ApiKey.d.ts +4 -0
  156. package/dist/HttpApi/ApiKey.d.ts.map +1 -0
  157. package/dist/HttpApi/ApiKey.js +4 -0
  158. package/dist/HttpApi/ApiKey.js.map +1 -0
  159. package/dist/HttpApi/Audit.d.ts +6 -0
  160. package/dist/HttpApi/Audit.d.ts.map +1 -0
  161. package/dist/HttpApi/Audit.js +10 -0
  162. package/dist/HttpApi/Audit.js.map +1 -0
  163. package/dist/HttpApi/ClientApi.d.ts +917 -0
  164. package/dist/HttpApi/ClientApi.d.ts.map +1 -0
  165. package/dist/HttpApi/ClientApi.js +101 -0
  166. package/dist/HttpApi/ClientApi.js.map +1 -0
  167. package/dist/HttpApi/EmailAuth.d.ts +6 -0
  168. package/dist/HttpApi/EmailAuth.d.ts.map +1 -0
  169. package/dist/HttpApi/EmailAuth.js +6 -0
  170. package/dist/HttpApi/EmailAuth.js.map +1 -0
  171. package/dist/HttpApi/EmailGuards.d.ts +115 -0
  172. package/dist/HttpApi/EmailGuards.d.ts.map +1 -0
  173. package/dist/HttpApi/EmailGuards.js +191 -0
  174. package/dist/HttpApi/EmailGuards.js.map +1 -0
  175. package/dist/HttpApi/EmailOtp.d.ts +6 -0
  176. package/dist/HttpApi/EmailOtp.d.ts.map +1 -0
  177. package/dist/HttpApi/EmailOtp.js +6 -0
  178. package/dist/HttpApi/EmailOtp.js.map +1 -0
  179. package/dist/HttpApi/EmailVerification.d.ts +6 -0
  180. package/dist/HttpApi/EmailVerification.d.ts.map +1 -0
  181. package/dist/HttpApi/EmailVerification.js +6 -0
  182. package/dist/HttpApi/EmailVerification.js.map +1 -0
  183. package/dist/HttpApi/Endpoints.d.ts +661 -301
  184. package/dist/HttpApi/Endpoints.d.ts.map +1 -1
  185. package/dist/HttpApi/Endpoints.js +207 -120
  186. package/dist/HttpApi/Endpoints.js.map +1 -1
  187. package/dist/HttpApi/Errors.d.ts +37 -10
  188. package/dist/HttpApi/Errors.d.ts.map +1 -1
  189. package/dist/HttpApi/Errors.js +42 -4
  190. package/dist/HttpApi/Errors.js.map +1 -1
  191. package/dist/HttpApi/Identity.d.ts +6 -0
  192. package/dist/HttpApi/Identity.d.ts.map +1 -0
  193. package/dist/HttpApi/Identity.js +6 -0
  194. package/dist/HttpApi/Identity.js.map +1 -0
  195. package/dist/HttpApi/IdentityGuards.d.ts +31 -0
  196. package/dist/HttpApi/IdentityGuards.d.ts.map +1 -0
  197. package/dist/HttpApi/IdentityGuards.js +33 -0
  198. package/dist/HttpApi/IdentityGuards.js.map +1 -0
  199. package/dist/HttpApi/Jwt.d.ts +4 -0
  200. package/dist/HttpApi/Jwt.d.ts.map +1 -0
  201. package/dist/HttpApi/Jwt.js +4 -0
  202. package/dist/HttpApi/Jwt.js.map +1 -0
  203. package/dist/HttpApi/JwtDiscovery.d.ts +4 -0
  204. package/dist/HttpApi/JwtDiscovery.d.ts.map +1 -0
  205. package/dist/HttpApi/JwtDiscovery.js +4 -0
  206. package/dist/HttpApi/JwtDiscovery.js.map +1 -0
  207. package/dist/HttpApi/LoginApproval.d.ts +5 -0
  208. package/dist/HttpApi/LoginApproval.d.ts.map +1 -0
  209. package/dist/HttpApi/LoginApproval.js +5 -0
  210. package/dist/HttpApi/LoginApproval.js.map +1 -0
  211. package/dist/HttpApi/LoginNotification.d.ts +5 -0
  212. package/dist/HttpApi/LoginNotification.d.ts.map +1 -0
  213. package/dist/HttpApi/LoginNotification.js +5 -0
  214. package/dist/HttpApi/LoginNotification.js.map +1 -0
  215. package/dist/HttpApi/MagicLink.d.ts +6 -0
  216. package/dist/HttpApi/MagicLink.d.ts.map +1 -0
  217. package/dist/HttpApi/MagicLink.js +6 -0
  218. package/dist/HttpApi/MagicLink.js.map +1 -0
  219. package/dist/HttpApi/Mfa.d.ts +5 -0
  220. package/dist/HttpApi/Mfa.d.ts.map +1 -0
  221. package/dist/HttpApi/Mfa.js +5 -0
  222. package/dist/HttpApi/Mfa.js.map +1 -0
  223. package/dist/HttpApi/Middleware.d.ts +26 -0
  224. package/dist/HttpApi/Middleware.d.ts.map +1 -0
  225. package/dist/HttpApi/Middleware.js +13 -0
  226. package/dist/HttpApi/Middleware.js.map +1 -0
  227. package/dist/HttpApi/OAuth.d.ts +4 -0
  228. package/dist/HttpApi/OAuth.d.ts.map +1 -0
  229. package/dist/HttpApi/OAuth.js +4 -0
  230. package/dist/HttpApi/OAuth.js.map +1 -0
  231. package/dist/HttpApi/OAuthDeviceAuthorization.d.ts +106 -0
  232. package/dist/HttpApi/OAuthDeviceAuthorization.d.ts.map +1 -0
  233. package/dist/HttpApi/OAuthDeviceAuthorization.js +415 -0
  234. package/dist/HttpApi/OAuthDeviceAuthorization.js.map +1 -0
  235. package/dist/HttpApi/OAuthProviderAuthorization.d.ts +4 -0
  236. package/dist/HttpApi/OAuthProviderAuthorization.d.ts.map +1 -0
  237. package/dist/HttpApi/OAuthProviderAuthorization.js +4 -0
  238. package/dist/HttpApi/OAuthProviderAuthorization.js.map +1 -0
  239. package/dist/HttpApi/OAuthToken.d.ts +4 -0
  240. package/dist/HttpApi/OAuthToken.d.ts.map +1 -0
  241. package/dist/HttpApi/OAuthToken.js +4 -0
  242. package/dist/HttpApi/OAuthToken.js.map +1 -0
  243. package/dist/HttpApi/OidcDiscovery.d.ts +4 -0
  244. package/dist/HttpApi/OidcDiscovery.d.ts.map +1 -0
  245. package/dist/HttpApi/OidcDiscovery.js +4 -0
  246. package/dist/HttpApi/OidcDiscovery.js.map +1 -0
  247. package/dist/HttpApi/Operations/AdminPermissionDefinition.d.ts +28 -0
  248. package/dist/HttpApi/Operations/AdminPermissionDefinition.d.ts.map +1 -0
  249. package/dist/HttpApi/Operations/AdminPermissionDefinition.js +5 -0
  250. package/dist/HttpApi/Operations/AdminPermissionDefinition.js.map +1 -0
  251. package/dist/HttpApi/Operations/AdminSession.d.ts +16 -0
  252. package/dist/HttpApi/Operations/AdminSession.d.ts.map +1 -0
  253. package/dist/HttpApi/Operations/AdminSession.js +5 -0
  254. package/dist/HttpApi/Operations/AdminSession.js.map +1 -0
  255. package/dist/HttpApi/Operations/ApiKey.d.ts +16 -0
  256. package/dist/HttpApi/Operations/ApiKey.d.ts.map +1 -0
  257. package/dist/HttpApi/Operations/ApiKey.js +5 -0
  258. package/dist/HttpApi/Operations/ApiKey.js.map +1 -0
  259. package/dist/HttpApi/Operations/Discovery.d.ts +19 -0
  260. package/dist/HttpApi/Operations/Discovery.d.ts.map +1 -0
  261. package/dist/HttpApi/Operations/Discovery.js +7 -0
  262. package/dist/HttpApi/Operations/Discovery.js.map +1 -0
  263. package/dist/HttpApi/Operations/EmailAuth.d.ts +12 -0
  264. package/dist/HttpApi/Operations/EmailAuth.d.ts.map +1 -0
  265. package/dist/HttpApi/Operations/EmailAuth.js +5 -0
  266. package/dist/HttpApi/Operations/EmailAuth.js.map +1 -0
  267. package/dist/HttpApi/Operations/EmailOtp.d.ts +14 -0
  268. package/dist/HttpApi/Operations/EmailOtp.d.ts.map +1 -0
  269. package/dist/HttpApi/Operations/EmailOtp.js +5 -0
  270. package/dist/HttpApi/Operations/EmailOtp.js.map +1 -0
  271. package/dist/HttpApi/Operations/EmailVerification.d.ts +14 -0
  272. package/dist/HttpApi/Operations/EmailVerification.d.ts.map +1 -0
  273. package/dist/HttpApi/Operations/EmailVerification.js +5 -0
  274. package/dist/HttpApi/Operations/EmailVerification.js.map +1 -0
  275. package/dist/HttpApi/Operations/HttpOperation.d.ts +4 -0
  276. package/dist/HttpApi/Operations/HttpOperation.d.ts.map +1 -0
  277. package/dist/HttpApi/Operations/HttpOperation.js +2 -0
  278. package/dist/HttpApi/Operations/HttpOperation.js.map +1 -0
  279. package/dist/HttpApi/Operations/Identity.d.ts +22 -0
  280. package/dist/HttpApi/Operations/Identity.d.ts.map +1 -0
  281. package/dist/HttpApi/Operations/Identity.js +5 -0
  282. package/dist/HttpApi/Operations/Identity.js.map +1 -0
  283. package/dist/HttpApi/Operations/Jwt.d.ts +14 -0
  284. package/dist/HttpApi/Operations/Jwt.d.ts.map +1 -0
  285. package/dist/HttpApi/Operations/Jwt.js +5 -0
  286. package/dist/HttpApi/Operations/Jwt.js.map +1 -0
  287. package/dist/HttpApi/Operations/LoginApproval.d.ts +16 -0
  288. package/dist/HttpApi/Operations/LoginApproval.d.ts.map +1 -0
  289. package/dist/HttpApi/Operations/LoginApproval.js +5 -0
  290. package/dist/HttpApi/Operations/LoginApproval.js.map +1 -0
  291. package/dist/HttpApi/Operations/MagicLink.d.ts +14 -0
  292. package/dist/HttpApi/Operations/MagicLink.d.ts.map +1 -0
  293. package/dist/HttpApi/Operations/MagicLink.js +5 -0
  294. package/dist/HttpApi/Operations/MagicLink.js.map +1 -0
  295. package/dist/HttpApi/Operations/Mfa.d.ts +24 -0
  296. package/dist/HttpApi/Operations/Mfa.d.ts.map +1 -0
  297. package/dist/HttpApi/Operations/Mfa.js +5 -0
  298. package/dist/HttpApi/Operations/Mfa.js.map +1 -0
  299. package/dist/HttpApi/Operations/OAuth.d.ts +20 -0
  300. package/dist/HttpApi/Operations/OAuth.d.ts.map +1 -0
  301. package/dist/HttpApi/Operations/OAuth.js +5 -0
  302. package/dist/HttpApi/Operations/OAuth.js.map +1 -0
  303. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts +23 -0
  304. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.d.ts.map +1 -0
  305. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js +7 -0
  306. package/dist/HttpApi/Operations/OAuthDeviceAuthorization.js.map +1 -0
  307. package/dist/HttpApi/Operations/OAuthProviderAuthorization.d.ts +12 -0
  308. package/dist/HttpApi/Operations/OAuthProviderAuthorization.d.ts.map +1 -0
  309. package/dist/HttpApi/Operations/OAuthProviderAuthorization.js +5 -0
  310. package/dist/HttpApi/Operations/OAuthProviderAuthorization.js.map +1 -0
  311. package/dist/HttpApi/Operations/OAuthToken.d.ts +26 -0
  312. package/dist/HttpApi/Operations/OAuthToken.d.ts.map +1 -0
  313. package/dist/HttpApi/Operations/OAuthToken.js +9 -0
  314. package/dist/HttpApi/Operations/OAuthToken.js.map +1 -0
  315. package/dist/HttpApi/Operations/Passkey.d.ts +22 -0
  316. package/dist/HttpApi/Operations/Passkey.d.ts.map +1 -0
  317. package/dist/HttpApi/Operations/Passkey.js +5 -0
  318. package/dist/HttpApi/Operations/Passkey.js.map +1 -0
  319. package/dist/HttpApi/Operations/Password.d.ts +22 -0
  320. package/dist/HttpApi/Operations/Password.d.ts.map +1 -0
  321. package/dist/HttpApi/Operations/Password.js +5 -0
  322. package/dist/HttpApi/Operations/Password.js.map +1 -0
  323. package/dist/HttpApi/Operations/RecoveryCodes.d.ts +20 -0
  324. package/dist/HttpApi/Operations/RecoveryCodes.d.ts.map +1 -0
  325. package/dist/HttpApi/Operations/RecoveryCodes.js +5 -0
  326. package/dist/HttpApi/Operations/RecoveryCodes.js.map +1 -0
  327. package/dist/HttpApi/Operations/RefreshToken.d.ts +12 -0
  328. package/dist/HttpApi/Operations/RefreshToken.d.ts.map +1 -0
  329. package/dist/HttpApi/Operations/RefreshToken.js +5 -0
  330. package/dist/HttpApi/Operations/RefreshToken.js.map +1 -0
  331. package/dist/HttpApi/Operations/Security.d.ts +12 -0
  332. package/dist/HttpApi/Operations/Security.d.ts.map +1 -0
  333. package/dist/HttpApi/Operations/Security.js +5 -0
  334. package/dist/HttpApi/Operations/Security.js.map +1 -0
  335. package/dist/HttpApi/Operations/SecurityTimeline.d.ts +19 -0
  336. package/dist/HttpApi/Operations/SecurityTimeline.d.ts.map +1 -0
  337. package/dist/HttpApi/Operations/SecurityTimeline.js +7 -0
  338. package/dist/HttpApi/Operations/SecurityTimeline.js.map +1 -0
  339. package/dist/HttpApi/Operations/Session.d.ts +22 -0
  340. package/dist/HttpApi/Operations/Session.d.ts.map +1 -0
  341. package/dist/HttpApi/Operations/Session.js +5 -0
  342. package/dist/HttpApi/Operations/Session.js.map +1 -0
  343. package/dist/HttpApi/Operations/StepUp.d.ts +22 -0
  344. package/dist/HttpApi/Operations/StepUp.d.ts.map +1 -0
  345. package/dist/HttpApi/Operations/StepUp.js +5 -0
  346. package/dist/HttpApi/Operations/StepUp.js.map +1 -0
  347. package/dist/HttpApi/Operations/Totp.d.ts +20 -0
  348. package/dist/HttpApi/Operations/Totp.d.ts.map +1 -0
  349. package/dist/HttpApi/Operations/Totp.js +5 -0
  350. package/dist/HttpApi/Operations/Totp.js.map +1 -0
  351. package/dist/HttpApi/Operations/TrustedDevice.d.ts +23 -0
  352. package/dist/HttpApi/Operations/TrustedDevice.d.ts.map +1 -0
  353. package/dist/HttpApi/Operations/TrustedDevice.js +7 -0
  354. package/dist/HttpApi/Operations/TrustedDevice.js.map +1 -0
  355. package/dist/HttpApi/Operations/index.d.ts +28 -0
  356. package/dist/HttpApi/Operations/index.d.ts.map +1 -0
  357. package/dist/HttpApi/Operations/index.js +28 -0
  358. package/dist/HttpApi/Operations/index.js.map +1 -0
  359. package/dist/HttpApi/Passkey.d.ts +5 -0
  360. package/dist/HttpApi/Passkey.d.ts.map +1 -0
  361. package/dist/HttpApi/Passkey.js +5 -0
  362. package/dist/HttpApi/Passkey.js.map +1 -0
  363. package/dist/HttpApi/Password.d.ts +220 -0
  364. package/dist/HttpApi/Password.d.ts.map +1 -0
  365. package/dist/HttpApi/Password.js +237 -0
  366. package/dist/HttpApi/Password.js.map +1 -0
  367. package/dist/HttpApi/PasswordContract.d.ts +307 -0
  368. package/dist/HttpApi/PasswordContract.d.ts.map +1 -0
  369. package/dist/HttpApi/PasswordContract.js +63 -0
  370. package/dist/HttpApi/PasswordContract.js.map +1 -0
  371. package/dist/HttpApi/PasswordGuards.d.ts +82 -0
  372. package/dist/HttpApi/PasswordGuards.d.ts.map +1 -0
  373. package/dist/HttpApi/PasswordGuards.js +179 -0
  374. package/dist/HttpApi/PasswordGuards.js.map +1 -0
  375. package/dist/HttpApi/RecoveryCodes.d.ts +5 -0
  376. package/dist/HttpApi/RecoveryCodes.d.ts.map +1 -0
  377. package/dist/HttpApi/RecoveryCodes.js +5 -0
  378. package/dist/HttpApi/RecoveryCodes.js.map +1 -0
  379. package/dist/HttpApi/RefreshToken.d.ts +4 -0
  380. package/dist/HttpApi/RefreshToken.d.ts.map +1 -0
  381. package/dist/HttpApi/RefreshToken.js +4 -0
  382. package/dist/HttpApi/RefreshToken.js.map +1 -0
  383. package/dist/HttpApi/RequestGuards.d.ts +42 -0
  384. package/dist/HttpApi/RequestGuards.d.ts.map +1 -0
  385. package/dist/HttpApi/RequestGuards.js +194 -0
  386. package/dist/HttpApi/RequestGuards.js.map +1 -0
  387. package/dist/HttpApi/Schemas.d.ts +399 -84
  388. package/dist/HttpApi/Schemas.d.ts.map +1 -1
  389. package/dist/HttpApi/Schemas.js +225 -27
  390. package/dist/HttpApi/Schemas.js.map +1 -1
  391. package/dist/HttpApi/Security.d.ts +12 -93
  392. package/dist/HttpApi/Security.d.ts.map +1 -1
  393. package/dist/HttpApi/Security.js +65 -356
  394. package/dist/HttpApi/Security.js.map +1 -1
  395. package/dist/HttpApi/SecurityTimeline.d.ts +4 -0
  396. package/dist/HttpApi/SecurityTimeline.d.ts.map +1 -0
  397. package/dist/HttpApi/SecurityTimeline.js +4 -0
  398. package/dist/HttpApi/SecurityTimeline.js.map +1 -0
  399. package/dist/HttpApi/Session.d.ts +5 -0
  400. package/dist/HttpApi/Session.d.ts.map +1 -0
  401. package/dist/HttpApi/Session.js +5 -0
  402. package/dist/HttpApi/Session.js.map +1 -0
  403. package/dist/HttpApi/SessionGuards.d.ts +15 -0
  404. package/dist/HttpApi/SessionGuards.d.ts.map +1 -0
  405. package/dist/HttpApi/SessionGuards.js +37 -0
  406. package/dist/HttpApi/SessionGuards.js.map +1 -0
  407. package/dist/HttpApi/StepUp.d.ts +5 -0
  408. package/dist/HttpApi/StepUp.d.ts.map +1 -0
  409. package/dist/HttpApi/StepUp.js +5 -0
  410. package/dist/HttpApi/StepUp.js.map +1 -0
  411. package/dist/HttpApi/Totp.d.ts +5 -0
  412. package/dist/HttpApi/Totp.d.ts.map +1 -0
  413. package/dist/HttpApi/Totp.js +5 -0
  414. package/dist/HttpApi/Totp.js.map +1 -0
  415. package/dist/HttpApi/Transport.d.ts +4 -6
  416. package/dist/HttpApi/Transport.d.ts.map +1 -1
  417. package/dist/HttpApi/Transport.js +62 -36
  418. package/dist/HttpApi/Transport.js.map +1 -1
  419. package/dist/HttpApi/TrustedDevice.d.ts +4 -0
  420. package/dist/HttpApi/TrustedDevice.d.ts.map +1 -0
  421. package/dist/HttpApi/TrustedDevice.js +4 -0
  422. package/dist/HttpApi/TrustedDevice.js.map +1 -0
  423. package/dist/HttpApi/index.d.ts +11 -3
  424. package/dist/HttpApi/index.d.ts.map +1 -1
  425. package/dist/HttpApi/index.js +10 -2
  426. package/dist/HttpApi/index.js.map +1 -1
  427. package/dist/Identity.d.ts +138 -0
  428. package/dist/Identity.d.ts.map +1 -0
  429. package/dist/Identity.js +105 -0
  430. package/dist/Identity.js.map +1 -0
  431. package/dist/IdentityManagement.d.ts +189 -0
  432. package/dist/IdentityManagement.d.ts.map +1 -0
  433. package/dist/IdentityManagement.js +317 -0
  434. package/dist/IdentityManagement.js.map +1 -0
  435. package/dist/IncidentAction.d.ts +1 -4
  436. package/dist/IncidentAction.d.ts.map +1 -1
  437. package/dist/IncidentAction.js +15 -9
  438. package/dist/IncidentAction.js.map +1 -1
  439. package/dist/Internal.d.ts +2 -0
  440. package/dist/Internal.d.ts.map +1 -1
  441. package/dist/Internal.js +30 -0
  442. package/dist/Internal.js.map +1 -1
  443. package/dist/Invitation.d.ts +362 -0
  444. package/dist/Invitation.d.ts.map +1 -0
  445. package/dist/Invitation.js +633 -0
  446. package/dist/Invitation.js.map +1 -0
  447. package/dist/IpQualityScore.d.ts +38 -0
  448. package/dist/IpQualityScore.d.ts.map +1 -0
  449. package/dist/IpQualityScore.js +215 -0
  450. package/dist/IpQualityScore.js.map +1 -0
  451. package/dist/Jwt.d.ts +8 -29
  452. package/dist/Jwt.d.ts.map +1 -1
  453. package/dist/Jwt.js +67 -56
  454. package/dist/Jwt.js.map +1 -1
  455. package/dist/LoginApproval.d.ts +15 -30
  456. package/dist/LoginApproval.d.ts.map +1 -1
  457. package/dist/LoginApproval.js +47 -41
  458. package/dist/LoginApproval.js.map +1 -1
  459. package/dist/LoginNotification.d.ts +7 -11
  460. package/dist/LoginNotification.d.ts.map +1 -1
  461. package/dist/LoginNotification.js +30 -17
  462. package/dist/LoginNotification.js.map +1 -1
  463. package/dist/LoginRisk.d.ts +11 -13
  464. package/dist/LoginRisk.d.ts.map +1 -1
  465. package/dist/LoginRisk.js +66 -26
  466. package/dist/LoginRisk.js.map +1 -1
  467. package/dist/LoginRiskEnrichment.d.ts +145 -0
  468. package/dist/LoginRiskEnrichment.d.ts.map +1 -0
  469. package/dist/LoginRiskEnrichment.js +220 -0
  470. package/dist/LoginRiskEnrichment.js.map +1 -0
  471. package/dist/MagicLink.d.ts +9 -8
  472. package/dist/MagicLink.d.ts.map +1 -1
  473. package/dist/MagicLink.js +40 -73
  474. package/dist/MagicLink.js.map +1 -1
  475. package/dist/Mailer.d.ts +19 -12
  476. package/dist/Mailer.d.ts.map +1 -1
  477. package/dist/Mailer.js +10 -12
  478. package/dist/Mailer.js.map +1 -1
  479. package/dist/OAuth.d.ts +138 -96
  480. package/dist/OAuth.d.ts.map +1 -1
  481. package/dist/OAuth.js +522 -221
  482. package/dist/OAuth.js.map +1 -1
  483. package/dist/OAuthDeviceAuthorization.d.ts +378 -0
  484. package/dist/OAuthDeviceAuthorization.d.ts.map +1 -0
  485. package/dist/OAuthDeviceAuthorization.js +860 -0
  486. package/dist/OAuthDeviceAuthorization.js.map +1 -0
  487. package/dist/OAuthDeviceClient.d.ts +76 -0
  488. package/dist/OAuthDeviceClient.d.ts.map +1 -0
  489. package/dist/OAuthDeviceClient.js +362 -0
  490. package/dist/OAuthDeviceClient.js.map +1 -0
  491. package/dist/Passkey.d.ts +15 -17
  492. package/dist/Passkey.d.ts.map +1 -1
  493. package/dist/Passkey.js +86 -39
  494. package/dist/Passkey.js.map +1 -1
  495. package/dist/PasskeyBrowser.d.ts +39 -0
  496. package/dist/PasskeyBrowser.d.ts.map +1 -0
  497. package/dist/PasskeyBrowser.js +206 -0
  498. package/dist/PasskeyBrowser.js.map +1 -0
  499. package/dist/PasskeySimpleWebAuthn.d.ts.map +1 -1
  500. package/dist/PasskeySimpleWebAuthn.js +19 -7
  501. package/dist/PasskeySimpleWebAuthn.js.map +1 -1
  502. package/dist/Password.d.ts +71 -37
  503. package/dist/Password.d.ts.map +1 -1
  504. package/dist/Password.js +295 -81
  505. package/dist/Password.js.map +1 -1
  506. package/dist/PasswordRisk.d.ts +63 -0
  507. package/dist/PasswordRisk.d.ts.map +1 -0
  508. package/dist/PasswordRisk.js +37 -0
  509. package/dist/PasswordRisk.js.map +1 -0
  510. package/dist/Permission.d.ts +308 -0
  511. package/dist/Permission.d.ts.map +1 -0
  512. package/dist/Permission.js +827 -0
  513. package/dist/Permission.js.map +1 -0
  514. package/dist/Policy.d.ts +31 -18
  515. package/dist/Policy.d.ts.map +1 -1
  516. package/dist/Policy.js +58 -14
  517. package/dist/Policy.js.map +1 -1
  518. package/dist/PostgresDelegatedAccessStorageMigrations.d.ts +7 -0
  519. package/dist/PostgresDelegatedAccessStorageMigrations.d.ts.map +1 -0
  520. package/dist/PostgresDelegatedAccessStorageMigrations.js +119 -0
  521. package/dist/PostgresDelegatedAccessStorageMigrations.js.map +1 -0
  522. package/dist/PostgresStorageMigrations.d.ts +16 -0
  523. package/dist/PostgresStorageMigrations.d.ts.map +1 -0
  524. package/dist/PostgresStorageMigrations.js +674 -0
  525. package/dist/PostgresStorageMigrations.js.map +1 -0
  526. package/dist/Privacy.d.ts +0 -3
  527. package/dist/Privacy.d.ts.map +1 -1
  528. package/dist/Privacy.js +2 -5
  529. package/dist/Privacy.js.map +1 -1
  530. package/dist/RateLimiter.d.ts +0 -3
  531. package/dist/RateLimiter.d.ts.map +1 -1
  532. package/dist/RateLimiter.js +1 -4
  533. package/dist/RateLimiter.js.map +1 -1
  534. package/dist/RecoveryCode.d.ts +83 -11
  535. package/dist/RecoveryCode.d.ts.map +1 -1
  536. package/dist/RecoveryCode.js +273 -75
  537. package/dist/RecoveryCode.js.map +1 -1
  538. package/dist/RecoveryPolicy.d.ts +81 -0
  539. package/dist/RecoveryPolicy.d.ts.map +1 -0
  540. package/dist/RecoveryPolicy.js +119 -0
  541. package/dist/RecoveryPolicy.js.map +1 -0
  542. package/dist/RefreshToken.d.ts +0 -9
  543. package/dist/RefreshToken.d.ts.map +1 -1
  544. package/dist/RefreshToken.js +31 -22
  545. package/dist/RefreshToken.js.map +1 -1
  546. package/dist/Retention.d.ts +6 -1
  547. package/dist/Retention.d.ts.map +1 -1
  548. package/dist/Retention.js +49 -12
  549. package/dist/Retention.js.map +1 -1
  550. package/dist/SecurityTimeline.d.ts +1 -4
  551. package/dist/SecurityTimeline.d.ts.map +1 -1
  552. package/dist/SecurityTimeline.js +110 -17
  553. package/dist/SecurityTimeline.js.map +1 -1
  554. package/dist/Sessions.d.ts +124 -29
  555. package/dist/Sessions.d.ts.map +1 -1
  556. package/dist/Sessions.js +626 -94
  557. package/dist/Sessions.js.map +1 -1
  558. package/dist/SqliteStorageSchemaData.d.ts +2 -0
  559. package/dist/SqliteStorageSchemaData.d.ts.map +1 -0
  560. package/dist/SqliteStorageSchemaData.js +508 -0
  561. package/dist/SqliteStorageSchemaData.js.map +1 -0
  562. package/dist/StepUp.d.ts +132 -11
  563. package/dist/StepUp.d.ts.map +1 -1
  564. package/dist/StepUp.js +387 -19
  565. package/dist/StepUp.js.map +1 -1
  566. package/dist/Storage.d.ts +89 -23
  567. package/dist/Storage.d.ts.map +1 -1
  568. package/dist/Storage.js +10 -12
  569. package/dist/Storage.js.map +1 -1
  570. package/dist/StorageMigrations.d.ts +7 -1
  571. package/dist/StorageMigrations.d.ts.map +1 -1
  572. package/dist/StorageMigrations.js +256 -0
  573. package/dist/StorageMigrations.js.map +1 -1
  574. package/dist/StorageSchemaGenerator.d.ts +544 -0
  575. package/dist/StorageSchemaGenerator.d.ts.map +1 -0
  576. package/dist/StorageSchemaGenerator.js +1418 -0
  577. package/dist/StorageSchemaGenerator.js.map +1 -0
  578. package/dist/StrongFactor.d.ts +64 -0
  579. package/dist/StrongFactor.d.ts.map +1 -0
  580. package/dist/StrongFactor.js +100 -0
  581. package/dist/StrongFactor.js.map +1 -0
  582. package/dist/Testing.js +2 -2
  583. package/dist/Testing.js.map +1 -1
  584. package/dist/Totp.d.ts +88 -13
  585. package/dist/Totp.d.ts.map +1 -1
  586. package/dist/Totp.js +192 -34
  587. package/dist/Totp.js.map +1 -1
  588. package/dist/TrustedDevice.d.ts +0 -9
  589. package/dist/TrustedDevice.d.ts.map +1 -1
  590. package/dist/TrustedDevice.js +15 -17
  591. package/dist/TrustedDevice.js.map +1 -1
  592. package/dist/WaitUntil.d.ts +0 -3
  593. package/dist/WaitUntil.d.ts.map +1 -1
  594. package/dist/WaitUntil.js +1 -4
  595. package/dist/WaitUntil.js.map +1 -1
  596. package/dist/Webhook.d.ts +42 -12
  597. package/dist/Webhook.d.ts.map +1 -1
  598. package/dist/Webhook.js +165 -26
  599. package/dist/Webhook.js.map +1 -1
  600. package/dist/alchemy/cloudflare/Email.d.ts.map +1 -1
  601. package/dist/alchemy/cloudflare/Email.js +9 -4
  602. package/dist/alchemy/cloudflare/Email.js.map +1 -1
  603. package/dist/cloudflare/Email.js +1 -1
  604. package/dist/cloudflare/Email.js.map +1 -1
  605. package/dist/cloudflare/RequestMetadata.d.ts +49 -0
  606. package/dist/cloudflare/RequestMetadata.d.ts.map +1 -0
  607. package/dist/cloudflare/RequestMetadata.js +71 -0
  608. package/dist/cloudflare/RequestMetadata.js.map +1 -0
  609. package/dist/index.d.ts +0 -35
  610. package/dist/index.d.ts.map +1 -1
  611. package/dist/index.js +0 -35
  612. package/dist/index.js.map +1 -1
  613. package/dist/internal/AuthFlowFinalizer.d.ts +31 -0
  614. package/dist/internal/AuthFlowFinalizer.d.ts.map +1 -0
  615. package/dist/internal/AuthFlowFinalizer.js +182 -0
  616. package/dist/internal/AuthFlowFinalizer.js.map +1 -0
  617. package/migrations/0001_auth_storage.sql +1 -0
  618. package/migrations/0006_auth_totp_factor.sql +1 -0
  619. package/migrations/0024_auth_permission.sql +39 -0
  620. package/migrations/0025_auth_permission_definition.sql +19 -0
  621. package/migrations/0026_auth_user_identity.sql +59 -0
  622. package/migrations/0027_auth_audit_log_storage_order.sql +46 -0
  623. package/migrations/0028_auth_oauth_client_secret_key.sql +39 -0
  624. package/migrations/0029_auth_oauth_device_authorization.sql +28 -0
  625. package/migrations/delegated-access/0001_auth_delegated_access.sql +152 -0
  626. package/migrations/postgres/0001_auth_core.sql +77 -0
  627. package/migrations/postgres/0002_auth_security_oauth.sql +65 -0
  628. package/migrations/postgres/0003_auth_credentials_tokens.sql +43 -0
  629. package/migrations/postgres/0004_auth_security_history.sql +103 -0
  630. package/migrations/postgres/0005_auth_webhooks.sql +29 -0
  631. package/migrations/postgres/0006_auth_domain_timeline.sql +50 -0
  632. package/migrations/postgres/0007_auth_oauth_clients.sql +85 -0
  633. package/migrations/postgres/0008_auth_oauth_tokens.sql +63 -0
  634. package/migrations/postgres/0009_auth_permissions.sql +66 -0
  635. package/migrations/postgres/0010_auth_oauth_device_authorization.sql +50 -0
  636. package/migrations/postgres/delegated-access/0001_auth_delegated_access.sql +112 -0
  637. package/package.json +309 -2
package/dist/Sessions.js CHANGED
@@ -1,15 +1,22 @@
1
- import { Context, Data, Duration, Effect, Layer, Option } from "effect";
1
+ import { Context, Data, Duration, Effect, Layer, Option, Result } from "effect";
2
+ import { AuthenticationEvidenceTimeError, CustomEvidencePolicies, CustomEvidencePolicyError, compactAuthenticationEventsResult, deriveAssuranceResult, deriveMfaVerifiedAtResult, emptyCustomEvidencePolicyRegistry, maximumSessionAuthenticationEvents, validateAuthenticationEvidenceTimestamps, } from "./Assurance.js";
2
3
  import { AuthSecrets, AuthSessionCookieConfig, AuthSessionsConfig, } from "./AuthConfig.js";
3
4
  import { Crypto } from "./Crypto.js";
4
- import { SessionId, SessionToken, UnixMillis } from "./Identifiers.js";
5
+ import { SessionId, SessionToken, UnixMillis, } from "./Identifiers.js";
5
6
  import { addMillis, currentUnixMillis, timingSafeEqualString, } from "./Internal.js";
7
+ import { RecoveryCodeSessionRotateStore } from "./RecoveryCode.js";
6
8
  import { SessionStore } from "./Storage.js";
9
+ import { TotpSessionRotateStore } from "./Totp.js";
7
10
  export const sessionRequestMetadataKey = "__effectAuthRequest";
8
11
  export const defaultSessionTtlPolicy = {
9
12
  idleTtl: Duration.days(30),
10
13
  absoluteTtl: Duration.days(90),
11
14
  refreshAfter: Duration.days(1),
12
15
  };
16
+ export class RecoveryCodeSessionRotation extends Context.Service()("auth/RecoveryCodeSessionRotation") {
17
+ }
18
+ export class TotpSessionRotation extends Context.Service()("auth/TotpSessionRotation") {
19
+ }
13
20
  export class SessionCreateError extends Data.TaggedError("SessionCreateError") {
14
21
  }
15
22
  export class SessionValidateError extends Data.TaggedError("SessionValidateError") {
@@ -26,9 +33,6 @@ export class SessionRevokeError extends Data.TaggedError("SessionRevokeError") {
26
33
  }
27
34
  export class Sessions extends Context.Service()("auth/Sessions") {
28
35
  }
29
- (function (Sessions) {
30
- Sessions.make = (service) => Sessions.of(service);
31
- })(Sessions || (Sessions = {}));
32
36
  const resolveTtl = (ttl) => ttl ?? defaultSessionTtlPolicy;
33
37
  const ttlMillis = (ttl) => Duration.toMillis(ttl);
34
38
  const sessionExpiresAt = (now, authTime, ttl) => UnixMillis(Math.min(Number(addMillis(now, ttlMillis(ttl.idleTtl))), Number(addMillis(authTime, ttlMillis(ttl.absoluteTtl)))));
@@ -59,9 +63,123 @@ const issuedFromRow = (row, token) => ({
59
63
  expiresAt: row.expiresAt,
60
64
  aal: row.aal,
61
65
  amr: row.amr,
62
- ...(row.mfaVerifiedAt === undefined ? {} : { mfaVerifiedAt: row.mfaVerifiedAt }),
66
+ authenticationEvents: row.authenticationEvents,
67
+ ...(row.mfaVerifiedAt === undefined
68
+ ? {}
69
+ : { mfaVerifiedAt: row.mfaVerifiedAt }),
63
70
  claims: row.claims,
71
+ ...(row.rotatedAt === undefined ? {} : { rotatedAt: row.rotatedAt }),
72
+ });
73
+ const requirements = (claims) => {
74
+ const sorted = [];
75
+ for (const requirement of new Set(claims?.requirements)) {
76
+ const index = sorted.findIndex((item) => item.localeCompare(requirement) > 0);
77
+ if (index === -1) {
78
+ sorted.push(requirement);
79
+ }
80
+ else {
81
+ sorted.splice(index, 0, requirement);
82
+ }
83
+ }
84
+ return sorted;
85
+ };
86
+ const changedRequirements = (left, right) => left.filter((requirement) => !right.includes(requirement));
87
+ /** Decorates only committed assurance rotations; audit failures never fail authentication. */
88
+ export const makeSessionsAssuranceAudit = (dependencies) => ({
89
+ ...dependencies.sessions,
90
+ assureAndRotate: (input) => dependencies.sessions.validate(input.token).pipe(Effect.mapError((cause) => new SessionRotateError({
91
+ message: "Failed to load session before assurance rotation",
92
+ cause: cause.cause instanceof CustomEvidencePolicyError ||
93
+ cause.cause instanceof AuthenticationEvidenceTimeError
94
+ ? cause.cause
95
+ : cause,
96
+ })), Effect.flatMap((before) => dependencies.sessions.assureAndRotate(input).pipe(Effect.tap((result) => {
97
+ const transition = dependencies.options.transition(input, result);
98
+ const rotatedAt = result.rotatedAt ?? result.authTime;
99
+ const context = dependencies.options.context(result.userId, result.sessionId);
100
+ const oldRequirements = requirements(before.currentSession.claims);
101
+ const newRequirements = requirements(result.claims);
102
+ return dependencies.auditLog
103
+ .emit({
104
+ type: transition.type,
105
+ actor: context.actor,
106
+ userId: result.userId,
107
+ sessionId: result.sessionId,
108
+ oldAal: before.currentSession.aal,
109
+ newAal: result.aal,
110
+ amr: result.amr,
111
+ method: transition.method,
112
+ rotatedAt,
113
+ requirementsEntered: changedRequirements(newRequirements, oldRequirements),
114
+ requirementsCleared: changedRequirements(oldRequirements, newRequirements),
115
+ occurredAt: rotatedAt,
116
+ ...(context.request === undefined
117
+ ? {}
118
+ : { request: context.request }),
119
+ ...(dependencies.options.eventId === undefined
120
+ ? {}
121
+ : {
122
+ id: dependencies.options.eventId(transition.type, result.sessionId, rotatedAt),
123
+ }),
124
+ })
125
+ .pipe(Effect.ignore);
126
+ })))),
64
127
  });
128
+ const emitAtomicAssurance = (auditLog, options, type, method, before, result) => {
129
+ const rotatedAt = result.rotatedAt ?? result.authTime;
130
+ const context = options.context(result.userId, result.sessionId);
131
+ const newRequirements = requirements(result.claims);
132
+ const requirementsEntered = type === "auth.session.recovery_remediation.entered" &&
133
+ newRequirements.includes("recovery_remediation")
134
+ ? ["recovery_remediation"]
135
+ : [];
136
+ return auditLog
137
+ .emit({
138
+ type,
139
+ actor: context.actor,
140
+ userId: result.userId,
141
+ sessionId: result.sessionId,
142
+ oldAal: before.level,
143
+ newAal: result.aal,
144
+ amr: result.amr,
145
+ method,
146
+ rotatedAt,
147
+ requirementsEntered,
148
+ requirementsCleared: [],
149
+ occurredAt: rotatedAt,
150
+ ...(context.request === undefined ? {} : { request: context.request }),
151
+ ...(options.eventId === undefined
152
+ ? {}
153
+ : { id: options.eventId(type, result.sessionId, rotatedAt) }),
154
+ })
155
+ .pipe(Effect.ignore);
156
+ };
157
+ export const makeTotpSessionRotationAudit = (dependencies) => {
158
+ const customEvidencePolicies = dependencies.customEvidencePolicies ?? emptyCustomEvidencePolicyRegistry;
159
+ return TotpSessionRotation.of({
160
+ acceptAndRotate: (input) => Effect.fromResult(deriveAssuranceResult(input.expectedAuthenticationEvents, {
161
+ customEvidencePolicies,
162
+ })).pipe(Effect.mapError((cause) => new SessionRotateError({
163
+ message: "Session evidence policy validation failed",
164
+ cause,
165
+ })), Effect.flatMap((before) => dependencies.rotation
166
+ .acceptAndRotate(input)
167
+ .pipe(Effect.tap((result) => emitAtomicAssurance(dependencies.auditLog, dependencies.options, "auth.session.step_up_completed", "totp", before, result))))),
168
+ });
169
+ };
170
+ export const makeRecoveryCodeSessionRotationAudit = (dependencies) => {
171
+ const customEvidencePolicies = dependencies.customEvidencePolicies ?? emptyCustomEvidencePolicyRegistry;
172
+ return RecoveryCodeSessionRotation.of({
173
+ consumeAndRotate: (input) => Effect.fromResult(deriveAssuranceResult(input.expectedAuthenticationEvents, {
174
+ customEvidencePolicies,
175
+ })).pipe(Effect.mapError((cause) => new SessionRotateError({
176
+ message: "Session evidence policy validation failed",
177
+ cause,
178
+ })), Effect.flatMap((before) => dependencies.rotation
179
+ .consumeAndRotate(input)
180
+ .pipe(Effect.tap((result) => emitAtomicAssurance(dependencies.auditLog, dependencies.options, "auth.session.recovery_remediation.entered", "recovery_code", before, result))))),
181
+ });
182
+ };
65
183
  const currentFromRow = (row) => ({
66
184
  sessionId: row.id,
67
185
  userId: row.userId,
@@ -69,7 +187,10 @@ const currentFromRow = (row) => ({
69
187
  expiresAt: row.expiresAt,
70
188
  aal: row.aal,
71
189
  amr: row.amr,
72
- ...(row.mfaVerifiedAt === undefined ? {} : { mfaVerifiedAt: row.mfaVerifiedAt }),
190
+ authenticationEvents: row.authenticationEvents,
191
+ ...(row.mfaVerifiedAt === undefined
192
+ ? {}
193
+ : { mfaVerifiedAt: row.mfaVerifiedAt }),
73
194
  claims: row.claims,
74
195
  });
75
196
  const infoFromRow = (row) => ({
@@ -81,25 +202,44 @@ const infoFromRow = (row) => ({
81
202
  expiresAt: row.expiresAt,
82
203
  aal: row.aal,
83
204
  amr: row.amr,
84
- ...(row.mfaVerifiedAt === undefined ? {} : { mfaVerifiedAt: row.mfaVerifiedAt }),
205
+ authenticationEvents: row.authenticationEvents,
206
+ ...(row.mfaVerifiedAt === undefined
207
+ ? {}
208
+ : { mfaVerifiedAt: row.mfaVerifiedAt }),
85
209
  claims: row.claims,
86
210
  ...(row.metadata === undefined ? {} : { metadata: row.metadata }),
87
211
  });
88
- const aalRank = {
89
- aal1: 1,
90
- aal2: 2,
91
- aal3: 3,
212
+ const asEvidence = (evidence) => Array.isArray(evidence) ? evidence : [evidence];
213
+ const summarizeAuthenticationEventsResult = (events, customEvidencePolicies) => {
214
+ const assurance = deriveAssuranceResult(events, { customEvidencePolicies });
215
+ if (Result.isFailure(assurance)) {
216
+ return Result.fail(assurance.failure);
217
+ }
218
+ const mfaVerifiedAt = deriveMfaVerifiedAtResult(events, customEvidencePolicies);
219
+ if (Result.isFailure(mfaVerifiedAt)) {
220
+ return Result.fail(mfaVerifiedAt.failure);
221
+ }
222
+ return Result.succeed({
223
+ assurance: assurance.success,
224
+ mfaVerifiedAt: mfaVerifiedAt.success,
225
+ });
92
226
  };
93
- const strongerAal = (left, right) => (aalRank[left] >= aalRank[right] ? left : right);
94
- const asMethods = (method) => typeof method === "string" ? [method] : method;
95
- const appendMethods = (current, methods) => {
96
- const next = [...current];
97
- for (const method of methods) {
98
- if (!next.includes(method)) {
99
- next.push(method);
100
- }
227
+ const prepareSessionAssuranceResult = (events, customEvidencePolicies, serverNow) => {
228
+ const timestampValidation = validateAuthenticationEvidenceTimestamps(events, serverNow);
229
+ if (Result.isFailure(timestampValidation)) {
230
+ return Result.fail(timestampValidation.failure);
231
+ }
232
+ const authenticationEvents = compactAuthenticationEventsResult(events, maximumSessionAuthenticationEvents, customEvidencePolicies);
233
+ if (Result.isFailure(authenticationEvents)) {
234
+ return Result.fail(authenticationEvents.failure);
101
235
  }
102
- return next;
236
+ const summary = summarizeAuthenticationEventsResult(authenticationEvents.success, customEvidencePolicies);
237
+ return Result.isFailure(summary)
238
+ ? Result.fail(summary.failure)
239
+ : Result.succeed({
240
+ authenticationEvents: authenticationEvents.success,
241
+ ...summary.success,
242
+ });
103
243
  };
104
244
  const sessionActivityTime = (row) => Number(row.lastSeenAt ?? row.createdAt);
105
245
  const activeSessionsForUser = (rows, now, ttl) => {
@@ -130,62 +270,116 @@ export const makeSessions = (dependencies) => {
130
270
  const ttl = resolveTtl(dependencies.ttl);
131
271
  const sessionIdBytes = dependencies.sessionIdBytes ?? 16;
132
272
  const sessionSecretBytes = dependencies.sessionSecretBytes ?? 32;
133
- return Sessions.make({
134
- create: Effect.fn("auth.session.create")(function* (input) {
135
- yield* Effect.annotateCurrentSpan({
136
- "auth.method": input.method,
137
- "auth.aal": input.aal,
138
- "auth.amr_count": input.amr.length,
273
+ const customEvidencePolicies = dependencies.customEvidencePolicies ?? emptyCustomEvidencePolicyRegistry;
274
+ const prepareAssurance = (events, serverNow) => prepareSessionAssuranceResult(events, customEvidencePolicies, serverNow);
275
+ const summarize = (events) => summarizeAuthenticationEventsResult(events, customEvidencePolicies);
276
+ const validateRowAssurance = (row, serverNow) => {
277
+ const timestampValidation = validateAuthenticationEvidenceTimestamps(row.authenticationEvents, serverNow);
278
+ if (Result.isFailure(timestampValidation)) {
279
+ return Result.fail(timestampValidation.failure);
280
+ }
281
+ const summary = summarize(row.authenticationEvents);
282
+ if (Result.isFailure(summary)) {
283
+ return Result.fail(summary.failure);
284
+ }
285
+ const { assurance, mfaVerifiedAt } = summary.success;
286
+ if (assurance.authenticatedAt === undefined ||
287
+ !assurance.primaryEstablished ||
288
+ assurance.level !== row.aal ||
289
+ JSON.stringify(assurance.amr) !== JSON.stringify(row.amr) ||
290
+ Number(assurance.authenticatedAt) !== Number(row.authTime) ||
291
+ mfaVerifiedAt !== row.mfaVerifiedAt) {
292
+ return Result.fail(new Error("Session assurance summary does not match registered evidence policy"));
293
+ }
294
+ return Result.void;
295
+ };
296
+ const prepareCreate = Effect.fn("auth.session.prepare_create")(function* (input) {
297
+ const serverNow = yield* currentUnixMillis;
298
+ const now = input.now ?? serverNow;
299
+ const preparedAssurance = yield* Effect.fromResult(prepareAssurance(input.authenticationEvents, serverNow)).pipe(Effect.mapError((cause) => new SessionCreateError({
300
+ message: "Session evidence policy validation failed",
301
+ cause,
302
+ })));
303
+ const { assurance, authenticationEvents, mfaVerifiedAt: derivedMfaVerifiedAt, } = preparedAssurance;
304
+ if (authenticationEvents.length === 0) {
305
+ return yield* new SessionCreateError({
306
+ message: "At least one authentication event is required",
139
307
  });
140
- const now = input.now ?? (yield* currentUnixMillis);
141
- const inputTtl = resolveTtl(input.ttl ?? ttl);
142
- const sessionId = SessionId(yield* dependencies.crypto.randomToken(sessionIdBytes).pipe(Effect.mapError((cause) => new SessionCreateError({
143
- message: "Failed to generate session id",
144
- cause,
145
- }))));
146
- const secret = yield* dependencies.crypto
147
- .randomToken(sessionSecretBytes)
148
- .pipe(Effect.mapError((cause) => new SessionCreateError({
149
- message: "Failed to generate session secret",
150
- cause,
151
- })));
152
- const token = makeSessionToken(sessionId, secret);
153
- const secretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, secret).pipe(Effect.mapError((cause) => new SessionCreateError({
154
- message: "Failed to hash session secret",
155
- cause,
156
- })));
157
- const expiresAt = sessionExpiresAt(now, now, inputTtl);
158
- yield* dependencies.sessionStore
159
- .insert({
160
- id: sessionId,
161
- userId: input.userId,
162
- secretHash,
163
- createdAt: now,
164
- expiresAt,
165
- authTime: now,
166
- aal: input.aal,
167
- amr: input.amr,
168
- mfaVerifiedAt: input.mfaVerifiedAt,
169
- claims: input.claims,
170
- metadata: input.metadata,
171
- })
172
- .pipe(Effect.mapError((cause) => new SessionCreateError({
173
- message: "Failed to store session",
174
- cause,
175
- })));
176
- return {
308
+ }
309
+ if (!assurance.primaryEstablished) {
310
+ return yield* new SessionCreateError({
311
+ message: "Authentication events did not establish a primary factor",
312
+ });
313
+ }
314
+ const authTime = assurance.authenticatedAt;
315
+ if (authTime === undefined) {
316
+ return yield* new SessionCreateError({
317
+ message: "Authentication events did not establish an auth time",
318
+ });
319
+ }
320
+ yield* Effect.annotateCurrentSpan({
321
+ "auth.aal": assurance.level,
322
+ "auth.amr_count": assurance.amr.length,
323
+ });
324
+ const inputTtl = resolveTtl(input.ttl ?? ttl);
325
+ const sessionId = SessionId(yield* dependencies.crypto.randomToken(sessionIdBytes).pipe(Effect.mapError((cause) => new SessionCreateError({
326
+ message: "Failed to generate session id",
327
+ cause,
328
+ }))));
329
+ const secret = yield* dependencies.crypto
330
+ .randomToken(sessionSecretBytes)
331
+ .pipe(Effect.mapError((cause) => new SessionCreateError({
332
+ message: "Failed to generate session secret",
333
+ cause,
334
+ })));
335
+ const token = makeSessionToken(sessionId, secret);
336
+ const secretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, secret).pipe(Effect.mapError((cause) => new SessionCreateError({
337
+ message: "Failed to hash session secret",
338
+ cause,
339
+ })));
340
+ const expiresAt = sessionExpiresAt(now, authTime, inputTtl);
341
+ const row = {
342
+ id: sessionId,
343
+ userId: input.userId,
344
+ secretHash,
345
+ createdAt: now,
346
+ expiresAt,
347
+ authTime,
348
+ authenticationEvents,
349
+ aal: assurance.level,
350
+ amr: assurance.amr,
351
+ mfaVerifiedAt: derivedMfaVerifiedAt,
352
+ claims: input.claims,
353
+ metadata: input.metadata,
354
+ };
355
+ return {
356
+ row,
357
+ session: {
177
358
  sessionId,
178
359
  userId: input.userId,
179
360
  token,
180
- authTime: now,
361
+ authTime,
181
362
  expiresAt,
182
- aal: input.aal,
183
- amr: input.amr,
184
- ...(input.mfaVerifiedAt === undefined
363
+ aal: assurance.level,
364
+ amr: assurance.amr,
365
+ authenticationEvents,
366
+ ...(derivedMfaVerifiedAt === undefined
185
367
  ? {}
186
- : { mfaVerifiedAt: input.mfaVerifiedAt }),
368
+ : { mfaVerifiedAt: derivedMfaVerifiedAt }),
187
369
  claims: input.claims,
188
- };
370
+ },
371
+ };
372
+ });
373
+ return Sessions.of({
374
+ customEvidencePolicies,
375
+ prepareCreate,
376
+ create: Effect.fn("auth.session.create")(function* (input) {
377
+ const prepared = yield* prepareCreate(input);
378
+ yield* dependencies.sessionStore.insert(prepared.row).pipe(Effect.mapError((cause) => new SessionCreateError({
379
+ message: "Failed to store session",
380
+ cause,
381
+ })));
382
+ return prepared.session;
189
383
  }),
190
384
  validate: Effect.fn("auth.session.validate")(function* (token) {
191
385
  const parsed = parseSessionToken(token);
@@ -209,6 +403,10 @@ export const makeSessions = (dependencies) => {
209
403
  });
210
404
  }
211
405
  const row = rowOption.value;
406
+ yield* Effect.fromResult(validateRowAssurance(row, now)).pipe(Effect.mapError((cause) => new SessionValidateError({
407
+ message: "Session evidence policy validation failed",
408
+ cause,
409
+ })));
212
410
  if (isExpired(row, now, ttl)) {
213
411
  return yield* new SessionValidateError({ message: "Session expired" });
214
412
  }
@@ -247,6 +445,10 @@ export const makeSessions = (dependencies) => {
247
445
  return yield* new SessionRefreshError({ message: "Session not found" });
248
446
  }
249
447
  const row = rowOption.value;
448
+ yield* Effect.fromResult(validateRowAssurance(row, now)).pipe(Effect.mapError((cause) => new SessionRefreshError({
449
+ message: "Session evidence policy validation failed",
450
+ cause,
451
+ })));
250
452
  if (isExpired(row, now, ttl)) {
251
453
  return yield* new SessionRefreshError({ message: "Session expired" });
252
454
  }
@@ -285,6 +487,19 @@ export const makeSessions = (dependencies) => {
285
487
  }),
286
488
  rotate: Effect.fn("auth.session.rotate")(function* (input) {
287
489
  const now = yield* currentUnixMillis;
490
+ const rowOption = yield* dependencies.sessionStore
491
+ .findById(input.sessionId)
492
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
493
+ message: "Failed to load session",
494
+ cause,
495
+ })));
496
+ if (Option.isNone(rowOption)) {
497
+ return yield* new SessionRotateError({ message: "Session not found" });
498
+ }
499
+ yield* Effect.fromResult(validateRowAssurance(rowOption.value, now)).pipe(Effect.mapError((cause) => new SessionRotateError({
500
+ message: "Session evidence policy validation failed",
501
+ cause,
502
+ })));
288
503
  const secret = yield* dependencies.crypto
289
504
  .randomToken(sessionSecretBytes)
290
505
  .pipe(Effect.mapError((cause) => new SessionRotateError({
@@ -324,6 +539,10 @@ export const makeSessions = (dependencies) => {
324
539
  message: "Session not found",
325
540
  });
326
541
  }
542
+ yield* Effect.fromResult(validateRowAssurance(rowOption.value, now)).pipe(Effect.mapError((cause) => new SessionUpdateClaimsError({
543
+ message: "Session evidence policy validation failed",
544
+ cause,
545
+ })));
327
546
  if (isExpired(rowOption.value, now, ttl)) {
328
547
  return yield* new SessionUpdateClaimsError({
329
548
  message: "Session expired",
@@ -333,11 +552,6 @@ export const makeSessions = (dependencies) => {
333
552
  .updateClaims({
334
553
  sessionId: input.sessionId,
335
554
  ...(input.claims === undefined ? {} : { claims: input.claims }),
336
- ...(input.aal === undefined ? {} : { aal: input.aal }),
337
- ...(input.amr === undefined ? {} : { amr: input.amr }),
338
- ...(input.mfaVerifiedAt === undefined
339
- ? {}
340
- : { mfaVerifiedAt: input.mfaVerifiedAt }),
341
555
  })
342
556
  .pipe(Effect.mapError((cause) => new SessionUpdateClaimsError({
343
557
  message: "Failed to update session claims",
@@ -350,12 +564,154 @@ export const makeSessions = (dependencies) => {
350
564
  }
351
565
  return currentFromRow(updated.value);
352
566
  }),
567
+ appendEvidence: Effect.fn("auth.session.append_evidence")(function* (sessionId, evidence, claims) {
568
+ const now = yield* currentUnixMillis;
569
+ const rowOption = yield* dependencies.sessionStore
570
+ .findById(sessionId)
571
+ .pipe(Effect.mapError((cause) => new SessionUpdateClaimsError({
572
+ message: "Failed to load session",
573
+ cause,
574
+ })));
575
+ if (Option.isNone(rowOption)) {
576
+ return yield* new SessionUpdateClaimsError({
577
+ message: "Session not found",
578
+ });
579
+ }
580
+ yield* Effect.fromResult(validateRowAssurance(rowOption.value, now)).pipe(Effect.mapError((cause) => new SessionUpdateClaimsError({
581
+ message: "Session evidence policy validation failed",
582
+ cause,
583
+ })));
584
+ const preparedAssurance = yield* Effect.fromResult(prepareAssurance([...rowOption.value.authenticationEvents, ...asEvidence(evidence)], now)).pipe(Effect.mapError((cause) => new SessionUpdateClaimsError({
585
+ message: "Session evidence policy validation failed",
586
+ cause,
587
+ })));
588
+ const { assurance, authenticationEvents, mfaVerifiedAt } = preparedAssurance;
589
+ if (!assurance.primaryEstablished) {
590
+ return yield* new SessionUpdateClaimsError({
591
+ message: "Session evidence did not establish a primary factor",
592
+ });
593
+ }
594
+ const updated = yield* dependencies.sessionStore
595
+ .appendEvidence({
596
+ sessionId,
597
+ authenticationEvents,
598
+ authTime: assurance.authenticatedAt ?? rowOption.value.authTime,
599
+ aal: assurance.level,
600
+ amr: assurance.amr,
601
+ mfaVerifiedAt,
602
+ ...(claims === undefined ? {} : { claims }),
603
+ })
604
+ .pipe(Effect.mapError((cause) => new SessionUpdateClaimsError({
605
+ message: "Failed to append session evidence",
606
+ cause,
607
+ })));
608
+ if (Option.isNone(updated)) {
609
+ return yield* new SessionUpdateClaimsError({
610
+ message: "Session not found",
611
+ });
612
+ }
613
+ return currentFromRow(updated.value);
614
+ }),
615
+ assureAndRotate: Effect.fn("auth.session.assure_and_rotate")(function* (input) {
616
+ const parsed = parseSessionToken(input.token);
617
+ if (parsed === undefined) {
618
+ return yield* new SessionRotateError({
619
+ message: "Invalid session token",
620
+ });
621
+ }
622
+ const now = yield* currentUnixMillis;
623
+ const current = yield* dependencies.sessionStore
624
+ .findById(parsed.sessionId)
625
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
626
+ message: "Failed to load session",
627
+ cause,
628
+ })));
629
+ if (Option.isNone(current) || isExpired(current.value, now, ttl)) {
630
+ return yield* new SessionRotateError({
631
+ message: "Session is not active",
632
+ });
633
+ }
634
+ yield* Effect.fromResult(validateRowAssurance(current.value, now)).pipe(Effect.mapError((cause) => new SessionRotateError({
635
+ message: "Session evidence policy validation failed",
636
+ cause,
637
+ })));
638
+ const expectedSecretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, parsed.secret).pipe(Effect.mapError((cause) => new SessionRotateError({
639
+ message: "Failed to hash session secret",
640
+ cause,
641
+ })));
642
+ const secretMatches = yield* timingSafeEqualString(dependencies.crypto, expectedSecretHash, current.value.secretHash).pipe(Effect.mapError((cause) => new SessionRotateError({
643
+ message: "Failed to compare session secret",
644
+ cause,
645
+ })));
646
+ if (!secretMatches) {
647
+ return yield* new SessionRotateError({
648
+ message: "Invalid session token",
649
+ });
650
+ }
651
+ const secret = yield* dependencies.crypto
652
+ .randomToken(sessionSecretBytes)
653
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
654
+ message: "Failed to generate session secret",
655
+ cause,
656
+ })));
657
+ const secretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, secret).pipe(Effect.mapError((cause) => new SessionRotateError({
658
+ message: "Failed to hash session secret",
659
+ cause,
660
+ })));
661
+ const activeEvents = input.supersedeRecoveryEvidence === true
662
+ ? current.value.authenticationEvents.filter((event) => event.type !== "recovery_code")
663
+ : current.value.authenticationEvents;
664
+ const preparedAssurance = yield* Effect.fromResult(prepareAssurance([...activeEvents, ...asEvidence(input.evidence)], now)).pipe(Effect.mapError((cause) => new SessionRotateError({
665
+ message: "Session evidence policy validation failed",
666
+ cause,
667
+ })));
668
+ const { assurance, authenticationEvents, mfaVerifiedAt } = preparedAssurance;
669
+ if (!assurance.primaryEstablished) {
670
+ return yield* new SessionRotateError({
671
+ message: "Session evidence did not establish a primary factor",
672
+ });
673
+ }
674
+ const updated = yield* dependencies.sessionStore
675
+ .assureAndRotate({
676
+ sessionId: parsed.sessionId,
677
+ expectedSecretHash,
678
+ expectedAuthenticationEvents: current.value.authenticationEvents,
679
+ secretHash,
680
+ rotatedAt: now,
681
+ now,
682
+ authenticationEvents,
683
+ authTime: assurance.authenticatedAt ?? current.value.authTime,
684
+ aal: assurance.level,
685
+ amr: assurance.amr,
686
+ mfaVerifiedAt,
687
+ ...(input.claims === undefined ? {} : { claims: input.claims }),
688
+ })
689
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
690
+ message: "Failed to update session assurance",
691
+ cause,
692
+ })));
693
+ if (Option.isNone(updated)) {
694
+ return yield* new SessionRotateError({
695
+ message: "Session changed or is not active",
696
+ });
697
+ }
698
+ return issuedFromRow(updated.value, makeSessionToken(parsed.sessionId, secret));
699
+ }),
353
700
  listForUser: Effect.fn("auth.session.list_for_user")(function* (input) {
354
701
  const now = yield* currentUnixMillis;
355
702
  const rows = yield* dependencies.sessionStore.listByUser(input).pipe(Effect.mapError((cause) => new SessionListError({
356
703
  message: "Failed to list user sessions",
357
704
  cause,
358
705
  })));
706
+ for (const row of rows) {
707
+ if (isExpired(row, now, ttl)) {
708
+ continue;
709
+ }
710
+ yield* Effect.fromResult(validateRowAssurance(row, now)).pipe(Effect.mapError((cause) => new SessionListError({
711
+ message: "Session evidence policy validation failed",
712
+ cause,
713
+ })));
714
+ }
359
715
  return activeSessionsForUser(rows, now, ttl);
360
716
  }),
361
717
  revoke: Effect.fn("auth.session.revoke")(function* (input) {
@@ -426,10 +782,194 @@ export const makeSessions = (dependencies) => {
426
782
  }),
427
783
  });
428
784
  };
785
+ export const makeTotpSessionRotation = (dependencies) => {
786
+ const ttl = dependencies.ttl ?? defaultSessionTtlPolicy;
787
+ const sessionSecretBytes = dependencies.sessionSecretBytes ?? 32;
788
+ const customEvidencePolicies = dependencies.customEvidencePolicies ?? emptyCustomEvidencePolicyRegistry;
789
+ return TotpSessionRotation.of({
790
+ acceptAndRotate: Effect.fn("auth.totp.accept_and_rotate")(function* (input) {
791
+ const parsed = parseSessionToken(input.token);
792
+ if (parsed === undefined) {
793
+ return yield* new SessionRotateError({
794
+ message: "Invalid session token",
795
+ });
796
+ }
797
+ const now = yield* currentUnixMillis;
798
+ const expectedSecretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, parsed.secret).pipe(Effect.mapError((cause) => new SessionRotateError({
799
+ message: "Failed to hash session secret",
800
+ cause,
801
+ })));
802
+ const secret = yield* dependencies.crypto
803
+ .randomToken(sessionSecretBytes)
804
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
805
+ message: "Failed to generate session secret",
806
+ cause,
807
+ })));
808
+ const secretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, secret).pipe(Effect.mapError((cause) => new SessionRotateError({
809
+ message: "Failed to hash session secret",
810
+ cause,
811
+ })));
812
+ const preparedAssurance = yield* Effect.fromResult(prepareSessionAssuranceResult([
813
+ ...input.expectedAuthenticationEvents,
814
+ ...asEvidence(input.evidence),
815
+ ], customEvidencePolicies, now)).pipe(Effect.mapError((cause) => new SessionRotateError({
816
+ message: "Session evidence policy validation failed",
817
+ cause,
818
+ })));
819
+ const { assurance, authenticationEvents, mfaVerifiedAt } = preparedAssurance;
820
+ if (!assurance.primaryEstablished) {
821
+ return yield* new SessionRotateError({
822
+ message: "Session evidence did not establish a primary factor",
823
+ });
824
+ }
825
+ const updated = yield* dependencies.store
826
+ .acceptAndRotate({
827
+ factorId: input.factorId,
828
+ userId: input.userId,
829
+ counter: input.acceptedCounter,
830
+ lastUsedAt: now,
831
+ ...(input.factorMetadata === undefined
832
+ ? {}
833
+ : { factorMetadata: input.factorMetadata }),
834
+ sessionId: parsed.sessionId,
835
+ expectedSecretHash,
836
+ expectedAuthenticationEvents: input.expectedAuthenticationEvents,
837
+ secretHash,
838
+ rotatedAt: now,
839
+ now,
840
+ authenticationEvents,
841
+ authTime: assurance.authenticatedAt ?? now,
842
+ aal: assurance.level,
843
+ amr: assurance.amr,
844
+ mfaVerifiedAt,
845
+ ...(input.claims === undefined ? {} : { claims: input.claims }),
846
+ })
847
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
848
+ message: "Failed to accept TOTP counter",
849
+ cause,
850
+ })));
851
+ if (Option.isNone(updated) || isExpired(updated.value, now, ttl)) {
852
+ return yield* new SessionRotateError({
853
+ message: "Session or TOTP factor changed",
854
+ });
855
+ }
856
+ return issuedFromRow(updated.value, makeSessionToken(parsed.sessionId, secret));
857
+ }),
858
+ });
859
+ };
860
+ export const makeRecoveryCodeSessionRotation = (dependencies) => {
861
+ const ttl = dependencies.ttl ?? defaultSessionTtlPolicy;
862
+ const sessionSecretBytes = dependencies.sessionSecretBytes ?? 32;
863
+ const customEvidencePolicies = dependencies.customEvidencePolicies ?? emptyCustomEvidencePolicyRegistry;
864
+ return RecoveryCodeSessionRotation.of({
865
+ consumeAndRotate: Effect.fn("auth.recovery_code.consume_and_rotate")(function* (input) {
866
+ const parsed = parseSessionToken(input.token);
867
+ if (parsed === undefined) {
868
+ return yield* new SessionRotateError({
869
+ message: "Invalid session token",
870
+ });
871
+ }
872
+ const now = yield* currentUnixMillis;
873
+ const expectedSecretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, parsed.secret).pipe(Effect.mapError((cause) => new SessionRotateError({
874
+ message: "Failed to hash session secret",
875
+ cause,
876
+ })));
877
+ const secret = yield* dependencies.crypto
878
+ .randomToken(sessionSecretBytes)
879
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
880
+ message: "Failed to generate session secret",
881
+ cause,
882
+ })));
883
+ const secretHash = yield* hashSessionSecret(dependencies.crypto, dependencies.secret, secret).pipe(Effect.mapError((cause) => new SessionRotateError({
884
+ message: "Failed to hash session secret",
885
+ cause,
886
+ })));
887
+ const preparedAssurance = yield* Effect.fromResult(prepareSessionAssuranceResult([
888
+ ...input.expectedAuthenticationEvents,
889
+ ...asEvidence(input.evidence),
890
+ ], customEvidencePolicies, now)).pipe(Effect.mapError((cause) => new SessionRotateError({
891
+ message: "Session evidence policy validation failed",
892
+ cause,
893
+ })));
894
+ const { assurance, authenticationEvents, mfaVerifiedAt } = preparedAssurance;
895
+ if (!assurance.primaryEstablished) {
896
+ return yield* new SessionRotateError({
897
+ message: "Session evidence did not establish a primary factor",
898
+ });
899
+ }
900
+ const updated = yield* dependencies.store
901
+ .consumeAndRotate({
902
+ codeId: input.codeId,
903
+ userId: input.userId,
904
+ usedAt: now,
905
+ ...(input.codeMetadata === undefined
906
+ ? {}
907
+ : { codeMetadata: input.codeMetadata }),
908
+ sessionId: parsed.sessionId,
909
+ expectedSecretHash,
910
+ expectedAuthenticationEvents: input.expectedAuthenticationEvents,
911
+ secretHash,
912
+ rotatedAt: now,
913
+ now,
914
+ authenticationEvents,
915
+ authTime: assurance.authenticatedAt ?? now,
916
+ aal: assurance.level,
917
+ amr: assurance.amr,
918
+ mfaVerifiedAt,
919
+ ...(input.claims === undefined ? {} : { claims: input.claims }),
920
+ })
921
+ .pipe(Effect.mapError((cause) => new SessionRotateError({
922
+ message: "Failed to consume recovery code",
923
+ cause,
924
+ })));
925
+ if (Option.isNone(updated) || isExpired(updated.value, now, ttl)) {
926
+ return yield* new SessionRotateError({
927
+ message: "Session changed or is not active",
928
+ });
929
+ }
930
+ return issuedFromRow(updated.value, makeSessionToken(parsed.sessionId, secret));
931
+ }),
932
+ });
933
+ };
934
+ export function RecoveryCodeSessionRotationLive(options) {
935
+ return Layer.effect(RecoveryCodeSessionRotation)(Effect.gen(function* () {
936
+ const crypto = yield* Crypto;
937
+ const store = yield* RecoveryCodeSessionRotateStore;
938
+ const customEvidencePolicies = yield* Effect.serviceOption(CustomEvidencePolicies);
939
+ const resolved = options ?? { secret: (yield* AuthSecrets).session };
940
+ return makeRecoveryCodeSessionRotation({
941
+ ...resolved,
942
+ crypto,
943
+ store,
944
+ ...(resolved.customEvidencePolicies === undefined &&
945
+ Option.isSome(customEvidencePolicies)
946
+ ? { customEvidencePolicies: customEvidencePolicies.value }
947
+ : {}),
948
+ });
949
+ }));
950
+ }
951
+ export function TotpSessionRotationLive(options) {
952
+ return Layer.effect(TotpSessionRotation)(Effect.gen(function* () {
953
+ const crypto = yield* Crypto;
954
+ const store = yield* TotpSessionRotateStore;
955
+ const customEvidencePolicies = yield* Effect.serviceOption(CustomEvidencePolicies);
956
+ const resolved = options ?? { secret: (yield* AuthSecrets).session };
957
+ return makeTotpSessionRotation({
958
+ ...resolved,
959
+ crypto,
960
+ store,
961
+ ...(resolved.customEvidencePolicies === undefined &&
962
+ Option.isSome(customEvidencePolicies)
963
+ ? { customEvidencePolicies: customEvidencePolicies.value }
964
+ : {}),
965
+ });
966
+ }));
967
+ }
429
968
  export function SessionsLive(options) {
430
969
  return Layer.effect(Sessions)(Effect.gen(function* () {
431
970
  const crypto = yield* Crypto;
432
971
  const sessionStore = yield* SessionStore;
972
+ const customEvidencePolicies = yield* Effect.serviceOption(CustomEvidencePolicies);
433
973
  const resolvedOptions = options ??
434
974
  {
435
975
  ...(yield* AuthSessionsConfig),
@@ -439,27 +979,25 @@ export function SessionsLive(options) {
439
979
  ...resolvedOptions,
440
980
  crypto,
441
981
  sessionStore,
982
+ ...(resolvedOptions.customEvidencePolicies === undefined &&
983
+ Option.isSome(customEvidencePolicies)
984
+ ? { customEvidencePolicies: customEvidencePolicies.value }
985
+ : {}),
442
986
  });
443
987
  }));
444
988
  }
445
989
  export const upgradeCurrentSession = (input) => Effect.gen(function* () {
446
990
  const current = yield* CurrentSession;
447
991
  const sessions = yield* Sessions;
448
- const now = input.now ?? (yield* currentUnixMillis);
449
- return yield* sessions.updateClaims({
450
- sessionId: current.sessionId,
451
- aal: strongerAal(current.aal, input.aal ?? "aal2"),
452
- amr: appendMethods(current.amr, asMethods(input.method)),
453
- mfaVerifiedAt: now,
454
- ...(input.claims === undefined ? {} : { claims: input.claims }),
455
- reason: input.reason ?? "mfa_verified",
456
- });
992
+ return yield* sessions.appendEvidence(current.sessionId, input.evidence, input.claims);
993
+ });
994
+ export const reauthenticateCurrentSession = (input) => Effect.gen(function* () {
995
+ const current = yield* CurrentSession;
996
+ const sessions = yield* Sessions;
997
+ return yield* sessions.appendEvidence(current.sessionId, input.evidence, input.claims);
457
998
  });
458
999
  export class SessionCookie extends Context.Service()("auth/SessionCookie") {
459
1000
  }
460
- (function (SessionCookie) {
461
- SessionCookie.make = (service) => SessionCookie.of(service);
462
- })(SessionCookie || (SessionCookie = {}));
463
1001
  export const defaultSessionCookieOptions = {
464
1002
  name: "__Host-session",
465
1003
  secure: true,
@@ -542,7 +1080,7 @@ const parseCookieHeader = (header, name) => {
542
1080
  };
543
1081
  export const makeSessionCookie = (options) => {
544
1082
  const resolved = resolveSessionCookieOptions(options);
545
- return SessionCookie.make({
1083
+ return SessionCookie.of({
546
1084
  read: Effect.fn("auth.session_cookie.read")((request) => Effect.succeed(parseCookieHeader(request.headers.get("Cookie"), resolved.name))),
547
1085
  commit: Effect.fn("auth.session_cookie.commit")((issued) => Effect.succeed(serializeSessionCookie(resolved, issued.token, issued.expiresAt))),
548
1086
  clear: Effect.fn("auth.session_cookie.clear")(() => Effect.succeed(serializeClearSessionCookie(resolved)))(),
@@ -554,12 +1092,6 @@ export const SessionCookieLive = (options) => Layer.effect(SessionCookie)(Effect
554
1092
  }));
555
1093
  export class CurrentSession extends Context.Service()("auth/CurrentSession") {
556
1094
  }
557
- (function (CurrentSession) {
558
- CurrentSession.make = (service) => CurrentSession.of(service);
559
- })(CurrentSession || (CurrentSession = {}));
560
1095
  export class CurrentActor extends Context.Service()("auth/CurrentActor") {
561
1096
  }
562
- (function (CurrentActor) {
563
- CurrentActor.make = (service) => CurrentActor.of(service);
564
- })(CurrentActor || (CurrentActor = {}));
565
1097
  //# sourceMappingURL=Sessions.js.map