@yielded/auth-persistence 0.1.0-beta.25 → 0.1.0-beta.27

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
@@ -0,0 +1,611 @@
1
+ /* oxlint-disable no-explicit-any -- physical mapping generics are erased only at this shared adapter boundary. */
2
+ import * as M from "@yielded/auth/Passkey";
3
+ import { SecurityRevision } from "@yielded/auth/Sessions";
4
+ import { Effect, Schema } from "effect";
5
+ import { SqlClient } from "effect/sql";
6
+ import type { Fragment } from "effect/sql/Statement";
7
+
8
+ import { randomId } from "./crypto";
9
+ import { sqlBatchAssertion } from "./d1-planning";
10
+ import { PersistenceMappingError } from "./mapping-error";
11
+ import type {
12
+ PasskeyCredentialInsert,
13
+ PasskeyManagementMapping,
14
+ } from "./models/passkey-write-model";
15
+ import type { SqlTable } from "./native-sql-table";
16
+ import { passkeyEnrollmentDigest, passkeyRemoveDigest } from "./passkey-actions";
17
+ import { passkeyManagementInputs } from "./passkey-inputs";
18
+ import { preparePasskeyNative, type NativePasskeyServices } from "./passkey-native";
19
+ import { passkeyNativeInvariant, type PasskeyNativeRow } from "./passkey-native-state";
20
+ import {
21
+ assessPasskeyAction,
22
+ passkeyCredentialKey,
23
+ passkeyMatchesAccess,
24
+ samePasskeyCredential,
25
+ samePasskeyRevision,
26
+ } from "./passkey-policy";
27
+ import { exactSqlText } from "./sql-change";
28
+ import {
29
+ appendSqlBatchStatement,
30
+ registerSqlBatchPostcondition,
31
+ registerSqlPostcondition,
32
+ } from "./sql-commit";
33
+ import type { TableModel } from "./table-model";
34
+
35
+ // Mapping callbacks retain concrete row/SQL types at the public driver boundary.
36
+ export type NativePasskeyManagementMapping = PasskeyManagementMapping<
37
+ TableModel,
38
+ TableModel,
39
+ TableModel,
40
+ TableModel,
41
+ unknown,
42
+ any
43
+ >;
44
+
45
+ export type NativePasskeyWriteMapping = Pick<
46
+ NativePasskeyManagementMapping,
47
+ "moduleId" | "read" | "write" | "clock" | "telemetry"
48
+ >;
49
+
50
+ export const makePasskeyNativeWrites = (
51
+ base: NativePasskeyServices,
52
+ mapping: NativePasskeyWriteMapping,
53
+ ) => {
54
+ const { state } = base;
55
+ const { sql, tables, subject, credential, factor, ceremony: flow } = state;
56
+ const read = mapping.read;
57
+ const invariant: typeof passkeyNativeInvariant = passkeyNativeInvariant;
58
+ const expression = tables.expression;
59
+
60
+ const eq = (table: SqlTable, key: string, value: unknown) =>
61
+ typeof value === "string"
62
+ ? exactSqlText(sql, table.column(key), table.value(key, value))
63
+ : sql`${table.column(key)} = ${table.value(key, value)}`;
64
+
65
+ const match = (table: SqlTable, values: Readonly<Record<string, unknown>>) =>
66
+ sql.and(
67
+ Object.entries(values)
68
+ .filter(([, value]) => value !== undefined)
69
+ .map(([key, value]) =>
70
+ value === null ? sql`${table.column(key)} is null` : eq(table, key, value),
71
+ ),
72
+ );
73
+
74
+ const check = (condition: Fragment) =>
75
+ Effect.gen(function* () {
76
+ const current = (yield* SqlClient.SqlClient).withoutTransforms();
77
+ const rows = yield* current`select case when ${condition} then 1 else 0 end as valid`;
78
+
79
+ if (rows.length !== 1 || Number(rows[0]!.valid) !== 1)
80
+ return yield* PersistenceMappingError.make({
81
+ operation: "mapping",
82
+ cause: "Passkey mutation postcondition failed",
83
+ });
84
+ });
85
+
86
+ const postcondition = (name: string, condition: Fragment) =>
87
+ base.batch
88
+ ? registerSqlBatchPostcondition({ name, statement: sqlBatchAssertion(sql, condition) })
89
+ : registerSqlPostcondition({ name, check: check(condition) });
90
+
91
+ const write = (statement: Fragment, count: number) =>
92
+ base.batch
93
+ ? flow.stage(statement, count)
94
+ : flow.change(statement).pipe(
95
+ Effect.flatMap((changed) =>
96
+ changed === count
97
+ ? Effect.void
98
+ : Effect.fail(
99
+ PersistenceMappingError.make({
100
+ operation: "mapping",
101
+ cause: "Passkey conditional write did not match",
102
+ }),
103
+ ),
104
+ ),
105
+ );
106
+
107
+ const summary = (row: PasskeyNativeRow) =>
108
+ Schema.decodeUnknownSync(M.PasskeyCredentialSummary)({
109
+ credentialId: row[read.credential.credentialId],
110
+ name: row[mapping.write.credential.name],
111
+ primarySignIn: read.credential.decode(row).primarySignIn,
112
+ createdAtMillis: mapping.clock.decodeInstant(row[mapping.write.credential.createdAt]),
113
+ ...(row[mapping.telemetry.lastUsedAt] === null ||
114
+ row[mapping.telemetry.lastUsedAt] === undefined
115
+ ? {}
116
+ : { lastUsedAtMillis: mapping.clock.decodeInstant(row[mapping.telemetry.lastUsedAt]) }),
117
+ });
118
+
119
+ const owned = (nativeId: unknown, credentialId?: string) =>
120
+ sql.and([
121
+ sql`${credential.column(read.credential.subjectId)} = ${credential.value(read.credential.subjectId, nativeId)}`,
122
+ ...(credentialId === undefined
123
+ ? []
124
+ : [eq(credential, read.credential.credentialId, credentialId)]),
125
+ state.active("credential"),
126
+ ]);
127
+
128
+ const subjectCondition = (current: M.PasskeyCredential["revision"]) => {
129
+ const id = state.native(current.subjectId);
130
+
131
+ return sql`exists(select 1 from ${subject.name} where ${subject.column(read.subject.id)} = ${subject.value(read.subject.id, id)} and ${eq(subject, read.subject.securityRevision, current.securityRevision)} and ${state.active("subject")}) and ${sql.and(current.credentials.map((entry) => sql`exists(select 1 from ${factor.name} where ${factor.column(read.authority.subjectId)} = ${factor.value(read.authority.subjectId, id)} and ${eq(factor, read.authority.credentialId, entry.credentialId)} and ${eq(factor, read.authority.revision, entry.revision)} and ${state.active("authority")})`))}`;
132
+ };
133
+
134
+ const insertCredential = Effect.fnUntraced(function* (
135
+ nativeId: unknown,
136
+ ceremony: M.PasskeyCeremony,
137
+ verified: M.PasskeyRegistrationVerified,
138
+ revision: M.PasskeyCredential["revision"],
139
+ name: string,
140
+ nowMillis: number,
141
+ subjectRow: Readonly<Record<string, unknown>>,
142
+ ) {
143
+ invariant(ceremony.context._tag === "Enrollment" || ceremony.context._tag === "Registration");
144
+ const credentialId = yield* randomId;
145
+ const marker = yield* randomId;
146
+ const credentialRevision = SecurityRevision.make(marker);
147
+
148
+ const value = M.snapshotPasskeySync(M.PasskeyCredential, {
149
+ credentialId,
150
+ requirement: yield* read.subject.decodeRequirement(subjectRow),
151
+ rpId: ceremony.profile.rpId,
152
+ protocolCredentialId: verified.protocolCredentialId,
153
+ userHandle: ceremony.context.userHandle,
154
+ publicKey: verified.publicKey,
155
+ algorithm: verified.algorithm,
156
+ profile: ceremony.profile,
157
+ revision: {
158
+ ...revision,
159
+ credentials: [...revision.credentials, { credentialId, revision: credentialRevision }],
160
+ },
161
+ active: true,
162
+ primarySignIn: ceremony.profile.primarySignIn && verified.userVerified,
163
+ enrollmentUserVerified: verified.userVerified,
164
+ backupEligible: verified.backupEligible,
165
+ backupState: verified.backupState,
166
+ counter: verified.counter,
167
+ });
168
+
169
+ const details = M.snapshotPasskeySync(M.PasskeyCredentialSummary, {
170
+ credentialId,
171
+ name,
172
+ primarySignIn: value.primarySignIn,
173
+ createdAtMillis: nowMillis,
174
+ });
175
+
176
+ const input: PasskeyCredentialInsert<unknown> = {
177
+ subjectId: nativeId,
178
+ credential: value,
179
+ summary: details,
180
+ marker,
181
+ };
182
+
183
+ const values = {
184
+ ...mapping.write.credential.encodeInsert(input),
185
+ [read.credential.credentialKey]: yield* passkeyCredentialKey(
186
+ value.rpId,
187
+ value.protocolCredentialId,
188
+ ),
189
+ };
190
+
191
+ const authorityValues = mapping.write.authority.encodeInsert(input);
192
+
193
+ yield* write(credential.insert(values), 1);
194
+ yield* write(factor.insert(authorityValues), 1);
195
+
196
+ // Application work may change telemetry or names, but cannot replace the
197
+ // enrolled key, ownership, semantic revision, or its authority factor.
198
+ const semanticKeys = [
199
+ read.credential.credentialId,
200
+ read.credential.subjectId,
201
+ read.credential.rpId,
202
+ read.credential.protocolCredentialId,
203
+ read.credential.credentialKey,
204
+ read.credential.userHandle,
205
+ read.credential.publicKey,
206
+ read.credential.algorithm,
207
+ read.credential.profile,
208
+ read.credential.credentialRevision,
209
+ read.credential.status,
210
+ read.credential.primarySignIn,
211
+ read.credential.enrollmentUserVerified,
212
+ read.credential.backupEligible,
213
+ ];
214
+
215
+ const semantic = Object.fromEntries(semanticKeys.map((key) => [key, values[key]]));
216
+
217
+ const authority = Object.fromEntries(
218
+ [
219
+ read.authority.subjectId,
220
+ read.authority.credentialId,
221
+ read.authority.revision,
222
+ read.authority.status,
223
+ ].map((key) => [key, authorityValues[key]]),
224
+ );
225
+
226
+ return {
227
+ details,
228
+ condition: sql`exists(select 1 from ${credential.name} where ${match(credential, semantic)}) and exists(select 1 from ${factor.name} where ${match(factor, authority)})`,
229
+ };
230
+ });
231
+
232
+ return {
233
+ summary,
234
+ owned,
235
+ subjectCondition,
236
+ insertCredential,
237
+ postcondition,
238
+ write,
239
+ check,
240
+ eq,
241
+ expression,
242
+ match,
243
+ };
244
+ };
245
+
246
+ export const makePasskeyNativeManagement = (
247
+ base: NativePasskeyServices,
248
+ mapping: NativePasskeyManagementMapping,
249
+ ) => {
250
+ const { state, run, advisory } = base;
251
+ const { sql, tables, subject, credential, factor, ceremony: flow } = state;
252
+ const read = mapping.read;
253
+ const invariant: typeof passkeyNativeInvariant = passkeyNativeInvariant;
254
+
255
+ const {
256
+ summary,
257
+ owned,
258
+ subjectCondition,
259
+ insertCredential,
260
+ postcondition,
261
+ write,
262
+ eq,
263
+ expression,
264
+ match,
265
+ } = makePasskeyNativeWrites(base, mapping);
266
+
267
+ const service: M.PasskeyManagementPersistence["Service"] = {
268
+ list: (original) =>
269
+ advisory(
270
+ Effect.gen(function* () {
271
+ const input = M.snapshotPasskeySync(passkeyManagementInputs.list, original);
272
+
273
+ invariant(flow.validModule(input.moduleId));
274
+ const nativeId = state.native(input.subjectId);
275
+
276
+ const rows =
277
+ yield* sql`select ${credential.fields("c_")} from ${credential.name} where ${owned(nativeId)} and ${expression(mapping.write.policy.metadata(nativeId))}
278
+ ${input.cursor === undefined ? sql`` : sql`and ${credential.column(read.credential.credentialId)} > ${credential.value(read.credential.credentialId, input.cursor)}`}
279
+ order by ${credential.column(read.credential.credentialId)} limit ${input.limit + 1}`;
280
+
281
+ const credentials = rows
282
+ .slice(0, input.limit)
283
+ .map((row) => summary(credential.decode(row, "c_")));
284
+
285
+ const cursor = rows.length > input.limit ? credentials.at(-1)?.credentialId : undefined;
286
+
287
+ return { credentials, ...(cursor === undefined ? {} : { cursor }) };
288
+ }),
289
+ ),
290
+ inspectRemove: (original) =>
291
+ advisory(
292
+ Effect.gen(function* () {
293
+ const input = M.snapshotPasskeySync(passkeyManagementInputs.inspectRemove, original);
294
+
295
+ if (!flow.validModule(input.moduleId)) return { _tag: "Rejected" } as const;
296
+ const nativeId = state.native(input.subjectId);
297
+ const current = yield* state.readAuthority(nativeId, false, input.credentialId);
298
+
299
+ if (current === undefined) return { _tag: "Rejected" } as const;
300
+
301
+ const value =
302
+ current.credential === undefined
303
+ ? undefined
304
+ : yield* state.decodeCredential(current.credential, current.revision, current.row);
305
+
306
+ return value === undefined
307
+ ? ({ _tag: "Rejected" } as const)
308
+ : ({ _tag: "Target", credential: value } as const);
309
+ }),
310
+ ),
311
+ completeEnrollment: (original, prepare) =>
312
+ run(
313
+ Effect.gen(function* () {
314
+ const input = M.snapshotPasskeySync(passkeyManagementInputs.completeEnrollment, original);
315
+ const ceremony = input.ceremony;
316
+
317
+ if (
318
+ !flow.validModule(ceremony.moduleId) ||
319
+ ceremony.context._tag !== "Enrollment" ||
320
+ !passkeyMatchesAccess(ceremony, input.access)
321
+ )
322
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
323
+ const context = ceremony.context;
324
+ const nativeId = state.native(context.revision.subjectId);
325
+ const current = yield* state.readAuthority(nativeId, !base.batch);
326
+
327
+ if (current === undefined)
328
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
329
+
330
+ const policy = M.snapshotPasskeySync(
331
+ M.PasskeyManagementPolicy,
332
+ mapping.write.policy.management(current.row),
333
+ );
334
+
335
+ const requirement = yield* mapping.write.policy.requirement(current.row, "enroll-begin");
336
+
337
+ const authority = assessPasskeyAction(
338
+ {
339
+ moduleId: mapping.moduleId,
340
+ revision: current.revision,
341
+ nowMillis: current.nowMillis,
342
+ currentRequirement: requirement,
343
+ expected: {
344
+ action: "enroll-begin",
345
+ commandId: ceremony.commandId,
346
+ flowId: ceremony.flowId,
347
+ bindingDigest: yield* passkeyEnrollmentDigest(ceremony),
348
+ revision: context.revision,
349
+ },
350
+ },
351
+ context.authorization,
352
+ {
353
+ ...policy,
354
+ maximumEvidenceAgeMillis: Math.min(
355
+ policy.maximumEvidenceAgeMillis,
356
+ input.management.maximumEvidenceAgeMillis,
357
+ ),
358
+ },
359
+ );
360
+
361
+ if (authority === undefined)
362
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
363
+ const cap = Math.min(policy.maximumCredentials, input.management.maximumCredentials);
364
+
365
+ const policyValues = Object.fromEntries(
366
+ mapping.write.policy.subjectColumns.map((key) => [key, current.row[key]]),
367
+ );
368
+
369
+ const policyUnchanged = sql`exists(select 1 from ${subject.name} where ${subject.column(read.subject.id)} = ${subject.value(read.subject.id, nativeId)} and ${match(subject, policyValues)})`;
370
+
371
+ const condition = sql`${subjectCondition(current.revision)} and ${policyUnchanged} and ${expression(mapping.write.policy.action(nativeId, context.authorization))} and ${expression(mapping.write.policy.metadata(nativeId))}
372
+ and ${state.now} < ${authority.expiresBeforeMillis} and (select count(*) from ${credential.name} where ${owned(nativeId)}) < ${cap}`;
373
+
374
+ const statement = flow.consume(input.access, ceremony, condition);
375
+
376
+ if (base.batch) yield* flow.stage(statement, 1);
377
+ else if ((yield* flow.change(statement)) !== 1)
378
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
379
+
380
+ const enrolled = yield* insertCredential(
381
+ nativeId,
382
+ ceremony,
383
+ input.verified,
384
+ current.revision,
385
+ context.name,
386
+ current.nowMillis,
387
+ current.row,
388
+ );
389
+
390
+ yield* postcondition(
391
+ "passkey-enrollment-authority",
392
+ sql`${enrolled.condition} and ${flow.absent(input.access)} and ${subjectCondition(current.revision)} and ${policyUnchanged} and (select count(*) from ${credential.name} where ${owned(nativeId)}) <= ${cap} and ${expression(mapping.write.policy.action(nativeId, context.authorization))} and ${state.now} < ${authority.expiresBeforeMillis}`,
393
+ );
394
+
395
+ return yield* preparePasskeyNative(
396
+ { _tag: "Enrolled", credential: enrolled.details },
397
+ prepare,
398
+ );
399
+ }),
400
+ ),
401
+ rename: (original, prepare) =>
402
+ run(
403
+ Effect.gen(function* () {
404
+ const input = M.snapshotPasskeySync(passkeyManagementInputs.rename, original);
405
+
406
+ if (!flow.validModule(input.moduleId))
407
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
408
+ const nativeId = state.native(input.subjectId);
409
+ const statement = sql`${credential.update({ [mapping.write.credential.name]: input.name })} where ${owned(nativeId, input.credentialId)} and ${expression(mapping.write.policy.metadata(nativeId))}`;
410
+ let rows: ReadonlyArray<PasskeyNativeRow>;
411
+
412
+ if (base.batch) {
413
+ rows =
414
+ yield* sql`select ${credential.fields("c_")} from ${credential.name} where ${owned(nativeId, input.credentialId)} and ${expression(mapping.write.policy.metadata(nativeId))}`;
415
+ if (rows.length !== 1)
416
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
417
+ yield* flow.stage(statement, 1);
418
+ } else {
419
+ rows = yield* sql.onDialectOrElse({
420
+ mysql: () =>
421
+ Effect.gen(function* () {
422
+ const changed = yield* flow.change(statement);
423
+
424
+ if (changed > 1) return [];
425
+
426
+ // With mysql2 -FOUND_ROWS an idempotent rename reports zero changes.
427
+ return yield* sql`select ${credential.fields("c_")} from ${credential.name} where ${owned(nativeId, input.credentialId)} and ${eq(credential, mapping.write.credential.name, input.name)} and ${expression(mapping.write.policy.metadata(nativeId))}`;
428
+ }),
429
+ orElse: () => sql`${statement} returning ${credential.fields("c_")}`,
430
+ });
431
+ }
432
+ if (rows.length !== 1) return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
433
+ const row = credential.decode(rows[0]!, "c_");
434
+
435
+ return yield* preparePasskeyNative(
436
+ {
437
+ _tag: "Renamed",
438
+ credential: summary({ ...row, [mapping.write.credential.name]: input.name }),
439
+ },
440
+ prepare,
441
+ );
442
+ }),
443
+ "statement",
444
+ ),
445
+ remove: (original, prepare) =>
446
+ run(
447
+ Effect.gen(function* () {
448
+ const input = M.snapshotPasskeySync(passkeyManagementInputs.remove, original);
449
+
450
+ if (!flow.validModule(input.moduleId))
451
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
452
+ const nativeId = state.native(input.credential.revision.subjectId);
453
+
454
+ const current = yield* state.readAuthority(
455
+ nativeId,
456
+ !base.batch,
457
+ input.credential.credentialId,
458
+ );
459
+
460
+ if (current === undefined)
461
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
462
+
463
+ const captured =
464
+ current.credential === undefined
465
+ ? undefined
466
+ : yield* state.decodeCredential(current.credential, current.revision, current.row);
467
+
468
+ const policy = M.snapshotPasskeySync(
469
+ M.PasskeyManagementPolicy,
470
+ mapping.write.policy.management(current.row),
471
+ );
472
+
473
+ if (
474
+ captured === undefined ||
475
+ !samePasskeyCredential(captured, input.credential) ||
476
+ !samePasskeyRevision(captured.revision, input.credential.revision) ||
477
+ ((policy.requireImmediateInvalidation ||
478
+ input.management.requireImmediateInvalidation) &&
479
+ mapping.invalidation.window.existingSessions !== "immediate") ||
480
+ Schema.encodeSync(Schema.fromJsonString(M.PasskeyRemoved.fields.invalidation))(
481
+ input.invalidation,
482
+ ) !==
483
+ Schema.encodeSync(Schema.fromJsonString(M.PasskeyRemoved.fields.invalidation))(
484
+ mapping.invalidation.window,
485
+ )
486
+ )
487
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
488
+ const requirement = yield* mapping.write.policy.requirement(current.row, "remove");
489
+
490
+ const authority = assessPasskeyAction(
491
+ {
492
+ moduleId: mapping.moduleId,
493
+ revision: current.revision,
494
+ nowMillis: current.nowMillis,
495
+ currentRequirement: requirement,
496
+ expected: {
497
+ action: "remove",
498
+ commandId: input.commandId,
499
+ flowId: input.commandId,
500
+ bindingDigest: yield* passkeyRemoveDigest(
501
+ mapping.moduleId,
502
+ input.commandId,
503
+ input.credential,
504
+ ),
505
+ revision: input.credential.revision,
506
+ },
507
+ },
508
+ input.authorization,
509
+ {
510
+ ...policy,
511
+ maximumEvidenceAgeMillis: Math.min(
512
+ policy.maximumEvidenceAgeMillis,
513
+ input.management.maximumEvidenceAgeMillis,
514
+ ),
515
+ },
516
+ );
517
+
518
+ if (authority === undefined)
519
+ return yield* preparePasskeyNative({ _tag: "Rejected" }, prepare);
520
+
521
+ const remaining = expression(
522
+ yield* mapping.write.policy.remainingSignIn(
523
+ nativeId,
524
+ captured.credentialId,
525
+ current.row,
526
+ ),
527
+ );
528
+
529
+ const allowed = expression(mapping.write.policy.action(nativeId, input.authorization));
530
+
531
+ const classify = Effect.gen(function* () {
532
+ const rows =
533
+ yield* sql`select case when ${remaining} then 1 else 0 end as remaining, case when ${allowed} and ${state.now} < ${authority.expiresBeforeMillis} and ${subjectCondition(current.revision)} then 1 else 0 end as allowed`;
534
+
535
+ return Number(rows[0]?.allowed) !== 1
536
+ ? ("Rejected" as const)
537
+ : Number(rows[0]?.remaining) !== 1
538
+ ? ("LastSignInMethod" as const)
539
+ : undefined;
540
+ });
541
+
542
+ const next = SecurityRevision.make(yield* randomId);
543
+ const update = sql`${subject.update({ [read.subject.securityRevision]: next })} where ${subject.column(read.subject.id)} = ${subject.value(read.subject.id, nativeId)} and ${eq(subject, read.subject.securityRevision, current.revision.securityRevision)} and ${state.active("subject")} and ${remaining} and ${allowed} and ${state.now} < ${authority.expiresBeforeMillis}`;
544
+
545
+ if (base.batch) {
546
+ const rejected = yield* classify;
547
+
548
+ if (rejected !== undefined)
549
+ return yield* preparePasskeyNative({ _tag: rejected }, prepare);
550
+ yield* write(update, 1);
551
+ } else if ((yield* flow.change(update)) !== 1) {
552
+ const rejected = yield* classify;
553
+
554
+ return yield* preparePasskeyNative({ _tag: rejected ?? "Rejected" }, prepare);
555
+ }
556
+ yield* write(
557
+ sql`${credential.update({ [read.credential.status]: mapping.write.credential.removedStatus, [read.credential.credentialRevision]: next })} where ${owned(nativeId, captured.credentialId)} and ${eq(credential, read.credential.credentialRevision, captured.revision.credentials.find((entry) => entry.credentialId === captured.credentialId)?.revision)}`,
558
+ 1,
559
+ );
560
+ yield* write(
561
+ sql`${factor.update({ [read.authority.status]: mapping.write.authority.removedStatus, [read.authority.revision]: next })} where ${factor.column(read.authority.subjectId)} = ${factor.value(read.authority.subjectId, nativeId)} and ${eq(factor, read.authority.credentialId, captured.credentialId)}`,
562
+ 1,
563
+ );
564
+
565
+ const policyValues = Object.fromEntries(
566
+ mapping.write.policy.subjectColumns.map((key) => [
567
+ key,
568
+ key === read.subject.securityRevision ? next : current.row[key],
569
+ ]),
570
+ );
571
+
572
+ const policyUnchanged = sql`exists(select 1 from ${subject.name} where ${subject.column(read.subject.id)} = ${subject.value(read.subject.id, nativeId)} and ${match(subject, policyValues)})`;
573
+
574
+ const invalidation = {
575
+ subjectId: nativeId,
576
+ previousRevision: current.revision.securityRevision,
577
+ securityRevision: next,
578
+ invalidation: input.invalidation,
579
+ };
580
+
581
+ const finalConditions: Array<Fragment> = [];
582
+
583
+ for (const mutation of mapping.invalidation.mutations) {
584
+ const table = tables(mutation.table);
585
+ const query = sql`${table.update(mutation.values(invalidation))} where ${expression(mutation.where(invalidation))}`;
586
+
587
+ if (base.batch) yield* appendSqlBatchStatement(query);
588
+ else yield* query;
589
+ finalConditions.push(expression(mutation.postcondition(invalidation)));
590
+ }
591
+ finalConditions.push(
592
+ sql`exists(select 1 from ${credential.name} where ${credential.column(read.credential.subjectId)} = ${credential.value(read.credential.subjectId, nativeId)} and ${eq(credential, read.credential.credentialId, captured.credentialId)} and ${eq(credential, read.credential.credentialRevision, next)} and ${eq(credential, read.credential.status, mapping.write.credential.removedStatus)}) and exists(select 1 from ${factor.name} where ${factor.column(read.authority.subjectId)} = ${factor.value(read.authority.subjectId, nativeId)} and ${eq(factor, read.authority.credentialId, captured.credentialId)} and ${eq(factor, read.authority.revision, next)} and ${eq(factor, read.authority.status, mapping.write.authority.removedStatus)})`,
593
+ );
594
+ finalConditions.push(
595
+ sql`${expression(mapping.invalidation.postcondition(invalidation))} and ${policyUnchanged} and ${remaining} and ${state.now} < ${authority.expiresBeforeMillis}`,
596
+ );
597
+ yield* postcondition("passkey-removal", sql.and(finalConditions));
598
+
599
+ return yield* preparePasskeyNative(
600
+ {
601
+ _tag: "Removed",
602
+ result: { credentialId: captured.credentialId, invalidation: input.invalidation },
603
+ },
604
+ prepare,
605
+ );
606
+ }),
607
+ ),
608
+ };
609
+
610
+ return { passkeyManagementPersistence: service };
611
+ };