@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
@@ -1,9 +1,9 @@
1
1
  import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { createEntity, createTextField, createTimestampField, } from "@cosmicdrift/kumiko-framework/engine";
3
- // Audit-Trail invalid Download-Attempts (S2.U7).
4
- // Schreibt eine Row pro 4xx im download-by-{token,job}-Pfad. DPO erkennt
5
- // damit Brute-Force / Anomalien (gleiche IP, viele invalid-Versuche).
6
- // Success-Downloads landen in download-token.lastUsedAt — nicht hier.
3
+ // Audit trail for rejected download attempts.
4
+ // Writes one row per 4xx response on the download-by-{token,job} path, allowing the DPO
5
+ // to detect brute-force probing and anomalies such as many invalid attempts from one IP.
6
+ // Successful downloads are recorded in download-token.lastUsedAt instead.
7
7
  export const downloadAttemptEntity = createEntity({
8
8
  table: "read_download_attempts",
9
9
  idType: "uuid",
@@ -23,11 +23,11 @@ export const downloadAttemptEntity = createEntity({
23
23
  personal: false,
24
24
  reason: "technical_reference",
25
25
  }),
26
- // Token-Hash (token-Pfad) oder NULL (job-Pfad / unbekannter Token).
26
+ // Token hash for the token path, or NULL for the job path or an unknown token.
27
27
  tokenHash: createTextField({ maxLength: 64, personal: false, reason: "technical_reference" }),
28
- // Job-ID wenn der attempt einen kannte. NULL bei unbekanntem Token.
28
+ // Job ID when the attempt identified one; NULL for an unknown token.
29
29
  jobId: createTextField({ personal: false, reason: "technical_reference" }),
30
- // User-ID wenn auth-Pfad (job). NULL bei anonymous (token-Pfad).
30
+ // User ID for the authenticated job path; NULL for anonymous token-path requests.
31
31
  attemptedByUserId: createTextField({ personal: false, reason: "pseudonymous_fk" }),
32
32
  // The anonymous token path has no owner, so those rows fall back to the tenant key;
33
33
  // find "exact" on ip because list-download-attempts filters by IP.
@@ -43,10 +43,10 @@ export const downloadAttemptEntity = createEntity({
43
43
  }),
44
44
  attemptedAt: createTimestampField({ required: true }),
45
45
  },
46
- // 90d hardDelete: unbounded growth = disk-bomb genau gegen das System
47
- // das den Brute-Force erkennen soll. Brute-Force-Patterns sind kurzfristig
48
- // (Stunden bis Tage) — 90d Window deckt forensik-Reviews + DPO-quartal-
49
- // Audits. Tenant kann via override verlängern (HR-Compliance).
46
+ // 90d hardDelete: unbounded growth would create a disk bomb targeting the system
47
+ // that detects brute-force activity. Brute-force patterns are short-lived (hours to days),
48
+ // while a 90d window covers forensic reviews and quarterly DPO audits.
49
+ // The tenant can extend retention through an override for HR compliance.
50
50
  retention: { keepFor: "90d", strategy: "hardDelete", reference: "attemptedAt" },
51
51
  });
52
52
  export const downloadAttemptsTable = buildEntityTable("downloadAttempt", downloadAttemptEntity);
@@ -1,40 +1,39 @@
1
1
  import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { createBigIntField, createEntity, createTextField, createTimestampField, } from "@cosmicdrift/kumiko-framework/engine";
3
- // Export-Download-Token (S2.U3 Atom 4a).
3
+ // Export-Download-Token.
4
4
  //
5
- // Sicherheits-Token fuer den Download-Endpoint (Atom 4b). Pattern:
6
- // 1. Worker generiert plain-Token (32 byte random base64url) +
7
- // Hash (SHA256 hex) beim Flip auf done.
8
- // 2. crud.create(downloadTokenEntity, ...) emittiert
9
- // `exportDownloadToken.created`-Event in den event-store. DB-Row
10
- // wird via Projection synchron geschrieben (Marten-Pattern, NICHT
11
- // direct-INSERT). Memory `feedback_event_store_tenant_consistency`.
12
- // 3. Plain bleibt im Worker-Memory + wird via RunExportJobsResult an
13
- // Atom 5 (Notification) weitergegeben. NIEMALS plain in DB.
14
- // 4. Atom 4b's Download-Endpoint: hashed incoming-Token + sucht den
15
- // Hash-Eintrag. Konstanter-Zeit-Vergleich gegen timing-attacks.
5
+ // Security token for the download endpoint. Pattern:
6
+ // 1. Worker generates a plain token (32 random bytes, base64url) +
7
+ // hash (SHA256 hex) when flipping to done.
8
+ // 2. crud.create(downloadTokenEntity, ...) emits
9
+ // `exportDownloadToken.created`-Event in the event store. The DB row
10
+ // is written synchronously via the projection (Marten pattern, NOT
11
+ // direct INSERT).
12
+ // 3. Plain token remains in worker memory + is passed via
13
+ // RunExportJobsResult to the notification flow. NEVER plain in DB.
14
+ // 4. The download endpoint hashes the incoming token + looks up the
15
+ // hash entry. Constant-time comparison against timing attacks.
16
16
  //
17
- // **Multi-use within TTL** (Plan-Decision 4a): Token wird beim Download
18
- // nicht "consumed". Mehrfach-Download bis expiresAt erlaubt — UX bei
19
- // Connection-Abbrueche, kein Re-Export-Zwang. Pattern matched Google-
20
- // Takeout (7d) + Facebook-Data-Download (4d).
17
+ // **Multi-use within TTL**: Token is not "consumed" on download.
18
+ // Multiple downloads until expiresAt are allowed — better UX for connection
19
+ // interruptions, no forced re-export. Pattern matches Google Takeout (7d)
20
+ // + Facebook Data Download (4d).
21
21
  //
22
- // **TTL = job.expiresAt** (denormalized, gleicher Wert wie Job-Row).
23
- // Storage-Cleanup-Pass nullt downloadStorageKey nach
24
- // expiresAt + exportStorageCleanupGraceHours. Token-Row bleibt liegen
25
- // (Audit-Trail) — Atom 4b's Download-Endpoint check't job.downloadStorageKey
26
- // != null vor Streaming + returns 410 Gone wenn Storage cleared.
22
+ // **TTL = job.expiresAt** (denormalized, same value as the job row).
23
+ // Storage cleanup nulls downloadStorageKey after
24
+ // expiresAt + exportStorageCleanupGraceHours. The token row remains
25
+ // (audit trail) — the download endpoint checks job.downloadStorageKey
26
+ // != null before streaming + returns 410 Gone when storage is cleared.
27
27
  //
28
- // **idType: "uuid"** matched ExportJob — Token-IDs reisen ueber
29
- // Process-Grenzen (audit-events fuer DPO, ggf. Re-Issue-Pfade).
28
+ // **idType: "uuid"** matches ExportJob — token IDs cross process
29
+ // boundaries (audit events for the DPO, possible re-issue paths).
30
30
  export const exportDownloadTokenEntity = createEntity({
31
31
  table: "read_export_download_tokens",
32
32
  idType: "uuid",
33
33
  fields: {
34
- // FK auf export-jobs. UNIQUE (siehe indexes) — 1 Token pro Job.
35
- // Audit-Trail-Argument: separate Token-Row statt Job-Spalten weil
36
- // Audit-Felder (lastUsedAt/IP/UA) semantisch zum Token, nicht zum
37
- // Job gehoeren.
34
+ // Foreign key to export jobs. UNIQUE (see indexes) enforces one token per
35
+ // job. A separate token row keeps token-specific audit fields
36
+ // (`lastUsedAt`/IP/UA) separate from the job.
38
37
  jobId: createTextField({
39
38
  required: true,
40
39
  personal: false,
@@ -48,22 +47,21 @@ export const exportDownloadTokenEntity = createEntity({
48
47
  personal: false,
49
48
  reason: "technical_reference",
50
49
  }),
51
- // Wann wurde das Token ausgegeben (= Job-Done-Flip-Zeit).
50
+ // The time the token was issued, when the job was marked done.
52
51
  issuedAt: createTimestampField({
53
52
  required: true,
54
53
  }),
55
- // Wann laeuft das Token ab. Identisch zu job.expiresAt
56
- // (denormalized — Worker setzt beide gleich beim Done-Flip).
54
+ // The token expires at the same time as `job.expiresAt`; the worker sets both
55
+ // values when marking the job done.
57
56
  expiresAt: createTimestampField({
58
57
  required: true,
59
58
  }),
60
- // Audit: wann wurde das Token zuletzt fuer einen Download genutzt.
61
- // NULL solange noch nie heruntergeladen. Atom 4b's Download-Endpoint
62
- // setzt es bei jedem successful Stream.
59
+ // Audit timestamp for the most recent download. NULL means the token has
60
+ // never been downloaded; the endpoint updates it after each successful
61
+ // stream.
63
62
  lastUsedAt: createTimestampField({}),
64
- // Audit: Anzahl der Downloads. Atom 4b incrementiert bei jedem
65
- // Stream. bigInt fuer fall einer pathologischer Re-Download-Schleife
66
- // (z.B. broken Sync-Tool).
63
+ // Audit count of downloads. `bigInt` accommodates pathological re-download
64
+ // loops, such as those caused by a broken sync tool.
67
65
  useCount: createBigIntField({}),
68
66
  // Audit: source IP of the last download. Helps the DPO investigate
69
67
  // unusual activity ("token was used from 5 different IPs"). Plain
@@ -83,11 +81,9 @@ export const exportDownloadTokenEntity = createEntity({
83
81
  reason: "is_business_data",
84
82
  }),
85
83
  },
86
- // 1 Token pro Job. UNIQUE auf jobId — Backstop fuer Worker-Idempotency
87
- // (Atom 3b's "2× run done-Job → no-op"). Der Worker created NIE ein
88
- // zweites Aggregat fuers gleiche jobId: Re-Runs rotieren das Token
89
- // in place via update (fw#832) — sonst kollidiert der Projection-
90
- // Rebuild an genau diesem Index.
84
+ // UNIQUE on `jobId` provides an idempotency backstop: rerunning a completed
85
+ // job must not create a second token aggregate. Re-runs update the existing
86
+ // token in place; otherwise projection rebuilds would collide on this index.
91
87
  indexes: [
92
88
  {
93
89
  unique: true,
@@ -6,10 +6,10 @@ export declare const EXPORT_JOB_STATUS: {
6
6
  };
7
7
  export type ExportJobStatus = (typeof EXPORT_JOB_STATUS)[keyof typeof EXPORT_JOB_STATUS];
8
8
  /**
9
- * DB-Constraint-Name fuer den Partial-UNIQUE-Index (1 aktiver Job pro
10
- * User). Single source of truth — request-export.write catched 23505
11
- * mit diesem Namen als Race-Schutz, Tests pinnen ihn als
12
- * `expectUniqueViolation`-Argument. Rename hier propagiert automatisch.
9
+ * Database constraint name for the partial UNIQUE index (one active job per
10
+ * user). This is the single source of truth: request-export.write catches
11
+ * 23505 with this name as race protection, and tests pin it as the
12
+ * `expectUniqueViolation` argument. Renaming it propagates automatically.
13
13
  */
14
14
  export declare const ACTIVE_JOB_CONSTRAINT = "read_export_jobs_one_active_per_user";
15
15
  export declare const exportJobEntity: import("@cosmicdrift/kumiko-types/fields").EntityDefinition<{
@@ -1,18 +1,17 @@
1
1
  import { buildEntityTable, sql } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { createBigIntField, createEntity, createLongTextField, createSelectField, createTextField, createTimestampField, } from "@cosmicdrift/kumiko-framework/engine";
3
- // Export-Job-Lifecycle (S2.U3+U4 Atom 1).
3
+ // Export-job lifecycle.
4
4
  //
5
- // Spec: docs/plans/architecture/user-data-rights.md "Async Export-Pipeline".
6
- // User triggert `request-export` → ExportJob (status="pending"). Worker
7
- // pickt auf → "running" → erfolgreich "done" + downloadStorageKey gesetzt
5
+ // User triggers `request-export` → ExportJob (status="pending"). The worker
6
+ // picks it up → "running" → on success, "done" + downloadStorageKey set
8
7
  // + expiresAt = completedAt + compliance-profile.userRights.exportDownloadTtl
9
- // (per-Tenant-konfigurierbar via Override, Default 7 Tage). Bei Throw
10
- // oder Stale-Timeout → "failed" mit errorMessage. Stale-Timeout +
11
- // Storage-Cleanup-Grace ebenfalls aus dem compliance-profile.
8
+ // (configurable per tenant via override, default 7 days). On throw or stale
9
+ // timeout → "failed" with errorMessage. Stale timeout and storage-cleanup
10
+ // grace are also read from the compliance profile.
12
11
  //
13
- // Status-Werte als Constants — Single source of truth fuer Worker,
14
- // Application-Code (request-export-Handler), UI-Banner (Polling) und
15
- // Drift-Guard im Test.
12
+ // Status values are constants—the single source of truth for the worker,
13
+ // application code (`request-export` handler), UI polling banner, and test
14
+ // drift guard.
16
15
  export const EXPORT_JOB_STATUS = {
17
16
  Pending: "pending",
18
17
  Running: "running",
@@ -20,10 +19,10 @@ export const EXPORT_JOB_STATUS = {
20
19
  Failed: "failed",
21
20
  };
22
21
  /**
23
- * DB-Constraint-Name fuer den Partial-UNIQUE-Index (1 aktiver Job pro
24
- * User). Single source of truth — request-export.write catched 23505
25
- * mit diesem Namen als Race-Schutz, Tests pinnen ihn als
26
- * `expectUniqueViolation`-Argument. Rename hier propagiert automatisch.
22
+ * Database constraint name for the partial UNIQUE index (one active job per
23
+ * user). This is the single source of truth: request-export.write catches
24
+ * 23505 with this name as race protection, and tests pin it as the
25
+ * `expectUniqueViolation` argument. Renaming it propagates automatically.
27
26
  */
28
27
  export const ACTIVE_JOB_CONSTRAINT = "read_export_jobs_one_active_per_user";
29
28
  const EXPORT_JOB_STATUS_OPTIONS = [
@@ -35,46 +34,45 @@ const EXPORT_JOB_STATUS_OPTIONS = [
35
34
  // **Tenant-agnostic** like userTable — one job per userId across all
36
35
  // memberships; the worker iterates cross-tenant via ctx.db.unsafeRaw (same pattern as runForgetCleanup).
37
36
  //
38
- // **Idempotency:** Partial-UNIQUE-Index auf `(userId)` WHERE
39
- // `status IN ('pending', 'running')`. User mit pending-Job kann keinen
40
- // zweiten parallelen Job starten — der Insert faellt mit Constraint-
41
- // Violation auf, der request-export-Handler (Atom 2) faengt das ab und
42
- // returnt den existing pending-Job (Insert-or-Return). Race-Window
43
- // null. Done/Failed-Jobs koennen beliebig viele pro User existieren
44
- // (Audit-Historie).
37
+ // **Idempotency:** Partial UNIQUE index on `(userId)` WHERE
38
+ // `status IN ('pending', 'running')`. A user with a pending job cannot start
39
+ // a second parallel job—the insert fails with a constraint violation, which
40
+ // the request-export handler catches and uses to return the existing pending
41
+ // job (insert-or-return). This closes the race window. Done/failed jobs can
42
+ // be retained indefinitely per user for audit history.
45
43
  //
46
- // **idType: "uuid"** — Job-IDs reisen ueber Process-Grenzen
47
- // (BullMQ-Payload, Job-Run-Logger, Audit-Events fuer DPO). Serial-IDs
48
- // sind nur prozess-lokal verlaesslich, UUIDs cross-process stabil.
44
+ // **idType: "uuid"** — job IDs cross process boundaries (BullMQ payloads,
45
+ // job-run logger, and audit events for the DPO). Serial IDs are only reliable
46
+ // within one process; UUIDs remain stable across processes.
49
47
  export const exportJobEntity = createEntity({
50
48
  table: "read_export_jobs",
51
49
  idType: "uuid",
52
50
  description: "One user's GDPR Art. 20 data-export request and its lifecycle: who asked, from which tenant, the pending/running/done/failed status, the timestamps, the download storage key and expiry, and any error the export worker hit.",
53
51
  fields: {
54
- // Tenant-agnostisch: Wert wird beim Schreiben gesetzt (Framework
55
- // braucht eine tenant_id-Spalte), domain-mäßig ignoriert.
56
- // Kein maxLength — folgt userTable.id + tenantMembershipsTable.userId
57
- // (beide ohne maxLength). UserId-Form ist Plattform-Konzern, hier
58
- // nur Storage.
52
+ // Tenant-agnostic: set when writing because the framework requires a
53
+ // tenant_id column, but ignored at the domain level.
54
+ // No maxLength — follows userTable.id and tenantMembershipsTable.userId
55
+ // (both have no maxLength). The userId shape is platform-wide; here it is
56
+ // only used for storage.
59
57
  userId: createTextField({
60
58
  required: true,
61
59
  searchable: true,
62
60
  personal: false,
63
61
  reason: "pseudonymous_fk",
64
62
  }),
65
- // **requestedFromTenantId** — der Tenant aus dem der User den Antrag
66
- // gestellt hat. Persistierter Audit-Pfad fuer den Worker (welches
67
- // Compliance-Profile gilt fuer Job-TTL/Stale/Cleanup) — DSGVO-
68
- // konsistent: 1 User = 1 effektives Profile pro Antrag, nicht "wechselt
69
- // mit jedem Cross-Tenant-Klick". Plan-Doc-Decision: Tenant aus 1. Klick
70
- // (Option a). Spalte heisst nicht einfach "tenantId" damit kein
71
- // Verwechseln mit der Framework-Auto-Spalte tenant_id.
63
+ // **requestedFromTenantId** — the tenant from which the user submitted the
64
+ // request. This persisted audit path tells the worker which compliance
65
+ // profile applies to the job TTL, stale timeout, and cleanup. This keeps
66
+ // one effective profile per request instead of changing with every
67
+ // cross-tenant click. The tenant is taken from the first click (option a).
68
+ // The column is not simply named "tenantId" to avoid confusion with the
69
+ // framework-generated tenant_id column.
72
70
  //
73
- // **Atom 3b Worker-Hinweis:** Profile-Resolution muss ueber
74
- // `requestedFromTenantId` laufen (`queryAs(systemUserOf(requestedFromTenantId),
75
- // "compliance-profiles:query:for-tenant", {})`), NICHT ueber
76
- // `executor.tenantId` — sonst kriegt ein Job-Pickup aus einem anderen
77
- // Tenant-Context ein falsches Profile.
71
+ // **Worker note:** Profile resolution must use `requestedFromTenantId`
72
+ // (`queryAs(systemUserOf(requestedFromTenantId),
73
+ // "compliance-profiles:query:for-tenant", {})`), not
74
+ // `executor.tenantId`; otherwise a job picked up from another tenant
75
+ // context would use the wrong profile.
78
76
  requestedFromTenantId: createTextField({
79
77
  required: true,
80
78
  personal: false,
@@ -85,36 +83,36 @@ export const exportJobEntity = createEntity({
85
83
  default: EXPORT_JOB_STATUS.Pending,
86
84
  options: EXPORT_JOB_STATUS_OPTIONS,
87
85
  }),
88
- // Wann hat der User den Job angefordert. Required — kein Job-Row
89
- // entsteht ohne Klick.
86
+ // When the user requested the job. Required because no job row exists
87
+ // without a request.
90
88
  requestedAt: createTimestampField({
91
89
  required: true,
92
90
  sortable: true,
93
91
  }),
94
- // Wann hat der Worker mit dem Pickup angefangen. NULL solange
95
- // `pending`. Stale-Detection nutzt das +
92
+ // When the worker began processing the job. NULL while `pending`.
93
+ // Stale detection uses this together with
96
94
  // compliance-profile.userRights.exportStaleTimeoutMinutes.
97
95
  startedAt: createTimestampField({}),
98
- // Wann hat der Worker abgeschlossen (success oder fail). NULL
99
- // solange running.
96
+ // When the worker completed the job, successfully or with failure. NULL
97
+ // while `running`.
100
98
  completedAt: createTimestampField({}),
101
- // Storage-Key des fertigen ZIP-Files. NULL solange nicht `done`.
102
- // Worker setzt das + die ZIP-Bytes via storage-provider.write(key).
103
- // Dies ist KEIN signed-URL — der Download-Endpoint generiert den
104
- // signed-URL on demand vom Storage-Provider (Atom 4).
99
+ // Storage key of the completed ZIP file. NULL until `done`.
100
+ // The worker sets this and writes the ZIP bytes via
101
+ // storage-provider.write(key).
102
+ // This is not a signed URL—the download endpoint generates the signed URL
103
+ // on demand through the storage provider.
105
104
  downloadStorageKey: createTextField({
106
105
  maxLength: 500,
107
106
  personal: false,
108
107
  reason: "technical_reference",
109
108
  }),
110
- // Ab wann ist der Download nicht mehr abrufbar. Worker setzt
109
+ // When the download is no longer available. The worker sets
111
110
  // `completedAt + compliance-profile.userRights.exportDownloadTtl`
112
- // beim Flip auf `done`. NULL fuer pending/running/failed.
111
+ // when switching to `done`. NULL for pending, running, and failed jobs.
113
112
  //
114
- // Storage-Cleanup-Pflicht: Worker laesst nach
115
- // `expiresAt + compliance-profile.userRights.exportStorageCleanupGraceHours`
116
- // einen separaten Pass loeschen damit abgelaufene ZIPs nicht auf S3
117
- // verbleiben.
113
+ // Storage cleanup requirement: after
114
+ // `expiresAt + compliance-profile.userRights.exportStorageCleanupGraceHours`,
115
+ // a separate pass deletes expired ZIPs so they do not remain on S3.
118
116
  expiresAt: createTimestampField({}),
119
117
  // Failed-state diagnostics. longText because hook errors with stack
120
118
  // traces can run several KB. `reason: "is_business_data"` because
@@ -123,19 +121,19 @@ export const exportJobEntity = createEntity({
123
121
  personal: false,
124
122
  reason: "is_business_data",
125
123
  }),
126
- // Audit-Info fuer Operator: wie gross war der Export. Hilft beim
127
- // Capacity-Planning + erkennt pathologische Cases (Streaming-ZIP
128
- // mit 5 GB Files schreibt mehrere Mrd Bytes, integer-Overflow waere
129
- // silent + Audit-Drift).
124
+ // Audit information for operators: the export size. This supports capacity
125
+ // planning and detects pathological cases (a streaming ZIP containing 5 GB
126
+ // of files writes several billion bytes, so integer overflow would cause
127
+ // silent audit drift).
130
128
  //
131
- // bigInt liefert JS-`number` Round-trip via mode:"number" — sicher
132
- // bis 2^53 ≈ 9 PB, JSON-tauglich fuer das Status-Polling.
129
+ // bigInt provides a JS-`number` round trip via mode:"number", safe up to
130
+ // 2^53 ≈ 9 PB and suitable for JSON-based status polling.
133
131
  bytesWritten: createBigIntField({}),
134
132
  },
135
- // Partial-UNIQUE-Index: nur 1 aktiver Job pro User, Done/Failed-
136
- // Historie ist unbeschraenkt. request-export.write nutzt App-side-
137
- // Pre-Check als primaeren Pfad + 23505-Catch dieser Constraint als
138
- // Race-Schutz fuer das <1ms-Window zwischen fetchOne + crud.create.
133
+ // Partial UNIQUE index: only one active job per user; done/failed history
134
+ // is unlimited. request-export.write uses an application-side pre-check as
135
+ // the primary path and catches this constraint's 23505 as race protection
136
+ // for the <1ms window between fetchOne and crud.create.
139
137
  indexes: [
140
138
  {
141
139
  unique: true,
@@ -1,19 +1,18 @@
1
1
  /**
2
- * Generiert ein neues Download-Token. plain wird dem User via Email
3
- * zugestellt (Atom 5); hash landet in der Token-DB-Row.
2
+ * Generates a new download token. The plain token is sent to the user by email;
3
+ * the hash is stored in the token database row.
4
4
  *
5
- * Token-Format: 32 byte random → base64url-encoded (~43 chars). URL-safe
6
- * fuer Magic-Link-Verwendung (kein +/= das URL-encoded werden muesste).
5
+ * Token format: 32 random bytes → base64url-encoded (~43 chars). URL-safe for
6
+ * Magic-Link use (no +/= characters that would need to be URL-encoded).
7
7
  */
8
8
  export declare function generateDownloadToken(): Promise<{
9
9
  readonly plain: string;
10
10
  readonly hash: string;
11
11
  }>;
12
12
  /**
13
- * Hashed einen plain-Token zu seiner DB-Repraesentation. Verify-Pfad
14
- * (Atom 4b's Download-Endpoint): hashed incoming-Token + sucht den Hash
15
- * in DB. Konstante-Zeit-String-Vergleich verhindert timing-attacks
16
- * (das macht der Caller via `crypto.subtle`-vergleich oder secure-
17
- * compare-helper).
13
+ * Hashes a plain token into its database representation. In the verification path,
14
+ * the download endpoint hashes the incoming token and looks up the hash in the
15
+ * database. A constant-time string comparison prevents timing attacks; the caller
16
+ * performs it via `crypto.subtle` or a secure comparison helper.
18
17
  */
19
18
  export declare function hashDownloadToken(plain: string): Promise<string>;
@@ -1,29 +1,26 @@
1
- // Download-Token-Helper (S2.U3 Atom 4a).
1
+ // Generates a cryptographically secure token to authorize the export ZIP download.
2
+ // Follows the Magic-Link/Bearer-Token pattern with a hash stored in the database:
2
3
  //
3
- // Generiert ein kryptographisch-sicheres Token zur Authorisierung des
4
- // Export-ZIP-Downloads. Pattern matched Magic-Link/Bearer-Token mit DB-
5
- // gespeichertem Hash:
6
- //
7
- // 1. Worker generiert plain-Token (32 byte random base64url) + Hash
4
+ // 1. The worker generates a plain token (32 random bytes, base64url) and its hash
8
5
  // (SHA256 hex).
9
- // 2. DB speichert NUR den Hash. Plain bleibt im Worker-Memory.
10
- // 3. Atom 5 (Notification) versendet plain via Email an User.
11
- // 4. Atom 4b (Download-Endpoint) hashet incoming-Token + vergleicht
12
- // mit DB-Hash → konstantes-Zeit-Vergleich gegen timing-attacks.
6
+ // 2. The database stores ONLY the hash. The plain token remains in worker memory.
7
+ // 3. The notification step sends the plain token to the user by email.
8
+ // 4. The download endpoint hashes the incoming token and compares it with the
9
+ // database hash using a constant-time comparison to prevent timing attacks.
13
10
  //
14
- // **Multi-use within TTL** (User-Choice 4a-Plan): Token wird NICHT
15
- // "consumed" beim Download — User kann mehrfach downloaden bis expiresAt.
16
- // Pattern matched Google-Takeout (7d) + Facebook-Data-Download (4d).
11
+ // **Multi-use within TTL:** The token is NOT "consumed" on download, so the user
12
+ // can download repeatedly until expiresAt. This matches Google-Takeout (7d) and
13
+ // Facebook-Data-Download (4d).
17
14
  //
18
15
  // **Universal Web-Crypto API:** crypto.getRandomValues + crypto.subtle.digest
19
- // laeuft in Bun + Node 19+ + Browser identisch — keine plattform-
20
- // spezifischen Imports (Memory `feedback_universal_deps`).
16
+ // runs identically in Bun, Node 19+, and browsers, avoiding platform-specific
17
+ // imports.
21
18
  /**
22
- * Generiert ein neues Download-Token. plain wird dem User via Email
23
- * zugestellt (Atom 5); hash landet in der Token-DB-Row.
19
+ * Generates a new download token. The plain token is sent to the user by email;
20
+ * the hash is stored in the token database row.
24
21
  *
25
- * Token-Format: 32 byte random → base64url-encoded (~43 chars). URL-safe
26
- * fuer Magic-Link-Verwendung (kein +/= das URL-encoded werden muesste).
22
+ * Token format: 32 random bytes → base64url-encoded (~43 chars). URL-safe for
23
+ * Magic-Link use (no +/= characters that would need to be URL-encoded).
27
24
  */
28
25
  export async function generateDownloadToken() {
29
26
  const randomBytes = crypto.getRandomValues(new Uint8Array(32));
@@ -32,11 +29,10 @@ export async function generateDownloadToken() {
32
29
  return { plain, hash };
33
30
  }
34
31
  /**
35
- * Hashed einen plain-Token zu seiner DB-Repraesentation. Verify-Pfad
36
- * (Atom 4b's Download-Endpoint): hashed incoming-Token + sucht den Hash
37
- * in DB. Konstante-Zeit-String-Vergleich verhindert timing-attacks
38
- * (das macht der Caller via `crypto.subtle`-vergleich oder secure-
39
- * compare-helper).
32
+ * Hashes a plain token into its database representation. In the verification path,
33
+ * the download endpoint hashes the incoming token and looks up the hash in the
34
+ * database. A constant-time string comparison prevents timing attacks; the caller
35
+ * performs it via `crypto.subtle` or a secure comparison helper.
40
36
  */
41
37
  export async function hashDownloadToken(plain) {
42
38
  const encoded = new TextEncoder().encode(plain);
@@ -44,7 +40,7 @@ export async function hashDownloadToken(plain) {
44
40
  return uint8ArrayToHex(new Uint8Array(digest));
45
41
  }
46
42
  function uint8ArrayToBase64Url(bytes) {
47
- // btoa erwartet binary-string. atob/btoa sind universal in Bun + Node + Browser.
43
+ // btoa expects a binary string. atob/btoa are universal in Bun, Node, and browsers.
48
44
  let binary = "";
49
45
  for (let i = 0; i < bytes.length; i++) {
50
46
  binary += String.fromCharCode(bytes[i]); // @cast-boundary dynamic-key
@@ -2,12 +2,12 @@ import { type TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
2
2
  import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
3
3
  import { type PublicDeletionRoutes } from "./public-deletion-gate.tsx";
4
4
  export type UserDataRightsClientOptions = {
5
- /** Key-weise Overrides über die Default-Bundles (de/en). */
5
+ /** Overrides merged into the default bundles (de/en). */
6
6
  readonly translations?: TranslationsByLocale;
7
- /** Wenn gesetzt: registriert die anonymen (login-freien) Lösch-Screens als
8
- * Gate auf den angegebenen Pfaden. Weglassen → nur der eingeloggte
9
- * privacy-center-Screen. Den Client VOR dem Auth-Client listen, sonst
10
- * landet der anonyme Besucher auf der Login-Maske. */
7
+ /** When set, registers the anonymous (login-free) deletion screens as a
8
+ * gate on the specified paths. If omitted, only the authenticated
9
+ * privacy-center screen is available. Register this client BEFORE the auth
10
+ * client; otherwise, anonymous visitors are redirected to the login screen. */
11
11
  readonly publicDeletion?: PublicDeletionRoutes;
12
12
  };
13
13
  export declare function userDataRightsClient(options?: UserDataRightsClientOptions): ClientFeatureDefinition;
@@ -6,7 +6,7 @@
6
6
  // createKumikoApp({ clientFeatures: [userDataRightsClient()] }); the screen
7
7
  // has no own r.nav, the app places it via r.nav.
8
8
  //
9
- // fw#2312: the former `privacyCenter: { showDeletion }` option is gone — a
9
+ // The former `privacyCenter: { showDeletion }` option is gone — a
10
10
  // declarative screen is now registered server-side once for all apps, so a
11
11
  // client prop can no longer toggle its sections/actions per app. Its
12
12
  // replacement is the server-side
@@ -1,10 +1,11 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // ConfirmAccountDeletionScreen — anonymer Apex-Screen Schritt 2. Liest das
3
- // Token aus dem URL-Fragment (`#token=…`, nie an den Server gesendet — landet
4
- // so nicht in Proxy-/Access-Logs, fw#1554) und dispatcht beim Bestätigen
5
- // user-data-rights:write:confirm-deletion-by-token → startet die Grace-Period.
2
+ // ConfirmAccountDeletionScreen — anonymous Apex screen, step 2. Reads the
3
+ // token from the URL fragment (`#token=…`, never sent to the server, so it does
4
+ // not appear in proxy/access logs) and dispatches
5
+ // user-data-rights:write:confirm-deletion-by-token on confirmation to start the
6
+ // grace period.
6
7
  //
7
- // App mountet den Screen unter der deletionVerifyUrl-Route (z.B.
8
+ // The app mounts this screen at the deletionVerifyUrl route (for example,
8
9
  // /delete-account/confirm) via createPublicSurface.
9
10
  import { useDispatcher, usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
10
11
  import { useState } from "react";
@@ -13,7 +13,7 @@ export const PRIVACY_CENTER_SCREEN_ID = "privacy-center";
13
13
  // compliance-profiles' COMPLIANCE_PROFILE_CATALOG_EXTENSION_NAME.
14
14
  export const EXPORT_SECTION_EXTENSION_NAME = "UserDataRightsExportSection";
15
15
  // enumOption keyPrefix for the privacy-center screen's `status` field
16
- // (fw#2315 pattern) — resolves the raw user-lifecycle enum value
16
+ // pattern — resolves the raw user-lifecycle enum value
17
17
  // (active/restricted/deletionRequested/deleted) to a translated label
18
18
  // instead of showing the raw string.
19
19
  export const STATUS_OPTION_KEY_PREFIX = "userDataRights.privacyCenter.field.status.option.";
@@ -1,8 +1,8 @@
1
- // Public exports für die Browser-Seite des user-data-rights Features —
2
- // die anonymen Apex-Deletion-Screens. Konsumiert via Sub-Path-Export
3
- // `@cosmicdrift/kumiko-bundled-features/user-data-rights/web`. Die Server-
4
- // Seite (defineFeature, Handler) lebt unter `.../user-data-rights` und hat
5
- // keine React-/DOM-Deps.
1
+ // Public exports for the browser side of the user-data-rights feature —
2
+ // the anonymous Apex deletion screens. Consumed via the subpath export
3
+ // `@cosmicdrift/kumiko-bundled-features/user-data-rights/web`. The server
4
+ // side (defineFeature, Handler) lives under `.../user-data-rights` and has
5
+ // no React/DOM dependencies.
6
6
  export { userDataRightsClient } from "./client-plugin.js";
7
7
  export { ConfirmAccountDeletionScreen } from "./confirm-deletion-screen.js";
8
8
  export { defaultTranslations } from "./default-translations.js";