@cosmicdrift/kumiko-samples 0.378.0 → 0.380.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 (509) hide show
  1. package/package.json +1 -1
  2. package/packages/bundled-features/package.json +18 -17
  3. package/packages/bundled-features/src/account-security/feature.ts +2 -2
  4. package/packages/bundled-features/src/account-security/index.ts +8 -8
  5. package/packages/bundled-features/src/account-security/{constants.ts → web/constants.ts} +0 -2
  6. package/packages/bundled-features/src/account-security/{i18n.ts → web/i18n.ts} +0 -1
  7. package/packages/bundled-features/src/admin-shell/feature.ts +10 -9
  8. package/packages/bundled-features/src/admin-shell/index.ts +8 -8
  9. package/packages/bundled-features/src/admin-shell/web/client-plugin.tsx +2 -3
  10. package/packages/bundled-features/src/admin-shell/{constants.ts → web/constants.ts} +0 -1
  11. package/packages/bundled-features/src/admin-shell/web/default-translations.ts +10 -0
  12. package/packages/bundled-features/src/admin-shell/web/i18n.ts +51 -9
  13. package/packages/bundled-features/src/admin-shell/web/index.ts +0 -1
  14. package/packages/bundled-features/src/audit/changes.json +7 -0
  15. package/packages/bundled-features/src/audit/feature.ts +72 -64
  16. package/packages/bundled-features/src/audit/handlers/audit-events.ts +153 -0
  17. package/packages/bundled-features/src/audit/handlers/audit-system-db.ts +13 -0
  18. package/packages/bundled-features/src/audit/handlers/details-all-tenants.query.ts +26 -0
  19. package/packages/bundled-features/src/audit/handlers/details.query.ts +11 -39
  20. package/packages/bundled-features/src/audit/handlers/list-all-tenants.query.ts +47 -0
  21. package/packages/bundled-features/src/audit/handlers/list.query.ts +16 -123
  22. package/packages/bundled-features/src/audit/handlers/resolve-audit-tenant.ts +21 -7
  23. package/packages/bundled-features/src/audit/index.ts +1 -1
  24. package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +4 -4
  25. package/packages/bundled-features/src/audit/screens.ts +82 -0
  26. package/packages/bundled-features/src/audit/web/client-plugin.tsx +2 -3
  27. package/packages/bundled-features/src/audit/{constants.ts → web/constants.ts} +11 -1
  28. package/packages/bundled-features/src/audit/web/default-translations.ts +7 -0
  29. package/packages/bundled-features/src/audit/web/i18n.ts +33 -7
  30. package/packages/bundled-features/src/audit/web/index.ts +0 -2
  31. package/packages/bundled-features/src/auth-email-password/bootstrap.ts +6 -6
  32. package/packages/bundled-features/src/auth-email-password/changes.json +6 -0
  33. package/packages/bundled-features/src/auth-email-password/errors.ts +1 -1
  34. package/packages/bundled-features/src/auth-email-password/feature.ts +2 -2
  35. package/packages/bundled-features/src/auth-email-password/handlers/confirm-account-unlock.write.ts +1 -1
  36. package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +4 -4
  37. package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +3 -3
  38. package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
  39. package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +38 -4
  40. package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +1 -1
  41. package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +1 -1
  42. package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +1 -1
  43. package/packages/bundled-features/src/auth-email-password/handlers/reset-password.write.ts +1 -1
  44. package/packages/bundled-features/src/auth-email-password/handlers/verify-email.write.ts +1 -1
  45. package/packages/bundled-features/src/auth-email-password/index.ts +6 -1
  46. package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +1 -1
  47. package/packages/bundled-features/src/auth-email-password/signup-activation.ts +1 -1
  48. package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +0 -1
  49. package/packages/bundled-features/src/auth-email-password/web/auth-form-logic.ts +0 -1
  50. package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +0 -1
  51. package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +0 -1
  52. package/packages/bundled-features/src/auth-email-password/web/auth-redirect.ts +0 -1
  53. package/packages/bundled-features/src/auth-email-password/web/client-actions.ts +0 -1
  54. package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +1 -2
  55. package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +0 -1
  56. package/packages/bundled-features/src/auth-email-password/{constants.ts → web/constants.ts} +3 -6
  57. package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +0 -1
  58. package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +0 -1
  59. package/packages/bundled-features/src/auth-email-password/{i18n.ts → web/i18n.ts} +3 -4
  60. package/packages/bundled-features/src/auth-email-password/web/index.ts +1 -2
  61. package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +2 -3
  62. package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +0 -1
  63. package/packages/bundled-features/src/auth-email-password/{mail-i18n.ts → web/mail-i18n.ts} +0 -1
  64. package/packages/bundled-features/src/auth-email-password/web/request-account-unlock-screen.tsx +0 -1
  65. package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +0 -1
  66. package/packages/bundled-features/src/auth-email-password/web/session-bootstrap-error.tsx +0 -1
  67. package/packages/bundled-features/src/auth-email-password/web/session.tsx +0 -1
  68. package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +2 -3
  69. package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +0 -1
  70. package/packages/bundled-features/src/auth-email-password/web/tenant-menu-items.tsx +0 -1
  71. package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +0 -1
  72. package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +0 -1
  73. package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +0 -1
  74. package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +0 -1
  75. package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
  76. package/packages/bundled-features/src/auth-mfa/errors.ts +2 -2
  77. package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +1 -1
  78. package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
  79. package/packages/bundled-features/src/auth-mfa/handlers/enable-start.write.ts +1 -1
  80. package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
  81. package/packages/bundled-features/src/auth-mfa/index.ts +8 -8
  82. package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +4 -4
  83. package/packages/bundled-features/src/auth-mfa/screens.ts +1 -1
  84. package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +0 -1
  85. package/packages/bundled-features/src/auth-mfa/{constants.ts → web/constants.ts} +0 -1
  86. package/packages/bundled-features/src/auth-mfa/web/i18n.ts +0 -1
  87. package/packages/bundled-features/src/auth-mfa/web/index.ts +0 -1
  88. package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +0 -1
  89. package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +1 -2
  90. package/packages/bundled-features/src/auth-mfa/web/mfa-recovery-codes-reveal.tsx +0 -1
  91. package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +1 -2
  92. package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +21 -23
  93. package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +0 -1
  94. package/packages/bundled-features/src/billing-foundation/changes.json +18 -0
  95. package/packages/bundled-features/src/billing-foundation/checkout-core.ts +3 -3
  96. package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-text.ts +2 -2
  97. package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +11 -3
  98. package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +11 -1
  99. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +1 -1
  100. package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +12 -1
  101. package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +12 -0
  102. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +6 -1
  103. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +1 -1
  104. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +167 -28
  105. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +102 -3
  106. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +43 -12
  107. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +202 -0
  108. package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +70 -0
  109. package/packages/bundled-features/src/billing-foundation/events.ts +20 -2
  110. package/packages/bundled-features/src/billing-foundation/feature.ts +5 -5
  111. package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +82 -9
  112. package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +1 -1
  113. package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +1 -1
  114. package/packages/bundled-features/src/billing-foundation/index.ts +27 -27
  115. package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +7 -7
  116. package/packages/bundled-features/src/billing-foundation/screens.ts +1 -1
  117. package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +1 -1
  118. package/packages/bundled-features/src/billing-foundation/types.ts +17 -3
  119. package/packages/bundled-features/src/billing-foundation/validate-options.ts +3 -3
  120. package/packages/bundled-features/src/billing-foundation/web/billing-contact-plan.tsx +1 -3
  121. package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +5 -7
  122. package/packages/bundled-features/src/billing-foundation/web/cancel-contract-dialog.tsx +1 -3
  123. package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +1 -3
  124. package/packages/bundled-features/src/billing-foundation/web/client-plugin.tsx +1 -2
  125. package/packages/bundled-features/src/billing-foundation/{constants.ts → web/constants.ts} +37 -31
  126. package/packages/bundled-features/src/billing-foundation/{consumer-protection → web/consumer-protection}/consent-locale.ts +0 -1
  127. package/packages/bundled-features/src/billing-foundation/{contact-card.ts → web/contact-card.ts} +0 -2
  128. package/packages/bundled-features/src/billing-foundation/web/index.ts +14 -15
  129. package/packages/bundled-features/src/billing-foundation/web/localized-params.ts +0 -2
  130. package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +5 -2
  131. package/packages/bundled-features/src/cap-overview/feature.ts +1 -1
  132. package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -1
  133. package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +2 -2
  134. package/packages/bundled-features/src/cap-overview/index.ts +9 -9
  135. package/packages/bundled-features/src/cap-overview/screens.ts +2 -2
  136. package/packages/bundled-features/src/cap-overview/web/cap-cards-panel.tsx +1 -2
  137. package/packages/bundled-features/src/cap-overview/web/cap-usage-bar.tsx +1 -2
  138. package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +0 -2
  139. package/packages/bundled-features/src/cap-overview/web/client-plugin.tsx +3 -4
  140. package/packages/bundled-features/src/cap-overview/{constants.ts → web/constants.ts} +0 -1
  141. package/packages/bundled-features/src/cap-overview/web/index.ts +0 -1
  142. package/packages/bundled-features/src/cap-overview/{usage-math.ts → web/usage-math.ts} +1 -2
  143. package/packages/bundled-features/src/compliance-profiles/feature.ts +5 -5
  144. package/packages/bundled-features/src/compliance-profiles/index.ts +6 -6
  145. package/packages/bundled-features/src/compliance-profiles/web/client-plugin.tsx +2 -3
  146. package/packages/bundled-features/src/compliance-profiles/web/compliance-profile-catalog.tsx +1 -2
  147. package/packages/bundled-features/src/compliance-profiles/{constants.ts → web/constants.ts} +0 -1
  148. package/packages/bundled-features/src/compliance-profiles/web/i18n.ts +0 -1
  149. package/packages/bundled-features/src/compliance-profiles/web/index.ts +0 -1
  150. package/packages/bundled-features/src/config/index.ts +6 -6
  151. package/packages/bundled-features/src/config/web/client-plugin.ts +1 -2
  152. package/packages/bundled-features/src/config/{constants.ts → web/constants.ts} +0 -1
  153. package/packages/bundled-features/src/config/web/i18n.ts +0 -1
  154. package/packages/bundled-features/src/config/web/index.ts +1 -3
  155. package/packages/bundled-features/src/config/write-helpers.ts +1 -1
  156. package/packages/bundled-features/src/custom-fields/feature.ts +8 -8
  157. package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +1 -1
  158. package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +1 -1
  159. package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +1 -1
  160. package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +4 -4
  161. package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +1 -1
  162. package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +1 -1
  163. package/packages/bundled-features/src/custom-fields/index.ts +8 -8
  164. package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +1 -1
  165. package/packages/bundled-features/src/custom-fields/schemas.ts +1 -1
  166. package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +1 -2
  167. package/packages/bundled-features/src/custom-fields/{constants.ts → web/constants.ts} +18 -19
  168. package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +1 -2
  169. package/packages/bundled-features/src/custom-fields/web/i18n.ts +0 -1
  170. package/packages/bundled-features/src/custom-fields/web/index.ts +2 -3
  171. package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +1 -2
  172. package/packages/bundled-features/src/delivery/address-opt-out.ts +1 -1
  173. package/packages/bundled-features/src/delivery/attempt-log-retention.ts +24 -8
  174. package/packages/bundled-features/src/delivery/changes.json +6 -0
  175. package/packages/bundled-features/src/delivery/constants.ts +2 -2
  176. package/packages/bundled-features/src/delivery/i18n.ts +1 -1
  177. package/packages/bundled-features/src/delivery/unsubscribe-page.ts +1 -1
  178. package/packages/bundled-features/src/delivery/web/client-plugin.tsx +6 -7
  179. package/packages/bundled-features/src/delivery/web/delivery-channel-cell.tsx +0 -1
  180. package/packages/bundled-features/src/delivery/web/delivery-error-cell.tsx +0 -1
  181. package/packages/bundled-features/src/delivery/web/delivery-status-cell.tsx +1 -2
  182. package/packages/bundled-features/src/delivery/web/delivery-time-cell.tsx +0 -1
  183. package/packages/bundled-features/src/delivery/web/delivery-type-cell.tsx +0 -1
  184. package/packages/bundled-features/src/delivery/web/index.ts +0 -1
  185. package/packages/bundled-features/src/delivery/{public-names.ts → web/public-names.ts} +0 -1
  186. package/packages/bundled-features/src/document-ingest-foundation/changes.json +6 -0
  187. package/packages/bundled-features/src/document-ingest-foundation/events.ts +4 -0
  188. package/packages/bundled-features/src/document-ingest-foundation/executor.ts +2 -1
  189. package/packages/bundled-features/src/document-ingest-foundation/feature.ts +18 -4
  190. package/packages/bundled-features/src/document-ingest-foundation/index.ts +1 -0
  191. package/packages/bundled-features/src/feature-toggles/feature.ts +7 -7
  192. package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +14 -13
  193. package/packages/bundled-features/src/feature-toggles/handlers/list.query.ts +1 -1
  194. package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +1 -1
  195. package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -3
  196. package/packages/bundled-features/src/feature-toggles/index.ts +6 -6
  197. package/packages/bundled-features/src/feature-toggles/web/client-plugin.tsx +1 -2
  198. package/packages/bundled-features/src/feature-toggles/{constants.ts → web/constants.ts} +0 -1
  199. package/packages/bundled-features/src/feature-toggles/web/i18n.ts +0 -1
  200. package/packages/bundled-features/src/feature-toggles/web/index.ts +0 -1
  201. package/packages/bundled-features/src/files/changes.json +7 -0
  202. package/packages/bundled-features/src/folders/feature.ts +1 -1
  203. package/packages/bundled-features/src/folders/handlers/clear-folder.write.ts +1 -1
  204. package/packages/bundled-features/src/folders/handlers/delete-folder.write.ts +1 -1
  205. package/packages/bundled-features/src/folders/handlers/set-folder.write.ts +1 -1
  206. package/packages/bundled-features/src/folders/index.ts +8 -8
  207. package/packages/bundled-features/src/folders/web/client-plugin.tsx +1 -3
  208. package/packages/bundled-features/src/folders/{constants.ts → web/constants.ts} +0 -1
  209. package/packages/bundled-features/src/folders/web/folder-manager.tsx +1 -2
  210. package/packages/bundled-features/src/folders/web/folder-section.tsx +1 -2
  211. package/packages/bundled-features/src/folders/web/i18n.ts +0 -1
  212. package/packages/bundled-features/src/folders/web/index.ts +1 -2
  213. package/packages/bundled-features/src/folders/web/tree.ts +0 -1
  214. package/packages/bundled-features/src/form-draft/changes.json +7 -0
  215. package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +25 -11
  216. package/packages/bundled-features/src/form-draft/decrypt-draft.ts +24 -0
  217. package/packages/bundled-features/src/form-draft/entity.ts +6 -9
  218. package/packages/bundled-features/src/form-draft/feature.ts +1 -1
  219. package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +26 -5
  220. package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
  221. package/packages/bundled-features/src/form-draft/handlers/get.query.ts +6 -7
  222. package/packages/bundled-features/src/form-draft/handlers/list.query.ts +13 -7
  223. package/packages/bundled-features/src/form-draft/handlers/save.write.ts +5 -5
  224. package/packages/bundled-features/src/form-draft/index.ts +8 -8
  225. package/packages/bundled-features/src/form-draft/lookup.ts +10 -4
  226. package/packages/bundled-features/src/form-draft/schemas.ts +1 -1
  227. package/packages/bundled-features/src/form-draft/{constants.ts → web/constants.ts} +0 -1
  228. package/packages/bundled-features/src/form-draft-user-data/hooks.ts +2 -2
  229. package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +10 -10
  230. package/packages/bundled-features/src/jobs/feature.ts +7 -7
  231. package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
  232. package/packages/bundled-features/src/jobs/handlers/trigger.write.ts +1 -1
  233. package/packages/bundled-features/src/jobs/index.ts +1 -1
  234. package/packages/bundled-features/src/jobs/job-run-table.ts +4 -3
  235. package/packages/bundled-features/src/jobs/web/client-plugin.tsx +2 -3
  236. package/packages/bundled-features/src/jobs/{constants.ts → web/constants.ts} +0 -1
  237. package/packages/bundled-features/src/jobs/web/default-translations.ts +7 -0
  238. package/packages/bundled-features/src/jobs/web/i18n.ts +53 -7
  239. package/packages/bundled-features/src/jobs/web/index.ts +0 -1
  240. package/packages/bundled-features/src/ledger/changes.json +7 -0
  241. package/packages/bundled-features/src/ledger/entity.ts +1 -1
  242. package/packages/bundled-features/src/ledger/feature.ts +1 -1
  243. package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +2 -10
  244. package/packages/bundled-features/src/ledger/handlers/create-transaction.write.ts +1 -1
  245. package/packages/bundled-features/src/ledger/handlers/reports.query.ts +1 -1
  246. package/packages/bundled-features/src/ledger/handlers/reverse-transaction.write.ts +1 -1
  247. package/packages/bundled-features/src/ledger/index.ts +13 -13
  248. package/packages/bundled-features/src/ledger/recurring.ts +1 -1
  249. package/packages/bundled-features/src/ledger/reports.ts +1 -1
  250. package/packages/bundled-features/src/ledger/schemas.ts +1 -1
  251. package/packages/bundled-features/src/ledger/{constants.ts → web/constants.ts} +0 -1
  252. package/packages/bundled-features/src/ledger/web/index.ts +11 -12
  253. package/packages/bundled-features/src/legal-pages/README.md +1 -1
  254. package/packages/bundled-features/src/legal-pages/feature.ts +5 -5
  255. package/packages/bundled-features/src/legal-pages/index.ts +11 -11
  256. package/packages/bundled-features/src/legal-pages/lib/boot-check.ts +1 -1
  257. package/packages/bundled-features/src/legal-pages/lib/validate-routes.ts +1 -1
  258. package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +1 -2
  259. package/packages/bundled-features/src/legal-pages/{constants.ts → web/constants.ts} +6 -8
  260. package/packages/bundled-features/src/legal-pages/web/index.ts +0 -1
  261. package/packages/bundled-features/src/managed-pages/feature.ts +1 -1
  262. package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +1 -2
  263. package/packages/bundled-features/src/managed-pages/web/default-translations.ts +17 -0
  264. package/packages/bundled-features/src/managed-pages/web/i18n.ts +59 -16
  265. package/packages/bundled-features/src/managed-pages/web/index.ts +1 -2
  266. package/packages/bundled-features/src/metrics/compute.ts +1 -1
  267. package/packages/bundled-features/src/metrics/feature.ts +6 -6
  268. package/packages/bundled-features/src/metrics/index.ts +8 -8
  269. package/packages/bundled-features/src/metrics/types.ts +1 -1
  270. package/packages/bundled-features/src/metrics/validate.ts +1 -1
  271. package/packages/bundled-features/src/metrics/{constants.ts → web/constants.ts} +0 -1
  272. package/packages/bundled-features/src/metrics/window.ts +1 -1
  273. package/packages/bundled-features/src/notes-history/feature.ts +1 -1
  274. package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +1 -1
  275. package/packages/bundled-features/src/notes-history/index.ts +8 -8
  276. package/packages/bundled-features/src/notes-history/web/client-plugin.tsx +1 -3
  277. package/packages/bundled-features/src/notes-history/{constants.ts → web/constants.ts} +0 -1
  278. package/packages/bundled-features/src/notes-history/web/i18n.ts +0 -1
  279. package/packages/bundled-features/src/notes-history/web/index.ts +2 -3
  280. package/packages/bundled-features/src/notes-history/web/notes-section.tsx +2 -3
  281. package/packages/bundled-features/src/personal-access-tokens/feature.ts +12 -10
  282. package/packages/bundled-features/src/personal-access-tokens/handlers/available-scopes.query.ts +1 -1
  283. package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +1 -1
  284. package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +1 -1
  285. package/packages/bundled-features/src/personal-access-tokens/hash.ts +1 -1
  286. package/packages/bundled-features/src/personal-access-tokens/i18n.ts +2 -2
  287. package/packages/bundled-features/src/personal-access-tokens/index.ts +5 -5
  288. package/packages/bundled-features/src/personal-access-tokens/resolver.ts +1 -1
  289. package/packages/bundled-features/src/personal-access-tokens/schema/api-token.ts +3 -3
  290. package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -2
  291. package/packages/bundled-features/src/personal-access-tokens/{constants.ts → web/constants.ts} +0 -1
  292. package/packages/bundled-features/src/personal-access-tokens/{scopes.ts → web/scopes.ts} +0 -1
  293. package/packages/bundled-features/src/presets/changes.json +7 -0
  294. package/packages/bundled-features/src/presets/index.ts +0 -1
  295. package/packages/bundled-features/src/presets/security-baseline.ts +1 -1
  296. package/packages/bundled-features/src/renderer-foundation/types.ts +1 -1
  297. package/packages/bundled-features/src/secrets/feature.ts +1 -1
  298. package/packages/bundled-features/src/secrets/handlers/delete.write.ts +1 -1
  299. package/packages/bundled-features/src/secrets/handlers/list.query.ts +1 -1
  300. package/packages/bundled-features/src/secrets/handlers/set.write.ts +1 -1
  301. package/packages/bundled-features/src/secrets/i18n.ts +1 -1
  302. package/packages/bundled-features/src/secrets/index.ts +8 -8
  303. package/packages/bundled-features/src/secrets/{constants.ts → web/constants.ts} +0 -1
  304. package/packages/bundled-features/src/secrets/write-gate.ts +1 -1
  305. package/packages/bundled-features/src/sessions/feature.ts +7 -4
  306. package/packages/bundled-features/src/sessions/schema/user-session.ts +2 -3
  307. package/packages/bundled-features/src/sessions/{i18n.ts → web/i18n.ts} +0 -1
  308. package/packages/bundled-features/src/shared/index.ts +6 -1
  309. package/packages/bundled-features/src/shared/purge-files-reaching-subject.ts +10 -2
  310. package/packages/bundled-features/src/shared/web/translate-or-raw.ts +0 -1
  311. package/packages/bundled-features/src/subscription-stripe/feature.ts +2 -0
  312. package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +19 -0
  313. package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +1 -0
  314. package/packages/bundled-features/src/tags/changes.json +6 -0
  315. package/packages/bundled-features/src/tags/feature.ts +1 -1
  316. package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +11 -7
  317. package/packages/bundled-features/src/tags/handlers/create-tag.write.ts +1 -1
  318. package/packages/bundled-features/src/tags/handlers/delete-tag.write.ts +4 -1
  319. package/packages/bundled-features/src/tags/handlers/remove-tag.write.ts +1 -1
  320. package/packages/bundled-features/src/tags/handlers/update-tag.write.ts +1 -1
  321. package/packages/bundled-features/src/tags/index.ts +12 -12
  322. package/packages/bundled-features/src/tags/screens.ts +1 -1
  323. package/packages/bundled-features/src/tags/web/client-plugin.tsx +1 -3
  324. package/packages/bundled-features/src/tags/{constants.ts → web/constants.ts} +4 -1
  325. package/packages/bundled-features/src/tags/web/entity-tags.tsx +1 -2
  326. package/packages/bundled-features/src/tags/web/i18n.ts +2 -2
  327. package/packages/bundled-features/src/tags/web/index.ts +2 -3
  328. package/packages/bundled-features/src/tags/web/tag-chip.tsx +0 -1
  329. package/packages/bundled-features/src/tags/web/tag-filter.tsx +1 -2
  330. package/packages/bundled-features/src/tags/web/tag-manager.tsx +5 -4
  331. package/packages/bundled-features/src/tags/web/tag-picker.tsx +0 -1
  332. package/packages/bundled-features/src/tags/web/tag-section.tsx +1 -2
  333. package/packages/bundled-features/src/tags/web/tags-cell.tsx +1 -2
  334. package/packages/bundled-features/src/template-resolver/README.md +1 -1
  335. package/packages/bundled-features/src/template-resolver/api.ts +75 -28
  336. package/packages/bundled-features/src/template-resolver/changes.json +43 -0
  337. package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -1
  338. package/packages/bundled-features/src/template-resolver/compile-steps-block.ts +2 -2
  339. package/packages/bundled-features/src/template-resolver/document-ops.ts +5 -5
  340. package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +4 -4
  341. package/packages/bundled-features/src/template-resolver/feature.ts +13 -4
  342. package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +6 -1
  343. package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +6 -2
  344. package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
  345. package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -1
  346. package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +19 -2
  347. package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +2 -2
  348. package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +7 -1
  349. package/packages/bundled-features/src/template-resolver/handlers/discard-draft.write.ts +1 -1
  350. package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +8 -2
  351. package/packages/bundled-features/src/template-resolver/handlers/document-blocks.query.ts +2 -2
  352. package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +5 -2
  353. package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +4 -2
  354. package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +10 -5
  355. package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +5 -2
  356. package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +68 -10
  357. package/packages/bundled-features/src/template-resolver/handlers/patch-draft.write.ts +1 -1
  358. package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +1 -1
  359. package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +1 -1
  360. package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +2 -2
  361. package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +1 -1
  362. package/packages/bundled-features/src/template-resolver/handlers/shared.ts +1 -1
  363. package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +6 -6
  364. package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +2 -2
  365. package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +8 -2
  366. package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +4 -2
  367. package/packages/bundled-features/src/template-resolver/i18n.ts +25 -0
  368. package/packages/bundled-features/src/template-resolver/index.ts +60 -59
  369. package/packages/bundled-features/src/template-resolver/layout-appearance.ts +1 -1
  370. package/packages/bundled-features/src/template-resolver/layout-regions.ts +1 -1
  371. package/packages/bundled-features/src/template-resolver/seeding.ts +16 -7
  372. package/packages/bundled-features/src/template-resolver/store-template-resource.ts +2 -2
  373. package/packages/bundled-features/src/template-resolver/table.ts +1 -1
  374. package/packages/bundled-features/src/template-resolver/template-bundle.ts +2 -2
  375. package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +82 -0
  376. package/packages/bundled-features/src/template-resolver/template-draft.ts +1 -1
  377. package/packages/bundled-features/src/template-resolver/template-edit-policy.ts +2 -2
  378. package/packages/bundled-features/src/template-resolver/template-meta.ts +2 -2
  379. package/packages/bundled-features/src/template-resolver/template-preview.ts +14 -10
  380. package/packages/bundled-features/src/template-resolver/template-usage.ts +1 -1
  381. package/packages/bundled-features/src/template-resolver/template-validation.ts +2 -2
  382. package/packages/bundled-features/src/template-resolver/testing.ts +2 -2
  383. package/packages/bundled-features/src/template-resolver/user-content-table.ts +1 -1
  384. package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +4 -5
  385. package/packages/bundled-features/src/template-resolver/{constants.ts → web/constants.ts} +7 -10
  386. package/packages/bundled-features/src/template-resolver/{document-blocks.ts → web/document-blocks.ts} +0 -1
  387. package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +2 -3
  388. package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +0 -1
  389. package/packages/bundled-features/src/template-resolver/{document-images.ts → web/document-images.ts} +0 -1
  390. package/packages/bundled-features/src/template-resolver/{document-schema.ts → web/document-schema.ts} +0 -1
  391. package/packages/bundled-features/src/template-resolver/{document-steps.ts → web/document-steps.ts} +0 -1
  392. package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +6 -7
  393. package/packages/bundled-features/src/template-resolver/web/document-toolbar-blocks.ts +2 -3
  394. package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +1 -2
  395. package/packages/bundled-features/src/template-resolver/web/i18n.ts +2 -1
  396. package/packages/bundled-features/src/template-resolver/web/index.ts +13 -14
  397. package/packages/bundled-features/src/template-resolver/{mail-constants.ts → web/mail-constants.ts} +0 -1
  398. package/packages/bundled-features/src/template-resolver/{pdf-constants.ts → web/pdf-constants.ts} +0 -1
  399. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +0 -1
  400. package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +5 -4
  401. package/packages/bundled-features/src/template-resolver/{placeholder-text.ts → web/placeholder-text.ts} +0 -1
  402. package/packages/bundled-features/src/template-resolver/{qualified-names.ts → web/qualified-names.ts} +0 -1
  403. package/packages/bundled-features/src/template-resolver/web/use-stable-by-key.ts +0 -1
  404. package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +1 -1
  405. package/packages/bundled-features/src/tenant/index.ts +7 -7
  406. package/packages/bundled-features/src/tenant/invitation-table.ts +1 -1
  407. package/packages/bundled-features/src/tenant/invited-membership.ts +1 -1
  408. package/packages/bundled-features/src/tenant/last-tenant-admin.ts +1 -1
  409. package/packages/bundled-features/src/tenant/member-role-options.ts +1 -1
  410. package/packages/bundled-features/src/tenant/screens.ts +2 -2
  411. package/packages/bundled-features/src/tenant/web/client-plugin.tsx +1 -2
  412. package/packages/bundled-features/src/tenant/{constants.ts → web/constants.ts} +3 -6
  413. package/packages/bundled-features/src/tenant/web/index.ts +0 -1
  414. package/packages/bundled-features/src/tenant/web/member-roles-cell.tsx +0 -1
  415. package/packages/bundled-features/src/tenant/web/member-status-cell.tsx +0 -1
  416. package/packages/bundled-features/src/tenant-lifecycle/stages.ts +2 -2
  417. package/packages/bundled-features/src/tier-engine/entity.ts +1 -1
  418. package/packages/bundled-features/src/tier-engine/feature.ts +7 -7
  419. package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +1 -1
  420. package/packages/bundled-features/src/tier-engine/index.ts +8 -8
  421. package/packages/bundled-features/src/tier-engine/web/client-plugin.tsx +2 -3
  422. package/packages/bundled-features/src/tier-engine/{constants.ts → web/constants.ts} +2 -3
  423. package/packages/bundled-features/src/tier-engine/{i18n.ts → web/i18n.ts} +0 -1
  424. package/packages/bundled-features/src/tier-engine/web/index.ts +0 -1
  425. package/packages/bundled-features/src/user/handlers/create.write.ts +1 -1
  426. package/packages/bundled-features/src/user/handlers/update-roles.ts +1 -1
  427. package/packages/bundled-features/src/user/handlers/update.write.ts +1 -1
  428. package/packages/bundled-features/src/user/index.ts +1 -1
  429. package/packages/bundled-features/src/user/invited-global-roles.ts +1 -1
  430. package/packages/bundled-features/src/user/schema/user.ts +1 -1
  431. package/packages/bundled-features/src/user/{constants.ts → web/constants.ts} +0 -1
  432. package/packages/bundled-features/src/user-data-rights/changes.json +14 -0
  433. package/packages/bundled-features/src/user-data-rights/env.ts +1 -1
  434. package/packages/bundled-features/src/user-data-rights/feature.ts +9 -9
  435. package/packages/bundled-features/src/user-data-rights/index.ts +1 -1
  436. package/packages/bundled-features/src/user-data-rights/lib/resolve-tenant-model.ts +1 -1
  437. package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +1 -1
  438. package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +2 -3
  439. package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +0 -1
  440. package/packages/bundled-features/src/user-data-rights/{constants.ts → web/constants.ts} +11 -12
  441. package/packages/bundled-features/src/user-data-rights/web/default-translations.ts +91 -0
  442. package/packages/bundled-features/src/user-data-rights/web/i18n.ts +41 -91
  443. package/packages/bundled-features/src/user-data-rights/web/index.ts +1 -2
  444. package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +1 -2
  445. package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +0 -1
  446. package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +0 -1
  447. package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +10 -1
  448. package/packages/bundled-features/src/user-profile/feature.ts +2 -2
  449. package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +1 -1
  450. package/packages/bundled-features/src/user-profile/index.ts +3 -2
  451. package/packages/bundled-features/src/user-profile/web/client-plugin.ts +2 -3
  452. package/packages/bundled-features/src/user-profile/{constants.ts → web/constants.ts} +0 -1
  453. package/packages/bundled-features/src/user-profile/{i18n.ts → web/i18n.ts} +0 -1
  454. package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +2 -3
  455. package/packages/bundled-features/src/waitlist/changes.json +6 -0
  456. package/packages/bundled-features/src/waitlist/entity.ts +1 -1
  457. package/packages/bundled-features/src/waitlist/feature.ts +5 -5
  458. package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +3 -3
  459. package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +5 -1
  460. package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +1 -1
  461. package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +3 -3
  462. package/packages/bundled-features/src/waitlist/import.ts +1 -1
  463. package/packages/bundled-features/src/waitlist/index.ts +11 -11
  464. package/packages/bundled-features/src/waitlist/legacy-migrate.ts +1 -1
  465. package/packages/bundled-features/src/waitlist/link-on-signup.ts +1 -1
  466. package/packages/bundled-features/src/waitlist/mail.ts +7 -6
  467. package/packages/bundled-features/src/waitlist/payloads.ts +1 -1
  468. package/packages/bundled-features/src/waitlist/screens.ts +1 -1
  469. package/packages/bundled-features/src/waitlist/{constants.ts → web/constants.ts} +0 -1
  470. package/samples/apps/styleguide/src/features/content/web.tsx +0 -1
  471. package/samples/apps/ui-walkthrough/src/app/client.tsx +2 -0
  472. package/samples/apps/ui-walkthrough/src/app/seed-rental.ts +17 -1
  473. package/samples/apps/ui-walkthrough/src/app/seed-templates.ts +11 -0
  474. package/samples/apps/ui-walkthrough/src/app/server.ts +2 -1
  475. package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +35 -7
  476. package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +6 -0
  477. package/samples/apps/ui-walkthrough/src/features/rental/entities.ts +27 -0
  478. package/samples/apps/ui-walkthrough/src/features/rental/feature.ts +61 -7
  479. package/samples/apps/ui-walkthrough/src/features/rental/i18n.ts +48 -24
  480. package/samples/apps/ui-walkthrough/src/features/rental/invoice-receive.ts +0 -1
  481. package/samples/apps/ui-walkthrough/src/features/rental/lease-support.ts +17 -1
  482. package/samples/apps/ui-walkthrough/src/features/rental/qualified-names.ts +3 -0
  483. package/samples/apps/ui-walkthrough/src/features/rental/receipts-upload.ts +70 -0
  484. package/samples/apps/ui-walkthrough/src/features/rental/screens.ts +90 -13
  485. package/samples/apps/ui-walkthrough/src/features/rental/web/index.ts +0 -2
  486. package/samples/apps/ui-walkthrough/src/features/subscription-plans/feature.ts +103 -0
  487. package/samples/apps/ui-walkthrough/src/features/subscription-plans/i18n.ts +36 -0
  488. package/samples/apps/ui-walkthrough/src/features/subscription-plans/index.ts +2 -0
  489. package/samples/apps/ui-walkthrough/src/features/subscription-plans/seed.ts +21 -0
  490. package/samples/apps/ui-walkthrough/src/run-config.ts +11 -0
  491. package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +1 -1
  492. package/samples/apps/use-all-bundled/feature-manifest.json +4 -4
  493. package/samples/apps/use-all-bundled/scripts/check-coverage.ts +1 -1
  494. package/samples/apps/use-all-bundled/src/app/dev-app-options.ts +3 -1
  495. package/samples/recipes/compose-stacks/README.md +1 -2
  496. package/samples/recipes/embedded/README.md +5 -5
  497. package/samples/recipes/embedded/src/handlers/invoice-receive.write.ts +0 -1
  498. package/samples/recipes/embedded/src/screens/invoice-receive.screen.ts +9 -12
  499. package/samples/recipes/legal-pages/README.md +2 -2
  500. package/samples/recipes/legal-pages/src/feature.ts +1 -1
  501. package/samples/recipes/reference-data/src/feature.ts +3 -7
  502. package/packages/bundled-features/src/admin-shell/i18n.ts +0 -54
  503. package/packages/bundled-features/src/audit/i18n.ts +0 -25
  504. package/packages/bundled-features/src/auth-mfa/web/qrcode-browser.d.ts +0 -11
  505. package/packages/bundled-features/src/jobs/i18n.ts +0 -55
  506. package/packages/bundled-features/src/managed-pages/i18n.ts +0 -63
  507. package/packages/bundled-features/src/presets/dsgvo-self-service.ts +0 -35
  508. package/packages/bundled-features/src/user-data-rights/i18n.ts +0 -44
  509. package/samples/apps/ui-walkthrough/src/features/rental/web/upload-standard-layout.tsx +0 -61
@@ -3,9 +3,9 @@ import {
3
3
  type WriteFailure,
4
4
  writeFailure,
5
5
  } from "@cosmicdrift/kumiko-framework/errors";
6
- import { AuthMfaErrorCodes } from "./constants.ts";
6
+ import { AuthMfaErrorCodes } from "./web/constants.ts";
7
7
 
8
- export { AuthMfaErrorCodes as AuthMfaErrors } from "./constants.ts";
8
+ export { AuthMfaErrorCodes as AuthMfaErrors } from "./web/constants.ts";
9
9
 
10
10
  export function mfaAlreadyEnabled(): WriteFailure {
11
11
  return writeFailure(
@@ -12,7 +12,6 @@ import * as z from "zod";
12
12
  import { burnToken, sessionLocaleField, sessionTimezoneField } from "../../shared/index.ts";
13
13
  import { USER_STATUS, UserQueries } from "../../user/index.ts";
14
14
  import { base32Decode } from "../base32.ts";
15
- import { MFA_VERIFY_LOCKOUT_MINUTES, MFA_VERIFY_MAX_ATTEMPTS } from "../constants.ts";
16
15
  import { findUserMfaRow } from "../db/queries.ts";
17
16
  import {
18
17
  invalidSetupToken,
@@ -28,6 +27,7 @@ import {
28
27
  } from "../mfa-verify-attempts.ts";
29
28
  import { encodeRecoveryCodes, userMfaEntity, userMfaTable } from "../schema/user-mfa.ts";
30
29
  import { verifyTotp } from "../totp.ts";
30
+ import { MFA_VERIFY_LOCKOUT_MINUTES, MFA_VERIFY_MAX_ATTEMPTS } from "../web/constants.ts";
31
31
 
32
32
  export type EnableConfirmPreauthOptions = {
33
33
  // Must match the secret enable-start-preauth.write.ts signs setupTokens
@@ -2,7 +2,6 @@ import { createTenantDb } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { defineWriteHandler, type SessionUser } from "@cosmicdrift/kumiko-framework/engine";
3
3
  import * as z from "zod";
4
4
  import { base32Encode } from "../base32.ts";
5
- import { MFA_SETUP_TOKEN_TTL_MINUTES } from "../constants.ts";
6
5
  import { findUserMfaRow } from "../db/queries.ts";
7
6
  import { invalidChallengeToken, mfaAlreadyEnabled } from "../errors.ts";
8
7
  import { verifyMfaPreauthSetupToken } from "../mfa-preauth-setup-token.ts";
@@ -10,6 +9,7 @@ import { signMfaSetupToken } from "../mfa-setup-token.ts";
10
9
  import { buildOtpauthUri } from "../otpauth-uri.ts";
11
10
  import { generateRecoveryCodes, hashRecoveryCodes } from "../recovery-codes.ts";
12
11
  import { generateTotpSecret } from "../totp.ts";
12
+ import { MFA_SETUP_TOKEN_TTL_MINUTES } from "../web/constants.ts";
13
13
 
14
14
  const ENABLE_START_PREAUTH_TENANT_REASON =
15
15
  "reads the MFA enrollment of the tenant named in the signed login/setup token, not the guest dispatch tenant";
@@ -2,13 +2,13 @@ import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import * as z from "zod";
3
3
  import { UserQueries } from "../../user/index.ts";
4
4
  import { base32Encode } from "../base32.ts";
5
- import { MFA_SETUP_TOKEN_TTL_MINUTES } from "../constants.ts";
6
5
  import { findUserMfaRow } from "../db/queries.ts";
7
6
  import { mfaAlreadyEnabled } from "../errors.ts";
8
7
  import { signMfaSetupToken } from "../mfa-setup-token.ts";
9
8
  import { buildOtpauthUri } from "../otpauth-uri.ts";
10
9
  import { generateRecoveryCodes, hashRecoveryCodes } from "../recovery-codes.ts";
11
10
  import { generateTotpSecret } from "../totp.ts";
11
+ import { MFA_SETUP_TOKEN_TTL_MINUTES } from "../web/constants.ts";
12
12
 
13
13
  export type EnableStartOptions = {
14
14
  readonly setupTokenSecret: string;
@@ -10,7 +10,6 @@ import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
10
10
  import * as z from "zod";
11
11
  import { burnToken, sessionLocaleField, sessionTimezoneField } from "../../shared/index.ts";
12
12
  import { USER_STATUS, UserQueries } from "../../user/index.ts";
13
- import { MFA_VERIFY_LOCKOUT_MINUTES, MFA_VERIFY_MAX_ATTEMPTS } from "../constants.ts";
14
13
  import { findUserMfaRow } from "../db/queries.ts";
15
14
  import { invalidChallengeToken, invalidTotpCode, tooManyAttempts } from "../errors.ts";
16
15
  import { verifyMfaChallengeToken } from "../mfa-challenge-token.ts";
@@ -21,6 +20,7 @@ import {
21
20
  } from "../mfa-verify-attempts.ts";
22
21
  import { encodeRecoveryCodes, userMfaEntity, userMfaTable } from "../schema/user-mfa.ts";
23
22
  import { verifyMfaFactor } from "../verify-factor.ts";
23
+ import { MFA_VERIFY_LOCKOUT_MINUTES, MFA_VERIFY_MAX_ATTEMPTS } from "../web/constants.ts";
24
24
 
25
25
  export type MfaVerifyOptions = {
26
26
  // Must match the secret the login handler signs mfa-challenge tokens
@@ -1,13 +1,5 @@
1
1
  export { base32Decode } from "./base32.ts";
2
2
  export { type MfaRequiredPolicy, mfaRequiredConfigHandle } from "./config.ts";
3
- export {
4
- AUTH_MFA_FEATURE,
5
- AuthMfaHandlers,
6
- AuthMfaQueries,
7
- MFA_DISABLE_SCREEN_ID,
8
- MFA_ENABLE_SCREEN_ID,
9
- MFA_REGENERATE_RECOVERY_SCREEN_ID,
10
- } from "./constants.ts";
11
3
  export { authMfaEnvSchema, mfaTokenSecretsEnvSchema } from "./env.ts";
12
4
  export type { AuthMfaFeatureOptions } from "./feature.ts";
13
5
  export { createAuthMfaFeature } from "./feature.ts";
@@ -33,3 +25,11 @@ export {
33
25
  resolveMfaTokenSecrets,
34
26
  resolveMfaTokenSecretsFromEnv,
35
27
  } from "./token-secrets.ts";
28
+ export {
29
+ AUTH_MFA_FEATURE,
30
+ AuthMfaHandlers,
31
+ AuthMfaQueries,
32
+ MFA_DISABLE_SCREEN_ID,
33
+ MFA_ENABLE_SCREEN_ID,
34
+ MFA_REGENERATE_RECOVERY_SCREEN_ID,
35
+ } from "./web/constants.ts";
@@ -7,13 +7,13 @@ import {
7
7
  type TenantId,
8
8
  } from "@cosmicdrift/kumiko-framework/engine";
9
9
  import { type MfaRequiredPolicy, mfaRequiredConfigHandle, mfaRequiredConfigKey } from "./config.ts";
10
- import {
11
- MFA_CHALLENGE_TOKEN_TTL_MINUTES,
12
- MFA_PREAUTH_SETUP_TOKEN_TTL_MINUTES,
13
- } from "./constants.ts";
14
10
  import { findUserMfaRow } from "./db/queries.ts";
15
11
  import { signMfaChallengeToken } from "./mfa-challenge-token.ts";
16
12
  import { signMfaPreauthSetupToken } from "./mfa-preauth-setup-token.ts";
13
+ import {
14
+ MFA_CHALLENGE_TOKEN_TTL_MINUTES,
15
+ MFA_PREAUTH_SETUP_TOKEN_TTL_MINUTES,
16
+ } from "./web/constants.ts";
17
17
 
18
18
  export type MfaStatusCheckResult =
19
19
  | { readonly required: false }
@@ -8,7 +8,7 @@ import {
8
8
  MFA_DISABLE_SCREEN_ID,
9
9
  MFA_ENABLE_SCREEN_ID,
10
10
  MFA_REGENERATE_RECOVERY_SCREEN_ID,
11
- } from "./constants.ts";
11
+ } from "./web/constants.ts";
12
12
 
13
13
  // Declarative TOTP-enrollment screen: mint (no input) -> reveal QR/secret/
14
14
  // recovery-codes -> confirm with a 6-digit code. `setupToken` is carried
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // Client-Feature-Factory für auth-mfa — mirrors emailPasswordClient()'s
3
2
  // shape so apps register both the same way:
4
3
  // createKumikoApp({ clientFeatures: [emailPasswordClient(), authMfaClient()] }).
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // Pure constants — client-marked so auth-mfa/web/ may import handler QNs
3
2
  // and the screen id without pulling the feature's server runtime barrel.
4
3
  // Qualified write-handler names — feature is registered as "auth-mfa", each
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // Default-Bundles für die auth-mfa Feature-UI. Merged in mit
3
2
  // authMfaClient() analog zu emailPasswordClient() aus auth-email-password.
4
3
  // Keys folgen `auth.mfa.<area>.<slug>`.
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // Public exports für die Browser-Seite des auth-mfa Features. Sub-Path-
3
2
  // Export `@cosmicdrift/kumiko-bundled-features/auth-mfa/web` — Server-Seite
4
3
  // (defineFeature) bleibt frei von React-/DOM-Deps, siehe auth-email-
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // Browser-Seite von POST /api/auth/mfa/verify — completes the two-step
3
2
  // login LoginScreen started when the server responded mfaRequired. Same
4
3
  // fetch/CSRF pattern as auth-email-password's login() (pre-session, no
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // MfaDisableDialog — confirm-with-code before turning MFA off. Uses the
3
2
  // generic Dialog primitive (unlike MfaRegenerateRecoveryDialog): disable is
4
3
  // single-step, no state to preserve after confirm, so
@@ -12,7 +11,7 @@
12
11
 
13
12
  import { useDispatcher, usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
14
13
  import { type ReactNode, useState } from "react";
15
- import { AuthMfaHandlers } from "../constants.ts";
14
+ import { AuthMfaHandlers } from "./constants.ts";
16
15
 
17
16
  export type MfaDisableDialogProps = {
18
17
  readonly open: boolean;
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // MfaRecoveryCodesReveal — one-time display of a fresh recovery-code set,
3
2
  // with an acknowledge-then-dismiss gate. Standalone so MfaRegenerateRecovery-
4
3
  // Dialog's caller can render it after the dialog closes — the codes only
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // MfaRegenerateRecoveryDialog — confirm-with-code, then the caller reveals
3
2
  // the new codes. The reveal itself can't live inside this Dialog: Dialog
4
3
  // closes in a `finally` right after onConfirm resolves (see profile-screen.
@@ -9,7 +8,7 @@
9
8
 
10
9
  import { useDispatcher, usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
11
10
  import { type ReactNode, useState } from "react";
12
- import { AuthMfaHandlers } from "../constants.ts";
11
+ import { AuthMfaHandlers } from "./constants.ts";
13
12
 
14
13
  export type MfaRegenerateRecoveryDialogProps = {
15
14
  readonly open: boolean;
@@ -1,6 +1,3 @@
1
- // @runtime client
2
- // Consumers that type-check this source never include the ambient declaration on their own.
3
- /// <reference path="./qrcode-browser.d.ts" />
4
1
  // Pre-auth twin of the declarative auth-mfa-enable secretMint screen: a user
5
2
  // blocked at login by MFA enforcement and not yet enrolled lands here
6
3
  // straight out of the login flow — there is no session yet. Identity comes
@@ -17,9 +14,6 @@
17
14
  // stays "unauthenticated" until the next reload.
18
15
 
19
16
  import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
20
- // qrcode's package.json#browser remap avoids Node-only deps (yargs/pngjs)
21
- // for bundlers that honor it — Metro doesn't, hence the explicit subpath.
22
- import QRCode from "qrcode/lib/browser.js";
23
17
  import { type FormEvent, type ReactNode, useState } from "react";
24
18
  // kumiko-lint-ignore cross-feature-import client-only component, the feature's server barrel has no web/ re-export
25
19
  import { AuthCard } from "../../auth-email-password/web/index.ts";
@@ -29,7 +23,7 @@ type SetupState = {
29
23
  readonly setupToken: string;
30
24
  readonly secretParam: string;
31
25
  readonly recoveryCodes: readonly string[];
32
- readonly qrSvg: string;
26
+ readonly otpauthUri: string;
33
27
  };
34
28
 
35
29
  // otpauth:// URIs put the secret in the query string — extract it for the
@@ -80,7 +74,7 @@ export function MfaSetupPreauthScreen({
80
74
  onCancel,
81
75
  }: MfaSetupPreauthScreenProps): ReactNode {
82
76
  const t = useTranslation();
83
- const { Button, Banner, Field, Form, Input, Section } = usePrimitives();
77
+ const { Button, Banner, Field, Form, Input, Section, SecretReveal } = usePrimitives();
84
78
 
85
79
  const [setup, setSetup] = useState<SetupState | null>(null);
86
80
  const [acknowledged, setAcknowledged] = useState(false);
@@ -100,18 +94,11 @@ export function MfaSetupPreauthScreen({
100
94
  setRetryAfterSeconds(res.error.retryAfterSeconds ?? null);
101
95
  return;
102
96
  }
103
- // errorCorrectionLevel "H" (~30% redundancy) — more resilient to
104
- // camera/lighting issues than the default, no downside for a code
105
- // this short-lived.
106
- const qrSvg = await QRCode.toString(res.data.otpauthUri, {
107
- type: "svg",
108
- errorCorrectionLevel: "H",
109
- });
110
97
  setSetup({
111
98
  setupToken: res.data.setupToken,
112
99
  secretParam: extractSecret(res.data.otpauthUri),
113
100
  recoveryCodes: res.data.recoveryCodes,
114
- qrSvg,
101
+ otpauthUri: res.data.otpauthUri,
115
102
  });
116
103
  setAcknowledged(false);
117
104
  setCode("");
@@ -192,13 +179,24 @@ export function MfaSetupPreauthScreen({
192
179
  <Form onSubmit={onSubmit}>
193
180
  <Section testId="mfa-setup-preauth-setup">
194
181
  <div className="flex flex-col items-center gap-2 text-center">
195
- <span className="text-sm font-semibold">{t("auth.mfa.enable.scanTitle")}</span>
196
- {/* qrcode's own SVG string output, not user input — safe to inline */}
197
- <div
198
- className="h-40 w-40"
199
- // biome-ignore lint/security/noDangerouslySetInnerHtml: qrcode-generated SVG, no user input
200
- dangerouslySetInnerHTML={{ __html: setup.qrSvg }}
201
- />
182
+ {SecretReveal !== undefined ? (
183
+ <SecretReveal
184
+ values={[
185
+ {
186
+ label: t("auth.mfa.enable.scanTitle"),
187
+ value: setup.otpauthUri,
188
+ qr: true,
189
+ copyable: false,
190
+ multiline: false,
191
+ },
192
+ ]}
193
+ copyLabel={t("kumiko.secretMint.copy")}
194
+ copiedLabel={t("kumiko.secretMint.copied")}
195
+ testId="mfa-setup-preauth-qr"
196
+ />
197
+ ) : (
198
+ <span className="text-sm font-semibold">{t("auth.mfa.enable.scanTitle")}</span>
199
+ )}
202
200
  <span className="text-xs text-muted-foreground">
203
201
  {t("auth.mfa.enable.manualEntry")}
204
202
  </span>
@@ -1,4 +1,3 @@
1
- // @runtime client
2
1
  // Login-Challenge-Step, gerendert wenn LoginScreen's onMfaChallenge feuert
3
2
  // (/auth/login antwortete mfaRequired). Stilistisch wie login-screen.tsx:
4
3
  // useState + direkter fetch-Call, kein Dispatcher — es existiert noch kein
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "version": "0.379.0",
4
+ "type": "fix",
5
+ "title": "Late Stripe events are dropped",
6
+ "detail": "The Stripe plugin passes event.created as providerEventAt, process-event stores it as providerEventAtIso in the subscription event and drops a created, updated or canceled event that is older than one already stored (result stale: true). A canceled subscription is no longer reactivated by a late delivery. Providers without a timestamp are unaffected; no migration."
7
+ },
8
+ {
9
+ "version": "0.379.0",
10
+ "type": "fix",
11
+ "title": "Contract mails reach users with encrypted email addresses",
12
+ "detail": "With a KMS configured, the contract confirmation and the receipt for a termination from the user account used the stored, encrypted email address as recipient. The mail channel refuses such addresses, so neither mail was sent and the send job failed after its retries. Both now decrypt the address first; an erased user gets no mail, as before for deleted users."
13
+ },
14
+ {
15
+ "version": "0.379.0",
16
+ "type": "improvement",
17
+ "title": "\"This cancellation was not me\" link in the public cancellation receipt",
18
+ "detail": "When a public § 312k declaration matches an account, the receipt mail carries a one-time link (random token, only its sha256 is stored as revocationTokenHash in the declared event). The link opens a confirmation page; confirming with POST takes the cancellation back until it takes effect, resumes the provider subscription through the new optional SubscriptionProviderPlugin.resumeSubscription (Stripe sets cancel_at_period_end to false) or asks the operator to do it by hand, appends contract-termination.revoked and notifies the operator. Unknown requests and wrong tokens get the same answer; after the effective date the page says it is too late. Declarations stored before this release have no token and cannot be revoked by link."
19
+ },
2
20
  {
3
21
  "version": "0.377.0",
4
22
  "type": "improvement",
@@ -11,13 +11,13 @@ import {
11
11
  UnconfiguredError,
12
12
  UnprocessableError,
13
13
  } from "@cosmicdrift/kumiko-framework/errors";
14
+ import { getSubscriptionForTenant } from "./get-subscription-for-tenant.ts";
15
+ import type { BillingPlanCatalog, SubscriptionProviderPlugin } from "./types.ts";
14
16
  import {
15
17
  BILLING_FOUNDATION_FEATURE,
16
18
  isSubscriptionBlockingCheckout,
17
19
  SUBSCRIPTION_PROVIDER_EXTENSION,
18
- } from "./constants.ts";
19
- import { getSubscriptionForTenant } from "./get-subscription-for-tenant.ts";
20
- import type { BillingPlanCatalog, SubscriptionProviderPlugin } from "./types.ts";
20
+ } from "./web/constants.ts";
21
21
 
22
22
  /** Narrows a `readonly string[]` to the non-empty tuple shape `z.enum`
23
23
  * needs. Callers only reach this with a catalog's `plans` — the feature
@@ -1,12 +1,12 @@
1
1
  import { createHash } from "node:crypto";
2
- import type { ConsentLocale } from "./consent-locale.ts";
2
+ import type { ConsentLocale } from "../web/consumer-protection/consent-locale.ts";
3
3
 
4
4
  export {
5
5
  CONSENT_LOCALES,
6
6
  type ConsentLocale,
7
7
  FALLBACK_CONSENT_LOCALE,
8
8
  resolveConsentLocale,
9
- } from "./consent-locale.ts";
9
+ } from "../web/consumer-protection/consent-locale.ts";
10
10
 
11
11
  // Legal texts, deliberately inline de/en: the wording is part of the recorded
12
12
  // consent, so it cannot follow the en-only i18n convention.
@@ -15,7 +15,6 @@ import * as z from "zod";
15
15
  import { requireTemplateResolver, TEXT_BLOCK_KIND } from "../../template-resolver/index.ts";
16
16
  import { UserQueries } from "../../user/index.ts";
17
17
  import { paymentAggregateId, subscriptionAggregateId } from "../aggregate-id.ts";
18
- import { CONTRACT_CONFIRMATION_NOTIFICATION_TYPE } from "../constants.ts";
19
18
  import {
20
19
  CHECKOUT_CONSENT_RECORDED_EVENT_QN,
21
20
  type CheckoutConsentRecordedPayload,
@@ -27,8 +26,10 @@ import {
27
26
  SUBSCRIPTION_AGGREGATE_TYPE,
28
27
  } from "../events.ts";
29
28
  import type { ConsumerProtectionOptions, ResolvedBillingFoundationOptions } from "../types.ts";
29
+ import { CONTRACT_CONFIRMATION_NOTIFICATION_TYPE } from "../web/constants.ts";
30
30
  import { contractConfirmationVariables } from "./confirmation-mail.ts";
31
31
  import { resolveConsentLocale } from "./consent-text.ts";
32
+ import { openStoredUserEmail } from "./stored-user-email.ts";
32
33
 
33
34
  export const issueContractConfirmationSchema = z
34
35
  .object({
@@ -142,7 +143,14 @@ export function createIssueContractConfirmationHandler(
142
143
  id: consent.actorUserId,
143
144
  }),
144
145
  );
145
- if (!recipient.success || recipient.data.isDeleted === true) {
146
+ const recipientEmail =
147
+ recipient.success && recipient.data.isDeleted !== true
148
+ ? await openStoredUserEmail(
149
+ recipient.data.email,
150
+ "billing-foundation:issue-contract-confirmation",
151
+ )
152
+ : null;
153
+ if (!recipient.success || recipientEmail === null) {
146
154
  ctx.log?.warn(
147
155
  `[billing-foundation:issue-contract-confirmation] recipient of consent ${payload.consentId} not found; no mail sent`,
148
156
  );
@@ -219,7 +227,7 @@ export function createIssueContractConfirmationHandler(
219
227
  await stream.appendOne({ type: CONTRACT_CONFIRMATION_ISSUED_EVENT_QN, payload: issued });
220
228
 
221
229
  await ctx.notify(CONTRACT_CONFIRMATION_NOTIFICATION_TYPE, {
222
- route: { email: recipient.data.email },
230
+ route: { email: recipientEmail },
223
231
  data: variables,
224
232
  locale,
225
233
  priority: "critical",
@@ -4,7 +4,12 @@ import {
4
4
  type TemplateVariables,
5
5
  templateVariable,
6
6
  } from "@cosmicdrift/kumiko-framework/engine";
7
- import { mailHeading, mailParagraph, mailRepeatedRows } from "../../shared/index.ts";
7
+ import {
8
+ mailHeading,
9
+ mailParagraph,
10
+ mailParagraphWithLink,
11
+ mailRepeatedRows,
12
+ } from "../../shared/index.ts";
8
13
  import { CONFIRMATION_LABELS } from "./confirmation-mail.ts";
9
14
  import { CONSENT_LOCALES, CONSENT_TEXTS, type ConsentLocale } from "./consent-text.ts";
10
15
  import { TERMINATION_TEXTS } from "./termination-texts.ts";
@@ -21,6 +26,7 @@ export const TERMINATION_RECEIPT_VARIABLES: TemplateVariables = {
21
26
  requestId: templateVariable.text({ required: true }),
22
27
  details: textRows(),
23
28
  operatorEmail: templateVariable.text({ required: true }),
29
+ revokeUrl: templateVariable.link(),
24
30
  };
25
31
 
26
32
  export const OPERATOR_NOTICE_VARIABLES: TemplateVariables = {
@@ -63,6 +69,10 @@ export function terminationReceiptTemplate(): NotificationLocalizedTemplate {
63
69
  mailRepeatedRows("details", "text"),
64
70
  mailParagraph(texts.receiptNextSteps),
65
71
  mailParagraph(texts.receiptRevoke(OPERATOR_EMAIL_SLOT)),
72
+ mailParagraphWithLink(texts.receiptNotMe, texts.receiptNotMeLink, "revokeUrl").replace(
73
+ "<p>",
74
+ '<p data-if="revokeUrl">',
75
+ ),
66
76
  mailParagraph(`${texts.contact} {operatorEmail}`),
67
77
  ].join(""),
68
78
  };
@@ -1,6 +1,5 @@
1
1
  import type { FeatureRegistrar } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import { paymentAggregateId, subscriptionAggregateId } from "../aggregate-id.ts";
3
- import { SubscriptionFoundationHandlers, SubscriptionStatuses } from "../constants.ts";
4
3
  import {
5
4
  CHECKOUT_CONSENT_RECORDED_EVENT_SHORT,
6
5
  CONTRACT_CONFIRMATION_ISSUED_EVENT_SHORT,
@@ -12,6 +11,7 @@ import {
12
11
  SUBSCRIPTION_UPDATED_EVENT_QN,
13
12
  } from "../events.ts";
14
13
  import type { ConsumerProtectionOptions, ResolvedBillingFoundationOptions } from "../types.ts";
14
+ import { SubscriptionFoundationHandlers, SubscriptionStatuses } from "../web/constants.ts";
15
15
  import { createIssueContractConfirmationHandler } from "./issue-confirmation.ts";
16
16
  import { registerConsumerProtectionMails } from "./mail-notifications.ts";
17
17
  import { registerContractTermination } from "./register-termination.ts";
@@ -1,15 +1,17 @@
1
1
  import type { FeatureRegistrar } from "@cosmicdrift/kumiko-framework/engine";
2
- import { SubscriptionCancelTimings, SubscriptionFoundationHandlers } from "../constants.ts";
3
2
  import {
4
3
  CONTRACT_TERMINATION_DECLARED_EVENT_QN,
5
4
  CONTRACT_TERMINATION_DECLARED_EVENT_SHORT,
6
5
  CONTRACT_TERMINATION_REQUESTED_EVENT_SHORT,
6
+ CONTRACT_TERMINATION_REVOKED_EVENT_SHORT,
7
7
  CONTRACT_TERMINATION_UNMATCHED_EVENT_SHORT,
8
8
  contractTerminationDeclaredPayloadSchema,
9
9
  contractTerminationRequestedPayloadSchema,
10
+ contractTerminationRevokedPayloadSchema,
10
11
  contractTerminationUnmatchedPayloadSchema,
11
12
  } from "../events.ts";
12
13
  import type { ConsumerProtectionOptions, ResolvedBillingFoundationOptions } from "../types.ts";
14
+ import { SubscriptionCancelTimings, SubscriptionFoundationHandlers } from "../web/constants.ts";
13
15
  import {
14
16
  createDeclareContractTerminationHandler,
15
17
  createRecordContractTerminationHandler,
@@ -20,6 +22,10 @@ import {
20
22
  createRequestContractTerminationHandler,
21
23
  createTerminateContractHandler,
22
24
  } from "./termination-request.ts";
25
+ import {
26
+ createRecordContractTerminationRevocationHandler,
27
+ createRevokeContractTerminationHandler,
28
+ } from "./termination-revoke.ts";
23
29
 
24
30
  export function registerContractTermination(
25
31
  r: FeatureRegistrar,
@@ -36,6 +42,9 @@ export function registerContractTermination(
36
42
  contractTerminationDeclaredPayloadSchema,
37
43
  { piiFields: "none" },
38
44
  );
45
+ r.defineEvent(CONTRACT_TERMINATION_REVOKED_EVENT_SHORT, contractTerminationRevokedPayloadSchema, {
46
+ piiFields: "none",
47
+ });
39
48
  r.defineEvent(
40
49
  CONTRACT_TERMINATION_UNMATCHED_EVENT_SHORT,
41
50
  contractTerminationUnmatchedPayloadSchema,
@@ -47,6 +56,8 @@ export function registerContractTermination(
47
56
  r.writeHandler(createRecordUnmatchedContractTerminationHandler());
48
57
  r.writeHandler(createRequestContractTerminationHandler(options, consumerProtection));
49
58
  r.writeHandler(createTerminateContractHandler(options, consumerProtection));
59
+ r.writeHandler(createRevokeContractTerminationHandler());
60
+ r.writeHandler(createRecordContractTerminationRevocationHandler(options, consumerProtection));
50
61
 
51
62
  // The provider cancel of a public declaration runs here, not in the
52
63
  // request: matched and unmatched requests then do the same work and the
@@ -0,0 +1,12 @@
1
+ import { PII_ERASED_SENTINEL } from "@cosmicdrift/kumiko-framework/crypto";
2
+ import { decryptStoredPii } from "../../shared/index.ts";
3
+
4
+ // findForAuth returns the stored column, which is ciphertext under an active KMS;
5
+ // channel-email refuses to mail a ciphertext address. Null for an erased subject.
6
+ export async function openStoredUserEmail(
7
+ stored: string,
8
+ fallbackRequestId: string,
9
+ ): Promise<string | null> {
10
+ const email = await decryptStoredPii(stored, "email", fallbackRequestId);
11
+ return email === PII_ERASED_SENTINEL ? null : email;
12
+ }
@@ -16,6 +16,8 @@ export type TerminationReceiptVariables = {
16
16
  readonly requestId: string;
17
17
  readonly details: readonly TextRow[];
18
18
  readonly operatorEmail: string;
19
+ /** Only a matched declaration carries the "this was not me" link. */
20
+ readonly revokeUrl?: string;
19
21
  };
20
22
 
21
23
  /** Variables of the operator notice template. */
@@ -92,9 +94,11 @@ export type TerminationReceiptArgs = {
92
94
  readonly receivedAtIso: string;
93
95
  readonly declaration: ReceiptDeclaration;
94
96
  readonly operatorEmail: string;
97
+ readonly revokeUrl?: string;
95
98
  };
96
99
 
97
- /** The content must not depend on whether (or how) the declaration matched a contract. */
100
+ /** Apart from the revoke link, the content must not depend on whether the declaration
101
+ * matched a contract; the link only goes to the address the declarant entered. */
98
102
  export function terminationReceiptVariables(
99
103
  args: TerminationReceiptArgs,
100
104
  ): TerminationReceiptVariables {
@@ -105,6 +109,7 @@ export function terminationReceiptVariables(
105
109
  requestId: args.requestId,
106
110
  details: declarationLines(args.declaration, args.locale),
107
111
  operatorEmail: args.operatorEmail,
112
+ ...(args.revokeUrl !== undefined && { revokeUrl: args.revokeUrl }),
108
113
  };
109
114
  }
110
115
 
@@ -1,8 +1,8 @@
1
1
  import type { HandlerContext } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
3
- import { CONTRACT_TERMINATION_OPERATOR_NOTIFICATION_TYPE } from "../constants.ts";
4
3
  import type { ProviderCancelOutcome } from "../events.ts";
5
4
  import type { ConsumerProtectionOptions } from "../types.ts";
5
+ import { CONTRACT_TERMINATION_OPERATOR_NOTIFICATION_TYPE } from "../web/constants.ts";
6
6
  import type { ConsentLocale } from "./consent-text.ts";
7
7
  import { type OperatorNoticeDeclaration, operatorNoticeVariables } from "./termination-mail.ts";
8
8
  import type { OperatorNoticeReason } from "./termination-texts.ts";