@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.0

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 (643) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.d.ts +7 -7
  4. package/dist/agent-tools/tool-dispatch.js +9 -9
  5. package/dist/audit/handlers/audit-events.js +1 -1
  6. package/dist/audit/screens.js +1 -1
  7. package/dist/auth-email-password/feature.js +1 -1
  8. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  9. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  10. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  11. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  12. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  13. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  14. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  15. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  16. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/login.write.js +1 -1
  18. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  19. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  20. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  21. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  22. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  23. package/dist/auth-email-password/index.js +5 -5
  24. package/dist/auth-email-password/lockout-store.js +1 -1
  25. package/dist/auth-email-password/seeding.d.ts +42 -45
  26. package/dist/auth-email-password/seeding.js +51 -53
  27. package/dist/auth-email-password/signup-token-store.js +8 -8
  28. package/dist/auth-email-password/testing.js +3 -3
  29. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  30. package/dist/auth-email-password/web/auth-client.js +36 -37
  31. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  32. package/dist/auth-email-password/web/auth-gate.js +15 -16
  33. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  34. package/dist/auth-email-password/web/client-plugin.js +4 -5
  35. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  36. package/dist/auth-email-password/web/constants.js +3 -3
  37. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  38. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  39. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  40. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  41. package/dist/auth-email-password/web/index.js +5 -5
  42. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  44. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  45. package/dist/auth-email-password/web/login-screen.js +2 -3
  46. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  47. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  48. package/dist/auth-email-password/web/session.d.ts +10 -9
  49. package/dist/auth-email-password/web/session.js +28 -29
  50. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  51. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  52. package/dist/auth-email-password/web/signup-screen.js +13 -13
  53. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  54. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  55. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  56. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  57. package/dist/auth-email-password/web/user-menu.js +12 -13
  58. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  59. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  60. package/dist/auth-foundation/boot-checks.js +4 -4
  61. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  62. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  63. package/dist/auth-foundation/types.js +2 -2
  64. package/dist/auth-mfa/feature-exports.d.ts +2 -2
  65. package/dist/auth-mfa/feature.js +8 -0
  66. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  67. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  68. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  69. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  70. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  71. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  72. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  73. package/dist/auth-mfa/token-secrets.js +1 -1
  74. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  75. package/dist/auth-mfa/web/client-plugin.js +1 -1
  76. package/dist/auth-mfa/web/i18n.js +8 -4
  77. package/dist/auth-mfa/web/index.js +4 -4
  78. package/dist/auth-mfa/web/mfa-client.js +17 -16
  79. package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
  80. package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
  81. package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
  82. package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
  83. package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
  84. package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
  85. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  86. package/dist/billing-foundation/aggregate-id.js +10 -11
  87. package/dist/billing-foundation/checkout-core.d.ts +9 -14
  88. package/dist/billing-foundation/checkout-core.js +24 -39
  89. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
  90. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
  91. package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
  92. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
  93. package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
  94. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
  95. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
  96. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
  97. package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
  98. package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
  99. package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
  100. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
  101. package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
  102. package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
  103. package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
  104. package/dist/billing-foundation/entities.js +27 -27
  105. package/dist/billing-foundation/events.d.ts +1 -0
  106. package/dist/billing-foundation/events.js +19 -17
  107. package/dist/billing-foundation/feature.js +45 -44
  108. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  109. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  110. package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
  111. package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
  112. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  113. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  114. package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
  115. package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
  116. package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
  117. package/dist/billing-foundation/handlers/process-event.write.js +28 -22
  118. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
  119. package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
  120. package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
  121. package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
  122. package/dist/billing-foundation/i18n.js +22 -0
  123. package/dist/billing-foundation/index.d.ts +1 -1
  124. package/dist/billing-foundation/plan-catalog.d.ts +21 -5
  125. package/dist/billing-foundation/plan-catalog.js +25 -16
  126. package/dist/billing-foundation/plan-switch.d.ts +12 -0
  127. package/dist/billing-foundation/plan-switch.js +60 -0
  128. package/dist/billing-foundation/projection.d.ts +15 -11
  129. package/dist/billing-foundation/projection.js +38 -37
  130. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  131. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  132. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  133. package/dist/billing-foundation/types.d.ts +97 -42
  134. package/dist/billing-foundation/types.js +29 -20
  135. package/dist/billing-foundation/validate-options.js +17 -0
  136. package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
  137. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
  138. package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
  139. package/dist/billing-foundation/web/constants.d.ts +4 -0
  140. package/dist/billing-foundation/web/constants.js +4 -0
  141. package/dist/billing-foundation/web/plan-price.d.ts +15 -0
  142. package/dist/billing-foundation/web/plan-price.js +32 -0
  143. package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
  144. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
  145. package/dist/cap-counter/aggregate-id.js +8 -9
  146. package/dist/cap-counter/cap-reservation.js +5 -1
  147. package/dist/cap-counter/constants.js +11 -12
  148. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  149. package/dist/cap-counter/enforce-cap.js +49 -49
  150. package/dist/cap-counter/entity.js +29 -29
  151. package/dist/cap-counter/feature.js +34 -35
  152. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  153. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  154. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  155. package/dist/cap-counter/stock-cap-guard.js +8 -2
  156. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  157. package/dist/channel-email/feature.js +1 -1
  158. package/dist/channel-email/smtp-transport.d.ts +18 -17
  159. package/dist/channel-email/smtp-transport.js +24 -21
  160. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  161. package/dist/compliance-profiles/feature.js +4 -4
  162. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  163. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  164. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  165. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  166. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  167. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  168. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  169. package/dist/compliance-profiles/seeding.js +14 -15
  170. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  171. package/dist/compliance-profiles-ops/index.js +2 -2
  172. package/dist/config/handlers/cascade.query.d.ts +5 -0
  173. package/dist/config/handlers/cascade.query.js +4 -3
  174. package/dist/config/handlers/readiness.query.d.ts +4 -4
  175. package/dist/config/handlers/readiness.query.js +1 -1
  176. package/dist/config/handlers/reencrypt.job.js +4 -5
  177. package/dist/config/handlers/set.write.js +4 -4
  178. package/dist/config/handlers/values.query.d.ts +5 -0
  179. package/dist/config/handlers/values.query.js +4 -3
  180. package/dist/config/resolver.js +4 -4
  181. package/dist/config/table.js +10 -10
  182. package/dist/config/write-helpers.d.ts +1 -0
  183. package/dist/config/write-helpers.js +19 -10
  184. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  185. package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
  186. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  187. package/dist/custom-fields/aggregate-id.js +16 -17
  188. package/dist/custom-fields/entity.js +49 -47
  189. package/dist/custom-fields/events.js +7 -8
  190. package/dist/custom-fields/feature.d.ts +14 -14
  191. package/dist/custom-fields/feature.js +53 -54
  192. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  193. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  194. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  195. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  196. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  197. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  198. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  199. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  200. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  201. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  202. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  203. package/dist/custom-fields/lib/field-access.js +2 -2
  204. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  205. package/dist/custom-fields/lib/quota.js +1 -1
  206. package/dist/custom-fields/lib/value-schema.js +10 -12
  207. package/dist/custom-fields/run-retention.js +3 -3
  208. package/dist/custom-fields/schemas.js +14 -14
  209. package/dist/custom-fields/web/client-plugin.js +2 -5
  210. package/dist/custom-fields/web/constants.js +2 -2
  211. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  212. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  213. package/dist/custom-fields/wire-for-entity.js +65 -67
  214. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  215. package/dist/data-retention/_internal/parse-override.js +2 -3
  216. package/dist/data-retention/feature.js +11 -18
  217. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  218. package/dist/data-retention/keep-for.d.ts +7 -7
  219. package/dist/data-retention/keep-for.js +15 -15
  220. package/dist/data-retention/override-schema.d.ts +3 -4
  221. package/dist/data-retention/override-schema.js +13 -15
  222. package/dist/data-retention/presets.d.ts +4 -5
  223. package/dist/data-retention/presets.js +18 -23
  224. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  225. package/dist/data-retention/resolver.d.ts +12 -12
  226. package/dist/data-retention/resolver.js +24 -23
  227. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  228. package/dist/data-retention/run-retention-cleanup.js +61 -51
  229. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  230. package/dist/delivery/channel-context.js +6 -3
  231. package/dist/delivery/db/queries/preferences.js +2 -2
  232. package/dist/delivery/delivery-service.js +22 -7
  233. package/dist/delivery/feature.js +2 -2
  234. package/dist/delivery/handlers/log.query.js +1 -1
  235. package/dist/delivery/handlers/preferences.query.d.ts +1 -1
  236. package/dist/delivery/handlers/preferences.query.js +20 -1
  237. package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
  238. package/dist/delivery/tables.js +9 -8
  239. package/dist/delivery/unsubscribe-link.d.ts +3 -1
  240. package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
  241. package/dist/delivery/unsubscribe-page-strings.js +1 -0
  242. package/dist/delivery/unsubscribe-page.d.ts +2 -0
  243. package/dist/delivery/unsubscribe-page.js +5 -0
  244. package/dist/delivery/unsubscribe.js +29 -11
  245. package/dist/document-ingest-foundation/entity.js +4 -4
  246. package/dist/document-ingest-foundation/events.js +2 -2
  247. package/dist/document-ingest-foundation/feature.js +2 -2
  248. package/dist/document-ingest-foundation/pages.js +1 -1
  249. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  250. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  251. package/dist/feature-toggles/feature.js +1 -1
  252. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  253. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  254. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  255. package/dist/feature-toggles/web/constants.js +1 -1
  256. package/dist/file-derivatives/feature.d.ts +1 -1
  257. package/dist/file-derivatives/feature.js +1 -1
  258. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  259. package/dist/file-derivatives/presets.js +1 -1
  260. package/dist/file-foundation/feature.js +6 -6
  261. package/dist/file-foundation/index.d.ts +1 -1
  262. package/dist/file-foundation/index.js +1 -1
  263. package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
  264. package/dist/file-foundation/read-file-ref-content.js +6 -1
  265. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  266. package/dist/file-provider-inmemory/feature.js +16 -16
  267. package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
  268. package/dist/file-provider-s3/feature.js +16 -16
  269. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  270. package/dist/files/feature.js +6 -6
  271. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  272. package/dist/files-tenant-data/hooks.js +24 -26
  273. package/dist/files-tenant-data/index.js +1 -1
  274. package/dist/folders/feature.d.ts +1 -1
  275. package/dist/folders/web/folder-manager.js +2 -2
  276. package/dist/folders/web/tree.js +5 -5
  277. package/dist/form-draft/db/queries/cleanup.js +3 -3
  278. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  279. package/dist/form-draft/decrypt-draft.js +5 -1
  280. package/dist/form-draft/entity.js +3 -3
  281. package/dist/form-draft/feature.js +4 -5
  282. package/dist/form-draft/handlers/discard.write.js +1 -1
  283. package/dist/form-draft/release-file-refs.js +6 -6
  284. package/dist/form-draft/schemas.js +3 -3
  285. package/dist/form-draft/web/constants.js +0 -2
  286. package/dist/host-routing/dispatch.js +11 -20
  287. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  288. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  289. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  290. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  291. package/dist/inbound-mail-foundation/constants.js +30 -33
  292. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  293. package/dist/inbound-mail-foundation/entities.js +47 -48
  294. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  295. package/dist/inbound-mail-foundation/events.js +50 -47
  296. package/dist/inbound-mail-foundation/feature.js +39 -39
  297. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  298. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  299. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  300. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  301. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  302. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  303. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  304. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
  305. package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
  306. package/dist/inbound-mail-foundation/i18n.js +0 -1
  307. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  308. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  309. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  310. package/dist/inbound-mail-foundation/projection.js +31 -29
  311. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  312. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  313. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  314. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  315. package/dist/inbound-mail-foundation/screens.js +0 -3
  316. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  317. package/dist/inbound-mail-foundation/types.d.ts +49 -49
  318. package/dist/inbound-mail-foundation/types.js +21 -21
  319. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  320. package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
  321. package/dist/inbound-provider-imap/credential-document.js +13 -13
  322. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  323. package/dist/inbound-provider-imap/feature.js +42 -40
  324. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  325. package/dist/inbound-provider-imap/imap-client.js +20 -19
  326. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  327. package/dist/inbound-provider-inmemory/feature.js +19 -19
  328. package/dist/jobs/db/queries/retention.js +2 -2
  329. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  330. package/dist/jobs/events.js +1 -1
  331. package/dist/jobs/feature.d.ts +1 -0
  332. package/dist/jobs/feature.js +13 -10
  333. package/dist/jobs/handlers/detail.query.js +4 -4
  334. package/dist/jobs/handlers/list.query.js +1 -1
  335. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  336. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  337. package/dist/jobs/handlers/retry.write.js +1 -1
  338. package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
  339. package/dist/jobs/handlers/tenant-failures.query.js +45 -41
  340. package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
  341. package/dist/jobs/handlers/tenant-runs.query.js +54 -50
  342. package/dist/jobs/job-instant.js +1 -1
  343. package/dist/jobs/job-run-logger.js +15 -15
  344. package/dist/jobs/job-run-table.js +3 -3
  345. package/dist/jobs/screens.js +1 -1
  346. package/dist/jobs/tenant-job-failure-table.js +1 -1
  347. package/dist/jobs/tenant-job-run-table.js +1 -1
  348. package/dist/ledger/entity.js +5 -5
  349. package/dist/ledger/feature.js +3 -3
  350. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  351. package/dist/ledger/recurring.js +12 -12
  352. package/dist/ledger/schemas.js +1 -1
  353. package/dist/ledger/web/constants.js +2 -2
  354. package/dist/ledger/web/index.js +7 -7
  355. package/dist/legal-pages/feature.d.ts +4 -4
  356. package/dist/legal-pages/feature.js +25 -26
  357. package/dist/legal-pages/markdown.js +3 -3
  358. package/dist/legal-pages/web/client-plugin.js +23 -24
  359. package/dist/legal-pages/web/index.js +0 -1
  360. package/dist/mail-foundation/feature.d.ts +5 -5
  361. package/dist/mail-foundation/feature.js +27 -25
  362. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  363. package/dist/mail-transport-inmemory/feature.js +27 -28
  364. package/dist/mail-transport-smtp/feature.js +20 -20
  365. package/dist/managed-pages/branding.js +6 -6
  366. package/dist/managed-pages/feature.d.ts +26 -26
  367. package/dist/managed-pages/feature.js +34 -34
  368. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  369. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  370. package/dist/managed-pages/handlers/set.write.js +5 -7
  371. package/dist/managed-pages/screens/page-screens.js +11 -11
  372. package/dist/managed-pages/seeding.js +8 -8
  373. package/dist/managed-pages/table.js +13 -12
  374. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  375. package/dist/managed-pages/web/client-plugin.js +5 -5
  376. package/dist/managed-pages/web/i18n.js +1 -1
  377. package/dist/notes-history/entity.js +4 -4
  378. package/dist/notes-history/feature.d.ts +2 -2
  379. package/dist/notes-history-user-data/hooks.js +1 -1
  380. package/dist/page-render/layout.js +9 -9
  381. package/dist/page-render/markdown.js +11 -11
  382. package/dist/page-render/security-headers.js +7 -6
  383. package/dist/personal-access-tokens/feature.d.ts +1 -1
  384. package/dist/personal-access-tokens/feature.js +9 -5
  385. package/dist/personal-access-tokens/roles.js +2 -2
  386. package/dist/readiness/handlers/status.query.js +3 -3
  387. package/dist/renderer-foundation/api.js +12 -13
  388. package/dist/renderer-foundation/constants.js +2 -2
  389. package/dist/renderer-foundation/feature.js +7 -7
  390. package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
  391. package/dist/renderer-pdf/render-table-pdf.js +22 -10
  392. package/dist/secrets/feature.js +9 -9
  393. package/dist/secrets/web/constants.js +2 -2
  394. package/dist/seo/feature.js +3 -3
  395. package/dist/sessions/constants.d.ts +1 -1
  396. package/dist/sessions/constants.js +1 -1
  397. package/dist/sessions/feature.d.ts +2 -2
  398. package/dist/sessions/feature.js +12 -8
  399. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  400. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  401. package/dist/sessions/handlers/revoke.write.js +1 -1
  402. package/dist/sessions/schema/user-session.js +4 -4
  403. package/dist/sessions/screens.js +2 -2
  404. package/dist/sessions/session-callbacks.js +2 -2
  405. package/dist/sessions/session-revoked-event.js +2 -2
  406. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  407. package/dist/shared/decrypt-stored-pii.d.ts +1 -0
  408. package/dist/shared/decrypt-stored-pii.js +7 -2
  409. package/dist/shared/encrypt-for-direct-write.js +1 -1
  410. package/dist/shared/index.d.ts +1 -1
  411. package/dist/shared/index.js +1 -1
  412. package/dist/shared/mail-template-body.d.ts +6 -2
  413. package/dist/shared/mail-template-body.js +7 -4
  414. package/dist/shared/map-with-concurrency.js +5 -4
  415. package/dist/shared/parent-visibility.js +2 -2
  416. package/dist/shared/password-hashing.js +1 -1
  417. package/dist/shared/signup-handover.js +1 -2
  418. package/dist/shared/single-use-token-store.js +1 -1
  419. package/dist/step-dispatcher/feature.js +1 -0
  420. package/dist/subscription-dodo/client.d.ts +17 -0
  421. package/dist/subscription-dodo/client.js +31 -0
  422. package/dist/subscription-dodo/constants.d.ts +12 -0
  423. package/dist/subscription-dodo/constants.js +19 -0
  424. package/dist/subscription-dodo/feature.d.ts +37 -0
  425. package/dist/subscription-dodo/feature.js +144 -0
  426. package/dist/subscription-dodo/index.d.ts +2 -0
  427. package/dist/subscription-dodo/index.js +4 -0
  428. package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
  429. package/dist/subscription-dodo/plugin-methods.js +260 -0
  430. package/dist/subscription-dodo/runtime.d.ts +27 -0
  431. package/dist/subscription-dodo/runtime.js +89 -0
  432. package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
  433. package/dist/subscription-dodo/verify-webhook.js +189 -0
  434. package/dist/subscription-mollie/constants.js +15 -17
  435. package/dist/subscription-mollie/feature.d.ts +17 -18
  436. package/dist/subscription-mollie/feature.js +24 -24
  437. package/dist/subscription-mollie/index.js +3 -3
  438. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  439. package/dist/subscription-mollie/plugin-methods.js +15 -14
  440. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  441. package/dist/subscription-mollie/verify-webhook.js +27 -27
  442. package/dist/subscription-stripe/constants.js +4 -6
  443. package/dist/subscription-stripe/feature.d.ts +14 -14
  444. package/dist/subscription-stripe/feature.js +36 -34
  445. package/dist/subscription-stripe/index.js +6 -6
  446. package/dist/subscription-stripe/plugin-methods.js +18 -18
  447. package/dist/subscription-stripe/runtime.d.ts +1 -1
  448. package/dist/subscription-stripe/runtime.js +8 -7
  449. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  450. package/dist/subscription-stripe/verify-webhook.js +59 -61
  451. package/dist/tags/feature.d.ts +3 -3
  452. package/dist/tags/screens.js +1 -1
  453. package/dist/template-resolver/api.d.ts +3 -2
  454. package/dist/template-resolver/api.js +34 -12
  455. package/dist/template-resolver/compile-document-body.js +1 -0
  456. package/dist/template-resolver/feature.js +2 -2
  457. package/dist/template-resolver/handlers/bundle-import.js +3 -3
  458. package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
  459. package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
  460. package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
  461. package/dist/template-resolver/handlers/document-base.js +3 -2
  462. package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
  463. package/dist/template-resolver/handlers/list.query.js +6 -7
  464. package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
  465. package/dist/template-resolver/handlers/overview.query.js +6 -3
  466. package/dist/template-resolver/handlers/shared.js +2 -2
  467. package/dist/template-resolver/handlers/template-write.js +3 -3
  468. package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
  469. package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
  470. package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
  471. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  472. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  473. package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
  474. package/dist/template-resolver/handlers/usage.query.js +26 -16
  475. package/dist/template-resolver/handlers/validate.query.js +7 -2
  476. package/dist/template-resolver/seeding.js +30 -14
  477. package/dist/template-resolver/store-template-resource.d.ts +1 -0
  478. package/dist/template-resolver/store-template-resource.js +19 -4
  479. package/dist/template-resolver/table.js +10 -11
  480. package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
  481. package/dist/template-resolver/template-delivery-policy.js +0 -6
  482. package/dist/template-resolver/template-meta.js +7 -4
  483. package/dist/template-resolver/template-preview.js +4 -3
  484. package/dist/template-resolver/web/client-plugin.js +2 -2
  485. package/dist/template-resolver/web/constants.d.ts +2 -2
  486. package/dist/template-resolver/web/constants.js +3 -3
  487. package/dist/template-resolver/web/index.d.ts +1 -0
  488. package/dist/template-resolver/web/index.js +1 -0
  489. package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
  490. package/dist/template-resolver/web/mail-layout-constants.js +7 -0
  491. package/dist/tenant/feature.js +7 -7
  492. package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
  493. package/dist/tenant/handlers/member-directory.query.js +11 -4
  494. package/dist/tenant/handlers/members.query.js +1 -1
  495. package/dist/tenant/handlers/team-list.query.js +1 -1
  496. package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
  497. package/dist/tenant/handlers/tenant-directory.query.js +9 -5
  498. package/dist/tenant/invitation-table.js +37 -40
  499. package/dist/tenant/membership-table.js +3 -3
  500. package/dist/tenant/schema/tenant.js +7 -9
  501. package/dist/tenant/screens.js +1 -1
  502. package/dist/tenant/seeding.d.ts +6 -5
  503. package/dist/tenant/seeding.js +12 -12
  504. package/dist/tenant/testing.js +5 -6
  505. package/dist/tenant/web/constants.js +2 -2
  506. package/dist/tenant-handover/events.js +5 -7
  507. package/dist/tenant-handover/feature.js +1 -1
  508. package/dist/tenant-handover/grant.js +1 -1
  509. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  510. package/dist/tenant-handover/move-entity-graph.js +8 -9
  511. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  512. package/dist/tenant-handover/transfer-graph.js +4 -5
  513. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  514. package/dist/tenant-lifecycle/constants.d.ts +1 -0
  515. package/dist/tenant-lifecycle/constants.js +4 -0
  516. package/dist/tenant-lifecycle/feature.js +1 -1
  517. package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
  518. package/dist/tenant-settings/constants.js +1 -1
  519. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  520. package/dist/tenant-settings/tenant-defaults.js +9 -2
  521. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  522. package/dist/tier-engine/aggregate-id.js +15 -16
  523. package/dist/tier-engine/compose-app.d.ts +14 -14
  524. package/dist/tier-engine/compose-app.js +1 -1
  525. package/dist/tier-engine/entity.js +18 -19
  526. package/dist/tier-engine/feature.d.ts +19 -17
  527. package/dist/tier-engine/feature.js +68 -69
  528. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  529. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  530. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
  531. package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
  532. package/dist/tier-engine/tier-resolver.js +2 -2
  533. package/dist/tier-engine/trial.js +8 -8
  534. package/dist/tier-engine/web/constants.js +2 -2
  535. package/dist/tier-engine/web/index.js +4 -4
  536. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  537. package/dist/user/handlers/create.write.js +4 -4
  538. package/dist/user/schema/user.d.ts +11 -11
  539. package/dist/user/schema/user.js +45 -44
  540. package/dist/user/seeding.d.ts +15 -15
  541. package/dist/user/seeding.js +28 -28
  542. package/dist/user/testing.js +3 -3
  543. package/dist/user-data-rights/audit-download.d.ts +8 -8
  544. package/dist/user-data-rights/audit-download.js +19 -20
  545. package/dist/user-data-rights/boot-checks.js +1 -1
  546. package/dist/user-data-rights/deletion-token.js +1 -1
  547. package/dist/user-data-rights/feature.d.ts +49 -50
  548. package/dist/user-data-rights/feature.js +54 -53
  549. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  550. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  551. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  552. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  553. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  554. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  555. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  556. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  557. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  558. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  559. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  560. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  561. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  562. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  563. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  564. package/dist/user-data-rights/index.js +8 -10
  565. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  566. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  567. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  568. package/dist/user-data-rights/run-export-jobs.js +130 -237
  569. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  570. package/dist/user-data-rights/run-forget-cleanup.js +65 -83
  571. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  572. package/dist/user-data-rights/run-user-export.js +55 -57
  573. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  574. package/dist/user-data-rights/schema/download-token.js +37 -41
  575. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  576. package/dist/user-data-rights/schema/export-job.js +65 -67
  577. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  578. package/dist/user-data-rights/token-helpers.js +21 -25
  579. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  580. package/dist/user-data-rights/web/client-plugin.js +1 -1
  581. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  582. package/dist/user-data-rights/web/constants.js +1 -1
  583. package/dist/user-data-rights/web/index.js +5 -5
  584. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  585. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  586. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  587. package/dist/user-data-rights/zip-path.d.ts +15 -15
  588. package/dist/user-data-rights/zip-path.js +41 -40
  589. package/dist/user-data-rights-defaults/feature.js +15 -15
  590. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  591. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  592. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  593. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  594. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  595. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  596. package/dist/user-profile/handlers/change-email.write.js +13 -13
  597. package/dist/user-profile/index.js +3 -3
  598. package/dist/user-profile/web/client-plugin.js +1 -1
  599. package/dist/user-profile/web/constants.js +1 -1
  600. package/dist/user-profile/web/profile-screen.js +1 -1
  601. package/dist/waitlist/handlers/export-purge.write.js +2 -1
  602. package/dist/waitlist/handlers/submit.write.js +5 -5
  603. package/dist/waitlist/import.d.ts +1 -0
  604. package/dist/waitlist/import.js +4 -0
  605. package/dist/waitlist/legacy-migrate.js +17 -6
  606. package/dist/waitlist/link-on-signup.js +18 -6
  607. package/dist/waitlist/options.d.ts +3 -0
  608. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  609. package/dist/workflow-runner/aggregate-id.js +1 -1
  610. package/dist/workflow-runner/event-subscriber.js +4 -5
  611. package/dist/workflow-runner/event-trigger.js +4 -17
  612. package/dist/workflow-runner/feature.js +2 -2
  613. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  614. package/dist/workflow-runner/pending-projection.js +6 -7
  615. package/dist/workflow-runner/runner.js +6 -6
  616. package/dist/workflow-runner/tables.js +6 -6
  617. package/dist/workflow-runner/workflow-registry.js +1 -1
  618. package/package.json +20 -10
  619. package/src/agent-tools/changes.json +6 -0
  620. package/src/audit/changes.json +12 -0
  621. package/src/auth-mfa/changes.json +6 -0
  622. package/src/billing-foundation/changes.json +55 -0
  623. package/src/cap-counter/changes.json +18 -0
  624. package/src/channel-email/changes.json +6 -0
  625. package/src/config/changes.json +12 -0
  626. package/src/crypto-shredding/changes.json +6 -0
  627. package/src/delivery/changes.json +30 -0
  628. package/src/form-draft/changes.json +6 -0
  629. package/src/host-routing/changes.json +6 -0
  630. package/src/inbound-mail-foundation/changes.json +18 -0
  631. package/src/jobs/changes.json +13 -0
  632. package/src/mail-foundation/changes.json +6 -0
  633. package/src/renderer-pdf/changes.json +6 -0
  634. package/src/step-dispatcher/changes.json +6 -0
  635. package/src/subscription-dodo/changes.json +14 -0
  636. package/src/subscription-stripe/changes.json +12 -0
  637. package/src/template-resolver/changes.json +48 -0
  638. package/src/tenant/changes.json +6 -0
  639. package/src/tenant-lifecycle/changes.json +6 -0
  640. package/src/tier-engine/changes.json +6 -0
  641. package/src/waitlist/changes.json +18 -0
  642. package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
  643. package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
@@ -1,23 +1,22 @@
1
- // Magic-Link-Signup, Step 2 (confirm).
1
+ // Magic-Link signup, step 2 (confirmation).
2
2
  //
3
- // Token aus URL + Password vom User → wir lösen den Token in Redis ein
4
- // und legen Tenant + User + TenantAdmin membership atomically. emailVerified
5
- // wird sofort auf true gesetzt — der Magic-Link IST der Beweis.
3
+ // Token from the URL + password from the user → redeem the token in Redis
4
+ // and atomically create the tenant, user, and TenantAdmin membership.
5
+ // emailVerified is set to true immediately—the magic link IS the proof.
6
6
  //
7
7
  // Pipeline:
8
8
  // 1. Redis check: token → email lookup
9
- // 2. Single-Use-Burn (SETNX) — gleichzeitiger Klick aus zwei Tabs
10
- // gewinnt nur einer
11
- // 3. Tenant-Key generieren (generateUniqueName mit DB-isAvailable-
12
- // check gegen tenants.key)
13
- // 4. provisionSignupAccount: Tenant + User + Membership in einem
14
- // Rutsch (durch event-store-executor; events + projection +
15
- // MSPs sehen das wie einen regulären create)
16
- // 5. Token-Keys löschen (burn-key bleibt für TTL-Replay-Protection)
9
+ // 2. Single-use burn (SETNX)—only one of two simultaneous tab clicks wins
10
+ // 3. Generate the tenant key (generateUniqueName with a DB isAvailable
11
+ // check against tenants.key)
12
+ // 4. provisionSignupAccount: create the tenant, user, and membership in one
13
+ // operation (through event-store-executor; events, projection, and MSPs
14
+ // see this as a regular create)
15
+ // 5. Delete the token keys (the burn key remains for TTL replay protection)
17
16
  //
18
- // Failure-Recovery: jeder Pfad nach dem burn checked `committed`-Flag;
19
- // bei !committed wird der burn released damit ein legitimer Retry
20
- // nicht durch einen stale Marker geblockt wird (wie reset/verify).
17
+ // Failure recovery: every path after the burn checks the `committed` flag;
18
+ // when !committed, the burn is released so a legitimate retry is not blocked
19
+ // by a stale marker, as with reset/verify.
21
20
  import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
22
21
  import { defineWriteHandler, } from "@cosmicdrift/kumiko-framework/engine";
23
22
  import { ConflictError, InternalError, reraiseAsKumikoError, writeFailure, } from "@cosmicdrift/kumiko-framework/errors";
@@ -87,21 +86,21 @@ export function createSignupConfirmHandler(opts = {}) {
87
86
  message: "signup-confirm requires ctx.redis for token consumption",
88
87
  }));
89
88
  }
90
- // Token-Lookup: nicht-existent / abgelaufen / schon konsumiert →
91
- // alle collapsen auf invalid_signup_token. Anti-enumeration.
89
+ // Token lookup: nonexistent, expired, and already-consumed tokens all
90
+ // collapse to invalid_signup_token to prevent enumeration.
92
91
  const email = await getEmailForSignupToken(ctx.redis, event.payload.token);
93
92
  if (!email)
94
93
  return invalidSignupToken();
95
- // Single-Use-Burn: zwei parallele Confirms aus verschiedenen
96
- // Tabs — einer wins, der andere kriegt invalid_signup_token.
94
+ // Single-use burn: of two parallel confirmations from different tabs,
95
+ // one succeeds and the other receives invalid_signup_token.
97
96
  const burn = await burnSignupToken(ctx.redis, event.payload.token);
98
97
  if (burn === "already-used")
99
98
  return invalidSignupToken();
100
99
  let committed = false;
101
100
  try {
102
- // Tenant-Key: 2-Wort-Slug aus framework/random, mit DB-Conflict-
103
- // Check gegen tenants.key. 22.500 Default-Combos + Suffix-
104
- // Fallback bei Kollision (siehe generateUniqueName).
101
+ // Tenant key: a two-word slug from framework/random, with a DB conflict
102
+ // check against tenants.key. 22,500 default combinations plus a
103
+ // suffix fallback in case of collision (see generateUniqueName).
105
104
  // @cast-boundary db-runner — helpers use only the query API that
106
105
  // DbConnection and DbTx share.
107
106
  const dbConn = ctx.db.unsafeRaw();
@@ -112,8 +111,8 @@ export function createSignupConfirmHandler(opts = {}) {
112
111
  },
113
112
  });
114
113
  const tenantId = generateId(); // @cast-boundary engine-payload
115
- // Display-Name aus email-prefix als sinnvolles Default; User kann
116
- // den Tenant-Namen + sein eigenes displayName später ändern.
114
+ // Use the email prefix as a meaningful default display name; the user can
115
+ // change the tenant name and their own displayName later.
117
116
  const displayName = email.split("@")[0] ?? email;
118
117
  const registrationLocale = registrationLocaleFromRequest();
119
118
  let provisioned;
@@ -128,25 +127,24 @@ export function createSignupConfirmHandler(opts = {}) {
128
127
  tenantName: tenantKey,
129
128
  ...registrationLocale,
130
129
  },
131
- // #1463: seedTenant's postSave hooks (tier-engine's auto-default-
130
+ // seedTenant's postSave hooks (tier-engine's auto-default-
132
131
  // tier, an app's auto-default-compliance) must fire on self-signup
133
132
  // exactly like they do on the regular TenantHandlers.create path.
134
133
  { registry: ctx.registry, context: ctx });
135
134
  }
136
135
  catch (err) {
137
- // Email hat bereits ein Konto — provisionSignupAccount ist create-only
138
- // (#365): sauberer User-Fehler, KEINE Session für den fremden Account.
139
- // committed bleibt false → der burn wird im finally released (ein
140
- // Retry scheitert wieder gleich, kein stale-Marker-Block).
136
+ // The email already has an account—provisionSignupAccount is create-only:
137
+ // return a clean user error and never create a session for that account.
138
+ // committed remains false, so finally releases the burn; a retry fails
139
+ // the same way without being blocked by a stale marker.
141
140
  if (err instanceof ConflictError)
142
141
  return signupEmailAlreadyRegistered();
143
142
  throw err;
144
143
  }
145
- // SessionUser für JWT-Mint. Roles aus INITIAL_SIGNUP_ROLES
146
- // damit DB-write (provisionSignupAccount) und Session-claim
147
- // dieselbe Quelle teilen — sonst hätten zwei Stellen "TenantAdmin"
148
- // hardcoded und ein Refactor würde role-mismatch zwischen DB
149
- // und JWT erzeugen.
144
+ // Build the SessionUser for JWT minting. Use roles from INITIAL_SIGNUP_ROLES
145
+ // so the database write (provisionSignupAccount) and session claim share
146
+ // one source; otherwise two hardcoded "TenantAdmin" values could drift
147
+ // during a refactor and create a role mismatch between the DB and JWT.
150
148
  const session = {
151
149
  id: provisioned.userId,
152
150
  tenantId: provisioned.tenantId,
@@ -195,9 +193,8 @@ export function createSignupConfirmHandler(opts = {}) {
195
193
  }
196
194
  finally {
197
195
  if (!committed && ctx.redis) {
198
- // Burn-release damit ein retry nach DB-Hiccup nicht blockt.
199
- // Token-Lookup-Keys bleiben — der User kann seinen Mail-Link
200
- // erneut klicken.
196
+ // Release the burn so a retry after a DB hiccup is not blocked.
197
+ // Keep the token lookup keys so the user can click the email link again.
201
198
  await unburnSignupToken(ctx.redis, event.payload.token);
202
199
  }
203
200
  }
@@ -15,7 +15,7 @@
15
15
  // Always-200 (enumeration-safe): the response looks the same for every
16
16
  // email, whether it's already registered or not. An email CAN already have
17
17
  // an account (seeding or an earlier signup) — the actual gate sits
18
- // deliberately in the confirm step (#365): signup-confirm rejects an
18
+ // deliberately in the confirm step: signup-confirm rejects an
19
19
  // already-registered email instead of reusing the existing user. Here it
20
20
  // stays always-200 + resend-idempotent so the request path leaks nothing;
21
21
  // suppressing the link on the request side would be defense-in-depth, but
@@ -31,10 +31,9 @@ import { issueSignupActivation } from "../signup-activation.js";
31
31
  import { storeSignupHandover, takeOverSignupHandoverForResend } from "../signup-token-store.js";
32
32
  const SignupRequestSchema = z.object({
33
33
  email: z.email(),
34
- // Cross-device try-first handover (kumiko-framework#3035 follow-up,
35
- // offlot-app#454) — see shared/signup-handover.ts for why the grant is
36
- // verified here and rebound to the signup token instead of the client
37
- // carrying it through the activation link.
34
+ // Cross-device try-first handover: see shared/signup-handover.ts for why the
35
+ // grant is verified here and rebound to the signup token instead of the
36
+ // client carrying it through the activation link.
38
37
  handover: z
39
38
  .object({
40
39
  entityType: z.string().min(1),
@@ -64,8 +63,8 @@ export function createSignupRequestHandler(opts) {
64
63
  // ctx.hasFeature() is fail-closed for *unregistered* names the moment
65
64
  // feature-toggles/tier-engine is wired, which silently kills
66
65
  // self-signup for every existing app that mounts auth-email-password
67
- // without also composing createAuthSelfRegistrationToggleFeature()
68
- // (#1468). Only gate when the toggle actually exists.
66
+ // without also composing createAuthSelfRegistrationToggleFeature().
67
+ // Only gate when the toggle actually exists.
69
68
  const gated = ctx.registry.getFeature(AUTH_SELF_REGISTRATION_FEATURE) !== undefined;
70
69
  if (gated && !(await ctx.hasFeature(AUTH_SELF_REGISTRATION_FEATURE))) {
71
70
  // No email address here — this fires on every no-op request, PII
@@ -6,5 +6,5 @@ export type SwitchTenantMfaGateData = {
6
6
  } | NonNullable<Awaited<ReturnType<typeof gateEnforceMfa>>>;
7
7
  export declare function createSwitchTenantMfaGateHandler(opts: Pick<LoginHandlerOptions, "mfaStatusChecker">): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"switch-tenant-mfa-gate", z.ZodObject<{
8
8
  userId: z.ZodString;
9
- tenantId: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
9
+ tenantId: z.ZodString;
10
10
  }, z.core.$strip>, SwitchTenantMfaGateData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
@@ -7,10 +7,7 @@ import { noMembership } from "../errors.js";
7
7
  import { gateEnforceMfa } from "./login.write.js";
8
8
  const SwitchTenantMfaGateSchema = z.object({
9
9
  userId: z.string().min(1),
10
- tenantId: z
11
- .string()
12
- .min(1)
13
- .transform((id) => id),
10
+ tenantId: z.string().min(1),
14
11
  });
15
12
  // Dispatched by POST /auth/switch-tenant with the system identity. The handler
16
13
  // resolves membership and roles itself, so the gate never trusts caller-supplied
@@ -9,11 +9,11 @@ export { BootstrapPlanError, BootstrapWriteError, bootstrapTenants } from "./boo
9
9
  export { authEmailPasswordEnvSchema, createAuthEmailPasswordFeature } from "./feature.js";
10
10
  export { AuthMailNotificationTypes } from "./mail-notifications.js";
11
11
  export { AUTH_SELF_REGISTRATION_FEATURE, createAuthSelfRegistrationToggleFeature, } from "./self-registration-toggle.js";
12
- // Generic HMAC-signed single-purpose token helpers. Re-exported damit
13
- // app-spezifische out-of-band-Flows (subscriber-confirm, magic-links,
14
- // invite-tokens) denselben battle-tested signer/verifier nutzen können
15
- // statt eigene HMAC-Logik zu duplizieren. Purpose-string diskriminiert
16
- // Cross-Replay zwischen Flows.
12
+ // Generic HMAC-signed single-purpose token helpers. Re-exported so
13
+ // app-specific out-of-band flows (subscriber-confirm, magic-links,
14
+ // invite-tokens) can use the same battle-tested signer/verifier
15
+ // instead of duplicating HMAC logic. The purpose string prevents
16
+ // cross-replay between flows.
17
17
  export { signToken, TokenPurpose, verifyToken } from "./signed-token.js";
18
18
  export { issueSignupActivation, SIGNUP_ACTIVATION_NOTIFICATION_TYPE, } from "./signup-activation.js";
19
19
  export { invalidateExistingSignupToken, normalizeEmail, SIGNUP_TOKEN_KEY_PREFIXES, storeSignupToken, } from "./signup-token-store.js";
@@ -17,7 +17,7 @@
17
17
  // semantics) live in shared/lockout-counter.ts — this file only wires the
18
18
  // account-lockout key prefixes onto it. See that file for why a lock
19
19
  // re-arms immediately after expiry, and why a successful login (or the
20
- // account-unlock magic-link flow, #1266, see
20
+ // account-unlock magic-link flow in
21
21
  // handlers/confirm-account-unlock.write.ts) is what resets the streak.
22
22
  import { createLockoutCounter } from "../shared/index.js";
23
23
  const COUNT_KEY_PREFIX = "kumiko:auth:lockout:count:";
@@ -8,53 +8,51 @@ export type SeedUserWithPasswordOptions = {
8
8
  readonly password: string;
9
9
  readonly displayName: string;
10
10
  readonly locale?: string;
11
- /** Globale Rollen — siehe SeedUserOptions.roles. */
11
+ /** Global roles — see SeedUserOptions.roles. */
12
12
  readonly roles?: readonly string[];
13
- /** Initial-emailVerified-Flag. Default false (Verify-Flow läuft).
14
- * Magic-Link-Signup setzt true weil der Mail-Klick die Email-
15
- * Ownership beweist. Siehe SeedUserOptions.emailVerified. */
13
+ /** Initial emailVerified flag. Defaults to false (the verification flow runs).
14
+ * Magic-link signup sets it to true because clicking the email proves
15
+ * ownership. See SeedUserOptions.emailVerified. */
16
16
  readonly emailVerified?: boolean;
17
17
  readonly by?: SessionUser;
18
18
  };
19
19
  /**
20
- * Seed a user mit Plain-Password (wird vor dem Insert mit argon2
21
- * gehasht). Liefert die userId, idempotent über email.
20
+ * Seed a user with a plaintext password (hashed with argon2 before insertion).
21
+ * Returns the userId and is idempotent by email.
22
22
  */
23
23
  export declare function seedUserWithPassword(db: DbConnection, options: SeedUserWithPasswordOptions, hooks?: SeedTenantHooks): Promise<{
24
24
  id: string;
25
25
  }>;
26
- /** Provisioning-Helper für Self-Signup-Confirm. Legt einen frischen
27
- * Tenant + Admin-User + Membership in einem Rutsch an — verwendet die
28
- * bestehende Event-Store-Pipeline (wie seedAdmin) und ist daher
29
- * konsistent mit dem regulären create-Pfad: events werden geschrieben,
30
- * Projections sind populated, MSPs/Audit sehen die neuen Rows.
26
+ /** Provisions a fresh tenant, admin user, and membership for self-signup
27
+ * confirmation in one operation. It uses the existing event-store pipeline
28
+ * (as seedAdmin), keeping it consistent with the regular create path:
29
+ * events are written, projections are populated, and MSPs/audit see the
30
+ * new rows.
31
31
  *
32
- * Naming-Hinweis: nutzt intern `seedTenant` / `seedUser*` —
33
- * diese Helpers sind production-grade (event-store-pipeline), das "seed"
34
- * im Namen ist historisch (zuerst für Tests + Bootstrap gebaut, dann
35
- * als General-Purpose-Helper exportiert). Rename `seed*` → `provision*`
36
- * ist als dedizierter Cleanup-PR geplant — disproportional zum Wert
37
- * innerhalb dieses Sprints, weil alle existing tests berührt würden.
32
+ * Naming note: internally uses `seedTenant` / `seedUser*`; these helpers are
33
+ * production-grade (event-store pipeline), and "seed" is historical because
34
+ * they were first built for tests and bootstrap before being exported as
35
+ * general-purpose helpers.
38
36
  *
39
- * Atomicity: läuft inside einer Drizzle-Tx wenn der Caller das angibt
40
- * (db.begin(tx => provisionSignupAccount(tx, ...)) — die seed-
41
- * helpers nehmen DbConnection|DbTx strukturell. Bei pure DbConnection
42
- * sind die 3 writes nicht atomic; bei Failure zwischen Schritten kann
43
- * ein orphan-Tenant zurückbleiben (Tenant ohne User → unused row;
44
- * User ohne Membership → "no_membership" beim ersten Login).
37
+ * Atomicity: runs inside a Drizzle transaction when the caller provides one
38
+ * (db.begin(tx => provisionSignupAccount(tx, ...)); the seed helpers accept
39
+ * DbConnection|DbTx structurally. With a plain DbConnection, the three writes
40
+ * are not atomic; a failure between steps can leave an orphan tenant (tenant
41
+ * without a user → unused row; user without a membership → "no_membership"
42
+ * on first login).
45
43
  *
46
- * Create-only: existiert bereits ein User mit dieser Email (Seeding oder
47
- * früherer Signup), wirft die Funktion einen ConflictError BEVOR ein Tenant
48
- * entsteht. Der Self-Signup-Pfad darf einen bestehenden User nicht still
49
- * wiederverwenden — sonst würde der Confirm-Schritt eine Session für ihn
50
- * minten (Account-Takeover, #365). `seedUser` selbst bleibt idempotent
51
- * add-only (für Bootstrap/Tests); die create-only-Garantie sitzt hier.
52
- * tenantKey-Kollisionen löst der Caller via generateUniqueName. */
44
+ * Create-only: if a user with this email already exists (from seeding or an
45
+ * earlier signup), the function throws a ConflictError BEFORE creating a
46
+ * tenant. The self-signup path must not silently reuse an existing user —
47
+ * otherwise the confirmation step could mint a session for that user
48
+ * (account takeover). `seedUser` itself remains idempotent and add-only
49
+ * (for bootstrap/tests); the create-only guarantee belongs here.
50
+ * The caller resolves tenantKey collisions via generateUniqueName. */
53
51
  /** Default membership roles for self-signup tenant owners. Shared between
54
- * provisionSignupAccount (DB-write) und signup-confirm-handler
55
- * (SessionUser-Konstruktion für JWT-Mint) — sonst hätten zwei
56
- * Stellen unabhängig "TenantAdmin" hardcoded und würden bei einem
57
- * Refactor zu role-mismatch zwischen DB und Session leiden. */
52
+ * provisionSignupAccount (DB write) and signup-confirm-handler
53
+ * (SessionUser construction for JWT minting); otherwise two locations would
54
+ * independently hardcode "TenantAdmin" and a refactor could cause a role
55
+ * mismatch between the database and the session. */
58
56
  export declare const INITIAL_SIGNUP_ROLES: readonly ["TenantAdmin", "Admin"];
59
57
  export type ProvisionSignupAccountOptions = {
60
58
  readonly email: string;
@@ -75,20 +73,19 @@ export type SeedAdminOptions = {
75
73
  readonly email: string;
76
74
  readonly password: string;
77
75
  readonly displayName: string;
78
- /** Tenants, in die der Admin als Mitglied eingetragen wird. Pro
79
- * Tenant kann eine eigene Rollenliste gesetzt werden — hilft beim
80
- * Sample-TenantSwitcher der pro Tenant unterschiedliche
81
- * Rollen-Listen zeigt. */
76
+ /** Tenants where the admin is added as a member. Each tenant can have
77
+ * its own role list, which lets the sample TenantSwitcher show different
78
+ * role lists for each tenant. */
82
79
  readonly memberships: ReadonlyArray<{
83
80
  readonly tenantId: TenantId;
84
81
  readonly tenantKey: string;
85
82
  readonly tenantName: string;
86
83
  readonly roles: readonly string[];
87
84
  }>;
88
- /** Globale Rollen die in users.roles landen — tenant-unabhängig.
89
- * Login-Handler mergt sie in jede Session parallel zu den tenant-
90
- * membership-Rollen. Typischer use-case: `["SystemAdmin"]` für
91
- * einen Plattform-Operator. Default: leer. */
85
+ /** Global roles stored in users.roles, independent of the tenant.
86
+ * The login handler merges them into every session alongside the tenant
87
+ * membership roles. Typical use case: `["SystemAdmin"]` for a platform
88
+ * operator. Default: empty. */
92
89
  readonly globalRoles?: readonly string[];
93
90
  /** Initial emailVerified state — defaults to false (unverified). Same
94
91
  * mechanism as seedUserWithPassword.emailVerified. Re-running the seed
@@ -98,9 +95,9 @@ export type SeedAdminOptions = {
98
95
  readonly by?: SessionUser;
99
96
  };
100
97
  /**
101
- * Seed-Convenience für Sample-Server: Admin-User mit gehashtem
102
- * Password + N Tenants + N Memberships. Alles idempotent (Re-Run im
103
- * persistent-DB-Modus läuft durch). Liefert die userId zurück.
98
+ * Seeding convenience for sample servers: an admin user with a hashed
99
+ * password, N tenants, and N memberships. Idempotent, so rerunning it in
100
+ * persistent-DB mode succeeds. Returns the userId.
104
101
  */
105
102
  export declare function seedAdmin(db: DbConnection, options: SeedAdminOptions): Promise<{
106
103
  id: string;
@@ -1,16 +1,16 @@
1
- // Stable seeding helpers fürs auth-email-password-Feature. Liegen unter
2
- // `/seeding` (nicht `/testing`) damit der Vertrag klar ist: hier ist
3
- // non-test code der bei jedem Dev-Boot + jedem Integration-Test läuft.
4
- // Test-spezifische Variationen (account-locked-Setup, expired-token,
5
- // race-conditions) werden NICHT als Knöpfe an diesen Helpers angebaut —
6
- // sie kommen als neue Funktionen daneben oder inline ins Test-File.
1
+ // Stable seeding helpers for the auth-email-password feature. They live under
2
+ // `/seeding` rather than `/testing` to make the contract clear: this is
3
+ // non-test code that runs on every dev boot and integration test.
4
+ // Test-specific variations (account-locked setup, expired-token,
5
+ // race-conditions) are NOT added as options to these helpers —
6
+ // they belong in separate functions or inline in the test file.
7
7
  //
8
- // Bündelt drei Schritte in einem Aufruf:
9
- // 1. argon2-Hash des Plain-Passworts
10
- // 2. seedUser() aus user/seeding
11
- // 3. seedTenant + seedTenantMembership aus tenant/seeding
12
- // Damit Sample-Server und Tests keine drei sub-paths zusammensammeln
13
- // müssen.
8
+ // Bundles three steps into one call:
9
+ // 1. argon2 hash of the plaintext password
10
+ // 2. seedUser() from user/seeding
11
+ // 3. seedTenant + seedTenantMembership from tenant/seeding
12
+ // This keeps sample servers and tests from having to assemble three
13
+ // sub-paths themselves.
14
14
  import { configuredBlindIndexKey, configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
15
15
  import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
16
16
  import { ConflictError } from "@cosmicdrift/kumiko-framework/errors";
@@ -24,21 +24,21 @@ import { USER_STATUS, userTable } from "../user/schema/user.js";
24
24
  // kumiko-lint-ignore cross-feature-import auth-tests need user+tenant seed-helpers
25
25
  import { reconcileSeededUserEmailVerified, rewriteSeededUserEmail, seedUser, } from "../user/seeding.js";
26
26
  const log = createFallbackLogger("auth-email-password-seeding");
27
- // Re-export für ergonomische Single-Import-Site in tests/seed-scripts.
28
- // Das Auth-Feature ist der natürliche Aufrufer für "seed admin user mit
29
- // password + tenant + membership" — wer das nutzt soll nicht aus drei
30
- // verschiedenen sub-paths zusammensammeln müssen.
27
+ // Re-export for a convenient single import site in tests/seed-scripts.
28
+ // The auth feature is the natural caller for "seed admin user with
29
+ // password + tenant + membership", so consumers do not need to assemble
30
+ // these helpers from three different sub-paths.
31
31
  // kumiko-lint-ignore cross-feature-import re-export of test-helpers
32
32
  export { seedTenant, seedTenantMembership } from "../tenant/seeding.js";
33
33
  // kumiko-lint-ignore cross-feature-import re-export of test-helpers
34
34
  export { seedUser } from "../user/seeding.js";
35
35
  /**
36
- * Seed a user mit Plain-Password (wird vor dem Insert mit argon2
37
- * gehasht). Liefert die userId, idempotent über email.
36
+ * Seed a user with a plaintext password (hashed with argon2 before insertion).
37
+ * Returns the userId and is idempotent by email.
38
38
  */
39
39
  export async function seedUserWithPassword(db, options,
40
40
  // Optional, append-only — same rationale as provisionSignupAccount's
41
- // hooks param (#1478): the self-signup path passes it through so `user`'s
41
+ // hooks param: the self-signup path passes it through so `user`'s
42
42
  // postSave hooks fire on self-signup same as on the regular create path.
43
43
  hooks) {
44
44
  const passwordHash = await hashPassword(options.password);
@@ -52,54 +52,52 @@ hooks) {
52
52
  ...(options.by !== undefined && { by: options.by }),
53
53
  }, hooks);
54
54
  }
55
- /** Provisioning-Helper für Self-Signup-Confirm. Legt einen frischen
56
- * Tenant + Admin-User + Membership in einem Rutsch an — verwendet die
57
- * bestehende Event-Store-Pipeline (wie seedAdmin) und ist daher
58
- * konsistent mit dem regulären create-Pfad: events werden geschrieben,
59
- * Projections sind populated, MSPs/Audit sehen die neuen Rows.
55
+ /** Provisions a fresh tenant, admin user, and membership for self-signup
56
+ * confirmation in one operation. It uses the existing event-store pipeline
57
+ * (as seedAdmin), keeping it consistent with the regular create path:
58
+ * events are written, projections are populated, and MSPs/audit see the
59
+ * new rows.
60
60
  *
61
- * Naming-Hinweis: nutzt intern `seedTenant` / `seedUser*` —
62
- * diese Helpers sind production-grade (event-store-pipeline), das "seed"
63
- * im Namen ist historisch (zuerst für Tests + Bootstrap gebaut, dann
64
- * als General-Purpose-Helper exportiert). Rename `seed*` → `provision*`
65
- * ist als dedizierter Cleanup-PR geplant — disproportional zum Wert
66
- * innerhalb dieses Sprints, weil alle existing tests berührt würden.
61
+ * Naming note: internally uses `seedTenant` / `seedUser*`; these helpers are
62
+ * production-grade (event-store pipeline), and "seed" is historical because
63
+ * they were first built for tests and bootstrap before being exported as
64
+ * general-purpose helpers.
67
65
  *
68
- * Atomicity: läuft inside einer Drizzle-Tx wenn der Caller das angibt
69
- * (db.begin(tx => provisionSignupAccount(tx, ...)) — die seed-
70
- * helpers nehmen DbConnection|DbTx strukturell. Bei pure DbConnection
71
- * sind die 3 writes nicht atomic; bei Failure zwischen Schritten kann
72
- * ein orphan-Tenant zurückbleiben (Tenant ohne User → unused row;
73
- * User ohne Membership → "no_membership" beim ersten Login).
66
+ * Atomicity: runs inside a Drizzle transaction when the caller provides one
67
+ * (db.begin(tx => provisionSignupAccount(tx, ...)); the seed helpers accept
68
+ * DbConnection|DbTx structurally. With a plain DbConnection, the three writes
69
+ * are not atomic; a failure between steps can leave an orphan tenant (tenant
70
+ * without a user → unused row; user without a membership → "no_membership"
71
+ * on first login).
74
72
  *
75
- * Create-only: existiert bereits ein User mit dieser Email (Seeding oder
76
- * früherer Signup), wirft die Funktion einen ConflictError BEVOR ein Tenant
77
- * entsteht. Der Self-Signup-Pfad darf einen bestehenden User nicht still
78
- * wiederverwenden — sonst würde der Confirm-Schritt eine Session für ihn
79
- * minten (Account-Takeover, #365). `seedUser` selbst bleibt idempotent
80
- * add-only (für Bootstrap/Tests); die create-only-Garantie sitzt hier.
81
- * tenantKey-Kollisionen löst der Caller via generateUniqueName. */
73
+ * Create-only: if a user with this email already exists (from seeding or an
74
+ * earlier signup), the function throws a ConflictError BEFORE creating a
75
+ * tenant. The self-signup path must not silently reuse an existing user —
76
+ * otherwise the confirmation step could mint a session for that user
77
+ * (account takeover). `seedUser` itself remains idempotent and add-only
78
+ * (for bootstrap/tests); the create-only guarantee belongs here.
79
+ * The caller resolves tenantKey collisions via generateUniqueName. */
82
80
  /** Default membership roles for self-signup tenant owners. Shared between
83
- * provisionSignupAccount (DB-write) und signup-confirm-handler
84
- * (SessionUser-Konstruktion für JWT-Mint) — sonst hätten zwei
85
- * Stellen unabhängig "TenantAdmin" hardcoded und würden bei einem
86
- * Refactor zu role-mismatch zwischen DB und Session leiden. */
81
+ * provisionSignupAccount (DB write) and signup-confirm-handler
82
+ * (SessionUser construction for JWT minting); otherwise two locations would
83
+ * independently hardcode "TenantAdmin" and a refactor could cause a role
84
+ * mismatch between the database and the session. */
87
85
  // TenantAdmin is the canonical owner role; Admin stays for handlers that still
88
86
  // gate on the legacy literal until those call sites move to access.admin.
89
87
  export const INITIAL_SIGNUP_ROLES = ["TenantAdmin", "Admin"];
90
88
  export async function provisionSignupAccount(db, options,
91
89
  // Optional, append-only — existing callers (tests, seed scripts) that
92
90
  // don't pass hooks keep today's behavior. The real signup-confirm
93
- // handler DOES pass it (#1463) so seedTenant/seedUserWithPassword/
91
+ // handler DOES pass it so seedTenant/seedUserWithPassword/
94
92
  // seedTenantMembership's postSave hooks (tier-engine's auto-default-tier,
95
93
  // app auto-default-compliance, a Welcome-notification hook, ...) fire on
96
94
  // self-signup for all three entities, same as they do on the regular
97
- // create paths (#1478 — this was only wired for tenant before).
95
+ // create paths — this was only wired for tenant before.
98
96
  hooks) {
99
97
  // Create-only guard BEFORE seedTenant: hard-abort on an already-registered
100
98
  // email, otherwise an orphaned tenant would be created and seedUser
101
99
  // (idempotent add-only) would silently return the existing userId ->
102
- // confirm mints a session for the wrong account (#365).
100
+ // confirm mints a session for the wrong account.
103
101
  // isDeleted: false — the partial bidx unique index only covers live rows,
104
102
  // so a soft-deleted row must not block re-registering its email.
105
103
  const existingUser = await fetchOne(db, userTable, { email: options.email, isDeleted: false });
@@ -126,9 +124,9 @@ hooks) {
126
124
  return { userId, tenantId: options.tenantId };
127
125
  }
128
126
  /**
129
- * Seed-Convenience für Sample-Server: Admin-User mit gehashtem
130
- * Password + N Tenants + N Memberships. Alles idempotent (Re-Run im
131
- * persistent-DB-Modus läuft durch). Liefert die userId zurück.
127
+ * Seeding convenience for sample servers: an admin user with a hashed
128
+ * password, N tenants, and N memberships. Idempotent, so rerunning it in
129
+ * persistent-DB mode succeeds. Returns the userId.
132
130
  */
133
131
  export async function seedAdmin(db, options) {
134
132
  const by = options.by ?? TestUsers.systemAdmin;
@@ -57,14 +57,14 @@ export async function deleteSignupToken(redis, args) {
57
57
  /** Burn release for failed-confirm paths (DB error etc.) so a legitimate
58
58
  * retry isn't blocked by a stale burn marker. */
59
59
  export const unburnSignupToken = store.unburn;
60
- // Cross-device try-first handover (kumiko-framework#3035 follow-up,
61
- // offlot-app#454): signup-request binds a verified tenant-handover grant to
62
- // its own signup token, in a SIBLING Redis namespace keyed the same way
63
- // (sha256(token)) so it stays byte-compatible with the token store above
64
- // without going through it — the binding has its own lifecycle (survives a
65
- // resend, is read once by signup-confirm) that doesn't fit the token↔email
66
- // pairing. Only {entityType, rowId, sourceTenantId} is ever stored — never
67
- // the grant token or the email (see shared/signup-handover.ts).
60
+ // Cross-device try-first handover:
61
+ // signup-request binds a verified tenant-handover grant to its own signup token,
62
+ // in a SIBLING Redis namespace keyed the same way (sha256(token)) so it stays
63
+ // byte-compatible with the token store above without going through it — the
64
+ // binding has its own lifecycle (survives a resend, is read once by
65
+ // signup-confirm) that doesn't fit the token↔email pairing. Only
66
+ // {entityType, rowId, sourceTenantId} is ever stored — never the grant token
67
+ // or the email (see shared/signup-handover.ts).
68
68
  const SIGNUP_HANDOVER_KEY_PREFIX = "signup:handover:";
69
69
  const signupHandoverBindingSchema = z.object({
70
70
  entityType: z.string().min(1),
@@ -1,4 +1,4 @@
1
- // /testing re-exportiert /seeding. Siehe ../tenant/testing.ts für die
2
- // Begründung — Helpers sind shared zwischen Tests und Dev-Server-
3
- // Bootstrap, /seeding ist die stabile Heimat.
1
+ // /testing re-exports /seeding. See ../tenant/testing.ts for the reason:
2
+ // Helpers are shared between tests and Dev-Server bootstrap, so /seeding is
3
+ // the stable home.
4
4
  export * from "./seeding.js";
@@ -1,8 +1,8 @@
1
1
  export type TenantSummary = {
2
2
  readonly tenantId: string;
3
3
  readonly roles: readonly string[];
4
- /** Display-Name aus /auth/tenants — fehlt nur bei App-eigenen
5
- * membership-Queries ohne tenantName-Anreicherung. */
4
+ /** Display name from /auth/tenants; absent only for app-owned membership
5
+ * queries without tenantName enrichment. */
6
6
  readonly name?: string;
7
7
  readonly key?: string;
8
8
  };