@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (643) hide show
  1. package/LICENSE +21 -57
  2. package/dist/agent-tools/tool-catalog.js +1 -1
  3. package/dist/agent-tools/tool-dispatch.d.ts +7 -7
  4. package/dist/agent-tools/tool-dispatch.js +9 -9
  5. package/dist/audit/handlers/audit-events.js +1 -1
  6. package/dist/audit/screens.js +1 -1
  7. package/dist/auth-email-password/feature.js +1 -1
  8. package/dist/auth-email-password/handlers/change-password.write.js +3 -3
  9. package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
  10. package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
  11. package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
  12. package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
  13. package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
  14. package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
  15. package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
  16. package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
  17. package/dist/auth-email-password/handlers/login.write.js +1 -1
  18. package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
  19. package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
  20. package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
  21. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
  22. package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
  23. package/dist/auth-email-password/index.js +5 -5
  24. package/dist/auth-email-password/lockout-store.js +1 -1
  25. package/dist/auth-email-password/seeding.d.ts +42 -45
  26. package/dist/auth-email-password/seeding.js +51 -53
  27. package/dist/auth-email-password/signup-token-store.js +8 -8
  28. package/dist/auth-email-password/testing.js +3 -3
  29. package/dist/auth-email-password/web/auth-client.d.ts +2 -2
  30. package/dist/auth-email-password/web/auth-client.js +36 -37
  31. package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
  32. package/dist/auth-email-password/web/auth-gate.js +15 -16
  33. package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
  34. package/dist/auth-email-password/web/client-plugin.js +4 -5
  35. package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
  36. package/dist/auth-email-password/web/constants.js +3 -3
  37. package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
  38. package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
  39. package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
  40. package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
  41. package/dist/auth-email-password/web/index.js +5 -5
  42. package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
  43. package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
  44. package/dist/auth-email-password/web/login-screen.d.ts +1 -1
  45. package/dist/auth-email-password/web/login-screen.js +2 -3
  46. package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
  47. package/dist/auth-email-password/web/reset-password-screen.js +12 -13
  48. package/dist/auth-email-password/web/session.d.ts +10 -9
  49. package/dist/auth-email-password/web/session.js +28 -29
  50. package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
  51. package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
  52. package/dist/auth-email-password/web/signup-screen.js +13 -13
  53. package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
  54. package/dist/auth-email-password/web/tenant-switcher.js +21 -22
  55. package/dist/auth-email-password/web/use-shell-user.js +12 -13
  56. package/dist/auth-email-password/web/user-menu.d.ts +4 -4
  57. package/dist/auth-email-password/web/user-menu.js +12 -13
  58. package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
  59. package/dist/auth-email-password/web/verify-email-screen.js +9 -10
  60. package/dist/auth-foundation/boot-checks.js +4 -4
  61. package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
  62. package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
  63. package/dist/auth-foundation/types.js +2 -2
  64. package/dist/auth-mfa/feature-exports.d.ts +2 -2
  65. package/dist/auth-mfa/feature.js +8 -0
  66. package/dist/auth-mfa/handlers/disable.write.js +3 -3
  67. package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
  68. package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
  69. package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
  70. package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
  71. package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
  72. package/dist/auth-mfa/handlers/verify.write.js +1 -1
  73. package/dist/auth-mfa/token-secrets.js +1 -1
  74. package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
  75. package/dist/auth-mfa/web/client-plugin.js +1 -1
  76. package/dist/auth-mfa/web/i18n.js +8 -4
  77. package/dist/auth-mfa/web/index.js +4 -4
  78. package/dist/auth-mfa/web/mfa-client.js +17 -16
  79. package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
  80. package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
  81. package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
  82. package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
  83. package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
  84. package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
  85. package/dist/billing-foundation/aggregate-id.d.ts +5 -5
  86. package/dist/billing-foundation/aggregate-id.js +10 -11
  87. package/dist/billing-foundation/checkout-core.d.ts +9 -14
  88. package/dist/billing-foundation/checkout-core.js +24 -39
  89. package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
  90. package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
  91. package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
  92. package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
  93. package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
  94. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
  95. package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
  96. package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
  97. package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
  98. package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
  99. package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
  100. package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
  101. package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
  102. package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
  103. package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
  104. package/dist/billing-foundation/entities.js +27 -27
  105. package/dist/billing-foundation/events.d.ts +1 -0
  106. package/dist/billing-foundation/events.js +19 -17
  107. package/dist/billing-foundation/feature.js +45 -44
  108. package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
  109. package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
  110. package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
  111. package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
  112. package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
  113. package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
  114. package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
  115. package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
  116. package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
  117. package/dist/billing-foundation/handlers/process-event.write.js +28 -22
  118. package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
  119. package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
  120. package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
  121. package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
  122. package/dist/billing-foundation/i18n.js +22 -0
  123. package/dist/billing-foundation/index.d.ts +1 -1
  124. package/dist/billing-foundation/plan-catalog.d.ts +21 -5
  125. package/dist/billing-foundation/plan-catalog.js +25 -16
  126. package/dist/billing-foundation/plan-switch.d.ts +12 -0
  127. package/dist/billing-foundation/plan-switch.js +60 -0
  128. package/dist/billing-foundation/projection.d.ts +15 -11
  129. package/dist/billing-foundation/projection.js +38 -37
  130. package/dist/billing-foundation/subscription-tier-sync.js +3 -3
  131. package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
  132. package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
  133. package/dist/billing-foundation/types.d.ts +97 -42
  134. package/dist/billing-foundation/types.js +29 -20
  135. package/dist/billing-foundation/validate-options.js +17 -0
  136. package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
  137. package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
  138. package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
  139. package/dist/billing-foundation/web/constants.d.ts +4 -0
  140. package/dist/billing-foundation/web/constants.js +4 -0
  141. package/dist/billing-foundation/web/plan-price.d.ts +15 -0
  142. package/dist/billing-foundation/web/plan-price.js +32 -0
  143. package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
  144. package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
  145. package/dist/cap-counter/aggregate-id.js +8 -9
  146. package/dist/cap-counter/cap-reservation.js +5 -1
  147. package/dist/cap-counter/constants.js +11 -12
  148. package/dist/cap-counter/enforce-cap.d.ts +59 -62
  149. package/dist/cap-counter/enforce-cap.js +49 -49
  150. package/dist/cap-counter/entity.js +29 -29
  151. package/dist/cap-counter/feature.js +34 -35
  152. package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
  153. package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
  154. package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
  155. package/dist/cap-counter/stock-cap-guard.js +8 -2
  156. package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
  157. package/dist/channel-email/feature.js +1 -1
  158. package/dist/channel-email/smtp-transport.d.ts +18 -17
  159. package/dist/channel-email/smtp-transport.js +24 -21
  160. package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
  161. package/dist/compliance-profiles/feature.js +4 -4
  162. package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
  163. package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
  164. package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
  165. package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
  166. package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
  167. package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
  168. package/dist/compliance-profiles/schema/profile-selection.js +18 -23
  169. package/dist/compliance-profiles/seeding.js +14 -15
  170. package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
  171. package/dist/compliance-profiles-ops/index.js +2 -2
  172. package/dist/config/handlers/cascade.query.d.ts +5 -0
  173. package/dist/config/handlers/cascade.query.js +4 -3
  174. package/dist/config/handlers/readiness.query.d.ts +4 -4
  175. package/dist/config/handlers/readiness.query.js +1 -1
  176. package/dist/config/handlers/reencrypt.job.js +4 -5
  177. package/dist/config/handlers/set.write.js +4 -4
  178. package/dist/config/handlers/values.query.d.ts +5 -0
  179. package/dist/config/handlers/values.query.js +4 -3
  180. package/dist/config/resolver.js +4 -4
  181. package/dist/config/table.js +10 -10
  182. package/dist/config/write-helpers.d.ts +1 -0
  183. package/dist/config/write-helpers.js +19 -10
  184. package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
  185. package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
  186. package/dist/custom-fields/aggregate-id.d.ts +12 -13
  187. package/dist/custom-fields/aggregate-id.js +16 -17
  188. package/dist/custom-fields/entity.js +49 -47
  189. package/dist/custom-fields/events.js +7 -8
  190. package/dist/custom-fields/feature.d.ts +14 -14
  191. package/dist/custom-fields/feature.js +53 -54
  192. package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
  193. package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
  194. package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
  195. package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
  196. package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
  197. package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
  198. package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
  199. package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
  200. package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
  201. package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
  202. package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
  203. package/dist/custom-fields/lib/field-access.js +2 -2
  204. package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
  205. package/dist/custom-fields/lib/quota.js +1 -1
  206. package/dist/custom-fields/lib/value-schema.js +10 -12
  207. package/dist/custom-fields/run-retention.js +3 -3
  208. package/dist/custom-fields/schemas.js +14 -14
  209. package/dist/custom-fields/web/client-plugin.js +2 -5
  210. package/dist/custom-fields/web/constants.js +2 -2
  211. package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
  212. package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
  213. package/dist/custom-fields/wire-for-entity.js +65 -67
  214. package/dist/custom-fields/wire-user-data-rights.js +3 -3
  215. package/dist/data-retention/_internal/parse-override.js +2 -3
  216. package/dist/data-retention/feature.js +11 -18
  217. package/dist/data-retention/handlers/policy-for.query.js +6 -6
  218. package/dist/data-retention/keep-for.d.ts +7 -7
  219. package/dist/data-retention/keep-for.js +15 -15
  220. package/dist/data-retention/override-schema.d.ts +3 -4
  221. package/dist/data-retention/override-schema.js +13 -15
  222. package/dist/data-retention/presets.d.ts +4 -5
  223. package/dist/data-retention/presets.js +18 -23
  224. package/dist/data-retention/resolve-tenant-preset.js +17 -16
  225. package/dist/data-retention/resolver.d.ts +12 -12
  226. package/dist/data-retention/resolver.js +24 -23
  227. package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
  228. package/dist/data-retention/run-retention-cleanup.js +61 -51
  229. package/dist/data-retention/schema/tenant-retention-override.js +13 -11
  230. package/dist/delivery/channel-context.js +6 -3
  231. package/dist/delivery/db/queries/preferences.js +2 -2
  232. package/dist/delivery/delivery-service.js +22 -7
  233. package/dist/delivery/feature.js +2 -2
  234. package/dist/delivery/handlers/log.query.js +1 -1
  235. package/dist/delivery/handlers/preferences.query.d.ts +1 -1
  236. package/dist/delivery/handlers/preferences.query.js +20 -1
  237. package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
  238. package/dist/delivery/tables.js +9 -8
  239. package/dist/delivery/unsubscribe-link.d.ts +3 -1
  240. package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
  241. package/dist/delivery/unsubscribe-page-strings.js +1 -0
  242. package/dist/delivery/unsubscribe-page.d.ts +2 -0
  243. package/dist/delivery/unsubscribe-page.js +5 -0
  244. package/dist/delivery/unsubscribe.js +29 -11
  245. package/dist/document-ingest-foundation/entity.js +4 -4
  246. package/dist/document-ingest-foundation/events.js +2 -2
  247. package/dist/document-ingest-foundation/feature.js +2 -2
  248. package/dist/document-ingest-foundation/pages.js +1 -1
  249. package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
  250. package/dist/feature-toggles/compose-tier-resolver.js +1 -1
  251. package/dist/feature-toggles/feature.js +1 -1
  252. package/dist/feature-toggles/global-feature-state-table.js +1 -1
  253. package/dist/feature-toggles/handlers/registered.query.js +5 -5
  254. package/dist/feature-toggles/toggle-sync-signal.js +1 -1
  255. package/dist/feature-toggles/web/constants.js +1 -1
  256. package/dist/file-derivatives/feature.d.ts +1 -1
  257. package/dist/file-derivatives/feature.js +1 -1
  258. package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
  259. package/dist/file-derivatives/presets.js +1 -1
  260. package/dist/file-foundation/feature.js +6 -6
  261. package/dist/file-foundation/index.d.ts +1 -1
  262. package/dist/file-foundation/index.js +1 -1
  263. package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
  264. package/dist/file-foundation/read-file-ref-content.js +6 -1
  265. package/dist/file-provider-inmemory/feature.d.ts +1 -1
  266. package/dist/file-provider-inmemory/feature.js +16 -16
  267. package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
  268. package/dist/file-provider-s3/feature.js +16 -16
  269. package/dist/file-provider-s3/lib/s3-provider.js +6 -6
  270. package/dist/files/feature.js +6 -6
  271. package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
  272. package/dist/files-tenant-data/hooks.js +24 -26
  273. package/dist/files-tenant-data/index.js +1 -1
  274. package/dist/folders/feature.d.ts +1 -1
  275. package/dist/folders/web/folder-manager.js +2 -2
  276. package/dist/folders/web/tree.js +5 -5
  277. package/dist/form-draft/db/queries/cleanup.js +3 -3
  278. package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
  279. package/dist/form-draft/decrypt-draft.js +5 -1
  280. package/dist/form-draft/entity.js +3 -3
  281. package/dist/form-draft/feature.js +4 -5
  282. package/dist/form-draft/handlers/discard.write.js +1 -1
  283. package/dist/form-draft/release-file-refs.js +6 -6
  284. package/dist/form-draft/schemas.js +3 -3
  285. package/dist/form-draft/web/constants.js +0 -2
  286. package/dist/host-routing/dispatch.js +11 -20
  287. package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
  288. package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
  289. package/dist/inbound-mail-foundation/connect-routes.js +4 -3
  290. package/dist/inbound-mail-foundation/constants.d.ts +22 -24
  291. package/dist/inbound-mail-foundation/constants.js +30 -33
  292. package/dist/inbound-mail-foundation/entities.d.ts +12 -12
  293. package/dist/inbound-mail-foundation/entities.js +47 -48
  294. package/dist/inbound-mail-foundation/events.d.ts +4 -3
  295. package/dist/inbound-mail-foundation/events.js +50 -47
  296. package/dist/inbound-mail-foundation/feature.js +39 -39
  297. package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
  298. package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
  299. package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
  300. package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
  301. package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
  302. package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
  303. package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
  304. package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
  305. package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
  306. package/dist/inbound-mail-foundation/i18n.js +0 -1
  307. package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
  308. package/dist/inbound-mail-foundation/oauth-state.js +11 -10
  309. package/dist/inbound-mail-foundation/projection.d.ts +4 -4
  310. package/dist/inbound-mail-foundation/projection.js +31 -29
  311. package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
  312. package/dist/inbound-mail-foundation/provider-factory.js +9 -9
  313. package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
  314. package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
  315. package/dist/inbound-mail-foundation/screens.js +0 -3
  316. package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
  317. package/dist/inbound-mail-foundation/types.d.ts +49 -49
  318. package/dist/inbound-mail-foundation/types.js +21 -21
  319. package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
  320. package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
  321. package/dist/inbound-provider-imap/credential-document.js +13 -13
  322. package/dist/inbound-provider-imap/feature.d.ts +2 -2
  323. package/dist/inbound-provider-imap/feature.js +42 -40
  324. package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
  325. package/dist/inbound-provider-imap/imap-client.js +20 -19
  326. package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
  327. package/dist/inbound-provider-inmemory/feature.js +19 -19
  328. package/dist/jobs/db/queries/retention.js +2 -2
  329. package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
  330. package/dist/jobs/events.js +1 -1
  331. package/dist/jobs/feature.d.ts +1 -0
  332. package/dist/jobs/feature.js +13 -10
  333. package/dist/jobs/handlers/detail.query.js +4 -4
  334. package/dist/jobs/handlers/list.query.js +1 -1
  335. package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
  336. package/dist/jobs/handlers/reindex-entity.job.js +1 -1
  337. package/dist/jobs/handlers/retry.write.js +1 -1
  338. package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
  339. package/dist/jobs/handlers/tenant-failures.query.js +45 -41
  340. package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
  341. package/dist/jobs/handlers/tenant-runs.query.js +54 -50
  342. package/dist/jobs/job-instant.js +1 -1
  343. package/dist/jobs/job-run-logger.js +15 -15
  344. package/dist/jobs/job-run-table.js +3 -3
  345. package/dist/jobs/screens.js +1 -1
  346. package/dist/jobs/tenant-job-failure-table.js +1 -1
  347. package/dist/jobs/tenant-job-run-table.js +1 -1
  348. package/dist/ledger/entity.js +5 -5
  349. package/dist/ledger/feature.js +3 -3
  350. package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
  351. package/dist/ledger/recurring.js +12 -12
  352. package/dist/ledger/schemas.js +1 -1
  353. package/dist/ledger/web/constants.js +2 -2
  354. package/dist/ledger/web/index.js +7 -7
  355. package/dist/legal-pages/feature.d.ts +4 -4
  356. package/dist/legal-pages/feature.js +25 -26
  357. package/dist/legal-pages/markdown.js +3 -3
  358. package/dist/legal-pages/web/client-plugin.js +23 -24
  359. package/dist/legal-pages/web/index.js +0 -1
  360. package/dist/mail-foundation/feature.d.ts +5 -5
  361. package/dist/mail-foundation/feature.js +27 -25
  362. package/dist/mail-transport-inmemory/feature.d.ts +4 -4
  363. package/dist/mail-transport-inmemory/feature.js +27 -28
  364. package/dist/mail-transport-smtp/feature.js +20 -20
  365. package/dist/managed-pages/branding.js +6 -6
  366. package/dist/managed-pages/feature.d.ts +26 -26
  367. package/dist/managed-pages/feature.js +34 -34
  368. package/dist/managed-pages/handlers/by-slug.query.js +5 -6
  369. package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
  370. package/dist/managed-pages/handlers/set.write.js +5 -7
  371. package/dist/managed-pages/screens/page-screens.js +11 -11
  372. package/dist/managed-pages/seeding.js +8 -8
  373. package/dist/managed-pages/table.js +13 -12
  374. package/dist/managed-pages/web/client-plugin.d.ts +1 -1
  375. package/dist/managed-pages/web/client-plugin.js +5 -5
  376. package/dist/managed-pages/web/i18n.js +1 -1
  377. package/dist/notes-history/entity.js +4 -4
  378. package/dist/notes-history/feature.d.ts +2 -2
  379. package/dist/notes-history-user-data/hooks.js +1 -1
  380. package/dist/page-render/layout.js +9 -9
  381. package/dist/page-render/markdown.js +11 -11
  382. package/dist/page-render/security-headers.js +7 -6
  383. package/dist/personal-access-tokens/feature.d.ts +1 -1
  384. package/dist/personal-access-tokens/feature.js +9 -5
  385. package/dist/personal-access-tokens/roles.js +2 -2
  386. package/dist/readiness/handlers/status.query.js +3 -3
  387. package/dist/renderer-foundation/api.js +12 -13
  388. package/dist/renderer-foundation/constants.js +2 -2
  389. package/dist/renderer-foundation/feature.js +7 -7
  390. package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
  391. package/dist/renderer-pdf/render-table-pdf.js +22 -10
  392. package/dist/secrets/feature.js +9 -9
  393. package/dist/secrets/web/constants.js +2 -2
  394. package/dist/seo/feature.js +3 -3
  395. package/dist/sessions/constants.d.ts +1 -1
  396. package/dist/sessions/constants.js +1 -1
  397. package/dist/sessions/feature.d.ts +2 -2
  398. package/dist/sessions/feature.js +12 -8
  399. package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
  400. package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
  401. package/dist/sessions/handlers/revoke.write.js +1 -1
  402. package/dist/sessions/schema/user-session.js +4 -4
  403. package/dist/sessions/screens.js +2 -2
  404. package/dist/sessions/session-callbacks.js +2 -2
  405. package/dist/sessions/session-revoked-event.js +2 -2
  406. package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
  407. package/dist/shared/decrypt-stored-pii.d.ts +1 -0
  408. package/dist/shared/decrypt-stored-pii.js +7 -2
  409. package/dist/shared/encrypt-for-direct-write.js +1 -1
  410. package/dist/shared/index.d.ts +1 -1
  411. package/dist/shared/index.js +1 -1
  412. package/dist/shared/mail-template-body.d.ts +6 -2
  413. package/dist/shared/mail-template-body.js +7 -4
  414. package/dist/shared/map-with-concurrency.js +5 -4
  415. package/dist/shared/parent-visibility.js +2 -2
  416. package/dist/shared/password-hashing.js +1 -1
  417. package/dist/shared/signup-handover.js +1 -2
  418. package/dist/shared/single-use-token-store.js +1 -1
  419. package/dist/step-dispatcher/feature.js +1 -0
  420. package/dist/subscription-dodo/client.d.ts +17 -0
  421. package/dist/subscription-dodo/client.js +31 -0
  422. package/dist/subscription-dodo/constants.d.ts +12 -0
  423. package/dist/subscription-dodo/constants.js +19 -0
  424. package/dist/subscription-dodo/feature.d.ts +37 -0
  425. package/dist/subscription-dodo/feature.js +144 -0
  426. package/dist/subscription-dodo/index.d.ts +2 -0
  427. package/dist/subscription-dodo/index.js +4 -0
  428. package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
  429. package/dist/subscription-dodo/plugin-methods.js +260 -0
  430. package/dist/subscription-dodo/runtime.d.ts +27 -0
  431. package/dist/subscription-dodo/runtime.js +89 -0
  432. package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
  433. package/dist/subscription-dodo/verify-webhook.js +189 -0
  434. package/dist/subscription-mollie/constants.js +15 -17
  435. package/dist/subscription-mollie/feature.d.ts +17 -18
  436. package/dist/subscription-mollie/feature.js +24 -24
  437. package/dist/subscription-mollie/index.js +3 -3
  438. package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
  439. package/dist/subscription-mollie/plugin-methods.js +15 -14
  440. package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
  441. package/dist/subscription-mollie/verify-webhook.js +27 -27
  442. package/dist/subscription-stripe/constants.js +4 -6
  443. package/dist/subscription-stripe/feature.d.ts +14 -14
  444. package/dist/subscription-stripe/feature.js +36 -34
  445. package/dist/subscription-stripe/index.js +6 -6
  446. package/dist/subscription-stripe/plugin-methods.js +18 -18
  447. package/dist/subscription-stripe/runtime.d.ts +1 -1
  448. package/dist/subscription-stripe/runtime.js +8 -7
  449. package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
  450. package/dist/subscription-stripe/verify-webhook.js +59 -61
  451. package/dist/tags/feature.d.ts +3 -3
  452. package/dist/tags/screens.js +1 -1
  453. package/dist/template-resolver/api.d.ts +3 -2
  454. package/dist/template-resolver/api.js +34 -12
  455. package/dist/template-resolver/compile-document-body.js +1 -0
  456. package/dist/template-resolver/feature.js +2 -2
  457. package/dist/template-resolver/handlers/bundle-import.js +3 -3
  458. package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
  459. package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
  460. package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
  461. package/dist/template-resolver/handlers/document-base.js +3 -2
  462. package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
  463. package/dist/template-resolver/handlers/list.query.js +6 -7
  464. package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
  465. package/dist/template-resolver/handlers/overview.query.js +6 -3
  466. package/dist/template-resolver/handlers/shared.js +2 -2
  467. package/dist/template-resolver/handlers/template-write.js +3 -3
  468. package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
  469. package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
  470. package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
  471. package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
  472. package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
  473. package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
  474. package/dist/template-resolver/handlers/usage.query.js +26 -16
  475. package/dist/template-resolver/handlers/validate.query.js +7 -2
  476. package/dist/template-resolver/seeding.js +30 -14
  477. package/dist/template-resolver/store-template-resource.d.ts +1 -0
  478. package/dist/template-resolver/store-template-resource.js +19 -4
  479. package/dist/template-resolver/table.js +10 -11
  480. package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
  481. package/dist/template-resolver/template-delivery-policy.js +0 -6
  482. package/dist/template-resolver/template-meta.js +7 -4
  483. package/dist/template-resolver/template-preview.js +4 -3
  484. package/dist/template-resolver/web/client-plugin.js +2 -2
  485. package/dist/template-resolver/web/constants.d.ts +2 -2
  486. package/dist/template-resolver/web/constants.js +3 -3
  487. package/dist/template-resolver/web/index.d.ts +1 -0
  488. package/dist/template-resolver/web/index.js +1 -0
  489. package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
  490. package/dist/template-resolver/web/mail-layout-constants.js +7 -0
  491. package/dist/tenant/feature.js +7 -7
  492. package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
  493. package/dist/tenant/handlers/member-directory.query.js +11 -4
  494. package/dist/tenant/handlers/members.query.js +1 -1
  495. package/dist/tenant/handlers/team-list.query.js +1 -1
  496. package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
  497. package/dist/tenant/handlers/tenant-directory.query.js +9 -5
  498. package/dist/tenant/invitation-table.js +37 -40
  499. package/dist/tenant/membership-table.js +3 -3
  500. package/dist/tenant/schema/tenant.js +7 -9
  501. package/dist/tenant/screens.js +1 -1
  502. package/dist/tenant/seeding.d.ts +6 -5
  503. package/dist/tenant/seeding.js +12 -12
  504. package/dist/tenant/testing.js +5 -6
  505. package/dist/tenant/web/constants.js +2 -2
  506. package/dist/tenant-handover/events.js +5 -7
  507. package/dist/tenant-handover/feature.js +1 -1
  508. package/dist/tenant-handover/grant.js +1 -1
  509. package/dist/tenant-handover/handlers/claim.write.js +1 -1
  510. package/dist/tenant-handover/move-entity-graph.js +8 -9
  511. package/dist/tenant-handover/signup-handover-provider.js +1 -2
  512. package/dist/tenant-handover/transfer-graph.js +4 -5
  513. package/dist/tenant-lifecycle/boot-checks.js +1 -1
  514. package/dist/tenant-lifecycle/constants.d.ts +1 -0
  515. package/dist/tenant-lifecycle/constants.js +4 -0
  516. package/dist/tenant-lifecycle/feature.js +1 -1
  517. package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
  518. package/dist/tenant-settings/constants.js +1 -1
  519. package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
  520. package/dist/tenant-settings/tenant-defaults.js +9 -2
  521. package/dist/tier-engine/aggregate-id.d.ts +11 -11
  522. package/dist/tier-engine/aggregate-id.js +15 -16
  523. package/dist/tier-engine/compose-app.d.ts +14 -14
  524. package/dist/tier-engine/compose-app.js +1 -1
  525. package/dist/tier-engine/entity.js +18 -19
  526. package/dist/tier-engine/feature.d.ts +19 -17
  527. package/dist/tier-engine/feature.js +68 -69
  528. package/dist/tier-engine/handlers/active-tier.query.js +6 -7
  529. package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
  530. package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
  531. package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
  532. package/dist/tier-engine/tier-resolver.js +2 -2
  533. package/dist/tier-engine/trial.js +8 -8
  534. package/dist/tier-engine/web/constants.js +2 -2
  535. package/dist/tier-engine/web/index.js +4 -4
  536. package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
  537. package/dist/user/handlers/create.write.js +4 -4
  538. package/dist/user/schema/user.d.ts +11 -11
  539. package/dist/user/schema/user.js +45 -44
  540. package/dist/user/seeding.d.ts +15 -15
  541. package/dist/user/seeding.js +28 -28
  542. package/dist/user/testing.js +3 -3
  543. package/dist/user-data-rights/audit-download.d.ts +8 -8
  544. package/dist/user-data-rights/audit-download.js +19 -20
  545. package/dist/user-data-rights/boot-checks.js +1 -1
  546. package/dist/user-data-rights/deletion-token.js +1 -1
  547. package/dist/user-data-rights/feature.d.ts +49 -50
  548. package/dist/user-data-rights/feature.js +54 -53
  549. package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
  550. package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
  551. package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
  552. package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
  553. package/dist/user-data-rights/handlers/export-status.query.js +8 -9
  554. package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
  555. package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
  556. package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
  557. package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
  558. package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
  559. package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
  560. package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
  561. package/dist/user-data-rights/handlers/request-export.write.js +42 -41
  562. package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
  563. package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
  564. package/dist/user-data-rights/index.js +8 -10
  565. package/dist/user-data-rights/lib/default-mailers.js +3 -3
  566. package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
  567. package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
  568. package/dist/user-data-rights/run-export-jobs.js +130 -237
  569. package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
  570. package/dist/user-data-rights/run-forget-cleanup.js +65 -83
  571. package/dist/user-data-rights/run-user-export.d.ts +34 -33
  572. package/dist/user-data-rights/run-user-export.js +55 -57
  573. package/dist/user-data-rights/schema/download-attempt.js +11 -11
  574. package/dist/user-data-rights/schema/download-token.js +37 -41
  575. package/dist/user-data-rights/schema/export-job.d.ts +4 -4
  576. package/dist/user-data-rights/schema/export-job.js +65 -67
  577. package/dist/user-data-rights/token-helpers.d.ts +8 -9
  578. package/dist/user-data-rights/token-helpers.js +21 -25
  579. package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
  580. package/dist/user-data-rights/web/client-plugin.js +1 -1
  581. package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
  582. package/dist/user-data-rights/web/constants.js +1 -1
  583. package/dist/user-data-rights/web/index.js +5 -5
  584. package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
  585. package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
  586. package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
  587. package/dist/user-data-rights/zip-path.d.ts +15 -15
  588. package/dist/user-data-rights/zip-path.js +41 -40
  589. package/dist/user-data-rights-defaults/feature.js +15 -15
  590. package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
  591. package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
  592. package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
  593. package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
  594. package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
  595. package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
  596. package/dist/user-profile/handlers/change-email.write.js +13 -13
  597. package/dist/user-profile/index.js +3 -3
  598. package/dist/user-profile/web/client-plugin.js +1 -1
  599. package/dist/user-profile/web/constants.js +1 -1
  600. package/dist/user-profile/web/profile-screen.js +1 -1
  601. package/dist/waitlist/handlers/export-purge.write.js +2 -1
  602. package/dist/waitlist/handlers/submit.write.js +5 -5
  603. package/dist/waitlist/import.d.ts +1 -0
  604. package/dist/waitlist/import.js +4 -0
  605. package/dist/waitlist/legacy-migrate.js +17 -6
  606. package/dist/waitlist/link-on-signup.js +18 -6
  607. package/dist/waitlist/options.d.ts +3 -0
  608. package/dist/workflow-runner/aggregate-id.d.ts +1 -1
  609. package/dist/workflow-runner/aggregate-id.js +1 -1
  610. package/dist/workflow-runner/event-subscriber.js +4 -5
  611. package/dist/workflow-runner/event-trigger.js +4 -17
  612. package/dist/workflow-runner/feature.js +2 -2
  613. package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
  614. package/dist/workflow-runner/pending-projection.js +6 -7
  615. package/dist/workflow-runner/runner.js +6 -6
  616. package/dist/workflow-runner/tables.js +6 -6
  617. package/dist/workflow-runner/workflow-registry.js +1 -1
  618. package/package.json +20 -10
  619. package/src/agent-tools/changes.json +6 -0
  620. package/src/audit/changes.json +12 -0
  621. package/src/auth-mfa/changes.json +6 -0
  622. package/src/billing-foundation/changes.json +55 -0
  623. package/src/cap-counter/changes.json +18 -0
  624. package/src/channel-email/changes.json +6 -0
  625. package/src/config/changes.json +12 -0
  626. package/src/crypto-shredding/changes.json +6 -0
  627. package/src/delivery/changes.json +30 -0
  628. package/src/form-draft/changes.json +6 -0
  629. package/src/host-routing/changes.json +6 -0
  630. package/src/inbound-mail-foundation/changes.json +18 -0
  631. package/src/jobs/changes.json +13 -0
  632. package/src/mail-foundation/changes.json +6 -0
  633. package/src/renderer-pdf/changes.json +6 -0
  634. package/src/step-dispatcher/changes.json +6 -0
  635. package/src/subscription-dodo/changes.json +14 -0
  636. package/src/subscription-stripe/changes.json +12 -0
  637. package/src/template-resolver/changes.json +48 -0
  638. package/src/tenant/changes.json +6 -0
  639. package/src/tenant-lifecycle/changes.json +6 -0
  640. package/src/tier-engine/changes.json +6 -0
  641. package/src/waitlist/changes.json +18 -0
  642. package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
  643. package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
@@ -11,11 +11,12 @@ export type SessionState = {
11
11
  readonly user: CurrentUserProfile | null;
12
12
  readonly activeTenantId: string | null;
13
13
  readonly tenants: readonly TenantSummary[];
14
- /** Merged session-roles für den active tenant: globalRoles (z.B.
15
- * SystemAdmin) + membership-roles des activeTenant. Server hat sie
16
- * schon im JWT gemerged, aber das JWT ist HttpOnly + nicht JS-lesbar;
17
- * Client computed dieselbe merge-Logik aus user.globalRoles +
18
- * tenants[active].roles damit nav-filtering greift. Dedupliziert. */
14
+ /** Merged session roles for the active tenant: globalRoles (for example,
15
+ * SystemAdmin) plus the active tenant's membership roles. The server has
16
+ * already merged them into the JWT, but the JWT is HttpOnly and cannot be
17
+ * read by JavaScript; the client computes the same merge from
18
+ * user.globalRoles + tenants[active].roles so navigation filtering works.
19
+ * The result is deduplicated. */
19
20
  readonly roles: readonly string[];
20
21
  readonly bootstrapFailure: SessionBootstrapFailure | null;
21
22
  /** Set when an authenticated session was ended server-side (revoked,
@@ -35,10 +36,10 @@ export type SessionApi = SessionState & {
35
36
  export declare const UNAUTHENTICATED: SessionState;
36
37
  export declare function hasLikelyAuthSession(cookieSource?: string): boolean;
37
38
  export declare function computeActiveRoles(user: CurrentUserProfile | null, activeTenantId: string | null, tenants: readonly TenantSummary[]): readonly string[];
38
- /** Internal — exposed for tests die einen Mock-SessionApi-Wert reinreichen
39
- * wollen, ohne durch SessionProvider's refresh-Lifecycle zu müssen. App-
40
- * Code nutzt SessionProvider + useSession; direkter Context-Zugriff ist
41
- * für Tests/Stories. */
39
+ /** Internal — exposed so tests can pass a mock SessionApi value
40
+ * without going through SessionProvider's refresh lifecycle. Application
41
+ * code uses SessionProvider + useSession; direct context access is
42
+ * intended for tests/stories. */
42
43
  export declare const SessionContext: import("react").Context<SessionApi | undefined>;
43
44
  export declare function SessionProvider({ children, postLogoutUrl, }: {
44
45
  readonly children: ReactNode;
@@ -1,13 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- // Session-State für den Browser-Renderer. Hält den aktuell eingeloggten
3
- // User (Profile + aktive Tenant-Zuordnung + Memberships), reagiert auf
4
- // Login/Logout/Switch-Tenant und refresh't die Daten automatisch.
2
+ // Session state for the browser renderer. Holds the currently signed-in
3
+ // user (profile + active tenant assignment + memberships), responds to
4
+ // login/logout/tenant switching, and refreshes the data automatically.
5
5
  //
6
- // Warum Context + useReducer statt z.B. Zustand? Weil die State-Menge
7
- // klein ist (ein Handful Felder, ein paar Transitionen) und wir damit
8
- // eine Dependency weniger im Browser-Bundle haben. Die Consumer leben
9
- // unter `<SessionProvider>`; der `useSession()`-Hook liefert den State
10
- // und die Transitions.
6
+ // Context + useReducer is used instead of, for example, Zustand because
7
+ // the state is small (a handful of fields and a few transitions), avoiding
8
+ // another dependency in the browser bundle. Consumers live under
9
+ // `<SessionProvider>`; the `useSession()` hook provides the state
10
+ // and transitions.
11
11
  import { CurrentUserProvider, useSessionEndedSignal, } from "@cosmicdrift/kumiko-renderer";
12
12
  import { readCsrfToken } from "@cosmicdrift/kumiko-renderer/live";
13
13
  import { createContext, useCallback, useContext, useEffect, useMemo, useState, } from "react";
@@ -34,14 +34,14 @@ const INITIAL = {
34
34
  bootstrapFailure: null,
35
35
  signedOutReason: null,
36
36
  };
37
- // kumiko_auth ist HttpOnly — kumiko_csrf wird beim Login gemeinsam gesetzt.
37
+ // kumiko_auth is HttpOnly; kumiko_csrf is set together with it at login.
38
38
  export function hasLikelyAuthSession(cookieSource) {
39
39
  return readCsrfToken(cookieSource) !== undefined;
40
40
  }
41
- // Exported damit tests den merge-pfad direkt pinnen können — der hier
42
- // muss byte-identisch zum server-side merge in auth-routes.ts +
43
- // login.write.ts sein, sonst sieht der Client andere session-rollen
44
- // als der Server.
41
+ // Exported so tests can pin the merge path directly: this must be
42
+ // byte-identical to the server-side merge in auth-routes.ts +
43
+ // login.write.ts, otherwise the client sees different session roles
44
+ // from the server.
45
45
  export function computeActiveRoles(user, activeTenantId, tenants) {
46
46
  if (user === null)
47
47
  return [];
@@ -51,13 +51,13 @@ export function computeActiveRoles(user, activeTenantId, tenants) {
51
51
  // login.write.ts).
52
52
  return Array.from(new Set([...user.globalRoles, ...membershipRoles]));
53
53
  }
54
- /** Internal — exposed for tests die einen Mock-SessionApi-Wert reinreichen
55
- * wollen, ohne durch SessionProvider's refresh-Lifecycle zu müssen. App-
56
- * Code nutzt SessionProvider + useSession; direkter Context-Zugriff ist
57
- * für Tests/Stories. */
54
+ /** Internal — exposed so tests can pass a mock SessionApi value
55
+ * without going through SessionProvider's refresh lifecycle. Application
56
+ * code uses SessionProvider + useSession; direct context access is
57
+ * intended for tests/stories. */
58
58
  export const SessionContext = createContext(undefined);
59
- // Eine Refresh-Runde: /auth/tenants → wenn 401 nicht-eingeloggt, sonst
60
- // /user:me. Beides zusammen ergibt den vollen SessionState.
59
+ // One refresh round: /auth/tenants → if 401, unauthenticated; otherwise
60
+ // /user:me. Together, both requests produce the complete SessionState.
61
61
  async function refresh() {
62
62
  if (!hasLikelyAuthSession()) {
63
63
  return UNAUTHENTICATED;
@@ -103,14 +103,14 @@ export function SessionProvider({ children, postLogoutUrl, }) {
103
103
  setState({ ...UNAUTHENTICATED, status: "error", bootstrapFailure: toBootstrapFailure(err) });
104
104
  }
105
105
  }, []);
106
- // kumiko-lint-ignore no-raw-hooks Phase-3 conversion tracked in #2312
106
+ // kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
107
107
  useEffect(() => {
108
108
  void doRefresh();
109
109
  }, [doRefresh]);
110
110
  const sessionEndedSignal = useSessionEndedSignal();
111
111
  // Only an authenticated session can "end": an anonymous 401 on a public
112
112
  // surface must not show the hint.
113
- // kumiko-lint-ignore no-raw-hooks Phase-3 conversion tracked in #2312
113
+ // kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
114
114
  useEffect(() => {
115
115
  return sessionEndedSignal?.subscribe(() => {
116
116
  setState((prev) => prev.status === "authenticated"
@@ -134,20 +134,19 @@ export function SessionProvider({ children, postLogoutUrl, }) {
134
134
  return;
135
135
  }
136
136
  setState(UNAUTHENTICATED);
137
- // Hard-Reload: React-Tree, dispatcher-live-Caches, EventSource —
138
- // alles fliegt auf Null. Nach Logout ist das der billigste Weg zu
139
- // sauberer Ausgangslage, ohne dass wir jeden einzelnen Consumer
140
- // per Context-Bust invalidieren müssen.
137
+ // Hard reload: the React tree, dispatcher live caches, and EventSource
138
+ // are all reset. After logout, this is the cheapest way to reach a clean
139
+ // state without having to invalidate every consumer through a context
140
+ // reset.
141
141
  if (typeof window !== "undefined") {
142
142
  window.location.reload();
143
143
  }
144
144
  }, [postLogoutUrl]);
145
145
  const switchTenant = useCallback(async (tenantId) => {
146
146
  await switchTenantApi(tenantId);
147
- // Tenant-Wechsel rotiert JWT + Cookies. React-Tree enthält
148
- // tenant-gebundene Caches (Queries, Live-Events) — simpler
149
- // Reload ist konsistent mit dem Logout-Pfad und vermeidet
150
- // halbe State-Übergänge.
147
+ // Tenant switching rotates the JWT + cookies. The React tree contains
148
+ // tenant-bound caches (queries, live events), so a simple reload is
149
+ // consistent with the logout path and avoids partial state transitions.
151
150
  if (typeof window !== "undefined") {
152
151
  window.location.reload();
153
152
  }
@@ -6,7 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  // JWT + cookies (auto-login!) and returns the tenantKey.
7
7
  //
8
8
  // Token source is read-once via useUrlToken: reads `?token=...` on mount
9
- // and scrubs the param from the URL afterwards (#774). Apps that inject a
9
+ // and scrubs the param from the URL afterwards. Apps that inject a
10
10
  // server-side token pass `token` as a prop instead.
11
11
  //
12
12
  // On success: shows a confirmation (account active, signed in) with a
@@ -82,8 +82,8 @@ export function SignupCompleteScreen({ title, token: tokenProp, loggedInHref = "
82
82
  (continueHref !== null
83
83
  ? t("auth.signupComplete.activatedTitle")
84
84
  : t("auth.signupComplete.title"));
85
- // Kein Token in der URL → klare Message statt Form ohne Token
86
- // (würde nur invalidSignupToken zeigen, verwirrend).
85
+ // No token in the URL → show a clear message instead of a form without a token
86
+ // (which would only show invalidSignupToken and confuse the user).
87
87
  if (token === "") {
88
88
  return (_jsxs(AuthCard, { title: effectiveTitle, children: [_jsx("p", { className: "text-sm text-muted-foreground", children: t("auth.signupComplete.missingToken") }), _jsx(Link, { href: loginHref, variant: "muted", children: t("auth.signup.haveAccount") })] }));
89
89
  }
@@ -2,7 +2,7 @@ import { type ReactNode } from "react";
2
2
  export type SignupScreenProps = {
3
3
  readonly title?: string;
4
4
  readonly subtitle?: ReactNode;
5
- /** href für den "Bereits einen Account?"-Link. App-spezifisch — Default
5
+ /** href for the "Already have an account?" link. App-specific; defaults to
6
6
  * "/login". */
7
7
  readonly loginHref?: string;
8
8
  };
@@ -1,16 +1,16 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // SignupScreen — Magic-Link-Self-Signup, Step 1.
2
+ // SignupScreen — Magic-Link self-signup, Step 1.
3
3
  //
4
- // Form mit Email-Input. Submit triggert /api/auth/signup-request
5
- // (silent-success, kein account-enumeration). UI zeigt unconditional
6
- // ein "Mail unterwegs"-Confirm mit Resend-Button — auch wenn die Email
7
- // schon registriert ist (Server schickt dann dieselbe Mail mit dem
8
- // existing Token aus Redis = idempotent).
4
+ // Form with an email input. Submission triggers /api/auth/signup-request
5
+ // (silent success, no account enumeration). The UI always shows a
6
+ // "email on its way" confirmation with a Resend button, even if the email
7
+ // is already registered (the server then sends the same email with the
8
+ // existing token from Redis, making the request idempotent).
9
9
  //
10
- // App ist verantwortlich, den Screen unter einer URL zu mounten (z.B.
11
- // /signup) und ihn anonymous reachable zu machen (AuthPathGate VOR
12
- // AuthGate). Apex-Marketing kann via Link "Kostenlos starten" auf den
13
- // /signup-Pfad routen.
10
+ // The app is responsible for mounting the screen at a URL (e.g.
11
+ // /signup) and making it anonymously reachable (AuthPathGate before
12
+ // AuthGate). An apex marketing site can route its "Start for free" link to
13
+ // the /signup path.
14
14
  import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
15
15
  import { useState } from "react";
16
16
  import { requestSignup } from "./auth-client.js";
@@ -53,9 +53,9 @@ export function SignupScreen({ title, subtitle, loginHref = "/login", }) {
53
53
  void doSubmit();
54
54
  };
55
55
  const onResend = async () => {
56
- // Resend nutzt den gleichen Endpunkt — Server returnt den existing
57
- // Token aus Redis und schickt eine zweite Mail mit dem GLEICHEN
58
- // Activation-Link (alte Mail bleibt also gültig).
56
+ // Resend uses the same endpoint: the server returns the existing
57
+ // token from Redis and sends a second email with the SAME
58
+ // activation link, so the old email remains valid.
59
59
  setSubmitting(true);
60
60
  setError(null);
61
61
  try {
@@ -1,9 +1,9 @@
1
1
  import { type ReactNode } from "react";
2
2
  export type TenantSwitcherProps = {
3
- /** Optional: liefert einen menschenlesbaren Namen pro Tenant-ID.
4
- * Default: die ID wird direkt angezeigt (kurze UUID genügt für
5
- * Dev-Umgebungen). Für prod sollte der Host z.B. die Tenant-Namen
6
- * beim Login cachen und hier durchreichen. */
3
+ /** Optional: provides a human-readable name for each tenant ID.
4
+ * Default: displays the ID directly (a short UUID is sufficient for
5
+ * development environments). In production, the host should cache
6
+ * tenant names at login and pass them here. */
7
7
  readonly tenantName?: (tenantId: string) => string;
8
8
  };
9
9
  export declare function TenantSwitcher({ tenantName }: TenantSwitcherProps): ReactNode;
@@ -1,18 +1,17 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // TenantSwitcher — kleines Dropdown, zeigt den aktiven Tenant und
3
- // erlaubt Wechsel zu anderen Memberships. Auf Radix-DropdownMenu für
4
- // konsistentes Verhalten (Click-outside/Escape/Keyboard-Nav).
2
+ // TenantSwitcher — compact dropdown showing the active tenant and
3
+ // allowing switches to other memberships. Uses Radix-DropdownMenu for
4
+ // consistent click-outside, Escape, and keyboard-navigation behavior.
5
5
  //
6
- // Rendert NICHT wenn kein User eingeloggt ist und auch NICHT wenn der
7
- // User nur einen Tenant hat (Single-Tenant-Apps brauchen keinen
8
- // Switcher).
6
+ // Does NOT render when no user is logged in or when the user has only one
7
+ // tenant (single-tenant apps do not need a switcher).
9
8
  //
10
- // Der Display-Name kommt aus einem optionalen `tenantName`-Prop
11
- // oder fallback zum ID-Hash. Design-Entscheidung: der TenantSwitcher
12
- // holt NICHT selbst tenant:query:me — das würde Round-Trips pro Mount
13
- // kosten und bräuchte Query-Caching-Infrastruktur. Stattdessen reicht
14
- // der Host den Resolver rein (kommt z.B. aus einer useTenantNames()-
15
- // Hook die einmalig am App-Boot geladen wird).
9
+ // The display name comes from the optional `tenantName` prop or falls back
10
+ // to the ID hash. Design decision: TenantSwitcher does NOT fetch
11
+ // tenant:query:me itself, which would cost round trips per mount and
12
+ // require query-caching infrastructure. Instead, the host passes in the
13
+ // resolver (for example, from a useTenantNames() hook loaded once at app
14
+ // boot).
16
15
  import { useTranslation } from "@cosmicdrift/kumiko-renderer";
17
16
  import { cn, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuLabel, DropdownMenuTrigger, } from "@cosmicdrift/kumiko-renderer/web";
18
17
  import { Building2, ChevronDown } from "lucide-react";
@@ -30,25 +29,25 @@ export function TenantSwitcher({ tenantName }) {
30
29
  await switchTenant(tenantId);
31
30
  }
32
31
  finally {
33
- // In der Praxis führt switchTenant zu einem full-page reload,
34
- // also sehen wir den cleared-state nie — das `finally` ist nur
35
- // für den Edge-Case dass switchTenant throwt, damit die UI
36
- // nicht mit dem Spinner hängen bleibt.
32
+ // In practice, switchTenant causes a full-page reload, so we never see
33
+ // the cleared state — `finally` only handles the edge case where
34
+ // switchTenant throws, preventing the UI from remaining stuck with
35
+ // the spinner.
37
36
  setSwitching(null);
38
37
  }
39
38
  }, [activeTenantId, switchTenant]);
40
- // Label-Priorität: App-eigener Resolver (Prop) > Server-geliefertes
41
- // name/key aus /auth/tenants > UUID-Präfix. Letzteres ist nur noch der
42
- // Notnagel — bei Seed-Tenants (00000000-…) ist es ununterscheidbar.
39
+ // Label priority: app-provided resolver (prop) > server-provided
40
+ // name/key from /auth/tenants > UUID prefix. The latter is only a
41
+ // last resort — it is indistinguishable for seeded tenants (00000000-…).
43
42
  const nameOf = (tenantId) => {
44
43
  if (tenantName !== undefined)
45
44
  return tenantName(tenantId);
46
45
  const membership = tenants.find((m) => m.tenantId === tenantId);
47
- // || statt ??: ein leerer name/key-String darf nicht als Label durchrutschen.
46
+ // || instead of ??: an empty name/key string must not be used as a label.
48
47
  return membership?.name || membership?.key || tenantId.slice(0, 8);
49
48
  };
50
- // Rendering-Gate: kein User → nix; nur ein Tenant → auch nix
51
- // (Single-Tenant-Apps brauchen keinen Switcher).
49
+ // Rendering gate: no user → nothing; only one tenant → nothing as well
50
+ // (single-tenant apps do not need a switcher).
52
51
  if (user === null || tenants.length <= 1)
53
52
  return null;
54
53
  const activeLabel = activeTenantId !== null ? nameOf(activeTenantId) : t("auth.tenant.switcher.none");
@@ -1,18 +1,17 @@
1
- // Liest den eingeloggten User + die Rollen aus dem aktiven Tenant aus
2
- // der Session. Der Hook ist die Standard-Brücke zwischen Session-State
3
- // und Layout-Komponenten (WorkspaceShell.user, DefaultAppShell-Gates,
4
- // custom permission checks).
1
+ // Reads the logged-in user and roles for the active tenant from the session.
2
+ // This hook is the standard bridge between session state and layout components
3
+ // (WorkspaceShell.user, DefaultAppShell gates, custom permission checks).
5
4
  //
6
- // Returns undefined solange:
7
- // - die Session lädt (status="loading")
8
- // - der User unauthenticated ist
9
- // - der activeTenantId in der tenants-Liste fehlt (defensiver Pfad —
10
- // sollte nicht passieren, schadet aber nicht zu prüfen)
5
+ // Returns undefined while:
6
+ // - the session is loading (status="loading")
7
+ // - the user is unauthenticated
8
+ // - activeTenantId is missing from the tenants list (a defensive path that
9
+ // should not occur, but is harmless to check)
11
10
  //
12
- // WorkspaceShell + DefaultAppShell akzeptieren undefined als "keine
13
- // Workspaces sichtbar", was im Loading-/Logged-Out-Fall die richtige UX
14
- // ist. Apps die mehr brauchen (Loading-Indicator etc.) prüfen
15
- // useSession().status direkt.
11
+ // WorkspaceShell and DefaultAppShell treat undefined as "no workspaces
12
+ // visible", which is the correct UX while loading or logged out. Apps that
13
+ // need more (such as a loading indicator) should check useSession().status
14
+ // directly.
16
15
  import { useMemo } from "react";
17
16
  import { useSession } from "./session.js";
18
17
  export function useShellUser() {
@@ -1,11 +1,11 @@
1
1
  import type { ReactNode } from "react";
2
2
  export type UserMenuVariant = "pill" | "sidebar";
3
3
  export type UserMenuProps = {
4
- /** Zusätzliche Menu-Items über dem Logout. Per-item class/behaviour
5
- * controlliert der Caller — wir packen nur den Frame drumrum. */
4
+ /** Additional menu items above logout. The caller controls per-item
5
+ * classes and behavior; this component only provides the surrounding frame. */
6
6
  readonly children?: ReactNode;
7
- /** "pill" (Default) = kompakter Topbar-Trigger; "sidebar" = volle NavUser-
8
- * Row (Avatar + Name + Email) für den `sidebarFooter`-Slot der App-Shell.
7
+ /** "pill" (default) = compact top-bar trigger; "sidebar" = full NavUser-
8
+ * row (avatar + name + email) for the App-Shell's `sidebarFooter` slot.
9
9
  * Requires a `SidebarProvider` ancestor — the default App-Shell
10
10
  * `sidebarFooter` slot already provides one. */
11
11
  readonly variant?: UserMenuVariant;
@@ -1,21 +1,20 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // UserMenu — Avatar-Dropdown für die Topbar (variant="pill", Default) oder den
3
- // Sidebar-Footer (variant="sidebar" = die sidebar-07-NavUser-Row). Zeigt
4
- // Name/Email + Logout. Auf Radix-DropdownMenu, damit Click-outside, Escape,
5
- // Focus-Management, Keyboard-Nav (↑↓/Home/End) und ARIA-Roles aus der Kiste
6
- // funktionieren.
2
+ // UserMenu — avatar dropdown for the top bar (variant="pill", default) or the
3
+ // sidebar footer (variant="sidebar" = the sidebar-07-NavUser-Row). Shows
4
+ // name/email and logout. Uses Radix-DropdownMenu so click-outside, Escape,
5
+ // focus management, keyboard navigation (↑↓/Home/End), and ARIA roles work
6
+ // out of the box.
7
7
  //
8
- // Rendert NICHTS wenn kein User eingeloggt ist — Hosts dürfen das
9
- // Component außerhalb des AuthGate einhängen ohne dass ein harter
10
- // Fehler entsteht.
8
+ // Renders nothing when no user is logged in, so hosts can mount the component
9
+ // outside AuthGate without causing a hard error.
11
10
  import { useTranslation } from "@cosmicdrift/kumiko-renderer";
12
11
  import { cn, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, SidebarMenu, SidebarMenuButton, SidebarMenuItem, } from "@cosmicdrift/kumiko-renderer/web";
13
12
  import { ChevronDown, ChevronsUpDown, LogOut } from "lucide-react";
14
13
  import { useSession } from "./session.js";
15
14
  function initials(value) {
16
- // Vor- und Nachname falls Displayname einen Spacebar hat, sonst
17
- // erste zwei Chars der Email-Lokalseite. Deterministisch,
18
- // damit der Avatar-Content nicht bei jedem Re-Render flattert.
15
+ // Uses the first and last name when the display name contains a space;
16
+ // otherwise uses the first two characters of the email local part. This is
17
+ // deterministic, so the avatar content does not change between re-renders.
19
18
  const trimmed = value.trim();
20
19
  if (trimmed.length === 0)
21
20
  return "?";
@@ -34,8 +33,8 @@ export function UserMenu({ children, variant = "pill" }) {
34
33
  const displayName = hasName ? user.displayName : user.email;
35
34
  const avatarText = initials(displayName);
36
35
  const content = (_jsxs(DropdownMenuContent, { align: variant === "sidebar" ? "start" : "end", "aria-label": t("auth.user.menu.label"), children: [_jsxs(DropdownMenuLabel, { className: "text-xs", children: [_jsx("div", { className: "font-medium text-foreground truncate", children: displayName }), hasName && _jsx("div", { className: "truncate", children: user.email })] }), _jsx(DropdownMenuSeparator, {}), children !== undefined && (_jsxs(_Fragment, { children: [children, _jsx(DropdownMenuSeparator, {})] })), _jsxs(DropdownMenuItem, { "data-testid": "user-menu-logout", onSelect: () => void logout(), children: [_jsx(LogOut, { className: "h-4 w-4" }), _jsx("span", { children: t("auth.user.menu.logout") })] })] }));
37
- // Sidebar-Footer: volle NavUser-Row (sidebar-07) als Dropdown-Trigger —
38
- // gleiche Optik wie SidebarUser, aber klickbar mit Logout/Profil.
36
+ // Sidebar footer: full NavUser row (sidebar-07) as the dropdown trigger —
37
+ // matches SidebarUser visually while providing clickable logout/profile actions.
39
38
  if (variant === "sidebar") {
40
39
  return (_jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(SidebarMenuButton, { size: "lg", className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground", children: [_jsx("span", { "aria-hidden": "true", className: "flex size-7 shrink-0 items-center justify-center rounded-full bg-sidebar-accent text-xs font-medium text-sidebar-accent-foreground", children: avatarText }), _jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [_jsx("span", { className: "truncate font-medium text-sidebar-foreground", children: displayName }), hasName && (_jsx("span", { className: "truncate text-xs text-sidebar-muted", children: user.email }))] }), _jsx(ChevronsUpDown, { className: "ml-auto size-4 text-sidebar-muted" })] }) }), content] }) }) }));
41
40
  }
@@ -1,9 +1,9 @@
1
1
  import { type ReactNode } from "react";
2
2
  export type VerifyEmailScreenProps = {
3
3
  readonly title?: string;
4
- /** Override für Token aus URL. Default: parsed aus `?token=...`. */
4
+ /** Override the token from the URL. Default: parsed from `?token=...`. */
5
5
  readonly token?: string;
6
- /** href für "Zum Login"-Link. Default "/login". */
6
+ /** href for the "Zum Login" link. Default "/login". */
7
7
  readonly loginHref?: string;
8
8
  };
9
9
  export declare function VerifyEmailScreen({ title, token: tokenProp, loginHref, }: VerifyEmailScreenProps): ReactNode;
@@ -1,14 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- // VerifyEmailScreen — liest `?token=...` aus URL, schickt ihn auto an
3
- // /api/auth/verify-email beim Mount, zeigt success/error. Idempotent
4
- // auf Server-Seite (mehrfaches Klicken setzt emailVerified=true erneut),
5
- // also kein Re-Submit-Risiko.
2
+ // VerifyEmailScreen — reads `?token=...` from the URL and automatically sends it to
3
+ // /api/auth/verify-email on mount, then shows success/error. The server-side
4
+ // operation is idempotent (repeating it sets emailVerified=true again), so
5
+ // retries are safe.
6
6
  //
7
- // useEffect mit empty-deps + once-Guard damit React Strict-Mode den
8
- // Verify-Call nur einmal feuert (Strict-Mode dispatched useEffect 2x in
9
- // dev). Token-roundtrip ist server-side single-use, aber wir wollen
10
- // nicht den ersten valid-call beim Mount und den zweiten als invalid-
11
- // Banner sehen.
7
+ // The empty-deps effect and once guard prevent React Strict Mode from firing
8
+ // the verification call twice (Strict Mode dispatches useEffect twice in dev).
9
+ // The token roundtrip is single-use server-side, but this avoids showing an
10
+ // invalid-token banner after the first valid mount call.
12
11
  import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
13
12
  import { useEffect, useRef, useState } from "react";
14
13
  import { verifyEmail } from "./auth-client.js";
@@ -19,7 +18,7 @@ export function VerifyEmailScreen({ title, token: tokenProp, loginHref = "/login
19
18
  const token = useUrlToken(tokenProp);
20
19
  const [status, setStatus] = useState(token === "" ? "missing-token" : "verifying");
21
20
  const startedRef = useRef(false);
22
- // kumiko-lint-ignore no-raw-hooks Phase-3 conversion tracked in #2312
21
+ // kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
23
22
  useEffect(() => {
24
23
  if (status !== "verifying")
25
24
  return;
@@ -1,5 +1,5 @@
1
1
  // Multiplicity boot-check for auth-foundation's `tokenVerifier` extension
2
- // point (#1368, #1570). Two static-shape conflicts a boot-check CAN catch (a
2
+ // point. Two static-shape conflicts a boot-check CAN catch (a
3
3
  // runtime shape-match predicate's overlap can't be proven at boot): a
4
4
  // malformed plugin registration, and two providers both claiming the same
5
5
  // shape (resolveTokenVerifier can't tell them apart). Zero tokenVerifier
@@ -30,7 +30,7 @@ export function validateTokenVerifierMultiplicity(features) {
30
30
  }
31
31
  if (namesByShape.size === 0) {
32
32
  // Session-only apps (email-password + sessions) never hit tokenVerifier —
33
- // cookie JWT auth uses sessionStore alone (#1570 / phronexsis#296).
33
+ // cookie JWT auth uses sessionStore alone.
34
34
  for (const feature of features) {
35
35
  for (const usage of feature.extensionUsages) {
36
36
  // skip: sessionStore present — tokenVerifier optional for cookie-session apps.
@@ -79,7 +79,7 @@ function validateSingleProvider(features, opts) {
79
79
  `only one ${label} provider may be mounted at a time.`);
80
80
  }
81
81
  }
82
- // Multiplicity boot-check for the `sessionStore` extension point (#1370).
82
+ // Multiplicity boot-check for the `sessionStore` extension point.
83
83
  // Single-provider, unlike tokenVerifier — no shape to route on, so ≥2 fails
84
84
  // boot. Zero registrations is a valid configuration (see
85
85
  // validateSingleProvider doc) — a pure machine API using auth-foundation for
@@ -93,7 +93,7 @@ export function validateSessionStoreMultiplicity(features) {
93
93
  shapeHint: "SessionStoreProvider — options must have a { build } shape",
94
94
  });
95
95
  }
96
- // Optional single-provider (#1373). Zero registrations = OK (single-tenant /
96
+ // Optional single-provider. Zero registrations = OK (single-tenant /
97
97
  // header-cookie path). ≥2 or malformed = boot fail.
98
98
  export function validateTenantResolverMultiplicity(features) {
99
99
  validateSingleProvider(features, {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Merge app-facing AnonymousAccessConfig with auth-foundation tenant providers.
3
- * Providers win over any leftover callback fields (hard cutover #1374).
3
+ * Providers win over any leftover callback fields.
4
4
  * Test stacks may still pass Resolved callbacks when no provider is mounted.
5
5
  */
6
6
  import type { AnonymousAccessConfig, AnonymousAccessResolved } from "@cosmicdrift/kumiko-framework/api";
@@ -10,7 +10,7 @@ export async function resolveAnonymousAccessFromRegistry(base, deps) {
10
10
  // (EXT_TENANT_RESOLVER/EXT_TENANT_EXISTENCE) alone must never make
11
11
  // anonymousAccess become defined for an app that never set it — that
12
12
  // would upgrade every roles:["anonymous"] handler to reachable without
13
- // a JWT the moment such a routing feature is mounted (#1452).
13
+ // a JWT the moment such a routing feature is mounted.
14
14
  if (!base) {
15
15
  const needing = ANONYMOUS_ROUTE_FEATURES.filter((name) => deps.registry.getFeature(name));
16
16
  if (needing.length > 0) {
@@ -19,7 +19,7 @@ export async function resolveAnonymousAccessFromRegistry(base, deps) {
19
19
  }
20
20
  return undefined;
21
21
  }
22
- // Fail-closed (#1374 security): inline tenantResolver without trust is the
22
+ // Fail-closed (security): inline tenantResolver without trust is the
23
23
  // old ambiguous config — providers always carry trust; test stacks must too.
24
24
  if (!tenantResolver &&
25
25
  base &&
@@ -29,7 +29,7 @@ export async function resolveAnonymousAccessFromRegistry(base, deps) {
29
29
  throw new Error("[auth-foundation] anonymousAccess.tenantResolver is set without resolverTrust — " +
30
30
  'declare "authoritative" or "fallback-only" (or mount an EXT_TENANT_RESOLVER provider).');
31
31
  }
32
- // Providers win (#1374). When none are mounted, keep any test-injected
32
+ // Providers win. When none are mounted, keep any test-injected
33
33
  // Resolved callbacks so framework middleware suites stay self-contained.
34
34
  return {
35
35
  ...(base ?? {}),
@@ -42,14 +42,14 @@ export function tokenShapeMatches(shape, rawToken) {
42
42
  export function tokenShapeKey(shape) {
43
43
  return shape.kind === "jwt" ? "jwt" : `prefix:${shape.prefix}`;
44
44
  }
45
- // Session-store extension point (#1370). Unlike EXT_TOKEN_VERIFIER, this is
45
+ // Session-store extension point. Unlike EXT_TOKEN_VERIFIER, this is
46
46
  // single-provider — sessions have no per-provider shape to route on, so
47
47
  // exactly one implementation must be registered (boot-fails on 0 or ≥2).
48
48
  export const EXT_SESSION_STORE = "sessionStore";
49
49
  export function isSessionStoreProvider(o) {
50
50
  return typeof o === "object" && o !== null && "build" in o && typeof o.build === "function";
51
51
  }
52
- // Tenant-resolution extension points (#1373). Both are single-provider and
52
+ // Tenant-resolution extension points. Both are single-provider and
53
53
  // optional — zero registered means today's single-tenant / header-cookie
54
54
  // path (no subdomain resolver, no existence check). ≥2 fails boot.
55
55
  export const EXT_TENANT_RESOLVER = "tenantResolver";
@@ -2,11 +2,11 @@ import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
2
2
  import type { MfaCodeVerifier } from "./mfa-code-verifier.ts";
3
3
  import type { MfaStatusChecker } from "./mfa-status-checker.ts";
4
4
  import type { MfaTokenSecretsEnv } from "./token-secrets.ts";
5
- export type BindMfaRevokeAllOtherSessions = (revoker: (userId: string, currentSid: string | undefined) => Promise<number>) => void;
5
+ export type BindMfaRevokeAllOtherSessions = (revoker: (userId: string, currentSid: string | undefined) => Promise<number>) => () => void;
6
6
  export declare function bindMfaRevokeAllOtherSessionsFromFeature(feature: FeatureDefinition): BindMfaRevokeAllOtherSessions | undefined;
7
7
  export declare function mfaStatusCheckerFromFeature(feature: FeatureDefinition): MfaStatusChecker | undefined;
8
8
  export declare function mfaVerifierFromFeature(feature: FeatureDefinition): MfaCodeVerifier | undefined;
9
9
  export type BindMfaTokenSecrets = (masterSecret: string, env: MfaTokenSecretsEnv) => void;
10
10
  export declare function bindMfaTokenSecretsFromFeature(feature: FeatureDefinition): BindMfaTokenSecrets | undefined;
11
- export type BindRevokeAllPatTokens = (revoker: (userId: string) => Promise<number>) => void;
11
+ export type BindRevokeAllPatTokens = (revoker: (userId: string) => Promise<number>) => () => void;
12
12
  export declare function bindRevokeAllPatTokensFromFeature(feature: FeatureDefinition): BindRevokeAllPatTokens | undefined;
@@ -147,9 +147,17 @@ export function createAuthMfaFeature(opts) {
147
147
  const verifyMfaCode = createMfaCodeVerifier();
148
148
  const bindRevokeAllOtherSessions = (revoker) => {
149
149
  revokeAllOtherSessions = revoker;
150
+ return () => {
151
+ if (revokeAllOtherSessions === revoker)
152
+ revokeAllOtherSessions = undefined;
153
+ };
150
154
  };
151
155
  const bindRevokeAllPatTokens = (revoker) => {
152
156
  revokeAllPatTokens = revoker;
157
+ return () => {
158
+ if (revokeAllPatTokens === revoker)
159
+ revokeAllPatTokens = undefined;
160
+ };
153
161
  };
154
162
  return {
155
163
  handlers,
@@ -30,9 +30,9 @@ export function createDisableHandler(opts) {
30
30
  if (!row)
31
31
  return mfaNotEnabled();
32
32
  // Fail closed, matching verify.write.ts/enable-confirm-preauth.write.ts
33
- // (#1467): without ctx.redis, verifyMfaFactor's TOTP-replay burn is
34
- // skipped, and a code observed once (phishing proxy/shoulder-surfing)
35
- // could be replayed within the ±1-step window to disable MFA outright.
33
+ // without ctx.redis, verifyMfaFactor's TOTP-replay burn is skipped, and
34
+ // a code observed once (phishing proxy/shoulder-surfing) could be
35
+ // replayed within the ±1-step window to disable MFA outright.
36
36
  // "no ctx.redis means no one gets through MFA login" doesn't cover
37
37
  // this route — it's session-authed, and JWTs issued before Redis was
38
38
  // unwired stay valid until they expire.