@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.387.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 (469) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/audit/screens.js +1 -1
  4. package/dist/auth-email-password/feature.js +1 -1
  5. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  6. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  7. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  8. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  9. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  10. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  11. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  12. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  13. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  14. package/dist/auth-email-password/handlers/login.write.js +1 -1
  15. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  16. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  17. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  18. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  19. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  20. package/dist/auth-email-password/index.js +5 -5
  21. package/dist/auth-email-password/lockout-store.js +1 -1
  22. package/dist/auth-email-password/seeding.d.ts +42 -45
  23. package/dist/auth-email-password/seeding.js +51 -53
  24. package/dist/auth-email-password/signup-token-store.js +8 -8
  25. package/dist/auth-email-password/testing.js +3 -3
  26. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  27. package/dist/auth-email-password/web/auth-client.js +36 -37
  28. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  29. package/dist/auth-email-password/web/auth-gate.js +15 -16
  30. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  31. package/dist/auth-email-password/web/client-plugin.js +4 -5
  32. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  33. package/dist/auth-email-password/web/constants.js +3 -3
  34. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  35. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  36. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  37. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  38. package/dist/auth-email-password/web/index.js +5 -5
  39. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  40. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  41. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  42. package/dist/auth-email-password/web/login-screen.js +2 -3
  43. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  44. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  45. package/dist/auth-email-password/web/session.d.ts +10 -9
  46. package/dist/auth-email-password/web/session.js +28 -29
  47. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  48. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  49. package/dist/auth-email-password/web/signup-screen.js +13 -13
  50. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  51. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  52. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  53. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  54. package/dist/auth-email-password/web/user-menu.js +12 -13
  55. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  56. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  57. package/dist/auth-foundation/boot-checks.js +4 -4
  58. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  59. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  60. package/dist/auth-foundation/types.js +2 -2
  61. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  62. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  63. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  64. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  65. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  66. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  67. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  68. package/dist/auth-mfa/token-secrets.js +1 -1
  69. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  70. package/dist/auth-mfa/web/client-plugin.js +1 -1
  71. package/dist/auth-mfa/web/i18n.js +3 -3
  72. package/dist/auth-mfa/web/index.js +4 -4
  73. package/dist/auth-mfa/web/mfa-client.js +17 -16
  74. package/dist/auth-mfa/web/mfa-verify-screen.js +6 -6
  75. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  76. package/dist/billing-foundation/aggregate-id.js +10 -11
  77. package/dist/billing-foundation/entities.js +27 -27
  78. package/dist/billing-foundation/events.js +18 -17
  79. package/dist/billing-foundation/feature.js +42 -43
  80. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  81. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  82. package/dist/billing-foundation/handlers/create-checkout-session.write.js +18 -17
  83. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  84. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  85. package/dist/billing-foundation/handlers/process-event.write.js +20 -20
  86. package/dist/billing-foundation/projection.d.ts +15 -11
  87. package/dist/billing-foundation/projection.js +38 -37
  88. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  89. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  90. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  91. package/dist/billing-foundation/types.d.ts +40 -41
  92. package/dist/billing-foundation/types.js +20 -20
  93. package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
  94. package/dist/cap-counter/aggregate-id.js +8 -9
  95. package/dist/cap-counter/constants.js +11 -12
  96. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  97. package/dist/cap-counter/enforce-cap.js +47 -48
  98. package/dist/cap-counter/entity.js +29 -29
  99. package/dist/cap-counter/feature.js +34 -35
  100. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  101. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  102. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  103. package/dist/cap-counter/stock-cap-guard.js +1 -1
  104. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  105. package/dist/channel-email/smtp-transport.d.ts +18 -17
  106. package/dist/channel-email/smtp-transport.js +24 -21
  107. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  108. package/dist/compliance-profiles/feature.js +4 -4
  109. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  110. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  111. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  112. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  113. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  114. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  115. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  116. package/dist/compliance-profiles/seeding.js +14 -15
  117. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  118. package/dist/compliance-profiles-ops/index.js +2 -2
  119. package/dist/config/handlers/readiness.query.d.ts +4 -4
  120. package/dist/config/handlers/readiness.query.js +1 -1
  121. package/dist/config/handlers/reencrypt.job.js +4 -5
  122. package/dist/config/handlers/set.write.js +4 -4
  123. package/dist/config/resolver.js +4 -4
  124. package/dist/config/table.js +10 -10
  125. package/dist/config/write-helpers.js +1 -1
  126. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  127. package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
  128. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  129. package/dist/custom-fields/aggregate-id.js +16 -17
  130. package/dist/custom-fields/entity.js +49 -47
  131. package/dist/custom-fields/events.js +7 -8
  132. package/dist/custom-fields/feature.d.ts +14 -14
  133. package/dist/custom-fields/feature.js +53 -54
  134. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  135. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  136. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  137. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  138. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  139. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  140. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  141. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  142. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  143. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  144. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  145. package/dist/custom-fields/lib/field-access.js +2 -2
  146. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  147. package/dist/custom-fields/lib/quota.js +1 -1
  148. package/dist/custom-fields/lib/value-schema.js +10 -12
  149. package/dist/custom-fields/run-retention.js +3 -3
  150. package/dist/custom-fields/schemas.js +14 -14
  151. package/dist/custom-fields/web/client-plugin.js +2 -5
  152. package/dist/custom-fields/web/constants.js +2 -2
  153. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  154. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  155. package/dist/custom-fields/wire-for-entity.js +65 -67
  156. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  157. package/dist/data-retention/_internal/parse-override.js +2 -3
  158. package/dist/data-retention/feature.js +11 -18
  159. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  160. package/dist/data-retention/keep-for.d.ts +7 -7
  161. package/dist/data-retention/keep-for.js +15 -15
  162. package/dist/data-retention/override-schema.d.ts +3 -4
  163. package/dist/data-retention/override-schema.js +13 -15
  164. package/dist/data-retention/presets.d.ts +4 -5
  165. package/dist/data-retention/presets.js +18 -23
  166. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  167. package/dist/data-retention/resolver.d.ts +12 -12
  168. package/dist/data-retention/resolver.js +24 -23
  169. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  170. package/dist/data-retention/run-retention-cleanup.js +61 -51
  171. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  172. package/dist/delivery/feature.js +2 -2
  173. package/dist/delivery/handlers/log.query.js +1 -1
  174. package/dist/delivery/tables.js +9 -8
  175. package/dist/delivery/unsubscribe.js +4 -4
  176. package/dist/document-ingest-foundation/entity.js +4 -4
  177. package/dist/document-ingest-foundation/events.js +2 -2
  178. package/dist/document-ingest-foundation/feature.js +2 -2
  179. package/dist/document-ingest-foundation/pages.js +1 -1
  180. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  181. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  182. package/dist/feature-toggles/feature.js +1 -1
  183. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  184. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  185. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  186. package/dist/feature-toggles/web/constants.js +1 -1
  187. package/dist/file-derivatives/feature.d.ts +1 -1
  188. package/dist/file-derivatives/feature.js +1 -1
  189. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  190. package/dist/file-derivatives/presets.js +1 -1
  191. package/dist/file-foundation/feature.js +6 -6
  192. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  193. package/dist/file-provider-inmemory/feature.js +16 -16
  194. package/dist/file-provider-s3/feature.js +16 -16
  195. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  196. package/dist/files/feature.js +6 -6
  197. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  198. package/dist/files-tenant-data/hooks.js +24 -26
  199. package/dist/files-tenant-data/index.js +1 -1
  200. package/dist/folders/feature.d.ts +1 -1
  201. package/dist/folders/web/folder-manager.js +2 -2
  202. package/dist/folders/web/tree.js +5 -5
  203. package/dist/form-draft/db/queries/cleanup.js +1 -1
  204. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  205. package/dist/form-draft/entity.js +3 -3
  206. package/dist/form-draft/feature.js +4 -5
  207. package/dist/form-draft/handlers/discard.write.js +1 -1
  208. package/dist/form-draft/release-file-refs.js +6 -6
  209. package/dist/form-draft/schemas.js +3 -3
  210. package/dist/form-draft/web/constants.js +0 -2
  211. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  212. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  213. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  214. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  215. package/dist/inbound-mail-foundation/constants.js +30 -33
  216. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  217. package/dist/inbound-mail-foundation/entities.js +47 -48
  218. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  219. package/dist/inbound-mail-foundation/events.js +50 -47
  220. package/dist/inbound-mail-foundation/feature.js +39 -39
  221. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  222. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  223. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  224. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  225. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  226. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  227. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  228. package/dist/inbound-mail-foundation/handlers/update-account.write.js +11 -11
  229. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  230. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  231. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  232. package/dist/inbound-mail-foundation/projection.js +31 -29
  233. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  234. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  235. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  236. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  237. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  238. package/dist/inbound-mail-foundation/types.d.ts +45 -46
  239. package/dist/inbound-mail-foundation/types.js +21 -21
  240. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  241. package/dist/inbound-mail-foundation/watch-supervisor.js +57 -56
  242. package/dist/inbound-provider-imap/credential-document.js +13 -13
  243. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  244. package/dist/inbound-provider-imap/feature.js +42 -40
  245. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  246. package/dist/inbound-provider-imap/imap-client.js +20 -19
  247. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  248. package/dist/inbound-provider-inmemory/feature.js +19 -19
  249. package/dist/jobs/db/queries/retention.js +2 -2
  250. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  251. package/dist/jobs/events.js +1 -1
  252. package/dist/jobs/feature.js +5 -6
  253. package/dist/jobs/handlers/detail.query.js +4 -4
  254. package/dist/jobs/handlers/list.query.js +1 -1
  255. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  256. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  257. package/dist/jobs/handlers/retry.write.js +1 -1
  258. package/dist/jobs/job-instant.js +1 -1
  259. package/dist/jobs/job-run-logger.js +10 -11
  260. package/dist/jobs/job-run-table.js +3 -3
  261. package/dist/jobs/screens.js +1 -1
  262. package/dist/jobs/tenant-job-failure-table.js +1 -1
  263. package/dist/jobs/tenant-job-run-table.js +1 -1
  264. package/dist/ledger/entity.js +5 -5
  265. package/dist/ledger/feature.js +3 -3
  266. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  267. package/dist/ledger/recurring.js +12 -12
  268. package/dist/ledger/schemas.js +1 -1
  269. package/dist/ledger/web/constants.js +2 -2
  270. package/dist/ledger/web/index.js +7 -7
  271. package/dist/legal-pages/feature.d.ts +4 -4
  272. package/dist/legal-pages/feature.js +25 -26
  273. package/dist/legal-pages/markdown.js +3 -3
  274. package/dist/legal-pages/web/client-plugin.js +23 -24
  275. package/dist/legal-pages/web/index.js +0 -1
  276. package/dist/mail-foundation/feature.d.ts +2 -2
  277. package/dist/mail-foundation/feature.js +24 -25
  278. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  279. package/dist/mail-transport-inmemory/feature.js +27 -28
  280. package/dist/mail-transport-smtp/feature.js +20 -20
  281. package/dist/managed-pages/branding.js +6 -6
  282. package/dist/managed-pages/feature.d.ts +26 -26
  283. package/dist/managed-pages/feature.js +34 -34
  284. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  285. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  286. package/dist/managed-pages/handlers/set.write.js +5 -7
  287. package/dist/managed-pages/screens/page-screens.js +11 -11
  288. package/dist/managed-pages/seeding.js +8 -8
  289. package/dist/managed-pages/table.js +13 -12
  290. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  291. package/dist/managed-pages/web/client-plugin.js +5 -5
  292. package/dist/managed-pages/web/i18n.js +1 -1
  293. package/dist/notes-history/entity.js +4 -4
  294. package/dist/notes-history/feature.d.ts +2 -2
  295. package/dist/notes-history-user-data/hooks.js +1 -1
  296. package/dist/page-render/layout.js +9 -9
  297. package/dist/page-render/markdown.js +11 -11
  298. package/dist/page-render/security-headers.js +7 -6
  299. package/dist/personal-access-tokens/feature.js +5 -5
  300. package/dist/personal-access-tokens/roles.js +2 -2
  301. package/dist/readiness/handlers/status.query.js +3 -3
  302. package/dist/renderer-foundation/api.js +12 -13
  303. package/dist/renderer-foundation/constants.js +2 -2
  304. package/dist/renderer-foundation/feature.js +7 -7
  305. package/dist/secrets/feature.js +9 -9
  306. package/dist/secrets/web/constants.js +2 -2
  307. package/dist/seo/feature.js +3 -3
  308. package/dist/sessions/constants.d.ts +1 -1
  309. package/dist/sessions/constants.js +1 -1
  310. package/dist/sessions/feature.js +8 -8
  311. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  312. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  313. package/dist/sessions/handlers/revoke.write.js +1 -1
  314. package/dist/sessions/schema/user-session.js +4 -4
  315. package/dist/sessions/screens.js +2 -2
  316. package/dist/sessions/session-callbacks.js +2 -2
  317. package/dist/sessions/session-revoked-event.js +2 -2
  318. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  319. package/dist/shared/decrypt-stored-pii.js +1 -1
  320. package/dist/shared/encrypt-for-direct-write.js +1 -1
  321. package/dist/shared/map-with-concurrency.js +5 -4
  322. package/dist/shared/parent-visibility.js +2 -2
  323. package/dist/shared/password-hashing.js +1 -1
  324. package/dist/shared/signup-handover.js +1 -2
  325. package/dist/shared/single-use-token-store.js +1 -1
  326. package/dist/subscription-mollie/constants.js +15 -17
  327. package/dist/subscription-mollie/feature.d.ts +17 -18
  328. package/dist/subscription-mollie/feature.js +24 -24
  329. package/dist/subscription-mollie/index.js +3 -3
  330. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  331. package/dist/subscription-mollie/plugin-methods.js +15 -14
  332. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  333. package/dist/subscription-mollie/verify-webhook.js +27 -27
  334. package/dist/subscription-stripe/constants.js +4 -6
  335. package/dist/subscription-stripe/feature.d.ts +14 -14
  336. package/dist/subscription-stripe/feature.js +35 -34
  337. package/dist/subscription-stripe/index.js +6 -6
  338. package/dist/subscription-stripe/plugin-methods.js +18 -18
  339. package/dist/subscription-stripe/runtime.d.ts +1 -1
  340. package/dist/subscription-stripe/runtime.js +1 -1
  341. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  342. package/dist/subscription-stripe/verify-webhook.js +59 -61
  343. package/dist/tags/feature.d.ts +3 -3
  344. package/dist/tags/screens.js +1 -1
  345. package/dist/template-resolver/api.js +10 -10
  346. package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
  347. package/dist/template-resolver/handlers/list.query.js +1 -1
  348. package/dist/template-resolver/handlers/shared.js +2 -2
  349. package/dist/template-resolver/handlers/template-write.js +3 -3
  350. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  351. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  352. package/dist/template-resolver/seeding.js +4 -4
  353. package/dist/template-resolver/table.js +10 -11
  354. package/dist/template-resolver/web/client-plugin.js +2 -2
  355. package/dist/tenant/feature.js +7 -7
  356. package/dist/tenant/handlers/member-directory.query.js +1 -1
  357. package/dist/tenant/handlers/members.query.js +1 -1
  358. package/dist/tenant/handlers/team-list.query.js +1 -1
  359. package/dist/tenant/handlers/tenant-directory.query.js +1 -1
  360. package/dist/tenant/invitation-table.js +37 -40
  361. package/dist/tenant/membership-table.js +3 -3
  362. package/dist/tenant/schema/tenant.js +7 -9
  363. package/dist/tenant/screens.js +1 -1
  364. package/dist/tenant/seeding.d.ts +6 -5
  365. package/dist/tenant/seeding.js +12 -12
  366. package/dist/tenant/testing.js +5 -6
  367. package/dist/tenant/web/constants.js +2 -2
  368. package/dist/tenant-handover/events.js +5 -7
  369. package/dist/tenant-handover/feature.js +1 -1
  370. package/dist/tenant-handover/grant.js +1 -1
  371. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  372. package/dist/tenant-handover/move-entity-graph.js +8 -9
  373. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  374. package/dist/tenant-handover/transfer-graph.js +4 -5
  375. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  376. package/dist/tenant-lifecycle/feature.js +1 -1
  377. package/dist/tenant-settings/constants.js +1 -1
  378. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  379. package/dist/tenant-settings/tenant-defaults.js +9 -2
  380. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  381. package/dist/tier-engine/aggregate-id.js +15 -16
  382. package/dist/tier-engine/compose-app.d.ts +14 -14
  383. package/dist/tier-engine/compose-app.js +1 -1
  384. package/dist/tier-engine/entity.js +18 -19
  385. package/dist/tier-engine/feature.d.ts +19 -17
  386. package/dist/tier-engine/feature.js +68 -69
  387. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  388. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  389. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +5 -5
  390. package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
  391. package/dist/tier-engine/tier-resolver.js +2 -2
  392. package/dist/tier-engine/trial.js +8 -8
  393. package/dist/tier-engine/web/index.js +4 -4
  394. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  395. package/dist/user/handlers/create.write.js +4 -4
  396. package/dist/user/schema/user.d.ts +11 -11
  397. package/dist/user/schema/user.js +45 -44
  398. package/dist/user/seeding.d.ts +15 -15
  399. package/dist/user/seeding.js +28 -28
  400. package/dist/user/testing.js +3 -3
  401. package/dist/user-data-rights/audit-download.d.ts +8 -8
  402. package/dist/user-data-rights/audit-download.js +19 -20
  403. package/dist/user-data-rights/boot-checks.js +1 -1
  404. package/dist/user-data-rights/deletion-token.js +1 -1
  405. package/dist/user-data-rights/feature.d.ts +49 -50
  406. package/dist/user-data-rights/feature.js +54 -53
  407. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  408. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  409. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  410. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  411. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  412. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  413. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  414. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  415. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  416. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  417. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  418. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  419. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  420. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  421. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  422. package/dist/user-data-rights/index.js +8 -10
  423. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  424. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  425. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  426. package/dist/user-data-rights/run-export-jobs.js +127 -233
  427. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  428. package/dist/user-data-rights/run-forget-cleanup.js +63 -82
  429. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  430. package/dist/user-data-rights/run-user-export.js +55 -57
  431. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  432. package/dist/user-data-rights/schema/download-token.js +37 -41
  433. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  434. package/dist/user-data-rights/schema/export-job.js +65 -67
  435. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  436. package/dist/user-data-rights/token-helpers.js +21 -25
  437. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  438. package/dist/user-data-rights/web/client-plugin.js +1 -1
  439. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  440. package/dist/user-data-rights/web/constants.js +1 -1
  441. package/dist/user-data-rights/web/index.js +5 -5
  442. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  443. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  444. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  445. package/dist/user-data-rights/zip-path.d.ts +15 -15
  446. package/dist/user-data-rights/zip-path.js +41 -40
  447. package/dist/user-data-rights-defaults/feature.js +15 -15
  448. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  449. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  450. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  451. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  452. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  453. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  454. package/dist/user-profile/handlers/change-email.write.js +13 -13
  455. package/dist/user-profile/index.js +3 -3
  456. package/dist/user-profile/web/client-plugin.js +1 -1
  457. package/dist/user-profile/web/constants.js +1 -1
  458. package/dist/user-profile/web/profile-screen.js +1 -1
  459. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  460. package/dist/workflow-runner/aggregate-id.js +1 -1
  461. package/dist/workflow-runner/event-subscriber.js +4 -5
  462. package/dist/workflow-runner/event-trigger.js +4 -17
  463. package/dist/workflow-runner/feature.js +2 -2
  464. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  465. package/dist/workflow-runner/pending-projection.js +6 -7
  466. package/dist/workflow-runner/runner.js +6 -6
  467. package/dist/workflow-runner/tables.js +6 -6
  468. package/dist/workflow-runner/workflow-registry.js +1 -1
  469. package/package.json +10 -10
@@ -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
  };
@@ -1,12 +1,11 @@
1
- // Browser-Seite der Auth-Routes. Dünne fetch-Wrapper um /api/auth/*
2
- // mit Cookie-Transport: JWT lebt im HttpOnly kumiko_auth-Cookie,
3
- // Double-Submit-CSRF-Token im JS-lesbaren kumiko_csrf-Cookie. Alle
4
- // state-changing Requests echo'n den CSRF-Token via X-CSRF-Token —
5
- // der Server rejected sonst mit csrf_token_missing.
1
+ // Browser-side wrappers around /api/auth/* using cookie transport: the JWT
2
+ // lives in the HttpOnly kumiko_auth cookie, while the Double-Submit CSRF
3
+ // token lives in the JS-readable kumiko_csrf cookie. Every state-changing
4
+ // request echoes the CSRF token via X-CSRF-Token; otherwise the server
5
+ // rejects it with csrf_token_missing.
6
6
  //
7
- // Die dispatcher-live nutzt denselben readCsrfToken-Helper; wir
8
- // reuse'n ihn hier, damit die Konstanten (Cookie-Name, Header-Name)
9
- // nicht divergieren.
7
+ // dispatcher-live uses the same readCsrfToken helper; reusing it here keeps
8
+ // the cookie and header constants from diverging.
10
9
  import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
11
10
  import { CSRF_HEADER_NAME, readCsrfToken } from "@cosmicdrift/kumiko-renderer/live";
12
11
  export function csrfHeader() {
@@ -70,8 +69,8 @@ export async function login(req) {
70
69
  return { kind: "success", data: toLoginResponse(body.token, body.user, body.landingPath) };
71
70
  }
72
71
  }
73
- // Der Server schickt error entweder als string ("invalid_body") oder als
74
- // strukturiertes Objekt. Wir ziehen uns den sprechendsten Reason raus.
72
+ // The server sends error either as a string ("invalid_body") or as a
73
+ // structured object. Extract the most descriptive reason.
75
74
  const err = body.error;
76
75
  if (typeof err === "string") {
77
76
  return { kind: "failure", error: { reason: err } };
@@ -87,10 +86,10 @@ export async function login(req) {
87
86
  },
88
87
  };
89
88
  }
90
- // POST /api/auth/logout. Server revoked die Session (wenn sessionRevoker
91
- // gewired ist) und clear't die Cookies. Wir triggern hinterher einen
92
- // Navigation-Refresh, damit alle caches (React-State, query-cache) auf
93
- // Null gehen — billigster Weg zu sauberer Ausgangslage.
89
+ // POST /api/auth/logout. The server revokes the session when
90
+ // sessionRevoker is wired and clears the cookies. A navigation refresh
91
+ // afterward ensures that all caches (React state, query cache) return to
92
+ // an unauthenticated state—the simplest way to restore a clean baseline.
94
93
  export async function logout() {
95
94
  await fetch("/api/auth/logout", {
96
95
  method: "POST",
@@ -98,11 +97,11 @@ export async function logout() {
98
97
  headers: { "Content-Type": "application/json", ...csrfHeader() },
99
98
  });
100
99
  }
101
- // 4xx/5xx → typed AuthTokenFailure parsen. 429 (Rate-Limit) hat einen
102
- // dedizierten reason damit das UI einen Retry-Hinweis zeigen kann.
100
+ // Parse 4xx/5xx responses into AuthTokenFailure. 429 uses a dedicated
101
+ // reason so the UI can display a retry hint.
103
102
  async function parseTokenFailure(res) {
104
103
  if (res.status === 429) {
105
- // @cast-boundary engine-payload — server schickt details.retryAfterSeconds bei 429
104
+ // @cast-boundary engine-payload — the server sends details.retryAfterSeconds for 429
106
105
  const body = (await res.json().catch(() => ({})));
107
106
  const retry = body.error?.details?.retryAfterSeconds;
108
107
  return { reason: "rate_limited", ...(retry !== undefined && { retryAfterSeconds: retry }) };
@@ -127,11 +126,12 @@ export async function requestPasswordReset(email) {
127
126
  return { ok: true };
128
127
  return { ok: false, error: await parseTokenFailure(res) };
129
128
  }
130
- // POST /api/auth/reset-password. Token aus URL + neues Passwort. Auf
131
- // 422 collapses der Server alle Token-Verify-Fehler (malformed / bad-
132
- // signature / expired) auf den einzigen Code `invalid_reset_token` —
133
- // anti-enumeration. Plus zod-validation-failures (newPassword < 8) als
134
- // eigene 4xx mit code "validation_failed". UI mappt reason → i18n-Key.
129
+ // POST /api/auth/reset-password. The token comes from the URL and the
130
+ // request includes the new password. On 422, the server collapses all
131
+ // token-verification errors (malformed, bad signature, expired) into the
132
+ // single code `invalid_reset_token` to prevent enumeration. Zod validation
133
+ // failures (newPassword < 8) use a separate 4xx code, "validation_failed".
134
+ // The UI maps reason to an i18n key.
135
135
  export async function resetPassword(token, newPassword) {
136
136
  const res = await fetch("/api/auth/reset-password", {
137
137
  method: "POST",
@@ -156,9 +156,9 @@ export async function requestEmailVerification(email) {
156
156
  return { ok: true };
157
157
  return { ok: false, error: await parseTokenFailure(res) };
158
158
  }
159
- // POST /api/auth/verify-email. Auto-submitted vom VerifyEmailScreen
160
- // nach `?token=...`-parse. Server collapses alle Verify-Failures auf
161
- // `invalid_verification_token` (anti-enumeration, parallel zu reset).
159
+ // POST /api/auth/verify-email. VerifyEmailScreen submits this automatically
160
+ // after parsing `?token=...`. The server collapses all verification failures
161
+ // into `invalid_verification_token` to prevent enumeration, as with reset.
162
162
  export async function verifyEmail(token) {
163
163
  const res = await fetch("/api/auth/verify-email", {
164
164
  method: "POST",
@@ -199,14 +199,13 @@ export async function confirmAccountUnlock(token) {
199
199
  return { ok: true };
200
200
  return { ok: false, error: await parseTokenFailure(res) };
201
201
  }
202
- // POST /api/auth/signup-request. Always-200 (anti-enumeration; wir
203
- // sagen nicht ob die Email schon registriert ist). Server schickt
204
- // Activation-Mail an die Adresse — beim Klick auf den Link landet der
205
- // User auf /signup/complete?token=… wo er sein Password setzt.
202
+ // POST /api/auth/signup-request. Always returns 200 to prevent enumeration;
203
+ // the response does not reveal whether the email is already registered. The
204
+ // server sends an activation email to the address; following its link takes
205
+ // the user to /signup/complete?token=… to set a password.
206
206
  export async function requestSignup(email,
207
- // Cross-device try-first handover (kumiko-framework#3035 follow-up,
208
- // offlot-app#454): forwards a row-bound tenant-handover grant so the
209
- // server can verify + rebind it to the signup token. The grant never
207
+ // Cross-device try-first handover: forwards a row-bound tenant-handover
208
+ // grant so the server can verify + rebind it to the signup token. The grant never
210
209
  // travels any further than this request — never in the URL, the mail,
211
210
  // or the confirm response.
212
211
  handover) {
@@ -243,8 +242,8 @@ export async function confirmSignup(token, password) {
243
242
  }
244
243
  return { ok: false, error: await parseTokenFailure(res) };
245
244
  }
246
- // GET /api/auth/tenants. Liefert die Memberships des aktuellen Users;
247
- // der Server liefert 401 wenn das Cookie fehlt oder abgelaufen ist.
245
+ // GET /api/auth/tenants. Returns the current user's memberships; the server
246
+ // returns 401 when the cookie is missing or expired.
248
247
  export async function fetchTenants() {
249
248
  const res = await fetch("/api/auth/tenants", {
250
249
  method: "GET",
@@ -258,9 +257,9 @@ export async function fetchTenants() {
258
257
  // @cast-boundary engine-payload — HTTP-API contract, server-side schema-validated
259
258
  return (await res.json());
260
259
  }
261
- // POST /api/auth/switch-tenant. Mintet ein neues JWT für den Ziel-Tenant
262
- // und rotated beide Cookies. 400 wenn already_in_tenant oder tenant_
263
- // switch_not_available, 403 wenn not_a_member.
260
+ // POST /api/auth/switch-tenant. Mints a new JWT for the target tenant and
261
+ // rotates both cookies. Returns 400 for already_in_tenant or
262
+ // tenant_switch_not_available, and 403 for not_a_member.
264
263
  export async function switchTenant(tenantId) {
265
264
  const res = await fetch("/api/auth/switch-tenant", {
266
265
  method: "POST",
@@ -25,21 +25,21 @@ export function useAuthShell() {
25
25
  export function AuthCard({ title, subtitle, className, headerClassName, titleClassName, bodyClassName, children, }) {
26
26
  const { Card } = usePrimitives();
27
27
  const shell = useAuthShell() ?? defaultAuthShell;
28
- // h1 (Seiten-Hauptüberschrift) via Header-Slot erhalten — die Card-Default-
29
- // Header wäre h3. padded:false = Form sitzt randlos wie bisher (bare form).
28
+ // Keep an h1 (page heading) through the header slot; the Card's default
29
+ // header would be h3. padded:false keeps the form edge-to-edge as before
30
+ // (bare form).
30
31
  const card = (_jsx(Card, { className: cn("w-full max-w-sm", className), options: { padded: false }, slots: {
31
32
  header: title !== undefined || subtitle !== undefined ? (_jsxs("div", { className: cn("flex flex-col space-y-1.5 p-6 pb-4", headerClassName), children: [title !== undefined && (_jsx("h1", { className: cn("text-xl font-semibold tracking-tight", titleClassName), children: title })), subtitle !== undefined && (_jsx("p", { className: "text-sm text-muted-foreground", children: subtitle }))] })) : undefined,
32
33
  }, children: _jsx(BareFormProvider, { children: _jsx("div", { className: cn("p-6 pt-0 flex flex-col gap-4", bodyClassName), children: children }) }) }));
33
34
  return shell(card);
34
35
  }
35
- // Liest `?<paramName>=<value>` aus der aktuellen URL — typisches
36
- // Pattern für Token-bearing Pages (reset, verify). Returnt "" wenn der
37
- // Browser nicht da ist (SSR-safety) oder der Parameter fehlt.
36
+ // Reads `?<paramName>=<value>` from the current URL, as used by token-bearing
37
+ // pages (reset, verify). Returns "" during SSR or when the parameter is absent.
38
38
  //
39
- // Nicht über useState/useEffect - das wäre ein read-once-on-mount
40
- // pattern aber URL-changes sind hier irrelevant (Token-Pages re-loaden
41
- // für neue Tokens). Caller setzt useState(() => parseUrlToken(...)) wenn
42
- // gewünscht.
39
+ // This is intentionally not read through useState/useEffect: that would be a
40
+ // read-once-on-mount pattern, while URL changes are irrelevant here because
41
+ // token pages reload for new tokens. Callers can use
42
+ // useState(() => parseUrlToken(...)) when needed.
43
43
  export function parseUrlToken(paramName = "token") {
44
44
  if (typeof window === "undefined")
45
45
  return "";
@@ -47,7 +47,7 @@ export function parseUrlToken(paramName = "token") {
47
47
  }
48
48
  // Reads the magic-link token from `?<paramName>=` once on mount, then strips
49
49
  // that param from the URL via history.replaceState so the single-use token
50
- // doesn't linger in browser history / Referer (#774). An explicit `override`
50
+ // doesn't linger in browser history / Referer. An explicit `override`
51
51
  // (server-injected token) short-circuits both the URL read and the scrub.
52
52
  export function useUrlToken(override, paramName = "token") {
53
53
  const [token] = useState(() => override ?? parseUrlToken(paramName));