@yielded/auth-persistence 0.1.0-beta.24 → 0.1.0-beta.26

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 (481) hide show
  1. package/README.md +6 -8
  2. package/dist/Adapter.d.mts +47 -33
  3. package/dist/Adapter.mjs +36 -23
  4. package/dist/OAuthPersistence.d.mts +35 -51
  5. package/dist/OAuthPersistence.mjs +60 -68
  6. package/dist/OAuthPersistence.mjs.map +1 -1
  7. package/dist/index.d.mts +2 -2
  8. package/dist/index.mjs +2 -2
  9. package/dist/internal/browser-login.d.mts +1 -1
  10. package/dist/internal/browser-login.mjs +29 -9
  11. package/dist/internal/browser-login.mjs.map +1 -1
  12. package/dist/internal/configuration.d.mts +13 -8
  13. package/dist/internal/configuration.mjs.map +1 -1
  14. package/dist/internal/crypto.d.mts +1 -0
  15. package/dist/internal/crypto.mjs +1 -1
  16. package/dist/internal/d1-planning.mjs +8 -0
  17. package/dist/internal/d1-planning.mjs.map +1 -0
  18. package/dist/internal/email-native-state.mjs +135 -0
  19. package/dist/internal/email-native-state.mjs.map +1 -0
  20. package/dist/internal/email-native.d.mts +17 -0
  21. package/dist/internal/email-native.mjs +245 -0
  22. package/dist/internal/email-native.mjs.map +1 -0
  23. package/dist/internal/email-policy.mjs +92 -0
  24. package/dist/internal/email-policy.mjs.map +1 -0
  25. package/dist/internal/email-registration-native.d.mts +38 -0
  26. package/dist/internal/email-registration-native.mjs +171 -0
  27. package/dist/internal/email-registration-native.mjs.map +1 -0
  28. package/dist/internal/models/email-model.d.mts +40 -104
  29. package/dist/internal/models/email-model.mjs +3 -5
  30. package/dist/internal/models/email-model.mjs.map +1 -1
  31. package/dist/internal/models/oauth-connected-model.d.mts +44 -213
  32. package/dist/internal/models/oauth-connected-model.mjs +6 -14
  33. package/dist/internal/models/oauth-connected-model.mjs.map +1 -1
  34. package/dist/internal/models/oauth-model.d.mts +95 -244
  35. package/dist/internal/models/oauth-model.mjs +28 -22
  36. package/dist/internal/models/oauth-model.mjs.map +1 -1
  37. package/dist/internal/models/passkey-model.d.mts +11 -147
  38. package/dist/internal/models/passkey-model.mjs +5 -24
  39. package/dist/internal/models/passkey-model.mjs.map +1 -1
  40. package/dist/internal/models/passkey-registration-ceremony-model.d.mts +5 -39
  41. package/dist/internal/models/passkey-write-model.d.mts +17 -75
  42. package/dist/internal/models/passkey-write-model.mjs +1 -7
  43. package/dist/internal/models/passkey-write-model.mjs.map +1 -1
  44. package/dist/internal/models/password-model.d.mts +16 -82
  45. package/dist/internal/models/password-model.mjs +1 -4
  46. package/dist/internal/models/password-model.mjs.map +1 -1
  47. package/dist/internal/models/phone-model.d.mts +86 -0
  48. package/dist/internal/models/phone-model.mjs +10 -0
  49. package/dist/internal/models/phone-model.mjs.map +1 -0
  50. package/dist/internal/models/proof-model.d.mts +43 -272
  51. package/dist/internal/models/proof-model.mjs +2 -10
  52. package/dist/internal/models/proof-model.mjs.map +1 -1
  53. package/dist/internal/models/session-model.d.mts +74 -93
  54. package/dist/internal/models/session-model.mjs +3 -11
  55. package/dist/internal/models/session-model.mjs.map +1 -1
  56. package/dist/internal/models/step-up-model.d.mts +12 -50
  57. package/dist/internal/models/step-up-model.mjs +2 -4
  58. package/dist/internal/models/step-up-model.mjs.map +1 -1
  59. package/dist/internal/models/totp-model.d.mts +76 -0
  60. package/dist/internal/models/totp-model.mjs +10 -0
  61. package/dist/internal/models/totp-model.mjs.map +1 -0
  62. package/dist/internal/native-sql-table.d.mts +21 -4
  63. package/dist/internal/native-sql-table.mjs +9 -5
  64. package/dist/internal/native-sql-table.mjs.map +1 -1
  65. package/dist/internal/oauth/native-accounts.d.mts +17 -0
  66. package/dist/internal/oauth/native-accounts.mjs +290 -0
  67. package/dist/internal/oauth/native-accounts.mjs.map +1 -0
  68. package/dist/internal/oauth/native-connected-state.d.mts +11 -0
  69. package/dist/internal/oauth/native-connected-state.mjs +146 -0
  70. package/dist/internal/oauth/native-connected-state.mjs.map +1 -0
  71. package/dist/internal/oauth/native-connected.d.mts +15 -0
  72. package/dist/internal/oauth/native-connected.mjs +462 -0
  73. package/dist/internal/oauth/native-connected.mjs.map +1 -0
  74. package/dist/internal/oauth/native-flow.mjs +138 -0
  75. package/dist/internal/oauth/native-flow.mjs.map +1 -0
  76. package/dist/internal/oauth/native-layers.d.mts +24 -0
  77. package/dist/internal/oauth/native-layers.mjs +13 -0
  78. package/dist/internal/oauth/native-layers.mjs.map +1 -0
  79. package/dist/internal/oauth/native-mutation.mjs +122 -0
  80. package/dist/internal/oauth/native-mutation.mjs.map +1 -0
  81. package/dist/internal/oauth/native-registration.d.mts +24 -0
  82. package/dist/internal/oauth/native-registration.mjs +328 -0
  83. package/dist/internal/oauth/native-registration.mjs.map +1 -0
  84. package/dist/internal/oauth/native-revocations.d.mts +17 -0
  85. package/dist/internal/oauth/native-revocations.mjs +106 -0
  86. package/dist/internal/oauth/native-revocations.mjs.map +1 -0
  87. package/dist/internal/oauth/native-sign-in.d.mts +17 -0
  88. package/dist/internal/oauth/native-sign-in.mjs +50 -0
  89. package/dist/internal/oauth/native-sign-in.mjs.map +1 -0
  90. package/dist/internal/oauth/native-state.d.mts +10 -0
  91. package/dist/internal/oauth/native-state.mjs +214 -0
  92. package/dist/internal/oauth/native-state.mjs.map +1 -0
  93. package/dist/internal/oauth/state.d.mts +10 -0
  94. package/dist/internal/oauth/state.mjs +3 -27
  95. package/dist/internal/oauth/state.mjs.map +1 -1
  96. package/dist/internal/passkey-actions.mjs +55 -0
  97. package/dist/internal/passkey-actions.mjs.map +1 -0
  98. package/dist/internal/passkey-inputs.mjs +73 -0
  99. package/dist/internal/passkey-inputs.mjs.map +1 -0
  100. package/dist/internal/passkey-managed.mjs +224 -0
  101. package/dist/internal/passkey-managed.mjs.map +1 -0
  102. package/dist/internal/passkey-native-ceremony.d.mts +35 -0
  103. package/dist/internal/passkey-native-ceremony.mjs +38 -0
  104. package/dist/internal/passkey-native-ceremony.mjs.map +1 -0
  105. package/dist/internal/passkey-native-flow.mjs +91 -0
  106. package/dist/internal/passkey-native-flow.mjs.map +1 -0
  107. package/dist/internal/passkey-native-registration.d.mts +10 -0
  108. package/dist/internal/passkey-native-registration.mjs +114 -0
  109. package/dist/internal/passkey-native-registration.mjs.map +1 -0
  110. package/dist/internal/passkey-native-state.d.mts +15 -0
  111. package/dist/internal/passkey-native-state.mjs +186 -0
  112. package/dist/internal/passkey-native-state.mjs.map +1 -0
  113. package/dist/internal/passkey-native-write.d.mts +82 -0
  114. package/dist/internal/passkey-native-write.mjs +330 -0
  115. package/dist/internal/passkey-native-write.mjs.map +1 -0
  116. package/dist/internal/passkey-native.d.mts +835 -0
  117. package/dist/internal/passkey-native.mjs +175 -0
  118. package/dist/internal/passkey-native.mjs.map +1 -0
  119. package/dist/internal/passkey-policy.mjs +115 -0
  120. package/dist/internal/passkey-policy.mjs.map +1 -0
  121. package/dist/internal/password-credentials.mjs +38 -9
  122. package/dist/internal/password-credentials.mjs.map +1 -1
  123. package/dist/internal/password-native.d.mts +14 -0
  124. package/dist/internal/password-native.mjs +292 -0
  125. package/dist/internal/password-native.mjs.map +1 -0
  126. package/dist/internal/password-policy.mjs +93 -0
  127. package/dist/internal/password-policy.mjs.map +1 -0
  128. package/dist/internal/password-registration-native.d.mts +22 -0
  129. package/dist/internal/password-registration-native.mjs +142 -0
  130. package/dist/internal/password-registration-native.mjs.map +1 -0
  131. package/dist/internal/persistence.d.mts +6 -19
  132. package/dist/internal/persistence.mjs +199 -166
  133. package/dist/internal/persistence.mjs.map +1 -1
  134. package/dist/internal/phone-composed.mjs +79 -0
  135. package/dist/internal/phone-composed.mjs.map +1 -0
  136. package/dist/internal/phone-native.d.mts +15 -0
  137. package/dist/internal/phone-native.mjs +354 -0
  138. package/dist/internal/phone-native.mjs.map +1 -0
  139. package/dist/internal/proof-native.d.mts +15 -0
  140. package/dist/internal/proof-native.mjs +289 -0
  141. package/dist/internal/proof-native.mjs.map +1 -0
  142. package/dist/internal/registration.mjs +50 -60
  143. package/dist/internal/registration.mjs.map +1 -1
  144. package/dist/internal/session-native-authority.d.mts +15 -0
  145. package/dist/internal/session-native-authority.mjs +91 -0
  146. package/dist/internal/session-native-authority.mjs.map +1 -0
  147. package/dist/internal/session-native-cleanup.d.mts +14 -0
  148. package/dist/internal/session-native-cleanup.mjs +48 -0
  149. package/dist/internal/session-native-cleanup.mjs.map +1 -0
  150. package/dist/internal/session-native-login.d.mts +15 -0
  151. package/dist/internal/session-native-login.mjs +87 -0
  152. package/dist/internal/session-native-login.mjs.map +1 -0
  153. package/dist/internal/session-native-pending-read.mjs +42 -0
  154. package/dist/internal/session-native-pending-read.mjs.map +1 -0
  155. package/dist/internal/session-native-pending.mjs +134 -0
  156. package/dist/internal/session-native-pending.mjs.map +1 -0
  157. package/dist/internal/session-native-record.mjs +79 -0
  158. package/dist/internal/session-native-record.mjs.map +1 -0
  159. package/dist/internal/session-native-state.mjs +130 -0
  160. package/dist/internal/session-native-state.mjs.map +1 -0
  161. package/dist/internal/session-native-stateful.d.mts +16 -0
  162. package/dist/internal/session-native-stateful.mjs +225 -0
  163. package/dist/internal/session-native-stateful.mjs.map +1 -0
  164. package/dist/internal/session-native-step-up.d.mts +15 -0
  165. package/dist/internal/session-native-step-up.mjs +212 -0
  166. package/dist/internal/session-native-step-up.mjs.map +1 -0
  167. package/dist/internal/session-native-validity.d.mts +15 -0
  168. package/dist/internal/session-native-validity.mjs +97 -0
  169. package/dist/internal/session-native-validity.mjs.map +1 -0
  170. package/dist/internal/session-policy.mjs +29 -0
  171. package/dist/internal/session-policy.mjs.map +1 -0
  172. package/dist/internal/sql-authority.d.mts +16 -0
  173. package/dist/internal/sql-authority.mjs +32 -0
  174. package/dist/internal/sql-authority.mjs.map +1 -0
  175. package/dist/internal/sql-change.mjs +21 -0
  176. package/dist/internal/sql-change.mjs.map +1 -0
  177. package/dist/internal/sql-cleanup.mjs +35 -0
  178. package/dist/internal/sql-cleanup.mjs.map +1 -0
  179. package/dist/internal/sql-commit.d.mts +72 -0
  180. package/dist/internal/sql-commit.mjs +176 -0
  181. package/dist/internal/sql-commit.mjs.map +1 -0
  182. package/dist/internal/sql-expression.d.mts +17 -0
  183. package/dist/internal/sql-expression.mjs +49 -0
  184. package/dist/internal/sql-expression.mjs.map +1 -0
  185. package/dist/internal/sql-oauth-connected-model.d.mts +7 -23
  186. package/dist/internal/sql-oauth-model.d.mts +27 -52
  187. package/dist/internal/sql-oauth-model.mjs +3 -4
  188. package/dist/internal/sql-oauth-model.mjs.map +1 -1
  189. package/dist/internal/sql-persistence.mjs +5 -9
  190. package/dist/internal/sql-persistence.mjs.map +1 -1
  191. package/dist/internal/sql-storage-validation.mjs +1 -2
  192. package/dist/internal/sql-storage-validation.mjs.map +1 -1
  193. package/dist/internal/sql-table.d.mts +3 -16
  194. package/dist/internal/sql-table.mjs +21 -42
  195. package/dist/internal/sql-table.mjs.map +1 -1
  196. package/dist/internal/standalone.mjs +2 -3
  197. package/dist/internal/standalone.mjs.map +1 -1
  198. package/dist/internal/step-up-state.mjs +5 -8
  199. package/dist/internal/step-up-state.mjs.map +1 -1
  200. package/dist/internal/storage-clock.mjs +44 -0
  201. package/dist/internal/storage-clock.mjs.map +1 -0
  202. package/dist/internal/storage-mapping.d.mts +11 -8
  203. package/dist/internal/storage-mapping.mjs +88 -302
  204. package/dist/internal/storage-mapping.mjs.map +1 -1
  205. package/dist/internal/storage-plans.mjs +15 -73
  206. package/dist/internal/storage-plans.mjs.map +1 -1
  207. package/dist/internal/storage-tables.d.mts +37 -520
  208. package/dist/internal/storage-tables.mjs +31 -211
  209. package/dist/internal/storage-tables.mjs.map +1 -1
  210. package/dist/internal/storage-validation.d.mts +1 -6
  211. package/dist/internal/storage-validation.mjs +1 -42
  212. package/dist/internal/storage-validation.mjs.map +1 -1
  213. package/dist/internal/table-model.d.mts +21 -0
  214. package/dist/internal/totp-native.d.mts +15 -0
  215. package/dist/internal/totp-native.mjs +401 -0
  216. package/dist/internal/totp-native.mjs.map +1 -0
  217. package/package.json +1 -1
  218. package/src/Adapter.ts +143 -199
  219. package/src/OAuthPersistence.ts +128 -271
  220. package/src/index.ts +1 -1
  221. package/src/internal/browser-login.ts +54 -24
  222. package/src/internal/configuration.ts +16 -31
  223. package/src/internal/d1-planning.ts +7 -0
  224. package/src/internal/email-native-state.ts +247 -0
  225. package/src/internal/email-native.ts +514 -0
  226. package/src/internal/email-policy.ts +235 -0
  227. package/src/internal/email-registration-native.ts +386 -0
  228. package/src/internal/models/email-model.ts +76 -214
  229. package/src/internal/models/oauth-connected-model.ts +50 -288
  230. package/src/internal/models/oauth-model.ts +147 -368
  231. package/src/internal/models/passkey-model.ts +11 -208
  232. package/src/internal/models/passkey-registration-ceremony-model.ts +6 -60
  233. package/src/internal/models/passkey-write-model.ts +14 -95
  234. package/src/internal/models/password-model.ts +28 -148
  235. package/src/internal/models/phone-model.ts +110 -0
  236. package/src/internal/models/proof-model.ts +48 -404
  237. package/src/internal/models/session-model.ts +102 -200
  238. package/src/internal/models/step-up-model.ts +17 -96
  239. package/src/internal/models/totp-model.ts +82 -0
  240. package/src/internal/native-sql-table.ts +32 -11
  241. package/src/internal/oauth/native-accounts.ts +576 -0
  242. package/src/internal/oauth/native-connected-state.ts +288 -0
  243. package/src/internal/oauth/native-connected.ts +888 -0
  244. package/src/internal/oauth/native-flow.ts +253 -0
  245. package/src/internal/oauth/native-layers.ts +83 -0
  246. package/src/internal/oauth/native-mutation.ts +222 -0
  247. package/src/internal/oauth/native-registration.ts +545 -0
  248. package/src/internal/oauth/native-revocations.ts +190 -0
  249. package/src/internal/oauth/native-sign-in.ts +111 -0
  250. package/src/internal/oauth/native-state.ts +346 -0
  251. package/src/internal/oauth/state.ts +2 -70
  252. package/src/internal/passkey-actions.ts +70 -0
  253. package/src/internal/passkey-inputs.ts +56 -0
  254. package/src/internal/passkey-managed.ts +360 -0
  255. package/src/internal/passkey-native-ceremony.ts +66 -0
  256. package/src/internal/passkey-native-flow.ts +140 -0
  257. package/src/internal/passkey-native-registration.ts +221 -0
  258. package/src/internal/passkey-native-state.ts +335 -0
  259. package/src/internal/passkey-native-write.ts +611 -0
  260. package/src/internal/passkey-native.ts +372 -0
  261. package/src/internal/passkey-policy.ts +246 -0
  262. package/src/internal/password-credentials.ts +52 -10
  263. package/src/internal/password-native.ts +571 -0
  264. package/src/internal/password-policy.ts +307 -0
  265. package/src/internal/password-registration-native.ts +322 -0
  266. package/src/internal/persistence.ts +336 -290
  267. package/src/internal/phone-composed.ts +86 -0
  268. package/src/internal/phone-native.ts +659 -0
  269. package/src/internal/proof-native.ts +448 -0
  270. package/src/internal/registration.ts +96 -143
  271. package/src/internal/session-native-authority.ts +247 -0
  272. package/src/internal/session-native-cleanup.ts +65 -0
  273. package/src/internal/session-native-login.ts +205 -0
  274. package/src/internal/session-native-pending-read.ts +68 -0
  275. package/src/internal/session-native-pending.ts +223 -0
  276. package/src/internal/session-native-record.ts +141 -0
  277. package/src/internal/session-native-state.ts +259 -0
  278. package/src/internal/session-native-stateful.ts +512 -0
  279. package/src/internal/session-native-step-up.ts +450 -0
  280. package/src/internal/session-native-validity.ts +208 -0
  281. package/src/internal/session-policy.ts +59 -0
  282. package/src/internal/sql-authority.ts +56 -0
  283. package/src/internal/sql-change.ts +38 -0
  284. package/src/internal/sql-cleanup.ts +56 -0
  285. package/src/internal/sql-commit.ts +435 -0
  286. package/src/internal/sql-expression.ts +94 -0
  287. package/src/internal/sql-metadata.ts +100 -0
  288. package/src/internal/sql-oauth-connected-model.ts +6 -95
  289. package/src/internal/sql-oauth-model.ts +31 -134
  290. package/src/internal/sql-persistence.ts +2 -6
  291. package/src/internal/sql-storage-validation.ts +1 -2
  292. package/src/internal/sql-table.ts +19 -52
  293. package/src/internal/standalone.ts +2 -11
  294. package/src/internal/step-up-state.ts +4 -17
  295. package/src/internal/storage-clock.ts +58 -0
  296. package/src/internal/storage-mapping.ts +125 -340
  297. package/src/internal/storage-plans.ts +14 -80
  298. package/src/internal/storage-tables.ts +28 -212
  299. package/src/internal/storage-validation.ts +0 -58
  300. package/src/internal/table-model.ts +24 -0
  301. package/src/internal/totp-native.ts +701 -0
  302. package/dist/internal/PasswordPreparedPostconditions.d.mts +0 -22
  303. package/dist/internal/PasswordPreparedPostconditions.mjs +0 -12
  304. package/dist/internal/PasswordPreparedPostconditions.mjs.map +0 -1
  305. package/dist/internal/authority-snapshot.mjs +0 -53
  306. package/dist/internal/authority-snapshot.mjs.map +0 -1
  307. package/dist/internal/email-kernel.d.mts +0 -276
  308. package/dist/internal/email-kernel.mjs +0 -497
  309. package/dist/internal/email-kernel.mjs.map +0 -1
  310. package/dist/internal/models/passkey-registration-ceremony-model.mjs +0 -18
  311. package/dist/internal/models/passkey-registration-ceremony-model.mjs.map +0 -1
  312. package/dist/internal/oauth/accounts.d.mts +0 -8
  313. package/dist/internal/oauth/accounts.mjs +0 -379
  314. package/dist/internal/oauth/accounts.mjs.map +0 -1
  315. package/dist/internal/oauth/connected-access.d.mts +0 -9
  316. package/dist/internal/oauth/connected-access.mjs +0 -229
  317. package/dist/internal/oauth/connected-access.mjs.map +0 -1
  318. package/dist/internal/oauth/connected-collection.d.mts +0 -7
  319. package/dist/internal/oauth/connected-collection.mjs +0 -214
  320. package/dist/internal/oauth/connected-collection.mjs.map +0 -1
  321. package/dist/internal/oauth/connected-custody.d.mts +0 -6
  322. package/dist/internal/oauth/connected-custody.mjs +0 -165
  323. package/dist/internal/oauth/connected-custody.mjs.map +0 -1
  324. package/dist/internal/oauth/connected-flow.d.mts +0 -7
  325. package/dist/internal/oauth/connected-flow.mjs +0 -324
  326. package/dist/internal/oauth/connected-flow.mjs.map +0 -1
  327. package/dist/internal/oauth/connected-input.mjs +0 -122
  328. package/dist/internal/oauth/connected-input.mjs.map +0 -1
  329. package/dist/internal/oauth/connected-keys.d.mts +0 -2
  330. package/dist/internal/oauth/connected-keys.mjs +0 -22
  331. package/dist/internal/oauth/connected-keys.mjs.map +0 -1
  332. package/dist/internal/oauth/connected-maintenance.d.mts +0 -9
  333. package/dist/internal/oauth/connected-maintenance.mjs +0 -226
  334. package/dist/internal/oauth/connected-maintenance.mjs.map +0 -1
  335. package/dist/internal/oauth/connected-management.d.mts +0 -9
  336. package/dist/internal/oauth/connected-management.mjs +0 -243
  337. package/dist/internal/oauth/connected-management.mjs.map +0 -1
  338. package/dist/internal/oauth/connected-reference.mjs +0 -63
  339. package/dist/internal/oauth/connected-reference.mjs.map +0 -1
  340. package/dist/internal/oauth/connected-settlement.d.mts +0 -8
  341. package/dist/internal/oauth/connected-settlement.mjs +0 -141
  342. package/dist/internal/oauth/connected-settlement.mjs.map +0 -1
  343. package/dist/internal/oauth/connected-sign-in.d.mts +0 -10
  344. package/dist/internal/oauth/connected-sign-in.mjs +0 -281
  345. package/dist/internal/oauth/connected-sign-in.mjs.map +0 -1
  346. package/dist/internal/oauth/connected-state.d.mts +0 -14
  347. package/dist/internal/oauth/connected-state.mjs +0 -469
  348. package/dist/internal/oauth/connected-state.mjs.map +0 -1
  349. package/dist/internal/oauth/connected-target.d.mts +0 -21
  350. package/dist/internal/oauth/connected-target.mjs +0 -117
  351. package/dist/internal/oauth/connected-target.mjs.map +0 -1
  352. package/dist/internal/oauth/flow.d.mts +0 -5
  353. package/dist/internal/oauth/flow.mjs +0 -279
  354. package/dist/internal/oauth/flow.mjs.map +0 -1
  355. package/dist/internal/oauth/input.mjs +0 -127
  356. package/dist/internal/oauth/input.mjs.map +0 -1
  357. package/dist/internal/oauth/owner.d.mts +0 -10
  358. package/dist/internal/oauth/owner.mjs +0 -10
  359. package/dist/internal/oauth/owner.mjs.map +0 -1
  360. package/dist/internal/oauth/query-compiler.d.mts +0 -7
  361. package/dist/internal/oauth/query-compiler.mjs +0 -9
  362. package/dist/internal/oauth/query-compiler.mjs.map +0 -1
  363. package/dist/internal/oauth/registration.d.mts +0 -7
  364. package/dist/internal/oauth/registration.mjs +0 -393
  365. package/dist/internal/oauth/registration.mjs.map +0 -1
  366. package/dist/internal/oauth/target.d.mts +0 -31
  367. package/dist/internal/oauth/target.mjs +0 -273
  368. package/dist/internal/oauth/target.mjs.map +0 -1
  369. package/dist/internal/oauth-kernel.d.mts +0 -1423
  370. package/dist/internal/oauth-kernel.mjs +0 -187
  371. package/dist/internal/oauth-kernel.mjs.map +0 -1
  372. package/dist/internal/passkey/admission.d.mts +0 -6
  373. package/dist/internal/passkey/admission.mjs +0 -220
  374. package/dist/internal/passkey/admission.mjs.map +0 -1
  375. package/dist/internal/passkey/credentials.d.mts +0 -14
  376. package/dist/internal/passkey/credentials.mjs +0 -249
  377. package/dist/internal/passkey/credentials.mjs.map +0 -1
  378. package/dist/internal/passkey/enrollment.mjs +0 -138
  379. package/dist/internal/passkey/enrollment.mjs.map +0 -1
  380. package/dist/internal/passkey/flow.d.mts +0 -21
  381. package/dist/internal/passkey/flow.mjs +0 -452
  382. package/dist/internal/passkey/flow.mjs.map +0 -1
  383. package/dist/internal/passkey/management.mjs +0 -231
  384. package/dist/internal/passkey/management.mjs.map +0 -1
  385. package/dist/internal/passkey/registration-ceremony.d.mts +0 -9
  386. package/dist/internal/passkey/registration-ceremony.mjs +0 -129
  387. package/dist/internal/passkey/registration-ceremony.mjs.map +0 -1
  388. package/dist/internal/passkey/registration-custody.d.mts +0 -2
  389. package/dist/internal/passkey/registration-custody.mjs +0 -52
  390. package/dist/internal/passkey/registration-custody.mjs.map +0 -1
  391. package/dist/internal/passkey/registration-write.mjs +0 -211
  392. package/dist/internal/passkey/registration-write.mjs.map +0 -1
  393. package/dist/internal/passkey/state.d.mts +0 -10
  394. package/dist/internal/passkey/state.mjs +0 -234
  395. package/dist/internal/passkey/state.mjs.map +0 -1
  396. package/dist/internal/passkey/target.d.mts +0 -20
  397. package/dist/internal/passkey/target.mjs +0 -200
  398. package/dist/internal/passkey/target.mjs.map +0 -1
  399. package/dist/internal/passkey/write-state.d.mts +0 -17
  400. package/dist/internal/passkey/write-state.mjs +0 -346
  401. package/dist/internal/passkey/write-state.mjs.map +0 -1
  402. package/dist/internal/passkey/write-target.mjs +0 -192
  403. package/dist/internal/passkey/write-target.mjs.map +0 -1
  404. package/dist/internal/passkey-kernel.d.mts +0 -6045
  405. package/dist/internal/passkey-kernel.mjs +0 -49
  406. package/dist/internal/passkey-kernel.mjs.map +0 -1
  407. package/dist/internal/passkeys.d.mts +0 -7
  408. package/dist/internal/passkeys.mjs +0 -387
  409. package/dist/internal/passkeys.mjs.map +0 -1
  410. package/dist/internal/password-credentials.d.mts +0 -11
  411. package/dist/internal/password-kernel.d.mts +0 -278
  412. package/dist/internal/password-kernel.mjs +0 -508
  413. package/dist/internal/password-kernel.mjs.map +0 -1
  414. package/dist/internal/phone-kernel.d.mts +0 -162
  415. package/dist/internal/phone-kernel.mjs +0 -437
  416. package/dist/internal/phone-kernel.mjs.map +0 -1
  417. package/dist/internal/proof-kernel.d.mts +0 -94
  418. package/dist/internal/proof-kernel.mjs +0 -624
  419. package/dist/internal/proof-kernel.mjs.map +0 -1
  420. package/dist/internal/query-operations.d.mts +0 -68
  421. package/dist/internal/session-kernel.d.mts +0 -62
  422. package/dist/internal/session-kernel.mjs +0 -820
  423. package/dist/internal/session-kernel.mjs.map +0 -1
  424. package/dist/internal/sql-oauth-connected-model.mjs +0 -7
  425. package/dist/internal/sql-oauth-connected-model.mjs.map +0 -1
  426. package/dist/internal/sql-query.d.mts +0 -12
  427. package/dist/internal/sql-query.mjs +0 -206
  428. package/dist/internal/sql-query.mjs.map +0 -1
  429. package/dist/internal/step-up-state.d.mts +0 -49
  430. package/dist/internal/transaction-execution-kernel.d.mts +0 -37
  431. package/dist/internal/transaction-execution-kernel.mjs +0 -120
  432. package/dist/internal/transaction-execution-kernel.mjs.map +0 -1
  433. package/dist/internal/transaction-kernel.d.mts +0 -81
  434. package/dist/internal/transaction-kernel.mjs +0 -264
  435. package/dist/internal/transaction-kernel.mjs.map +0 -1
  436. package/src/internal/PasswordPreparedPostconditions.ts +0 -30
  437. package/src/internal/authority-snapshot.ts +0 -91
  438. package/src/internal/email-kernel.ts +0 -1555
  439. package/src/internal/oauth/accounts.ts +0 -838
  440. package/src/internal/oauth/connected-access.ts +0 -388
  441. package/src/internal/oauth/connected-collection.ts +0 -345
  442. package/src/internal/oauth/connected-custody.ts +0 -308
  443. package/src/internal/oauth/connected-flow.ts +0 -562
  444. package/src/internal/oauth/connected-input.ts +0 -147
  445. package/src/internal/oauth/connected-keys.ts +0 -31
  446. package/src/internal/oauth/connected-maintenance.ts +0 -379
  447. package/src/internal/oauth/connected-management.ts +0 -391
  448. package/src/internal/oauth/connected-reference.ts +0 -135
  449. package/src/internal/oauth/connected-settlement.ts +0 -278
  450. package/src/internal/oauth/connected-sign-in.ts +0 -472
  451. package/src/internal/oauth/connected-state.ts +0 -924
  452. package/src/internal/oauth/connected-target.ts +0 -307
  453. package/src/internal/oauth/flow.ts +0 -505
  454. package/src/internal/oauth/input.ts +0 -201
  455. package/src/internal/oauth/owner.ts +0 -22
  456. package/src/internal/oauth/query-compiler.ts +0 -15
  457. package/src/internal/oauth/registration.ts +0 -676
  458. package/src/internal/oauth/target.ts +0 -803
  459. package/src/internal/oauth-kernel.ts +0 -294
  460. package/src/internal/passkey/admission.ts +0 -368
  461. package/src/internal/passkey/credentials.ts +0 -511
  462. package/src/internal/passkey/enrollment.ts +0 -326
  463. package/src/internal/passkey/flow.ts +0 -1062
  464. package/src/internal/passkey/management.ts +0 -426
  465. package/src/internal/passkey/registration-ceremony.ts +0 -283
  466. package/src/internal/passkey/registration-custody.ts +0 -91
  467. package/src/internal/passkey/registration-write.ts +0 -426
  468. package/src/internal/passkey/state.ts +0 -351
  469. package/src/internal/passkey/target.ts +0 -598
  470. package/src/internal/passkey/write-state.ts +0 -678
  471. package/src/internal/passkey/write-target.ts +0 -450
  472. package/src/internal/passkey-kernel.ts +0 -112
  473. package/src/internal/passkeys.ts +0 -652
  474. package/src/internal/password-kernel.ts +0 -1522
  475. package/src/internal/phone-kernel.ts +0 -872
  476. package/src/internal/proof-kernel.ts +0 -1992
  477. package/src/internal/query-operations.ts +0 -91
  478. package/src/internal/session-kernel.ts +0 -2406
  479. package/src/internal/sql-query.ts +0 -304
  480. package/src/internal/transaction-execution-kernel.ts +0 -335
  481. package/src/internal/transaction-kernel.ts +0 -603
@@ -1,9 +1,15 @@
1
1
  import { EmailAddressPersistence, EmailUnavailable } from "@yielded/auth/Email";
2
- import { LifecycleHooks } from "@yielded/auth/Hooks";
3
- import type { PasskeyConfig } from "@yielded/auth/Passkey";
2
+ import type { LifecycleHooks } from "@yielded/auth/Hooks";
3
+ import { hasCommitScope } from "@yielded/auth/Hooks";
4
+ import {
5
+ PasskeyCredentials,
6
+ PasskeyManagementPersistence,
7
+ PasskeyPersistence,
8
+ PasskeyUnavailable,
9
+ } from "@yielded/auth/Passkey";
4
10
  import { PasswordPersistence, PasswordUnavailable } from "@yielded/auth/Password";
5
11
  import { hooksLayer } from "@yielded/auth/Persistence";
6
- import { PhoneAdmission, PhoneSignInTargets, PhoneOtpUnavailable } from "@yielded/auth/PhoneOtp";
12
+ import { PhoneSignInTargets, PhoneOtpUnavailable } from "@yielded/auth/PhoneOtp";
7
13
  import { ProofPersistence, ProofUnavailable } from "@yielded/auth/Proofs";
8
14
  import { AuthenticationAuthority, SessionUnavailable } from "@yielded/auth/Sessions";
9
15
  import { Context, type Crypto, Effect, Layer, Schema } from "effect";
@@ -24,27 +30,22 @@ import {
24
30
  type SubjectOptions,
25
31
  type PasskeyFeature,
26
32
  type PasskeyRequirement,
27
- type MappingInput,
28
33
  } from "./configuration";
29
- import { randomId } from "./crypto";
30
- import { makeEmailKernel, CurrentEmailSql, type EmailSqlDatabase } from "./email-kernel";
34
+ import { makeNativeEmailAddressServices } from "./email-native";
31
35
  import { PersistenceMappingError } from "./mapping-error";
32
36
  import type { NativeSqlTables } from "./native-sql-table";
33
- import {
34
- makePasswordKernel,
35
- CurrentPasswordSql,
36
- type PasswordSqlDatabase,
37
- } from "./password-kernel";
38
- import { makePhoneKernel, CurrentPhoneTransaction } from "./phone-kernel";
39
- import {
40
- makeProofKernel,
41
- CurrentProofSql,
42
- type ProofSqlDatabase,
43
- type ProofSqlQuery,
44
- } from "./proof-kernel";
45
- import type { QueryOperations } from "./query-operations";
37
+ import { makeManagedPasskeys } from "./passkey-managed";
38
+ import { makeNativePasswordServices } from "./password-native";
39
+ import { makeComposedPhoneTargets } from "./phone-composed";
40
+ import { makeNativeProofServices } from "./proof-native";
46
41
  import { makeRegistrationAuthority } from "./registration";
47
- import { makeSessionKernel, CurrentSessionSql, type SessionSqlDatabase } from "./session-kernel";
42
+ import type { PasswordRegistrationAuthority } from "./registration-contract";
43
+ import { makeNativeAuthenticationAuthorityServices } from "./session-native-authority";
44
+ import { makeNativeSessionCleanupServices } from "./session-native-cleanup";
45
+ import { makeNativePendingAuthenticationServices } from "./session-native-login";
46
+ import { makeNativeStatefulSessionServices } from "./session-native-stateful";
47
+ import { makeNativeSessionStepUpServices } from "./session-native-step-up";
48
+ import { SqlBatchCommit } from "./sql-commit";
48
49
  import { requireStandalone } from "./standalone";
49
50
  import { makeMappings } from "./storage-mapping";
50
51
  import {
@@ -58,35 +59,12 @@ import {
58
59
  withStorageValidation,
59
60
  type StorageValidation,
60
61
  } from "./storage-validation";
61
- import { makeTransactionExecutionKernel } from "./transaction-execution-kernel";
62
- import {
63
- makeTransactionKernel,
64
- NativeDatabase,
65
- type TransactionNativeDatabase,
66
- } from "./transaction-kernel";
67
62
 
68
- export interface Backend<T extends object, R> {
63
+ export interface Backend<T extends object, R, Database extends object = object> {
69
64
  readonly makeTable: (definition: StorageTable) => T;
70
65
  readonly describe: (table: T) => StorageTable;
71
- readonly acquire: Effect.Effect<object, PersistenceConfigurationError, R | SqlClient.SqlClient>;
72
- readonly operations: QueryOperations;
73
- readonly nativeTables: (client: SqlClient.SqlClient, database: object) => NativeSqlTables;
74
- readonly passkeys: (input: {
75
- readonly storage: MappingInput;
76
- readonly namespace: string;
77
- readonly dialect: "pg" | "sqlite";
78
- readonly features: ReadonlyArray<PasskeyFeature>;
79
- readonly passwordModules: ReadonlyArray<string>;
80
- }) => Effect.Effect<
81
- Context.Context<never>,
82
- PersistenceConfigurationError,
83
- | PasskeyConfig
84
- | LifecycleHooks
85
- | SqlClient.SqlClient
86
- | NativeDatabase
87
- | CurrentProofSql
88
- | Crypto.Crypto
89
- >;
66
+ readonly acquire: Effect.Effect<Database, PersistenceConfigurationError, R | SqlClient.SqlClient>;
67
+ readonly nativeTables: (database: Database) => NativeSqlTables;
90
68
  }
91
69
 
92
70
  const configError = (reason: string) => PersistenceConfigurationError.make({ reason });
@@ -110,17 +88,9 @@ const timestampKeys = new Set([
110
88
  "dedupUntil",
111
89
  ]);
112
90
 
113
- export const createPersistence = <T extends object, R>(
114
- backend: Backend<T, R>,
91
+ export const createPersistence = <T extends object, R, Database extends object = object>(
92
+ backend: Backend<T, R, Database>,
115
93
  ): PersistenceApi<T, R> => {
116
- const proofKernel = makeProofKernel(backend.operations);
117
- const passwordKernel = makePasswordKernel(backend.operations, proofKernel, backend.nativeTables);
118
- const emailKernel = makeEmailKernel(backend.operations, proofKernel);
119
- const sessionKernel = makeSessionKernel(backend.operations, backend.nativeTables);
120
- const transactionKernel = makeTransactionKernel(backend.operations);
121
- const executionKernel = makeTransactionExecutionKernel(transactionKernel);
122
- const phoneKernel = makePhoneKernel(backend.operations, transactionKernel);
123
-
124
94
  const make = <C extends ClaimsCodec, const Id extends string, const A extends Definition<C, Id>>(
125
95
  auth: A & Definition<C, Id>,
126
96
  ) => {
@@ -139,34 +109,12 @@ export const createPersistence = <T extends object, R>(
139
109
  const email = features.some((feature) => feature?.kind === "email" && feature.addresses);
140
110
  const proofs = phone || management || email;
141
111
 
142
- const roles: StorageRole[] = ["identifiers", "credentials", "sessions", "sessionFlows"];
143
-
144
- if (password) roles.push("passwords", "passwordCommands");
145
- if (management) roles.push("passwordRegistrations");
146
- if (email) roles.push("emailCredentials", "emailCommands");
147
- if (phone) roles.push("phoneState");
148
- if (passkeys.length > 0)
149
- roles.push(
150
- "passkeyCredentials",
151
- "passkeyOwnership",
152
- "passkeyHandles",
153
- "passkeyModules",
154
- "passkeyFlows",
155
- "passkeyAdmissions",
156
- "passkeyCharges",
157
- );
158
- if (passkeys.some((feature) => feature.management)) roles.push("passkeyCommands");
159
- if (proofs)
160
- roles.push(
161
- "proofRequests",
162
- "proofSeries",
163
- "proofGenerations",
164
- "proofContinuations",
165
- "proofScopes",
166
- "proofAbuse",
167
- "proofFailures",
168
- "proofCommands",
169
- );
112
+ const roles: StorageRole[] = ["identifiers", "credentials", "sessions", "pending"];
113
+
114
+ if (password) roles.push("passwords");
115
+ if (email) roles.push("emailCredentials");
116
+ if (passkeys.length > 0) roles.push("passkeyCredentials", "passkeyFlows");
117
+ if (proofs) roles.push("proofs");
170
118
 
171
119
  const ConfigKey = Context.Service<
172
120
  ConfigId<A["namespace"]>,
@@ -287,7 +235,6 @@ export const createPersistence = <T extends object, R>(
287
235
  const services = Layer.effectContext(
288
236
  Effect.gen(function* () {
289
237
  const storage = yield* ConfigKey;
290
- const hooks = yield* LifecycleHooks;
291
238
  const client = yield* SqlClient.SqlClient;
292
239
  const database = yield* backend.acquire;
293
240
 
@@ -338,89 +285,75 @@ export const createPersistence = <T extends object, R>(
338
285
  yield* validateStorageBatch(dialect, validations);
339
286
  const mappings = yield* makeMappings(storage);
340
287
 
341
- const standalone = <E>(error: () => E) =>
342
- requireStandalone(error, client.transactionService);
288
+ const nativeTables = backend.nativeTables(database);
289
+ const sessionMapping = mappings.sessions(auth.claims, auth.sessions.moduleId);
290
+ const pendingMapping = mappings.pending(auth.claims, auth.sessions.moduleId);
343
291
 
344
- // Backend validation owns the foreign query-builder shape, never the decoded rows.
345
- const native = database as ProofSqlDatabase &
346
- PasswordSqlDatabase &
347
- EmailSqlDatabase &
348
- SessionSqlDatabase &
349
- TransactionNativeDatabase;
292
+ const sessionServices = yield* makeNativeStatefulSessionServices(
293
+ nativeTables,
294
+ sessionMapping,
295
+ );
350
296
 
351
- const options = {
352
- mode: "interactive" as const,
353
- locking: dialect === "pg",
354
- standaloneGuard: standalone(() => SessionUnavailable.make({})),
355
- };
297
+ const { authenticationAuthority } = yield* makeNativeAuthenticationAuthorityServices(
298
+ nativeTables,
299
+ sessionMapping,
300
+ );
356
301
 
357
- const sessionMapping = mappings.sessions(auth.claims);
302
+ const { pendingAuthentication } = yield* makeNativePendingAuthenticationServices(
303
+ nativeTables,
304
+ pendingMapping,
305
+ );
358
306
 
359
- const sessionServices = yield* sessionKernel
360
- .makeSqlStatefulSessions(sessionMapping, options)
361
- .pipe(
362
- Effect.provideService(CurrentSessionSql, native),
363
- Effect.provideService(NativeDatabase, native),
364
- );
307
+ const { sessionStepUpPersistence } = yield* makeNativeSessionStepUpServices(nativeTables, {
308
+ ...pendingMapping,
309
+ source: {
310
+ kind: "Stateful",
311
+ session: sessionMapping.session,
312
+ sessionId: sessionMapping.sessionId,
313
+ constraints: { sessionDigest: "unique(session.digest)" },
314
+ },
315
+ });
365
316
 
366
- const authority = yield* sessionKernel
367
- .makeSqlAuthenticationAuthority<C["Type"]>(
368
- { ...mappings.authority(), isConstraintConflict: () => false },
369
- options,
370
- )
371
- .pipe(
372
- Effect.provideService(CurrentSessionSql, native),
373
- Effect.provideService(NativeDatabase, native),
374
- );
317
+ const { sessionCleanup } = yield* makeNativeSessionCleanupServices(
318
+ nativeTables,
319
+ pendingMapping,
320
+ );
375
321
 
376
- let context: Context.Context<never> = Context.make(AuthenticationAuthority, authority).pipe(
322
+ let context: Context.Context<never> = Context.make(
323
+ AuthenticationAuthority,
324
+ authenticationAuthority,
325
+ ).pipe(
377
326
  Context.add(
378
327
  auth.sessions.StatefulSessionPersistence,
379
328
  sessionServices.statefulSessionPersistence,
380
329
  ),
381
330
  Context.add(auth.sessions.SessionRepository, sessionServices.sessionRepository),
331
+ Context.add(auth.sessions.PendingAuthentication, pendingAuthentication),
332
+ Context.add(auth.sessions.SessionStepUpPersistence, sessionStepUpPersistence),
333
+ Context.add(auth.sessions.SessionCleanup, sessionCleanup),
382
334
  );
383
335
 
384
- const proofConfiguration = proofs
385
- ? {
386
- mapping: mappings.proofs(),
387
- configuration: {
388
- mode: "interactive" as const,
389
- locking: dialect === "pg",
390
- standaloneGuard: standalone(() => ProofUnavailable.make({})),
391
- insertIfAbsent: (query: ProofSqlQuery) => query.onConflictDoNothing(),
392
- },
393
- }
394
- : undefined;
395
-
396
- if (proofConfiguration !== undefined) {
397
- context = Context.add(
398
- context,
399
- ProofPersistence,
400
- yield* proofKernel
401
- .makeSqlProofPersistence(proofConfiguration.mapping, proofConfiguration.configuration)
402
- .pipe(
403
- Effect.provideService(CurrentProofSql, native),
404
- Effect.provideService(NativeDatabase, native),
405
- ),
336
+ const proofMapping = proofs ? mappings.proofs() : undefined;
337
+
338
+ if (proofMapping !== undefined) {
339
+ const services = yield* makeNativeProofServices(
340
+ backend.nativeTables(database),
341
+ proofMapping,
406
342
  );
343
+
344
+ context = Context.add(context, ProofPersistence, services.proofPersistence);
407
345
  }
408
346
 
409
347
  if (password) {
410
- const persistence = yield* passwordKernel
411
- .makeSqlPasswordPersistence(mappings.passwords(), {
412
- mode: "interactive",
413
- locking: dialect === "pg",
414
- standaloneGuard: standalone(() => PasswordUnavailable.make({})),
415
- insertIfAbsent: (query) => query.onConflictDoNothing(),
416
- ...(proofConfiguration === undefined ? {} : { proof: proofConfiguration }),
417
- })
418
- .pipe(
419
- Effect.provideService(CurrentPasswordSql, native),
420
- Effect.provideService(NativeDatabase, native),
421
- );
348
+ const mapping = mappings.passwords();
422
349
 
423
- context = Context.add(context, PasswordPersistence, persistence);
350
+ const services = yield* makeNativePasswordServices(
351
+ backend.nativeTables(database),
352
+ mapping,
353
+ proofMapping,
354
+ );
355
+
356
+ context = Context.add(context, PasswordPersistence, services.passwordPersistence);
424
357
  }
425
358
  for (const [name, strategy] of Object.entries(auth.strategies)) {
426
359
  if (strategy.persistence?.kind !== "password" || !strategy.persistence.management)
@@ -431,168 +364,63 @@ export const createPersistence = <T extends object, R>(
431
364
  return yield* configError(`Missing subject provisioning for ${name}`);
432
365
 
433
366
  const registration = yield* makeRegistrationAuthority(
434
- mappings,
435
- backend.operations,
436
- standalone(() => PasswordUnavailable.make({})),
367
+ backend.nativeTables(database),
368
+ mappings.passwords(),
437
369
  ProvisioningKey,
438
370
  name,
439
- ).pipe(Effect.provideService(CurrentPasswordSql, native));
371
+ );
440
372
 
441
373
  context = Context.add(context, key, registration);
442
374
  }
443
- if (email) {
375
+ if (email)
444
376
  context = Context.add(
445
377
  context,
446
378
  EmailAddressPersistence,
447
- yield* emailKernel
448
- .makeSqlEmailAddressPersistence(mappings.emails(), {
449
- mode: "interactive",
450
- locking: dialect === "pg",
451
- standaloneGuard: standalone(() => EmailUnavailable.make({})),
452
- ...(proofConfiguration === undefined ? {} : { proof: proofConfiguration }),
453
- })
454
- .pipe(
455
- Effect.provideService(CurrentEmailSql, native),
456
- Effect.provideService(NativeDatabase, native),
457
- ),
379
+ (yield* makeNativeEmailAddressServices(
380
+ backend.nativeTables(database),
381
+ mappings.emails(),
382
+ proofMapping,
383
+ )).emailAddressPersistence,
458
384
  );
459
- }
460
- if (phone) {
461
- const { column, eq } = backend.operations;
462
-
463
- const mapping = (moduleId: string) => ({
464
- moduleId,
465
- subject: {
466
- table: storage.subjects.table,
467
- id: storage.subjects.id,
468
- securityRevision: storage.subjects.securityRevision,
469
- activeCondition: eq(
470
- column(storage.subjects.table, storage.subjects.status),
471
- storage.subjects.activeValue,
472
- ),
473
- },
474
- subjectIds: {
475
- toNative: storage.subjects.toNativeSync,
476
- toSubject: storage.subjects.toSubjectSync,
477
- },
478
- identifier: {
479
- table: mappings.table("identifiers"),
480
- namespace: "namespace",
481
- value: "value",
482
- subjectId: "subjectId",
483
- revision: "revision",
484
- verifiedAt: "verifiedAt",
485
- activeCondition: eq(column(mappings.table("identifiers"), "active"), true),
486
- },
487
- credential: {
488
- table: mappings.table("credentials"),
489
- id: "credentialId",
490
- subjectId: "subjectId",
491
- revision: "revision",
492
- activeCondition: eq(column(mappings.table("credentials"), "active"), true),
493
- },
494
- state: {
495
- table: mappings.table("phoneState"),
496
- scope: "scope",
497
- state: "state",
498
- version: "version",
499
- encodeInsert: (row: object) => row,
500
- },
501
- admission: {
502
- windowMillis: 60_000,
503
- networkRequests: 10,
504
- networkAttempts: 100,
505
- maximumMessages: 10,
506
- requestRetentionMillis: 86_400_000,
507
- },
508
- engineNowMillis: backend.operations
509
- .sql`${dialect === "pg" ? backend.operations.sql`cast(extract(epoch from clock_timestamp()) * 1000 as bigint)` : backend.operations.sql`cast(round((julianday('now') - 2440587.5) * 86400000) as integer)`}`,
510
- encodeInstant: storage.encodeInstant,
511
- });
512
-
513
- const execution = yield* executionKernel
514
- .makeTransactionExecution(
515
- CurrentPhoneTransaction,
516
- {
517
- mode: "interactive",
518
- dialect,
519
- locking: dialect === "pg",
520
- standaloneGuard: () => standalone(() => PhoneOtpUnavailable.make({})),
521
- },
522
- () => PhoneOtpUnavailable.make({}),
523
- randomId,
524
- )
525
- .pipe(Effect.provideService(NativeDatabase, native));
526
-
527
- const run = <Value, E, Requirements>(
528
- work: Effect.Effect<Value, E, Requirements>,
529
- mutation = true,
530
- ) =>
531
- execution.admit.pipe(
532
- Effect.andThen(execution.run(work, mutation)),
533
- Effect.provideService(LifecycleHooks, hooks),
534
- );
535
-
536
- const allowed = (moduleId: string) =>
537
- features.some((feature) => feature?.kind === "phone" && feature.moduleId === moduleId);
538
-
539
- const admission = PhoneAdmission.of({
540
- admit: (request) =>
541
- allowed(request.moduleId)
542
- ? run(phoneKernel.admitPhone(mapping(request.moduleId), request))
543
- : Effect.fail(PhoneOtpUnavailable.make({})),
544
- cleanup: (request) =>
545
- allowed(request.moduleId)
546
- ? run(phoneKernel.cleanupPhoneAdmission(mapping(request.moduleId), request))
547
- : Effect.fail(PhoneOtpUnavailable.make({})),
548
- });
549
385
 
550
- const targets = PhoneSignInTargets.of({
551
- lookup: (request) =>
552
- allowed(request.moduleId)
553
- ? run(phoneKernel.lookupPhone(mapping(request.moduleId), request), false)
554
- : Effect.fail(PhoneOtpUnavailable.make({})),
555
- });
556
-
557
- context = context.pipe(
558
- Context.add(PhoneAdmission, admission),
559
- Context.add(PhoneSignInTargets, targets),
386
+ if (phone)
387
+ context = Context.add(
388
+ context,
389
+ PhoneSignInTargets,
390
+ yield* makeComposedPhoneTargets(
391
+ backend.nativeTables(database),
392
+ storage,
393
+ mappings.proofs(),
394
+ features.flatMap((feature) => (feature?.kind === "phone" ? [feature.moduleId] : [])),
395
+ ),
560
396
  );
561
- }
562
397
 
563
398
  if (passkeys.length > 0) {
564
399
  // Auth capability metadata determines whether PasskeyConfig is required.
565
- const services = backend.passkeys({
566
- storage,
567
- namespace: auth.namespace,
568
- dialect,
569
- features: passkeys,
570
- passwordModules: features.flatMap((feature) =>
571
- feature?.kind === "password" ? [feature.moduleId] : [],
572
- ),
573
- }) as Effect.Effect<
400
+ const services = makeManagedPasskeys(
401
+ {
402
+ storage,
403
+ namespace: auth.namespace,
404
+ dialect,
405
+ features: passkeys,
406
+ passwordModules: features.flatMap((feature) =>
407
+ feature?.kind === "password" ? [feature.moduleId] : [],
408
+ ),
409
+ },
410
+ backend.nativeTables(database),
411
+ ) as Effect.Effect<
574
412
  Context.Context<never>,
575
413
  PersistenceConfigurationError,
576
- | PasskeyRequirement<A>
577
- | Crypto.Crypto
578
- | LifecycleHooks
579
- | SqlClient.SqlClient
580
- | NativeDatabase
581
- | CurrentProofSql
414
+ PasskeyRequirement<A> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient
582
415
  >;
583
416
 
584
- context = Context.merge(
585
- context,
586
- yield* services.pipe(
587
- Effect.provideService(NativeDatabase, native),
588
- Effect.provideService(CurrentProofSql, native),
589
- ),
590
- );
417
+ context = Context.merge(context, yield* services);
591
418
  }
592
419
 
593
420
  // The checked capability metadata above determines exactly these service keys.
594
421
  return context as Context.Context<Ports<C, Id, A>>;
595
422
  }).pipe(
423
+ Effect.provideService(SqlBatchCommit, undefined),
596
424
  withStorageValidation,
597
425
  Effect.mapError((error) =>
598
426
  Schema.is(PersistenceConfigurationError)(error)
@@ -602,10 +430,228 @@ export const createPersistence = <T extends object, R>(
602
430
  ),
603
431
  ).pipe(Layer.provide(hooksLayer));
604
432
 
433
+ const layer = Layer.effectContext(
434
+ Effect.gen(function* () {
435
+ const scope = yield* Effect.scope;
436
+ const captured = yield* Effect.context<Layer.Services<typeof services>>();
437
+ const client = Context.get(captured, SqlClient.SqlClient);
438
+
439
+ // Construction uses the layer's exact environment and lifetime, never the
440
+ // first operation's SQL transaction, service overrides, or request scope.
441
+ // Cache the full exit: concurrent callers share failures/interruption too,
442
+ // and cannot retry partially completed setup within this acquired layer.
443
+ const initialize = yield* Effect.cached(
444
+ Layer.buildWithScope(services, scope).pipe(Effect.setContext(captured)),
445
+ );
446
+
447
+ const service = Effect.fnUntraced(function* <I, S, Failure>(
448
+ key: Context.Key<I, S>,
449
+ unavailable: () => Failure,
450
+ standalone = true,
451
+ ): Effect.fn.Return<S, Failure> {
452
+ // Reject unsupported ownership before setup can perform any writes.
453
+ // Session/authority reads retain their existing ambient-read semantics.
454
+ if (standalone) {
455
+ if (yield* hasCommitScope) return yield* Effect.fail(unavailable());
456
+ yield* requireStandalone(unavailable, client.transactionService);
457
+ }
458
+ const acquired = yield* initialize.pipe(Effect.mapError(unavailable));
459
+ const value = Context.getOrUndefined(acquired, key);
460
+
461
+ return value === undefined ? yield* Effect.fail(unavailable()) : value;
462
+ });
463
+
464
+ const sessionUnavailable = () => SessionUnavailable.make({});
465
+ const authority = service(AuthenticationAuthority, sessionUnavailable, false);
466
+ const authorityMutation = service(AuthenticationAuthority, sessionUnavailable);
467
+
468
+ const sessions = service(
469
+ auth.sessions.StatefulSessionPersistence,
470
+ sessionUnavailable,
471
+ false,
472
+ );
473
+
474
+ const sessionMutations = service(
475
+ auth.sessions.StatefulSessionPersistence,
476
+ sessionUnavailable,
477
+ );
478
+
479
+ const repository = service(auth.sessions.SessionRepository, sessionUnavailable, false);
480
+ const pendingRead = service(auth.sessions.PendingAuthentication, sessionUnavailable, false);
481
+ const pendingMutation = service(auth.sessions.PendingAuthentication, sessionUnavailable);
482
+
483
+ const stepUpRead = service(
484
+ auth.sessions.SessionStepUpPersistence,
485
+ sessionUnavailable,
486
+ false,
487
+ );
488
+
489
+ const stepUpMutation = service(auth.sessions.SessionStepUpPersistence, sessionUnavailable);
490
+ const cleanup = service(auth.sessions.SessionCleanup, sessionUnavailable);
491
+
492
+ let context: Context.Context<never> = Context.make(AuthenticationAuthority, {
493
+ capture: (subjectId, credentialIds) =>
494
+ Effect.flatMap(authority, (s) => s.capture(subjectId, credentialIds)),
495
+ requirements: (evidence) => Effect.flatMap(authority, (s) => s.requirements(evidence)),
496
+ approve: (input, prepare) =>
497
+ Effect.flatMap(authorityMutation, (s) => s.approve(input, prepare)),
498
+ }).pipe(
499
+ Context.add(auth.sessions.StatefulSessionPersistence, {
500
+ establish: (input, prepare) =>
501
+ Effect.flatMap(sessionMutations, (s) => s.establish(input, prepare)),
502
+ verify: (input) => Effect.flatMap(sessions, (s) => s.verify(input)),
503
+ rotate: (input, prepare) =>
504
+ Effect.flatMap(sessionMutations, (s) => s.rotate(input, prepare)),
505
+ revokeDigest: (digest, prepare) =>
506
+ Effect.flatMap(sessionMutations, (s) => s.revokeDigest(digest, prepare)),
507
+ revoke: (input, prepare) =>
508
+ Effect.flatMap(sessionMutations, (s) => s.revoke(input, prepare)),
509
+ revokeAll: (input, prepare) =>
510
+ Effect.flatMap(sessionMutations, (s) => s.revokeAll(input, prepare)),
511
+ }),
512
+ Context.add(auth.sessions.SessionRepository, {
513
+ list: (input) => Effect.flatMap(repository, (s) => s.list(input)),
514
+ }),
515
+ Context.add(auth.sessions.PendingAuthentication, {
516
+ create: (input, now, prepare) =>
517
+ Effect.flatMap(pendingMutation, (s) => s.create(input, now, prepare)),
518
+ read: (input) => Effect.flatMap(pendingRead, (s) => s.read(input)),
519
+ reject: (input, prepare) =>
520
+ Effect.flatMap(pendingMutation, (s) => s.reject(input, prepare)),
521
+ }),
522
+ Context.add(auth.sessions.SessionStepUpPersistence, {
523
+ create: (input, now, prepare) =>
524
+ Effect.flatMap(stepUpMutation, (s) => s.create(input, now, prepare)),
525
+ read: (input) => Effect.flatMap(stepUpRead, (s) => s.read(input)),
526
+ reject: (input, prepare) =>
527
+ Effect.flatMap(stepUpMutation, (s) => s.reject(input, prepare)),
528
+ complete: (plan, prepare) =>
529
+ Effect.flatMap(stepUpMutation, (s) => s.complete(plan, prepare)),
530
+ }),
531
+ Context.add(auth.sessions.SessionCleanup, {
532
+ cleanup: (input) => Effect.flatMap(cleanup, (s) => s.cleanup(input)),
533
+ }),
534
+ );
535
+
536
+ if (proofs) {
537
+ const persistence = service(ProofPersistence, () => ProofUnavailable.make({}));
538
+
539
+ context = Context.add(context, ProofPersistence, {
540
+ issue: (input, prepare) => Effect.flatMap(persistence, (s) => s.issue(input, prepare)),
541
+ redeem: (input, prepare) =>
542
+ Effect.flatMap(persistence, (s) => s.redeem(input, prepare)),
543
+ cancel: (input, prepare) =>
544
+ Effect.flatMap(persistence, (s) => s.cancel(input, prepare)),
545
+ cleanup: (input, prepare) =>
546
+ Effect.flatMap(persistence, (s) => s.cleanup(input, prepare)),
547
+ });
548
+ }
549
+ if (password) {
550
+ const persistence = service(PasswordPersistence, () => PasswordUnavailable.make({}));
551
+
552
+ context = Context.add(context, PasswordPersistence, {
553
+ findCredential: (input) => Effect.flatMap(persistence, (s) => s.findCredential(input)),
554
+ rehashIfCurrent: (input) =>
555
+ Effect.flatMap(persistence, (s) => s.rehashIfCurrent(input)),
556
+ readForSubject: (input) => Effect.flatMap(persistence, (s) => s.readForSubject(input)),
557
+ recoveryTarget: (input) => Effect.flatMap(persistence, (s) => s.recoveryTarget(input)),
558
+ addIfAbsent: (input, prepare) =>
559
+ Effect.flatMap(persistence, (s) => s.addIfAbsent(input, prepare)),
560
+ replaceIfCurrent: (input, prepare) =>
561
+ Effect.flatMap(persistence, (s) => s.replaceIfCurrent(input, prepare)),
562
+ resetWithProof: (input, prepare) =>
563
+ Effect.flatMap(persistence, (s) => s.resetWithProof(input, prepare)),
564
+ });
565
+ }
566
+ for (const [name, strategy] of Object.entries(auth.strategies)) {
567
+ if (strategy.persistence?.kind !== "password" || !strategy.persistence.management)
568
+ continue;
569
+ const key = strategy.RegistrationAuthority;
570
+
571
+ if (key === undefined)
572
+ return yield* configError(`Missing subject provisioning for ${name}`);
573
+
574
+ // The heterogeneous strategy table erases the registration input type;
575
+ // its decoded value is forwarded unchanged to the same authority key.
576
+ const registration = service(
577
+ key as Context.Key<unknown, PasswordRegistrationAuthority<unknown>>,
578
+ () => PasswordUnavailable.make({}),
579
+ );
580
+
581
+ context = Context.add(context, key, {
582
+ register: (input, prepare) =>
583
+ Effect.flatMap(registration, (s) => s.register(input, prepare)),
584
+ } satisfies PasswordRegistrationAuthority<unknown>);
585
+ }
586
+ if (email) {
587
+ const persistence = service(EmailAddressPersistence, () => EmailUnavailable.make({}));
588
+
589
+ context = Context.add(context, EmailAddressPersistence, {
590
+ target: (input) => Effect.flatMap(persistence, (s) => s.target(input)),
591
+ verifyWithProof: (input, prepare) =>
592
+ Effect.flatMap(persistence, (s) => s.verifyWithProof(input, prepare)),
593
+ changeWithProof: (input, prepare) =>
594
+ Effect.flatMap(persistence, (s) => s.changeWithProof(input, prepare)),
595
+ });
596
+ }
597
+ if (phone) {
598
+ const unavailable = () => PhoneOtpUnavailable.make({});
599
+ const targets = service(PhoneSignInTargets, unavailable);
600
+
601
+ context = context.pipe(
602
+ Context.add(PhoneSignInTargets, {
603
+ lookup: (input) => Effect.flatMap(targets, (s) => s.lookup(input)),
604
+ }),
605
+ );
606
+ }
607
+ if (passkeys.length > 0) {
608
+ const unavailable = () => PasskeyUnavailable.make({});
609
+ const credentials = service(PasskeyCredentials, unavailable);
610
+ const persistence = service(PasskeyPersistence, unavailable);
611
+
612
+ context = context.pipe(
613
+ Context.add(PasskeyCredentials, {
614
+ lookup: (input) => Effect.flatMap(credentials, (s) => s.lookup(input)),
615
+ listForSubject: (input) =>
616
+ Effect.flatMap(credentials, (s) => s.listForSubject(input)),
617
+ }),
618
+ Context.add(PasskeyPersistence, {
619
+ issue: (input, prepare) =>
620
+ Effect.flatMap(persistence, (s) => s.issue(input, prepare)),
621
+ context: (input) => Effect.flatMap(persistence, (s) => s.context(input)),
622
+ consume: (input, prepare) =>
623
+ Effect.flatMap(persistence, (s) => s.consume(input, prepare)),
624
+ cleanup: (input, prepare) =>
625
+ Effect.flatMap(persistence, (s) => s.cleanup(input, prepare)),
626
+ }),
627
+ );
628
+ if (passkeys.some((feature) => feature.management)) {
629
+ const manager = service(PasskeyManagementPersistence, unavailable);
630
+
631
+ context = context.pipe(
632
+ Context.add(PasskeyManagementPersistence, {
633
+ list: (input) => Effect.flatMap(manager, (s) => s.list(input)),
634
+ completeEnrollment: (input, prepare) =>
635
+ Effect.flatMap(manager, (s) => s.completeEnrollment(input, prepare)),
636
+ inspectRemove: (input) => Effect.flatMap(manager, (s) => s.inspectRemove(input)),
637
+ remove: (input, prepare) =>
638
+ Effect.flatMap(manager, (s) => s.remove(input, prepare)),
639
+ rename: (input, prepare) =>
640
+ Effect.flatMap(manager, (s) => s.rename(input, prepare)),
641
+ }),
642
+ );
643
+ }
644
+ }
645
+
646
+ // Match the same capability-selected service keys as the acquired graph.
647
+ return context as Context.Context<Ports<C, Id, A>>;
648
+ }),
649
+ );
650
+
605
651
  return {
606
652
  Config,
607
653
  Provisioning: ProvisioningKey,
608
- layer: services,
654
+ layer,
609
655
  managed: <N, Instant = number>(options: {
610
656
  readonly subjects: SubjectOptions<T, N>;
611
657
  readonly tables?: Partial<Record<Roles<C, Id, A>, T>>;