@yielded/auth-persistence 0.1.0-beta.25 → 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 +14 -81
  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 +26 -147
  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 -354
  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 -1556
  439. package/src/internal/oauth/accounts.ts +0 -839
  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 -692
  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 -1523
  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
@@ -2,7 +2,11 @@ import { Persistence, Record, Unavailable } from "@yielded/auth/BrowserLogin";
2
2
  import { Effect, Layer, Schema } from "effect";
3
3
  import { SqlClient } from "effect/sql";
4
4
 
5
- import { requireStandalone } from "./standalone";
5
+ import { makeNativeSqlTables } from "./native-sql-table";
6
+ import { exactSqlText } from "./sql-change";
7
+ import { cleanupSqlRows } from "./sql-cleanup";
8
+ import { makeSqlCommitExecutor } from "./sql-commit";
9
+ import { Table } from "./sql-table";
6
10
 
7
11
  const codec = Schema.fromJsonString(Record);
8
12
  const Row = Schema.Struct({ payload: Schema.String, version: Schema.String });
@@ -26,10 +30,19 @@ const layer = Layer.effect(
26
30
 
27
31
  if (!sql.onDialectOrElse({ sqlite: () => true, pg: () => true, orElse: () => false }))
28
32
  return yield* Unavailable.make({});
29
- const standalone = requireStandalone(() => Unavailable.make({}), sql.transactionService);
30
-
31
- const failure = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
32
- effect.pipe(Effect.mapError(() => Unavailable.make({})));
33
+ const executor = yield* makeSqlCommitExecutor(() => Unavailable.make({}));
34
+
35
+ const table = makeNativeSqlTables(sql)(
36
+ new Table(
37
+ "yielded_browser_login",
38
+ {
39
+ namespace: { name: "namespace", type: "text" },
40
+ attemptId: { name: "attempt_id", type: "text" },
41
+ expiresAt: { name: "expires_at_millis", type: "integer" },
42
+ },
43
+ [["namespace", "attemptId"]],
44
+ ),
45
+ );
33
46
 
34
47
  const clock = sql.onDialectOrElse({
35
48
  sqlite: () => sql.literal("CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)"),
@@ -37,9 +50,22 @@ const layer = Layer.effect(
37
50
  });
38
51
 
39
52
  return Persistence.of({
53
+ cleanup: ({ namespace, limit }) =>
54
+ executor.run(
55
+ cleanupSqlRows(
56
+ [
57
+ {
58
+ table,
59
+ keys: ["namespace", "attemptId"],
60
+ due: sql`${exactSqlText(sql, table.column("namespace"), table.value("namespace", namespace))} and ${table.column("expiresAt")} <= ${clock}`,
61
+ order: [table.column("expiresAt"), table.column("attemptId")],
62
+ },
63
+ ],
64
+ limit,
65
+ ),
66
+ "statement",
67
+ ),
40
68
  get: Effect.fnUntraced(function* (namespace, id) {
41
- yield* standalone;
42
-
43
69
  const rows =
44
70
  yield* sql`SELECT payload, version FROM yielded_browser_login WHERE namespace = ${namespace} AND attempt_id = ${id}`;
45
71
 
@@ -51,32 +77,36 @@ const layer = Layer.effect(
51
77
  if (record.version !== row.version) return yield* Unavailable.make({});
52
78
 
53
79
  return record;
54
- }, failure),
55
- insert: Effect.fnUntraced(function* (namespace, id, record) {
56
- yield* standalone;
57
- const payload = yield* Schema.encodeEffect(codec)(record);
80
+ }, executor.read),
81
+ insert: Effect.fnUntraced(
82
+ function* (namespace, id, record) {
83
+ const payload = yield* Schema.encodeEffect(codec)(record);
58
84
 
59
- const rows =
60
- yield* sql`INSERT INTO yielded_browser_login (namespace, attempt_id, version, expires_at_millis, payload)
85
+ const rows =
86
+ yield* sql`INSERT INTO yielded_browser_login (namespace, attempt_id, version, expires_at_millis, payload)
61
87
  SELECT ${namespace}, ${id}, ${record.version}, ${record.expiresAtMillis}, ${payload}
62
88
  WHERE ${record.expiresAtMillis} > ${clock}
63
89
  ON CONFLICT (namespace, attempt_id) DO NOTHING RETURNING version`;
64
90
 
65
- return rows.length === 1;
66
- }, failure),
67
- compareAndSet: Effect.fnUntraced(function* (namespace, id, version, record) {
68
- yield* standalone;
69
- if (version === record.version) return yield* Unavailable.make({});
70
- const payload = yield* Schema.encodeEffect(codec)(record);
71
-
72
- const rows =
73
- yield* sql`UPDATE yielded_browser_login SET version = ${record.version}, payload = ${payload}
91
+ return rows.length === 1;
92
+ },
93
+ (effect) => executor.run(effect, "statement"),
94
+ ),
95
+ compareAndSet: Effect.fnUntraced(
96
+ function* (namespace, id, version, record) {
97
+ if (version === record.version) return yield* Unavailable.make({});
98
+ const payload = yield* Schema.encodeEffect(codec)(record);
99
+
100
+ const rows =
101
+ yield* sql`UPDATE yielded_browser_login SET version = ${record.version}, payload = ${payload}
74
102
  WHERE namespace = ${namespace} AND attempt_id = ${id} AND version = ${version}
75
103
  AND expires_at_millis = ${record.expiresAtMillis} AND expires_at_millis > ${clock}
76
104
  RETURNING version`;
77
105
 
78
- return rows.length === 1;
79
- }, failure),
106
+ return rows.length === 1;
107
+ },
108
+ (effect) => executor.run(effect, "statement"),
109
+ ),
80
110
  });
81
111
  }),
82
112
  );
@@ -4,7 +4,6 @@ import type {
4
4
  PasskeyActionChallenge,
5
5
  PasskeyConfig,
6
6
  PasskeyCredentials,
7
- PasskeyEnrollmentContext,
8
7
  PasskeyManagementPersistence,
9
8
  PasskeyManagementPolicy,
10
9
  PasskeyMethodPolicy,
@@ -16,7 +15,7 @@ import type {
16
15
  PasswordPersistence,
17
16
  PasswordUnavailable,
18
17
  } from "@yielded/auth/Password";
19
- import type { PhoneAdmission, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
18
+ import type { PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
20
19
  import type { ProofPersistence } from "@yielded/auth/Proofs";
21
20
  import type { SubjectId } from "@yielded/auth/Schema";
22
21
  import type {
@@ -106,6 +105,7 @@ export type Provisioning<A extends { readonly strategies: Readonly<Record<string
106
105
  ? K
107
106
  : never
108
107
  ]: (input: {
108
+ readonly requestId: string;
109
109
  readonly identifier: LoginIdentifier;
110
110
  readonly registration: Registration<A["strategies"][K]>;
111
111
  }) => Effect.Effect<SubjectId, PasswordUnavailable>;
@@ -115,15 +115,7 @@ export type ProvisioningRequirement<
115
115
  A extends { readonly namespace: string; readonly strategies: Readonly<Record<string, Strategy>> },
116
116
  > = ManagedPassword<A> extends never ? never : ProvisioningId<A["namespace"]>;
117
117
 
118
- type ProofRoles =
119
- | "proofRequests"
120
- | "proofSeries"
121
- | "proofGenerations"
122
- | "proofContinuations"
123
- | "proofScopes"
124
- | "proofAbuse"
125
- | "proofFailures"
126
- | "proofCommands";
118
+ type ProofRoles = "proofs";
127
119
 
128
120
  type UsesProofs<A extends { readonly strategies: Readonly<Record<string, Strategy>> }> =
129
121
  | Enabled<A, "phone">
@@ -134,36 +126,25 @@ export type Ports<C extends ClaimsCodec, Id extends string, A extends Definition
134
126
  | AuthenticationAuthority
135
127
  | KeyId<A["sessions"]["StatefulSessionPersistence"]>
136
128
  | KeyId<A["sessions"]["SessionRepository"]>
129
+ | KeyId<A["sessions"]["PendingAuthentication"]>
130
+ | KeyId<A["sessions"]["SessionStepUpPersistence"]>
131
+ | KeyId<A["sessions"]["SessionCleanup"]>
137
132
  | (Enabled<A, "password"> extends never ? never : PasswordPersistence)
138
133
  | KeyId<RegistrationKey<ManagedPassword<A>>>
139
134
  | (Enabled<A, "passkey"> extends never ? never : PasskeyPersistence | PasskeyCredentials)
140
- | (ManagedPasskey<A> extends never
141
- ? never
142
- : PasskeyManagementPersistence | PasskeyEnrollmentContext)
135
+ | (ManagedPasskey<A> extends never ? never : PasskeyManagementPersistence)
143
136
  | (Enabled<A, "email"> extends never ? never : EmailAddressPersistence)
144
137
  | (UsesProofs<A> extends never ? never : ProofPersistence)
145
- | (Enabled<A, "phone"> extends never ? never : PhoneAdmission | PhoneSignInTargets);
138
+ | (Enabled<A, "phone"> extends never ? never : PhoneSignInTargets);
146
139
 
147
140
  export type Roles<C extends ClaimsCodec, Id extends string, A extends Definition<C, Id>> =
148
141
  | "identifiers"
149
142
  | "credentials"
150
143
  | "sessions"
151
- | "sessionFlows"
152
- | (Enabled<A, "password"> extends never ? never : "passwords" | "passwordCommands")
153
- | (ManagedPassword<A> extends never ? never : "passwordRegistrations")
154
- | (Enabled<A, "phone"> extends never ? never : "phoneState")
155
- | (Enabled<A, "email"> extends never ? never : "emailCredentials" | "emailCommands")
156
- | (Enabled<A, "passkey"> extends never
157
- ? never
158
- :
159
- | "passkeyCredentials"
160
- | "passkeyOwnership"
161
- | "passkeyHandles"
162
- | "passkeyModules"
163
- | "passkeyFlows"
164
- | "passkeyAdmissions"
165
- | "passkeyCharges")
166
- | (ManagedPasskey<A> extends never ? never : "passkeyCommands")
144
+ | "pending"
145
+ | (Enabled<A, "password"> extends never ? never : "passwords")
146
+ | (Enabled<A, "email"> extends never ? never : "emailCredentials")
147
+ | (Enabled<A, "passkey"> extends never ? never : "passkeyCredentials" | "passkeyFlows")
167
148
  | (UsesProofs<A> extends never ? never : ProofRoles);
168
149
 
169
150
  export interface SubjectOptions<T extends object, NativeId> {
@@ -241,6 +222,10 @@ export interface BoundPersistence<
241
222
  * Do not perform external side effects or open an independent transaction here.
242
223
  */
243
224
  readonly Provisioning: Context.Service<ProvisioningRequirement<A>, Provisioning<A>>;
225
+ /** Capture dependencies at acquisition; validate SQL metadata and configure storage
226
+ * once on the first service operation. Initialization failures become that port's
227
+ * unavailable error. Failure or interruption remains cached until layer reacquisition.
228
+ */
244
229
  readonly layer: Layer.Layer<
245
230
  Ports<C, Id, A>,
246
231
  PersistenceConfigurationError,
@@ -0,0 +1,7 @@
1
+ import type { SqlClient } from "effect/sql/SqlClient";
2
+ import type { Fragment } from "effect/sql/Statement";
3
+
4
+ /** A false predicate aborts the current D1 batch; checking its result after
5
+ * batch completion would be too late to roll the protected mutation back. */
6
+ export const sqlBatchAssertion = (sql: SqlClient, condition: Fragment) =>
7
+ sql`select case when ${condition} then 1 else json_extract('[]', '$[auth-batch-precondition]') end as valid`;
@@ -0,0 +1,247 @@
1
+ import { EmailCredentialSnapshot, EmailUnavailable } from "@yielded/auth/Email";
2
+ import { LoginIdentifier } from "@yielded/auth/Identity";
3
+ import type { SubjectId } from "@yielded/auth/Schema";
4
+ import { AuthenticationRevision } from "@yielded/auth/Sessions";
5
+ import { Effect, Option, Schema } from "effect";
6
+ import { SqlClient } from "effect/sql/SqlClient";
7
+ import type { Fragment } from "effect/sql/Statement";
8
+
9
+ import type { AnyEmailSignInMapping } from "./models/email-model";
10
+ import type { NativeSqlTables, SqlTable } from "./native-sql-table";
11
+ import { exactSqlText } from "./sql-change";
12
+
13
+ export const emailUnavailable = () => EmailUnavailable.make({});
14
+
15
+ export const ensureEmail: (condition: unknown) => asserts condition = (condition) => {
16
+ if (!condition) throw emailUnavailable();
17
+ };
18
+
19
+ /** Every role binds the decoded native subject through its own physical column codec. */
20
+ export const makeNativeEmailReader = Effect.fnUntraced(function* (
21
+ tables: NativeSqlTables,
22
+ mapping: AnyEmailSignInMapping,
23
+ engineNow?: Fragment,
24
+ ) {
25
+ const sql = (yield* SqlClient).withoutTransforms();
26
+
27
+ const s = mapping.subject,
28
+ i = mapping.identifier,
29
+ c = mapping.credential,
30
+ a = mapping.authorityCredential;
31
+
32
+ const subject = tables(s.table).as("email_subject"),
33
+ targetIdentifier = tables(i.table).as("email_target_identifier"),
34
+ sourceIdentifier = tables(i.table).as("email_source_identifier"),
35
+ targetCredential = tables(c.table).as("email_target_credential"),
36
+ sourceCredential = tables(c.table).as("email_source_credential"),
37
+ authority = tables(a.table).as("email_authority"),
38
+ sourceAuthority = tables(a.table).as("email_source_authority"),
39
+ cardinality = tables(c.table).as("email_cardinality");
40
+
41
+ const exact = (t: SqlTable, key: string, value: unknown) =>
42
+ exactSqlText(sql, t.column(key), t.value(key, value));
43
+
44
+ const id = (t: SqlTable, key: string, value: unknown) =>
45
+ sql`${t.column(key)} = ${t.value(key, value)}`;
46
+
47
+ const identifierKey = (t: SqlTable, value: LoginIdentifier) =>
48
+ sql.and([exact(t, i.namespace, value.namespace), exact(t, i.value, value.value)]);
49
+
50
+ const credentialKey = (t: SqlTable, moduleId: string, value: LoginIdentifier) =>
51
+ sql.and([
52
+ exact(t, c.moduleId, moduleId),
53
+ exact(t, c.identifierNamespace, value.namespace),
54
+ exact(t, c.identifierValue, value.value),
55
+ ]);
56
+
57
+ const selected = (t: SqlTable, row: Record<string, unknown>, prefix: string, key: string) => {
58
+ const decoded = t.decode(row, prefix);
59
+
60
+ return decoded[key] === null || decoded[key] === undefined ? undefined : decoded;
61
+ };
62
+
63
+ const owned = Effect.fnUntraced(function* (
64
+ row: Record<string, unknown> | undefined,
65
+ key: string,
66
+ subjectId: SubjectId,
67
+ ) {
68
+ return row !== undefined && (yield* mapping.subjectId.toSubject(row[key])) === subjectId;
69
+ });
70
+
71
+ const read = Effect.fnUntraced(function* (input: {
72
+ readonly moduleId: string;
73
+ readonly subjectId: SubjectId;
74
+ readonly identifier: LoginIdentifier;
75
+ readonly sourceCredentialId?: string;
76
+ readonly sourceIdentifier?: LoginIdentifier;
77
+ readonly single?: boolean;
78
+ readonly validity?: Fragment;
79
+ }) {
80
+ const native = yield* mapping.subjectId.toNative(input.subjectId);
81
+ let source = input.sourceIdentifier;
82
+
83
+ if (input.sourceCredentialId !== undefined && source === undefined) {
84
+ const table = tables(c.table);
85
+
86
+ const rows =
87
+ yield* sql`select ${table.fields("email_source_lookup_")} from ${table.name} where ${exact(table, c.moduleId, input.moduleId)} and ${exact(table, c.credentialId, input.sourceCredentialId)} and ${id(table, c.subjectId, native)} limit 2`;
88
+
89
+ if (rows.length !== 1) return undefined;
90
+ const row = table.decode(rows[0]!, "email_source_lookup_");
91
+
92
+ ensureEmail(row[c.credentialId] === input.sourceCredentialId);
93
+ source = yield* Schema.decodeUnknownEffect(LoginIdentifier)({
94
+ namespace: row[c.identifierNamespace],
95
+ value: row[c.identifierValue],
96
+ });
97
+ }
98
+
99
+ const rows =
100
+ yield* sql`select ${subject.fields("email_subject_")}, ${targetIdentifier.fields("email_target_identifier_")}, ${sourceIdentifier.fields("email_source_identifier_")}, ${targetCredential.fields("email_target_credential_")}, ${sourceCredential.fields("email_source_credential_")}, ${authority.fields("email_authority_")}, ${sourceAuthority.fields("email_source_authority_")}, ${engineNow ?? sql`0`} as engine_now, case when ${input.single === true && input.sourceCredentialId === undefined ? sql`exists(select 1 from ${cardinality.name} where ${id(cardinality, c.subjectId, native)} and ${exact(cardinality, c.moduleId, input.moduleId)} and ${id(cardinality, c.status, c.activeStatusValue)})` : sql`1 = 0`} then 1 else 0 end as cardinality_conflict
101
+ from ${subject.name}
102
+ left join ${targetIdentifier.name} on ${identifierKey(targetIdentifier, input.identifier)}
103
+ left join ${sourceIdentifier.name} on ${source === undefined ? sql`1 = 0` : identifierKey(sourceIdentifier, source)}
104
+ left join ${targetCredential.name} on ${credentialKey(targetCredential, input.moduleId, input.identifier)}
105
+ left join ${sourceCredential.name} on ${input.sourceCredentialId === undefined ? sql`1 = 0` : sql.and([exact(sourceCredential, c.moduleId, input.moduleId), exact(sourceCredential, c.credentialId, input.sourceCredentialId)])}
106
+ left join ${sourceAuthority.name} on ${input.sourceCredentialId === undefined ? sql`1 = 0` : sql.and([id(sourceAuthority, a.subjectId, native), exact(sourceAuthority, a.credentialId, input.sourceCredentialId)])}
107
+ left join ${authority.name} on ${id(authority, a.subjectId, native)} and ${id(authority, a.status, a.activeStatusValue)}
108
+ where ${id(subject, s.id, native)} and ${input.validity ?? sql`1 = 1`} limit 65`;
109
+
110
+ ensureEmail(rows.length <= 64);
111
+ const first = rows[0];
112
+
113
+ if (first === undefined) return undefined;
114
+ const subjectRow = subject.decode(first, "email_subject_");
115
+
116
+ ensureEmail((yield* mapping.subjectId.toSubject(subjectRow[s.id])) === input.subjectId);
117
+ if (!s.isActiveStatus(subjectRow[s.status])) return undefined;
118
+ const factors: { readonly credentialId: unknown; readonly revision: unknown }[] = [];
119
+
120
+ for (const row of rows) {
121
+ const factor = selected(authority, row, "email_authority_", a.credentialId);
122
+
123
+ if (factor === undefined) continue;
124
+ ensureEmail(
125
+ (yield* owned(factor, a.subjectId, input.subjectId)) && a.isActiveStatus(factor[a.status]),
126
+ );
127
+ ensureEmail(!factors.some((f) => f.credentialId === factor[a.credentialId]));
128
+ factors.push({ credentialId: factor[a.credentialId], revision: factor[a.revision] });
129
+ }
130
+
131
+ const revision = yield* Schema.decodeUnknownEffect(AuthenticationRevision)({
132
+ subjectId: input.subjectId,
133
+ securityRevision: subjectRow[s.securityRevision],
134
+ credentials: factors.sort((a, b) =>
135
+ String(a.credentialId).localeCompare(String(b.credentialId)),
136
+ ),
137
+ });
138
+
139
+ const targetRow = selected(targetIdentifier, first, "email_target_identifier_", i.namespace),
140
+ sourceRow = selected(sourceIdentifier, first, "email_source_identifier_", i.namespace),
141
+ targetFactor = selected(targetCredential, first, "email_target_credential_", c.credentialId),
142
+ sourceFactor = selected(sourceCredential, first, "email_source_credential_", c.credentialId);
143
+
144
+ const snapshot = Effect.fnUntraced(function* (
145
+ identifierRow: Record<string, unknown> | undefined,
146
+ credentialRow: Record<string, unknown> | undefined,
147
+ value: LoginIdentifier | undefined,
148
+ ) {
149
+ if (
150
+ identifierRow === undefined ||
151
+ credentialRow === undefined ||
152
+ value === undefined ||
153
+ !i.isCurrent(identifierRow) ||
154
+ identifierRow[i.verifiedAt] === null ||
155
+ identifierRow[i.verifiedAt] === undefined ||
156
+ !c.isActiveStatus(credentialRow[c.status]) ||
157
+ !(yield* owned(identifierRow, i.subjectId, input.subjectId)) ||
158
+ !(yield* owned(credentialRow, c.subjectId, input.subjectId))
159
+ )
160
+ return undefined;
161
+ ensureEmail(
162
+ identifierRow[i.namespace] === value.namespace &&
163
+ identifierRow[i.value] === value.value &&
164
+ credentialRow[c.moduleId] === input.moduleId &&
165
+ credentialRow[c.identifierNamespace] === value.namespace &&
166
+ credentialRow[c.identifierValue] === value.value,
167
+ );
168
+ if (
169
+ !revision.credentials.some(
170
+ (f) =>
171
+ f.credentialId === credentialRow[c.credentialId] &&
172
+ f.revision === credentialRow[c.credentialRevision],
173
+ )
174
+ )
175
+ return undefined;
176
+
177
+ const decoded = yield* c.decode({
178
+ moduleId: input.moduleId,
179
+ subject: subjectRow,
180
+ identifier: identifierRow,
181
+ credential: credentialRow,
182
+ });
183
+
184
+ return yield* Schema.decodeEffect(EmailCredentialSnapshot)({
185
+ ...decoded,
186
+ revision,
187
+ requirement: yield* s.decodeRequirement(subjectRow),
188
+ });
189
+ });
190
+
191
+ ensureEmail(
192
+ targetRow === undefined ||
193
+ (targetRow[i.namespace] === input.identifier.namespace &&
194
+ targetRow[i.value] === input.identifier.value),
195
+ );
196
+ ensureEmail(
197
+ targetFactor === undefined ||
198
+ (targetFactor[c.moduleId] === input.moduleId &&
199
+ targetFactor[c.identifierNamespace] === input.identifier.namespace &&
200
+ targetFactor[c.identifierValue] === input.identifier.value),
201
+ );
202
+ const now = Number(first.engine_now);
203
+
204
+ ensureEmail(Number.isSafeInteger(now));
205
+
206
+ return {
207
+ native,
208
+ subject: subjectRow,
209
+ revision,
210
+ targetIdentifier: targetRow,
211
+ sourceIdentifier: sourceRow,
212
+ targetCredential: targetFactor,
213
+ sourceCredential: sourceFactor,
214
+ sourceAuthority: selected(sourceAuthority, first, "email_source_authority_", a.credentialId),
215
+ targetSnapshot: yield* snapshot(targetRow, targetFactor, input.identifier),
216
+ sourceSnapshot: yield* snapshot(sourceRow, sourceFactor, source),
217
+ cardinalityConflict: Number(first.cardinality_conflict) === 1,
218
+ now,
219
+ };
220
+ });
221
+
222
+ const lookup = Effect.fnUntraced(function* (input: {
223
+ readonly moduleId: string;
224
+ readonly identifier: LoginIdentifier;
225
+ }) {
226
+ const table = tables(i.table);
227
+
228
+ const rows =
229
+ yield* sql`select ${table.fields("email_lookup_")} from ${table.name} where ${identifierKey(table, input.identifier)} limit 2`;
230
+
231
+ if (rows.length === 0) return Option.none();
232
+ ensureEmail(rows.length === 1);
233
+ const row = table.decode(rows[0]!, "email_lookup_");
234
+
235
+ ensureEmail(
236
+ row[i.namespace] === input.identifier.namespace && row[i.value] === input.identifier.value,
237
+ );
238
+ if (!i.isCurrent(row) || row[i.verifiedAt] === null || row[i.verifiedAt] === undefined)
239
+ return Option.none();
240
+ const subjectId = yield* mapping.subjectId.toSubject(row[i.subjectId]);
241
+ const result = yield* read({ ...input, subjectId });
242
+
243
+ return Option.fromUndefinedOr(result?.targetSnapshot);
244
+ });
245
+
246
+ return { read, lookup };
247
+ });