@cosmicdrift/kumiko-samples 0.369.0 → 0.371.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.
- package/package.json +1 -1
- package/packages/bundled-features/package.json +21 -11
- package/packages/bundled-features/src/account-security/README.md +31 -0
- package/packages/bundled-features/src/account-security/changes.json +8 -0
- package/packages/bundled-features/src/account-security/constants.ts +6 -0
- package/packages/bundled-features/src/account-security/feature.ts +100 -0
- package/packages/bundled-features/src/account-security/i18n.ts +9 -0
- package/packages/bundled-features/src/account-security/index.ts +13 -0
- package/packages/bundled-features/src/admin-shell/feature.ts +4 -4
- package/packages/bundled-features/src/admin-shell/index.ts +4 -4
- package/packages/bundled-features/src/admin-shell/overview-allowlist.ts +3 -3
- package/packages/bundled-features/src/admin-shell/overview-panels.ts +3 -3
- package/packages/bundled-features/src/admin-shell/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/admin-shell/web/i18n.ts +1 -1
- package/packages/bundled-features/src/admin-shell/web/index.ts +1 -1
- package/packages/bundled-features/src/agent-tools/agent-doc-lint.ts +1 -1
- package/packages/bundled-features/src/agent-tools/agent-manifest.ts +2 -2
- package/packages/bundled-features/src/agent-tools/feature.ts +1 -1
- package/packages/bundled-features/src/agent-tools/index.ts +8 -8
- package/packages/bundled-features/src/agent-tools/manifest-deny-qns.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +3 -3
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +2 -2
- package/packages/bundled-features/src/audit/feature.ts +6 -6
- package/packages/bundled-features/src/audit/handlers/details.query.ts +3 -3
- package/packages/bundled-features/src/audit/handlers/list.query.ts +3 -3
- package/packages/bundled-features/src/audit/handlers/resolve-audit-tenant.ts +1 -1
- package/packages/bundled-features/src/audit/index.ts +3 -3
- package/packages/bundled-features/src/audit/run-escape-hatch-retention.ts +4 -4
- package/packages/bundled-features/src/audit/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/audit/web/i18n.ts +1 -1
- package/packages/bundled-features/src/audit/web/index.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/bootstrap.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/changes.json +6 -0
- package/packages/bundled-features/src/auth-email-password/errors.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/feature.ts +26 -24
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-account-unlock.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +7 -7
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +11 -11
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +11 -11
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/request-account-unlock.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/request-email-verification.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/request-password-reset.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/reset-password.write.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +7 -7
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +7 -7
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/handlers/token-request-handler.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/verify-email.write.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/index.ts +13 -13
- package/packages/bundled-features/src/auth-email-password/invite-token-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/magic-link-mail.ts +2 -2
- package/packages/bundled-features/src/auth-email-password/mail-notifications.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/reset-token.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/signed-token.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/signup-activation.ts +4 -4
- package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/testing.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/unlock-token.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/verification-token.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +4 -4
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +2 -2
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +2 -2
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +2 -2
- package/packages/bundled-features/src/auth-email-password/web/index.ts +42 -42
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +4 -4
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +4 -4
- package/packages/bundled-features/src/auth-email-password/web/request-account-unlock-screen.tsx +2 -2
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/session-bootstrap-error.tsx +2 -2
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +4 -4
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/tenant-menu-items.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +2 -2
- package/packages/bundled-features/src/auth-foundation/boot-checks.ts +1 -1
- package/packages/bundled-features/src/auth-foundation/changes.json +14 -0
- package/packages/bundled-features/src/auth-foundation/feature.ts +3 -6
- package/packages/bundled-features/src/auth-foundation/index.ts +3 -4
- package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +19 -4
- package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
- package/packages/bundled-features/src/auth-mfa/db/queries.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/env.ts +28 -0
- package/packages/bundled-features/src/auth-mfa/errors.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/feature-exports.ts +100 -0
- package/packages/bundled-features/src/auth-mfa/feature.ts +86 -105
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +10 -10
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +7 -7
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +9 -9
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start.write.ts +9 -9
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/status.query.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +9 -9
- package/packages/bundled-features/src/auth-mfa/index.ts +16 -11
- package/packages/bundled-features/src/auth-mfa/mfa-challenge-token.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/mfa-code-verifier.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/mfa-preauth-setup-token.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/mfa-status-checker.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/mfa-verify-attempts.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/otpauth-uri.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/recovery-codes.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/screens.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/testing.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/token-secrets.ts +26 -0
- package/packages/bundled-features/src/auth-mfa/verify-factor.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/index.ts +15 -15
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +1 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +1 -1
- package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +2 -2
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +2 -2
- package/packages/bundled-features/src/auth-mfa-user-data/changes.json +10 -1
- package/packages/bundled-features/src/auth-mfa-user-data/hooks.ts +2 -2
- package/packages/bundled-features/src/auth-mfa-user-data/index.ts +1 -4
- package/packages/bundled-features/src/billing-foundation/billing-info-query.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/changes.json +14 -0
- package/packages/bundled-features/src/billing-foundation/checkout-core.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-text.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +8 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-consent.ts +7 -7
- package/packages/bundled-features/src/billing-foundation/consumer-protection/register-termination.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-mail.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-notify.ts +6 -6
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-pages.ts +7 -7
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +10 -10
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -12
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/events.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/feature.ts +19 -22
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +6 -6
- package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +2 -2
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/handlers/process-payment-event.write.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +5 -5
- package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/index.ts +17 -16
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/projection.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/screens.ts +1 -1
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +88 -22
- package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/types.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/validate-options.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
- package/packages/bundled-features/src/billing-foundation/web/cancel-contract-dialog.tsx +2 -2
- package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +2 -2
- package/packages/bundled-features/src/billing-foundation/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/billing-foundation/web/index.ts +6 -6
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +5 -4
- package/packages/bundled-features/src/cap-counter/book-cap-usage.ts +3 -3
- package/packages/bundled-features/src/cap-counter/calendar-cap-usage-reservation.ts +4 -4
- package/packages/bundled-features/src/cap-counter/cap-reservation.ts +4 -4
- package/packages/bundled-features/src/cap-counter/changes.json +8 -0
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +2 -2
- package/packages/bundled-features/src/cap-counter/feature.ts +8 -11
- package/packages/bundled-features/src/cap-counter/handlers/get-counter.query.ts +1 -1
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +2 -2
- package/packages/bundled-features/src/cap-counter/handlers/increment.write.ts +1 -1
- package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +1 -1
- package/packages/bundled-features/src/cap-counter/index.ts +13 -13
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +1 -1
- package/packages/bundled-features/src/cap-counter/value-cap-guard.ts +2 -2
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +4 -4
- package/packages/bundled-features/src/cap-overview/feature.ts +8 -8
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +3 -3
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +7 -7
- package/packages/bundled-features/src/cap-overview/handlers/tenant-options.query.ts +1 -1
- package/packages/bundled-features/src/cap-overview/index.ts +6 -6
- package/packages/bundled-features/src/cap-overview/screens.ts +2 -2
- package/packages/bundled-features/src/cap-overview/types.ts +1 -1
- package/packages/bundled-features/src/cap-overview/usage-math.ts +1 -1
- package/packages/bundled-features/src/cap-overview/web/cap-cards-panel.tsx +3 -3
- package/packages/bundled-features/src/cap-overview/web/cap-usage-bar.tsx +2 -2
- package/packages/bundled-features/src/cap-overview/web/cap-usage-cell.tsx +2 -2
- package/packages/bundled-features/src/cap-overview/web/client-plugin.tsx +3 -3
- package/packages/bundled-features/src/cap-overview/web/index.ts +4 -4
- package/packages/bundled-features/src/channel-discord/discord-channel.ts +1 -1
- package/packages/bundled-features/src/channel-discord/feature.ts +1 -1
- package/packages/bundled-features/src/channel-discord/index.ts +2 -2
- package/packages/bundled-features/src/channel-email/changes.json +6 -0
- package/packages/bundled-features/src/channel-email/email-channel.ts +4 -4
- package/packages/bundled-features/src/channel-email/env.ts +28 -0
- package/packages/bundled-features/src/channel-email/feature.ts +8 -4
- package/packages/bundled-features/src/channel-email/index.ts +6 -5
- package/packages/bundled-features/src/channel-email/pii-guard.ts +1 -1
- package/packages/bundled-features/src/channel-email/smtp-transport.ts +1 -1
- package/packages/bundled-features/src/channel-email/types.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/feature.ts +6 -6
- package/packages/bundled-features/src/channel-in-app/handlers/inbox.query.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/mark-all-read.write.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/mark-read.write.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +1 -1
- package/packages/bundled-features/src/channel-in-app/in-app-channel.ts +2 -2
- package/packages/bundled-features/src/channel-in-app/index.ts +4 -4
- package/packages/bundled-features/src/channel-push/feature.ts +1 -1
- package/packages/bundled-features/src/channel-push/index.ts +3 -3
- package/packages/bundled-features/src/channel-push/push-channel.ts +2 -2
- package/packages/bundled-features/src/channel-slack/feature.ts +1 -1
- package/packages/bundled-features/src/channel-slack/index.ts +2 -2
- package/packages/bundled-features/src/channel-slack/slack-channel.ts +1 -1
- package/packages/bundled-features/src/channel-teams/feature.ts +1 -1
- package/packages/bundled-features/src/channel-teams/index.ts +2 -2
- package/packages/bundled-features/src/channel-teams/teams-channel.ts +1 -1
- package/packages/bundled-features/src/channel-telegram/feature.ts +1 -1
- package/packages/bundled-features/src/channel-telegram/index.ts +2 -2
- package/packages/bundled-features/src/channel-telegram/telegram-channel.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/feature.ts +9 -9
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +2 -2
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +2 -2
- package/packages/bundled-features/src/compliance-profiles/index.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +1 -1
- package/packages/bundled-features/src/compliance-profiles/web/client-plugin.tsx +3 -3
- package/packages/bundled-features/src/compliance-profiles/web/compliance-profile-catalog.tsx +1 -1
- package/packages/bundled-features/src/compliance-profiles/web/index.ts +2 -2
- package/packages/bundled-features/src/compliance-profiles-ops/changes.json +10 -0
- package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +2 -2
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +1 -4
- package/packages/bundled-features/src/config/db/queries/resolver.ts +1 -1
- package/packages/bundled-features/src/config/feature.ts +11 -11
- package/packages/bundled-features/src/config/handlers/cascade.query.ts +3 -3
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +2 -2
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +2 -2
- package/packages/bundled-features/src/config/handlers/reset.write.ts +3 -3
- package/packages/bundled-features/src/config/handlers/schema.query.ts +1 -1
- package/packages/bundled-features/src/config/handlers/selected-extensions.query.ts +3 -3
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/handlers/values.query.ts +3 -3
- package/packages/bundled-features/src/config/index.ts +9 -9
- package/packages/bundled-features/src/config/resolver.ts +2 -2
- package/packages/bundled-features/src/config/web/client-plugin.ts +2 -2
- package/packages/bundled-features/src/config/web/index.ts +2 -2
- package/packages/bundled-features/src/config/write-helpers.ts +3 -3
- package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
- package/packages/bundled-features/src/crypto-shredding/env/index.ts +94 -0
- package/packages/bundled-features/src/crypto-shredding/feature.ts +9 -5
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +6 -6
- package/packages/bundled-features/src/crypto-shredding/index.ts +4 -3
- package/packages/bundled-features/src/custom-fields/changes.json +8 -0
- package/packages/bundled-features/src/custom-fields/executor.ts +1 -1
- package/packages/bundled-features/src/custom-fields/feature.ts +10 -13
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +3 -3
- package/packages/bundled-features/src/custom-fields/handlers/define-system-field.write.ts +5 -5
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +5 -5
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +4 -4
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +5 -5
- package/packages/bundled-features/src/custom-fields/index.ts +10 -11
- package/packages/bundled-features/src/custom-fields/lib/define-or-resurrect.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/field-definition-row.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +1 -1
- package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
- package/packages/bundled-features/src/custom-fields/schemas.ts +1 -1
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +3 -3
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +1 -1
- package/packages/bundled-features/src/custom-fields/web/index.ts +3 -3
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +4 -4
- package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +1 -1
- package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -2
- package/packages/bundled-features/src/data-retention/feature.ts +11 -11
- package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +2 -2
- package/packages/bundled-features/src/data-retention/index.ts +3 -3
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +6 -6
- package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +2 -2
- package/packages/bundled-features/src/data-retention/resolver.ts +1 -1
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +5 -5
- package/packages/bundled-features/src/delivery/address-opt-out.ts +2 -2
- package/packages/bundled-features/src/delivery/attachment-ref.ts +3 -3
- package/packages/bundled-features/src/delivery/attempt-log-retention.ts +1 -1
- package/packages/bundled-features/src/delivery/attempt-log.ts +4 -4
- package/packages/bundled-features/src/delivery/changes.json +13 -0
- package/packages/bundled-features/src/delivery/channel-context.ts +5 -5
- package/packages/bundled-features/src/delivery/chat-webhook-channel.ts +2 -2
- package/packages/bundled-features/src/delivery/constants.ts +2 -2
- package/packages/bundled-features/src/delivery/db/queries/address-opt-outs.ts +1 -1
- package/packages/bundled-features/src/delivery/delivery-service.ts +11 -11
- package/packages/bundled-features/src/delivery/events.ts +1 -1
- package/packages/bundled-features/src/delivery/feature.ts +15 -13
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +4 -4
- package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +1 -1
- package/packages/bundled-features/src/delivery/handlers/resubscribe-address.write.ts +2 -2
- package/packages/bundled-features/src/delivery/handlers/resubscribe-user.write.ts +2 -2
- package/packages/bundled-features/src/delivery/handlers/set-preference.write.ts +2 -2
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-address.write.ts +2 -2
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +56 -0
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-user.write.ts +2 -2
- package/packages/bundled-features/src/delivery/i18n.ts +1 -1
- package/packages/bundled-features/src/delivery/index.ts +20 -20
- package/packages/bundled-features/src/delivery/jobs.ts +7 -7
- package/packages/bundled-features/src/delivery/notify-factory.ts +1 -1
- package/packages/bundled-features/src/delivery/public-names.ts +1 -0
- package/packages/bundled-features/src/delivery/testing.ts +5 -5
- package/packages/bundled-features/src/delivery/types.ts +3 -3
- package/packages/bundled-features/src/delivery/unsubscribe-link.ts +4 -4
- package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +5 -0
- package/packages/bundled-features/src/delivery/unsubscribe-page.ts +226 -0
- package/packages/bundled-features/src/delivery/unsubscribe.ts +204 -108
- package/packages/bundled-features/src/delivery/upsert-preference.ts +1 -1
- package/packages/bundled-features/src/delivery/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/delivery/web/delivery-channel-cell.tsx +1 -1
- package/packages/bundled-features/src/delivery/web/delivery-error-cell.tsx +1 -1
- package/packages/bundled-features/src/delivery/web/delivery-status-cell.tsx +2 -2
- package/packages/bundled-features/src/delivery/web/delivery-type-cell.tsx +1 -1
- package/packages/bundled-features/src/delivery/web/index.ts +2 -2
- package/packages/bundled-features/src/derivatives-sharp/changes.json +8 -0
- package/packages/bundled-features/src/derivatives-sharp/feature.ts +1 -4
- package/packages/bundled-features/src/derivatives-sharp/index.ts +2 -2
- package/packages/bundled-features/src/derivatives-sharp/render.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/boot-checks.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/changes.json +8 -0
- package/packages/bundled-features/src/document-ingest-foundation/executor.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +7 -10
- package/packages/bundled-features/src/document-ingest-foundation/forget-extract-with-file-ref.ts +3 -3
- package/packages/bundled-features/src/document-ingest-foundation/index.ts +7 -10
- package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/providers.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/write-document-extract.ts +4 -4
- package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/feature.ts +12 -12
- package/packages/bundled-features/src/feature-toggles/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +2 -2
- package/packages/bundled-features/src/feature-toggles/handlers/set.write.ts +3 -3
- package/packages/bundled-features/src/feature-toggles/index.ts +3 -3
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +2 -2
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/feature-toggles/web/index.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/changes.json +8 -0
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -5
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant-by-file-ref.query.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/index.ts +4 -4
- package/packages/bundled-features/src/file-foundation/changes.json +8 -0
- package/packages/bundled-features/src/file-foundation/feature.ts +0 -3
- package/packages/bundled-features/src/file-foundation/index.ts +2 -3
- package/packages/bundled-features/src/file-provider-inmemory/changes.json +10 -1
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +0 -3
- package/packages/bundled-features/src/file-provider-inmemory/index.ts +1 -2
- package/packages/bundled-features/src/file-provider-s3/changes.json +28 -0
- package/packages/bundled-features/src/file-provider-s3/env-feature.ts +10 -7
- package/packages/bundled-features/src/file-provider-s3/env-schema.ts +73 -0
- package/packages/bundled-features/src/file-provider-s3/feature.ts +2 -5
- package/packages/bundled-features/src/file-provider-s3/index.ts +2 -2
- package/packages/bundled-features/src/file-provider-s3/lib/env-helper.ts +1 -1
- package/packages/bundled-features/src/file-provider-s3/lib/index.ts +3 -3
- package/packages/bundled-features/src/files/index.ts +1 -1
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +2 -2
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +1 -1
- package/packages/bundled-features/src/files-tenant-data/index.ts +4 -4
- package/packages/bundled-features/src/folders/changes.json +8 -0
- package/packages/bundled-features/src/folders/executor.ts +1 -1
- package/packages/bundled-features/src/folders/feature.ts +6 -9
- package/packages/bundled-features/src/folders/handlers/clear-folder.write.ts +5 -5
- package/packages/bundled-features/src/folders/handlers/delete-folder.write.ts +3 -3
- package/packages/bundled-features/src/folders/handlers/set-folder.write.ts +5 -5
- package/packages/bundled-features/src/folders/index.ts +7 -8
- package/packages/bundled-features/src/folders/web/client-plugin.tsx +3 -3
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
- package/packages/bundled-features/src/folders/web/folder-section.tsx +2 -2
- package/packages/bundled-features/src/folders/web/index.ts +5 -5
- package/packages/bundled-features/src/folders-user-data/changes.json +10 -1
- package/packages/bundled-features/src/folders-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/folders-user-data/index.ts +1 -4
- package/packages/bundled-features/src/form-draft/changes.json +8 -0
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/entity.ts +1 -1
- package/packages/bundled-features/src/form-draft/executor.ts +1 -1
- package/packages/bundled-features/src/form-draft/feature.ts +7 -10
- package/packages/bundled-features/src/form-draft/handlers/cleanup.job.ts +4 -4
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +6 -6
- package/packages/bundled-features/src/form-draft/handlers/get.query.ts +4 -4
- package/packages/bundled-features/src/form-draft/handlers/list.query.ts +3 -3
- package/packages/bundled-features/src/form-draft/handlers/save.write.ts +5 -5
- package/packages/bundled-features/src/form-draft/index.ts +10 -10
- package/packages/bundled-features/src/form-draft/lookup.ts +2 -2
- package/packages/bundled-features/src/form-draft/release-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/schemas.ts +1 -1
- package/packages/bundled-features/src/form-draft-user-data/changes.json +10 -1
- package/packages/bundled-features/src/form-draft-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/form-draft-user-data/index.ts +1 -4
- package/packages/bundled-features/src/foundation-shared/build-info-env.ts +16 -0
- package/packages/bundled-features/src/foundation-shared/changes.json +8 -1
- package/packages/bundled-features/src/foundation-shared/demo-admin-env.ts +24 -0
- package/packages/bundled-features/src/foundation-shared/index.ts +5 -3
- package/packages/bundled-features/src/foundation-shared/mail-host-policy.ts +1 -1
- package/packages/bundled-features/src/host-routing/README.md +89 -0
- package/packages/bundled-features/src/host-routing/changes.json +8 -0
- package/packages/bundled-features/src/host-routing/constants.ts +24 -0
- package/packages/bundled-features/src/host-routing/dispatch.ts +130 -0
- package/packages/bundled-features/src/host-routing/feature.ts +146 -0
- package/packages/bundled-features/src/host-routing/host.ts +42 -0
- package/packages/bundled-features/src/host-routing/index.ts +21 -0
- package/packages/bundled-features/src/host-routing/options.ts +43 -0
- package/packages/bundled-features/src/host-routing/validate-options.ts +38 -0
- package/packages/bundled-features/src/inbound-mail-foundation/changes.json +8 -0
- package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +5 -5
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +12 -15
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +4 -4
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/index.ts +12 -12
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-access-token.ts +2 -2
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +2 -2
- package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +2 -2
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +3 -3
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +1 -1
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +6 -6
- package/packages/bundled-features/src/inbound-provider-imap/changes.json +8 -0
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +3 -6
- package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +1 -1
- package/packages/bundled-features/src/inbound-provider-imap/index.ts +3 -4
- package/packages/bundled-features/src/inbound-provider-inmemory/changes.json +10 -1
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +0 -3
- package/packages/bundled-features/src/inbound-provider-inmemory/index.ts +1 -2
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +3 -3
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +5 -5
- package/packages/bundled-features/src/jobs/feature.ts +16 -16
- package/packages/bundled-features/src/jobs/handlers/catalog.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +2 -2
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/jobs/handlers/retention-cleanup.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +3 -3
- package/packages/bundled-features/src/jobs/handlers/stale-run-sweep.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/trigger.write.ts +2 -2
- package/packages/bundled-features/src/jobs/index.ts +9 -9
- package/packages/bundled-features/src/jobs/job-run-logger.ts +6 -6
- package/packages/bundled-features/src/jobs/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/jobs/web/i18n.ts +1 -1
- package/packages/bundled-features/src/jobs/web/index.ts +1 -1
- package/packages/bundled-features/src/ledger/changes.json +8 -0
- package/packages/bundled-features/src/ledger/entity.ts +1 -1
- package/packages/bundled-features/src/ledger/executor.ts +1 -1
- package/packages/bundled-features/src/ledger/feature.ts +7 -10
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +5 -5
- package/packages/bundled-features/src/ledger/handlers/create-transaction.write.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/reports.query.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/reverse-transaction.write.ts +5 -5
- package/packages/bundled-features/src/ledger/index.ts +10 -11
- package/packages/bundled-features/src/ledger/recurring.ts +2 -2
- package/packages/bundled-features/src/ledger/reports.ts +2 -2
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/web/index.ts +3 -3
- package/packages/bundled-features/src/legal-pages/README.md +39 -0
- package/packages/bundled-features/src/legal-pages/changes.json +6 -0
- package/packages/bundled-features/src/legal-pages/constants.ts +22 -0
- package/packages/bundled-features/src/legal-pages/feature.ts +14 -7
- package/packages/bundled-features/src/legal-pages/index.ts +12 -3
- package/packages/bundled-features/src/legal-pages/layout.ts +45 -0
- package/packages/bundled-features/src/legal-pages/lib/boot-check.ts +1 -1
- package/packages/bundled-features/src/legal-pages/lib/validate-routes.ts +1 -1
- package/packages/bundled-features/src/legal-pages/markdown.ts +2 -2
- package/packages/bundled-features/src/legal-pages/seed.ts +53 -0
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/legal-pages/web/index.ts +1 -1
- package/packages/bundled-features/src/mail-foundation/changes.json +10 -1
- package/packages/bundled-features/src/mail-foundation/feature.ts +1 -4
- package/packages/bundled-features/src/mail-foundation/index.ts +1 -2
- package/packages/bundled-features/src/mail-transport-inmemory/changes.json +10 -1
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +0 -3
- package/packages/bundled-features/src/mail-transport-inmemory/index.ts +1 -2
- package/packages/bundled-features/src/mail-transport-smtp/changes.json +8 -0
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +2 -5
- package/packages/bundled-features/src/mail-transport-smtp/index.ts +1 -2
- package/packages/bundled-features/src/managed-pages/branding.ts +1 -1
- package/packages/bundled-features/src/managed-pages/css-gate.ts +1 -1
- package/packages/bundled-features/src/managed-pages/feature.ts +12 -12
- package/packages/bundled-features/src/managed-pages/handlers/branding.query.ts +1 -1
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +1 -1
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +1 -1
- package/packages/bundled-features/src/managed-pages/handlers/page-crud.ts +1 -1
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +2 -2
- package/packages/bundled-features/src/managed-pages/index.ts +5 -5
- package/packages/bundled-features/src/managed-pages/screens/branding-screen.ts +1 -1
- package/packages/bundled-features/src/managed-pages/seeding.ts +1 -1
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +1 -1
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
- package/packages/bundled-features/src/managed-pages/web/index.ts +2 -2
- package/packages/bundled-features/src/metrics/compute.ts +3 -3
- package/packages/bundled-features/src/metrics/default-metrics.ts +5 -5
- package/packages/bundled-features/src/metrics/feature.ts +7 -7
- package/packages/bundled-features/src/metrics/filters.ts +1 -1
- package/packages/bundled-features/src/metrics/index.ts +5 -5
- package/packages/bundled-features/src/metrics/types.ts +1 -1
- package/packages/bundled-features/src/metrics/validate.ts +3 -3
- package/packages/bundled-features/src/metrics/window.ts +2 -2
- package/packages/bundled-features/src/notes-history/changes.json +8 -0
- package/packages/bundled-features/src/notes-history/executor.ts +1 -1
- package/packages/bundled-features/src/notes-history/feature.ts +6 -9
- package/packages/bundled-features/src/notes-history/handlers/add-note.write.ts +6 -6
- package/packages/bundled-features/src/notes-history/index.ts +6 -7
- package/packages/bundled-features/src/notes-history/web/client-plugin.tsx +3 -3
- package/packages/bundled-features/src/notes-history/web/index.ts +3 -3
- package/packages/bundled-features/src/notes-history/web/notes-section.tsx +1 -1
- package/packages/bundled-features/src/notes-history-user-data/changes.json +8 -0
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/notes-history-user-data/index.ts +2 -5
- package/packages/bundled-features/src/page-render/cached-page-response.ts +1 -1
- package/packages/bundled-features/src/page-render/index.ts +7 -7
- package/packages/bundled-features/src/page-render/layout.ts +2 -2
- package/packages/bundled-features/src/page-render/web.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +13 -13
- package/packages/bundled-features/src/personal-access-tokens/handlers/available-scopes.query.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/handlers/create.write.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/handlers/list.query.ts +3 -3
- package/packages/bundled-features/src/personal-access-tokens/handlers/revoke.write.ts +3 -3
- package/packages/bundled-features/src/personal-access-tokens/hash.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/i18n.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/index.ts +13 -13
- package/packages/bundled-features/src/personal-access-tokens/resolver.ts +5 -5
- package/packages/bundled-features/src/personal-access-tokens/revoke-for-user.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
- package/packages/bundled-features/src/personal-access-tokens/schema/api-token.ts +1 -1
- package/packages/bundled-features/src/personal-access-tokens/screens.ts +2 -2
- package/packages/bundled-features/src/presets/changes.json +6 -0
- package/packages/bundled-features/src/presets/dsgvo-self-service.ts +7 -5
- package/packages/bundled-features/src/presets/index.ts +2 -2
- package/packages/bundled-features/src/presets/security-baseline.ts +6 -4
- package/packages/bundled-features/src/rate-limiting/feature.ts +2 -2
- package/packages/bundled-features/src/rate-limiting/handlers/bucket-access.ts +1 -1
- package/packages/bundled-features/src/rate-limiting/handlers/status.query.ts +2 -2
- package/packages/bundled-features/src/rate-limiting/index.ts +2 -2
- package/packages/bundled-features/src/readiness/changes.json +10 -1
- package/packages/bundled-features/src/readiness/feature.ts +1 -4
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +1 -1
- package/packages/bundled-features/src/readiness/index.ts +3 -3
- package/packages/bundled-features/src/renderer-foundation/api.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/index.ts +8 -5
- package/packages/bundled-features/src/renderer-foundation/types.ts +22 -2
- package/packages/bundled-features/src/renderer-pdf/feature.ts +2 -2
- package/packages/bundled-features/src/renderer-pdf/index.ts +2 -2
- package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +2 -2
- package/packages/bundled-features/src/secrets/changes.json +12 -0
- package/packages/bundled-features/src/secrets/constants.ts +9 -0
- package/packages/bundled-features/src/secrets/db/queries/read.ts +1 -1
- package/packages/bundled-features/src/secrets/feature.ts +17 -13
- package/packages/bundled-features/src/secrets/handlers/delete.write.ts +5 -5
- package/packages/bundled-features/src/secrets/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/secrets/handlers/rotate.job.ts +2 -2
- package/packages/bundled-features/src/secrets/handlers/set.write.ts +5 -5
- package/packages/bundled-features/src/secrets/i18n.ts +1 -1
- package/packages/bundled-features/src/secrets/index.ts +9 -7
- package/packages/bundled-features/src/secrets/secrets-context.ts +3 -3
- package/packages/bundled-features/src/secrets/write-gate.ts +1 -1
- package/packages/bundled-features/src/seo/feature.ts +8 -8
- package/packages/bundled-features/src/seo/handlers/seo-config.query.ts +1 -1
- package/packages/bundled-features/src/seo/index.ts +6 -6
- package/packages/bundled-features/src/sessions/feature.ts +13 -13
- package/packages/bundled-features/src/sessions/handlers/cleanup.job.ts +1 -1
- package/packages/bundled-features/src/sessions/handlers/detail.query.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/mine.query.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +3 -3
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +3 -3
- package/packages/bundled-features/src/sessions/index.ts +8 -8
- package/packages/bundled-features/src/sessions/schema/user-session.ts +1 -1
- package/packages/bundled-features/src/sessions/screens.ts +1 -1
- package/packages/bundled-features/src/sessions/session-callbacks.ts +6 -6
- package/packages/bundled-features/src/sessions/testing.ts +1 -1
- package/packages/bundled-features/src/shared/index.ts +31 -31
- package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
- package/packages/bundled-features/src/shared/row-bound-grant.ts +1 -1
- package/packages/bundled-features/src/step-dispatcher/deliver-dispatch-request.ts +4 -4
- package/packages/bundled-features/src/step-dispatcher/dispatch-payload.ts +2 -2
- package/packages/bundled-features/src/step-dispatcher/feature.ts +3 -3
- package/packages/bundled-features/src/step-dispatcher/index.ts +3 -3
- package/packages/bundled-features/src/step-dispatcher/webhook-runner.ts +1 -1
- package/packages/bundled-features/src/subscription-mollie/feature.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +2 -2
- package/packages/bundled-features/src/subscription-stripe/changes.json +6 -0
- package/packages/bundled-features/src/subscription-stripe/feature.ts +34 -6
- package/packages/bundled-features/src/subscription-stripe/index.ts +3 -2
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +2 -2
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +1 -1
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +2 -2
- package/packages/bundled-features/src/tags/changes.json +8 -0
- package/packages/bundled-features/src/tags/executor.ts +1 -1
- package/packages/bundled-features/src/tags/feature.ts +11 -14
- package/packages/bundled-features/src/tags/handlers/assign-tag.write.ts +5 -5
- package/packages/bundled-features/src/tags/handlers/create-tag.write.ts +3 -3
- package/packages/bundled-features/src/tags/handlers/delete-tag.write.ts +3 -3
- package/packages/bundled-features/src/tags/handlers/remove-tag.write.ts +5 -5
- package/packages/bundled-features/src/tags/handlers/update-tag.write.ts +3 -3
- package/packages/bundled-features/src/tags/index.ts +11 -11
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/tags/web/client-plugin.tsx +5 -5
- package/packages/bundled-features/src/tags/web/entity-tags.tsx +2 -2
- package/packages/bundled-features/src/tags/web/index.ts +9 -9
- package/packages/bundled-features/src/tags/web/tag-filter.tsx +3 -3
- package/packages/bundled-features/src/tags/web/tag-manager.tsx +2 -2
- package/packages/bundled-features/src/tags/web/tag-picker.tsx +1 -1
- package/packages/bundled-features/src/tags/web/tag-section.tsx +3 -3
- package/packages/bundled-features/src/tags/web/tags-cell.tsx +2 -2
- package/packages/bundled-features/src/template-resolver/api.ts +7 -7
- package/packages/bundled-features/src/template-resolver/changes.json +6 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +4 -4
- package/packages/bundled-features/src/template-resolver/compile-steps-block.ts +3 -3
- package/packages/bundled-features/src/template-resolver/constants.ts +1 -1
- package/packages/bundled-features/src/template-resolver/document-sanitizer.ts +4 -4
- package/packages/bundled-features/src/template-resolver/document-schema.ts +1 -1
- package/packages/bundled-features/src/template-resolver/feature.ts +31 -31
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +11 -11
- package/packages/bundled-features/src/template-resolver/handlers/by-slug.query.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/by-tenant.query.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/collection-item.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-list.query.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/collection-set.write.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/collection-shared.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +13 -13
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/discard-draft.write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/export-bundle.query.ts +7 -7
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/import-bundle-system.write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/import-bundle.write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/layout-source.query.ts +7 -7
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +4 -4
- package/packages/bundled-features/src/template-resolver/handlers/override-diff.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +6 -6
- package/packages/bundled-features/src/template-resolver/handlers/preview.query.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/reset-to-system.write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/resource-link-pdf.write.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/resource-remove.write.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/resource-shared.ts +1 -1
- package/packages/bundled-features/src/template-resolver/handlers/resource-upload.write.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/send-test.write.ts +6 -6
- package/packages/bundled-features/src/template-resolver/handlers/set.write.ts +7 -7
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/template-gates.ts +7 -7
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +10 -10
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/toggle-status.write.ts +6 -6
- package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +8 -8
- package/packages/bundled-features/src/template-resolver/index.ts +25 -25
- package/packages/bundled-features/src/template-resolver/layout-appearance.ts +2 -2
- package/packages/bundled-features/src/template-resolver/layout-regions.ts +2 -2
- package/packages/bundled-features/src/template-resolver/linked-resources.ts +2 -2
- package/packages/bundled-features/src/template-resolver/preview-display-html.ts +1 -1
- package/packages/bundled-features/src/template-resolver/print-document.ts +1 -1
- package/packages/bundled-features/src/template-resolver/resource-image.ts +1 -1
- package/packages/bundled-features/src/template-resolver/seeding.ts +10 -10
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +10 -10
- package/packages/bundled-features/src/template-resolver/table.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-bundle.ts +4 -4
- package/packages/bundled-features/src/template-resolver/template-diff.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-draft.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-meta.ts +2 -2
- package/packages/bundled-features/src/template-resolver/template-preview.ts +40 -25
- package/packages/bundled-features/src/template-resolver/template-resources.ts +4 -4
- package/packages/bundled-features/src/template-resolver/template-system-only.ts +1 -1
- package/packages/bundled-features/src/template-resolver/template-usage.ts +4 -1
- package/packages/bundled-features/src/template-resolver/template-validation.ts +3 -3
- package/packages/bundled-features/src/template-resolver/testing.ts +4 -4
- package/packages/bundled-features/src/template-resolver/user-content-table.ts +2 -2
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +4 -4
- package/packages/bundled-features/src/template-resolver/web/document-editor-extensions.ts +8 -5
- package/packages/bundled-features/src/template-resolver/web/document-editor.tsx +2 -2
- package/packages/bundled-features/src/template-resolver/web/document-tiptap-editor.tsx +30 -11
- package/packages/bundled-features/src/template-resolver/web/editor-handle.ts +2 -2
- package/packages/bundled-features/src/template-resolver/web/index.ts +7 -7
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor-lazy.tsx +3 -3
- package/packages/bundled-features/src/template-resolver/web/placeholder-line-editor.tsx +6 -6
- package/packages/bundled-features/src/template-resolver/web/placeholder-text.ts +1 -1
- package/packages/bundled-features/src/template-resolver-user-data/changes.json +10 -0
- package/packages/bundled-features/src/template-resolver-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/template-resolver-user-data/index.ts +1 -4
- package/packages/bundled-features/src/tenant/cancel-pending-invitation.ts +2 -2
- package/packages/bundled-features/src/tenant/command-schemas.ts +6 -6
- package/packages/bundled-features/src/tenant/decrypt-tenant-names.ts +1 -1
- package/packages/bundled-features/src/tenant/feature.ts +24 -24
- package/packages/bundled-features/src/tenant/handlers/active-tenant-ids.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/add-member.write.ts +3 -3
- package/packages/bundled-features/src/tenant/handlers/cancel-invitation.write.ts +2 -2
- package/packages/bundled-features/src/tenant/handlers/create.write.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/invitations.query.ts +3 -3
- package/packages/bundled-features/src/tenant/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/me.query.ts +2 -2
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +4 -4
- package/packages/bundled-features/src/tenant/handlers/member-role-availability.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +3 -3
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +3 -3
- package/packages/bundled-features/src/tenant/handlers/remove-member.write.ts +6 -6
- package/packages/bundled-features/src/tenant/handlers/resolve-user-ids.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +5 -5
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +3 -3
- package/packages/bundled-features/src/tenant/handlers/toggle-enabled.write.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/update-member-roles.write.ts +3 -3
- package/packages/bundled-features/src/tenant/handlers/update.write.ts +1 -1
- package/packages/bundled-features/src/tenant/index.ts +10 -10
- package/packages/bundled-features/src/tenant/invitation-table.ts +1 -1
- package/packages/bundled-features/src/tenant/invited-membership.ts +4 -4
- package/packages/bundled-features/src/tenant/is-tenant-serving-public-content.ts +1 -1
- package/packages/bundled-features/src/tenant/last-tenant-admin.ts +2 -2
- package/packages/bundled-features/src/tenant/member-role-options.ts +1 -1
- package/packages/bundled-features/src/tenant/screens.ts +2 -2
- package/packages/bundled-features/src/tenant/seeding.ts +3 -3
- package/packages/bundled-features/src/tenant/testing.ts +1 -1
- package/packages/bundled-features/src/tenant/web/client-plugin.tsx +3 -3
- package/packages/bundled-features/src/tenant/web/index.ts +3 -3
- package/packages/bundled-features/src/tenant/web/member-roles-cell.tsx +1 -1
- package/packages/bundled-features/src/tenant/web/member-status-cell.tsx +1 -1
- package/packages/bundled-features/src/tenant-handover/feature.ts +4 -4
- package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +5 -5
- package/packages/bundled-features/src/tenant-handover/index.ts +3 -3
- package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/root-anchor.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +5 -5
- package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +8 -8
- package/packages/bundled-features/src/tenant-lifecycle/handlers/cancel-destruction.write.ts +4 -4
- package/packages/bundled-features/src/tenant-lifecycle/handlers/request-destruction.write.ts +5 -5
- package/packages/bundled-features/src/tenant-lifecycle/index.ts +3 -3
- package/packages/bundled-features/src/tenant-lifecycle/lib/revoke-tenant-sessions.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/lifecycle-gate.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +5 -5
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +3 -3
- package/packages/bundled-features/src/tenant-lifecycle/testing.ts +3 -3
- package/packages/bundled-features/src/tenant-settings/changes.json +10 -1
- package/packages/bundled-features/src/tenant-settings/feature.ts +2 -5
- package/packages/bundled-features/src/tenant-settings/index.ts +4 -5
- package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +1 -1
- package/packages/bundled-features/src/tier-engine/changes.json +8 -0
- package/packages/bundled-features/src/tier-engine/entity.ts +1 -1
- package/packages/bundled-features/src/tier-engine/feature.ts +10 -13
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +1 -1
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +4 -4
- package/packages/bundled-features/src/tier-engine/i18n.ts +4 -10
- package/packages/bundled-features/src/tier-engine/index.ts +8 -9
- package/packages/bundled-features/src/tier-engine/tier-option-gate.ts +1 -1
- package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
- package/packages/bundled-features/src/tier-engine/web/client-plugin.tsx +9 -3
- package/packages/bundled-features/src/tier-engine/web/index.ts +1 -1
- package/packages/bundled-features/src/user/command-schemas.ts +2 -2
- package/packages/bundled-features/src/user/feature.ts +10 -10
- package/packages/bundled-features/src/user/handlers/create.write.ts +3 -3
- package/packages/bundled-features/src/user/handlers/detail.query.ts +2 -2
- package/packages/bundled-features/src/user/handlers/find-for-auth.query.ts +1 -1
- package/packages/bundled-features/src/user/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/user/handlers/me.query.ts +1 -1
- package/packages/bundled-features/src/user/handlers/update-roles.ts +2 -2
- package/packages/bundled-features/src/user/handlers/update.write.ts +4 -4
- package/packages/bundled-features/src/user/index.ts +8 -8
- package/packages/bundled-features/src/user/invited-global-roles.ts +2 -2
- package/packages/bundled-features/src/user/principal-status.ts +1 -1
- package/packages/bundled-features/src/user/resolve-display-names.ts +2 -2
- package/packages/bundled-features/src/user/schema/user.ts +1 -1
- package/packages/bundled-features/src/user/seeding.ts +2 -2
- package/packages/bundled-features/src/user/testing.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/db/queries/export-jobs.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/db/queries/forget-cleanup.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +31 -31
- package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/handlers/deletion-grace-period.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/handlers/download-attempt-list.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/handlers/export-job-detail.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/export-job-list.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/index.ts +13 -13
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +7 -7
- package/packages/bundled-features/src/user-data-rights/lib/deny-if-target-outside-admin-tenant.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/lib/mail-transport-resolver.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/lib/resolve-tenant-model.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/lib/storage-provider-resolver.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/mail-notifications.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +6 -6
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +4 -4
- package/packages/bundled-features/src/user-data-rights/web/i18n.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/index.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +1 -1
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +11 -11
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/api-token.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/config-value.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/download-attempt.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/in-app-message.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/tenant-invitation.userdata-hook.ts +4 -4
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/index.ts +11 -11
- package/packages/bundled-features/src/user-profile/feature.ts +2 -2
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +4 -4
- package/packages/bundled-features/src/user-profile/index.ts +2 -2
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +3 -3
- package/packages/bundled-features/src/user-profile/web/index.ts +2 -2
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +3 -3
- package/packages/bundled-features/src/waitlist/changes.json +7 -0
- package/packages/bundled-features/src/waitlist/constants.ts +12 -0
- package/packages/bundled-features/src/waitlist/entity.ts +5 -3
- package/packages/bundled-features/src/waitlist/entries-admin.ts +55 -0
- package/packages/bundled-features/src/waitlist/feature.ts +33 -12
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +81 -0
- package/packages/bundled-features/src/waitlist/handlers/invite.write.ts +7 -7
- package/packages/bundled-features/src/waitlist/handlers/list.query.ts +2 -2
- package/packages/bundled-features/src/waitlist/handlers/reject.write.ts +5 -5
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
- package/packages/bundled-features/src/waitlist/i18n.ts +4 -0
- package/packages/bundled-features/src/waitlist/import.ts +83 -0
- package/packages/bundled-features/src/waitlist/index.ts +23 -5
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +220 -0
- package/packages/bundled-features/src/waitlist/lib.ts +5 -5
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +106 -0
- package/packages/bundled-features/src/waitlist/mail.ts +1 -1
- package/packages/bundled-features/src/waitlist/options.ts +15 -3
- package/packages/bundled-features/src/waitlist/payloads.ts +3 -1
- package/packages/bundled-features/src/waitlist/screens.ts +2 -2
- package/packages/bundled-features/src/waitlist/user-data-hooks.ts +3 -3
- package/packages/bundled-features/src/workflow-runner/changes.json +8 -0
- package/packages/bundled-features/src/workflow-runner/db/queries/due-runs.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/feature.ts +4 -7
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +3 -3
- package/packages/bundled-features/src/workflow-runner/index.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +1 -1
- package/samples/apps/ui-walkthrough/package.json +2 -1
- package/samples/apps/ui-walkthrough/src/app/auth-constants.ts +4 -0
- package/samples/apps/ui-walkthrough/src/app/server.ts +10 -1
- package/samples/apps/ui-walkthrough/src/app/template-seed-data.ts +1 -1
- package/samples/apps/ui-walkthrough/src/features/billing/feature.ts +11 -10
- package/samples/apps/ui-walkthrough/src/features/billing/i18n.ts +22 -1
- package/samples/apps/ui-walkthrough/src/run-config.ts +14 -5
- package/samples/apps/ui-walkthrough/tsconfig.json +1 -0
- package/samples/apps/use-all-bundled/feature-manifest.json +44 -3
- package/samples/apps/use-all-bundled/scripts/check-coverage.ts +2 -3
- package/samples/apps/use-all-bundled/src/run-config.ts +22 -20
- package/samples/recipes/apex-surface-auth/README.md +1 -0
- package/samples/recipes/apex-surface-auth/src/feature.ts +1 -1
- package/samples/recipes/api-worker-split/bin/api.ts +6 -1
- package/samples/recipes/app-config/README.md +28 -0
- package/samples/recipes/app-config/kumiko.config.ts +9 -0
- package/samples/recipes/app-config/package.json +8 -0
- package/samples/recipes/app-config/src/feature.ts +6 -0
- package/samples/recipes/app-config/tsconfig.json +22 -0
- package/samples/recipes/auth-mfa/README.md +14 -0
- package/samples/recipes/auth-mfa/src/feature.ts +7 -0
- package/samples/recipes/compose-stacks/README.md +60 -0
- package/samples/recipes/compose-stacks/package.json +11 -0
- package/samples/recipes/compose-stacks/src/app.ts +44 -0
- package/samples/recipes/env-composition/README.md +36 -0
- package/samples/recipes/env-composition/bin/server.ts +15 -0
- package/samples/recipes/env-composition/package.json +15 -0
- package/samples/recipes/env-composition/src/env.ts +47 -0
- package/samples/recipes/host-routing/README.md +25 -0
- package/samples/recipes/host-routing/package.json +12 -0
- package/samples/recipes/host-routing/src/feature.ts +35 -0
- package/samples/recipes/legal-pages/README.md +15 -0
- package/samples/recipes/legal-pages/src/feature.ts +13 -2
- package/samples/recipes/managed-config/README.md +1 -0
- package/samples/recipes/managed-pages/README.md +1 -0
- package/samples/recipes/prod-boot-options/README.md +48 -0
- package/samples/recipes/prod-boot-options/bin/server.ts +11 -0
- package/samples/recipes/prod-boot-options/package.json +13 -0
- package/samples/recipes/prod-boot-options/src/app.ts +32 -0
- package/samples/recipes/security-baseline/README.md +16 -13
- package/samples/recipes/security-baseline/package.json +2 -1
- package/samples/recipes/security-baseline/src/feature.ts +3 -3
- package/packages/bundled-features/src/file-provider-s3-env/changes.json +0 -1
- package/packages/bundled-features/src/file-provider-s3-env/index.ts +0 -8
- package/packages/bundled-features/src/files-provider-s3/changes.json +0 -1
- package/packages/bundled-features/src/files-provider-s3/index.ts +0 -11
|
@@ -2,8 +2,8 @@ import type { TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
|
2
2
|
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
3
3
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
import type { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
|
-
import { formDraftTable } from "./executor.
|
|
6
|
-
import type { FormDraftBlob } from "./schemas.
|
|
5
|
+
import { formDraftTable } from "./executor.ts";
|
|
6
|
+
import type { FormDraftBlob } from "./schemas.ts";
|
|
7
7
|
|
|
8
8
|
export type FormDraftRow = {
|
|
9
9
|
readonly id: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
|
-
import type { FormDraftBlob } from "./schemas.
|
|
2
|
+
import type { FormDraftBlob } from "./schemas.ts";
|
|
3
3
|
|
|
4
4
|
// The draft blob's `values` is free-form by design (issue #1889: form-draft
|
|
5
5
|
// never knows the consuming form's field schema, only { values, stepIndex,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
import { FORM_DRAFT_KEY_MAX_LENGTH, FORM_DRAFT_VALUES_MAX_BYTES } from "./constants.
|
|
2
|
+
import { FORM_DRAFT_KEY_MAX_LENGTH, FORM_DRAFT_VALUES_MAX_BYTES } from "./constants.ts";
|
|
3
3
|
|
|
4
4
|
const draftKeySchema = z.string().trim().min(1).max(FORM_DRAFT_KEY_MAX_LENGTH);
|
|
5
5
|
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
[
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.370.0",
|
|
4
|
+
"type": "breaking",
|
|
5
|
+
"title": "The deprecated formDraftUserDataFeature constant is removed",
|
|
6
|
+
"detail": "formDraftUserDataFeature was kept next to createFormDraftUserDataFeature() for one release. Mount the feature by calling createFormDraftUserDataFeature().",
|
|
7
|
+
"migration": "Run bun kumiko-upgrade --apply. It replaces formDraftUserDataFeature with createFormDraftUserDataFeature().",
|
|
8
|
+
"codemod": "scripts/codemod/feature-factory.ts"
|
|
9
|
+
}
|
|
10
|
+
]
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
type UserDataDeleteHook,
|
|
10
10
|
type UserDataExportHook,
|
|
11
11
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
12
|
-
import { formDraftExecutor, formDraftTable } from "../form-draft/index.
|
|
12
|
+
import { formDraftExecutor, formDraftTable } from "../form-draft/index.ts";
|
|
13
13
|
|
|
14
14
|
export const formDraftExportHook: UserDataExportHook = async (ctx) => {
|
|
15
15
|
const rows = await ctx.db.selectMany(formDraftTable, {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// pull a hard dependency. Mirrors notes-history-user-data.
|
|
7
7
|
|
|
8
8
|
import { defineFeature, EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
|
|
9
|
-
import { formDraftDeleteHook, formDraftExportHook } from "./hooks.
|
|
9
|
+
import { formDraftDeleteHook, formDraftExportHook } from "./hooks.ts";
|
|
10
10
|
|
|
11
11
|
export function createFormDraftUserDataFeature() {
|
|
12
12
|
return defineFeature(
|
|
@@ -25,6 +25,3 @@ export function createFormDraftUserDataFeature() {
|
|
|
25
25
|
{ dedupeOptions: {} },
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
/** @deprecated Use createFormDraftUserDataFeature(). Run `bun kumiko-upgrade --apply`. Removed in the first release after 2026-10-29. */
|
|
30
|
-
export const formDraftUserDataFeature = createFormDraftUserDataFeature();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
|
|
3
|
+
/** `BUILD_VERSION`/`BUILD_TIME`, passed from the Dockerfile build args and
|
|
4
|
+
* served by the health and version routes ("dev"/"unknown" when unset). */
|
|
5
|
+
export const buildInfoEnvSchema = z.object({
|
|
6
|
+
BUILD_VERSION: z
|
|
7
|
+
.string()
|
|
8
|
+
.min(1)
|
|
9
|
+
.optional()
|
|
10
|
+
.describe("Release version baked into the image (git tag or sha). Default: dev."),
|
|
11
|
+
BUILD_TIME: z
|
|
12
|
+
.string()
|
|
13
|
+
.min(1)
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Image build timestamp (ISO 8601). Default: unknown."),
|
|
16
|
+
});
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
[
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.370.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "buildInfoEnvSchema and demoAdminEnvSchema",
|
|
6
|
+
"detail": "buildInfoEnvSchema declares BUILD_VERSION and BUILD_TIME. demoAdminEnvSchema declares the seed logins DEMO_ADMIN_EMAIL and DEMO_SYSADMIN_EMAIL (required), their passwords (optional, at least 16 characters) and an optional DEMO_TENANT_ID. Apps add both through extend."
|
|
7
|
+
}
|
|
8
|
+
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
|
|
3
|
+
const SEED_PASSWORD_MIN_LENGTH = 16;
|
|
4
|
+
|
|
5
|
+
function seedPassword(description: string) {
|
|
6
|
+
return z
|
|
7
|
+
.string()
|
|
8
|
+
.min(SEED_PASSWORD_MIN_LENGTH)
|
|
9
|
+
.optional()
|
|
10
|
+
.describe(`${description} Generate with: openssl rand -hex 24`)
|
|
11
|
+
.meta({ kumiko: { pulumi: { generator: "openssl rand -hex 24", secret: true } } });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Logins seeded on first boot: the demo tenant admin and the SystemAdmin.
|
|
15
|
+
* The emails are required so a deploy never seeds an account nobody can
|
|
16
|
+
* reach; a missing password skips that seed. An app with other rules
|
|
17
|
+
* overrides single keys by spreading `.shape` before its own fields. */
|
|
18
|
+
export const demoAdminEnvSchema = z.object({
|
|
19
|
+
DEMO_ADMIN_EMAIL: z.email().describe("Login of the demo tenant admin seeded on first boot."),
|
|
20
|
+
DEMO_ADMIN_PASSWORD: seedPassword("Password of the seeded demo tenant admin."),
|
|
21
|
+
DEMO_SYSADMIN_EMAIL: z.email().describe("Login of the SystemAdmin seeded on first boot."),
|
|
22
|
+
DEMO_SYSADMIN_PASSWORD: seedPassword("Password of the seeded SystemAdmin."),
|
|
23
|
+
DEMO_TENANT_ID: z.uuid().optional().describe("Id of the seeded demo tenant. Default: generated."),
|
|
24
|
+
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// Public API of foundation-shared — utilities consumed by the per-tenant
|
|
2
2
|
// Foundation packages (ai-foundation, mail-foundation, file-foundation).
|
|
3
3
|
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
4
|
+
export { buildInfoEnvSchema } from "./build-info-env.ts";
|
|
5
|
+
export { requireDefined, requireNonEmpty, requireSecretSet } from "./config-helpers.ts";
|
|
6
|
+
export { demoAdminEnvSchema } from "./demo-admin-env.ts";
|
|
7
|
+
export { isHostAllowlisted, readHostAllowlistFromEnv } from "./host-allowlist.ts";
|
|
6
8
|
export {
|
|
7
9
|
BlockedHostError,
|
|
8
10
|
HostResolutionError,
|
|
@@ -12,4 +14,4 @@ export {
|
|
|
12
14
|
mailAllowedPrivateHostsEnvSchema,
|
|
13
15
|
readAllowedPrivateMailHostsFromEnv,
|
|
14
16
|
resolveMailConnectTarget,
|
|
15
|
-
} from "./mail-host-policy.
|
|
17
|
+
} from "./mail-host-policy.ts";
|
|
@@ -17,7 +17,7 @@ import type { lookup } from "node:dns/promises";
|
|
|
17
17
|
import { isIP } from "node:net";
|
|
18
18
|
import { resolvePublicHostname } from "@cosmicdrift/kumiko-framework/http";
|
|
19
19
|
import * as z from "zod";
|
|
20
|
-
import { isHostAllowlisted, readHostAllowlistFromEnv } from "./host-allowlist.
|
|
20
|
+
import { isHostAllowlisted, readHostAllowlistFromEnv } from "./host-allowlist.ts";
|
|
21
21
|
|
|
22
22
|
export const MAIL_ALLOWED_PRIVATE_HOSTS_ENV_VAR = "KUMIKO_MAIL_ALLOWED_PRIVATE_HOSTS";
|
|
23
23
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# host-routing
|
|
2
|
+
|
|
3
|
+
Tenant routing by host or path for apps with tenant subdomains, a tenant path
|
|
4
|
+
prefix or locale-prefixed marketing pages. Two halves:
|
|
5
|
+
|
|
6
|
+
- `createHostRoutingFeature(options)`: the server half. In `tenantBy: "host"` it
|
|
7
|
+
registers an authoritative tenant resolver (`<key>.<baseDomain>` → tenant),
|
|
8
|
+
so anonymous API calls get their tenant from the Host header only; a
|
|
9
|
+
disagreeing `X-Tenant` header or cookie answers `400 tenant_mismatch`, and the
|
|
10
|
+
apex or an unknown host answers `400 tenant_required`. Set
|
|
11
|
+
`apexAnonymousTenantId` and the apex answers as that tenant instead (host
|
|
12
|
+
mode: authoritative; path mode: only when the client names no tenant). Path
|
|
13
|
+
keys may be any 1 to 50 unreserved URL characters, subdomain keys must be
|
|
14
|
+
one lowercase DNS label. In both modes it
|
|
15
|
+
registers a tenant existence check: a client-named tenant must exist, be
|
|
16
|
+
enabled and be active. It also owns the anonymous, rate-limited
|
|
17
|
+
`host-routing:query:tenant-key-exists` query.
|
|
18
|
+
- `createHostDispatch(options)`: the page half for `runProdApp({ hostDispatch })`.
|
|
19
|
+
It picks the HTML file and optional CSP per host, answers the locale redirect
|
|
20
|
+
and returns 404 for unknown tenants and unknown hosts.
|
|
21
|
+
|
|
22
|
+
The dev server uses the same decision through
|
|
23
|
+
`toDevHostDispatch(dispatch, { entries, staticDir })` from
|
|
24
|
+
`@cosmicdrift/kumiko-dev-server`.
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import {
|
|
30
|
+
createHostDispatch,
|
|
31
|
+
createHostRoutingFeature,
|
|
32
|
+
type HostRoutingOptions,
|
|
33
|
+
} from "@cosmicdrift/kumiko-bundled-features/host-routing";
|
|
34
|
+
import { resolveAnonymousAccessFromRegistry } from "@cosmicdrift/kumiko-bundled-features/auth-foundation";
|
|
35
|
+
|
|
36
|
+
const routing: HostRoutingOptions = {
|
|
37
|
+
tenantBy: "host",
|
|
38
|
+
baseDomain: "example.com",
|
|
39
|
+
apex: { file: "index.html", localeFiles: { en: "en/index.html" } },
|
|
40
|
+
tenant: { file: "app.html", csp: "default-src 'self'; frame-ancestors 'none'" },
|
|
41
|
+
unknownTenant: { file: "unknown-tenant.html" },
|
|
42
|
+
hosts: { "admin.example.com": { file: "admin.html" } },
|
|
43
|
+
locales: { default: "de", prefixed: ["en"] },
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
runProdApp({
|
|
47
|
+
features: [...FEATURES, createHostRoutingFeature(routing)],
|
|
48
|
+
anonymousAccess: () => ({}),
|
|
49
|
+
hostDispatch: createHostDispatch(routing),
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`anonymousAccess` stays an app opt-in: the providers are merged in only when
|
|
54
|
+
the app sets it.
|
|
55
|
+
|
|
56
|
+
## Options
|
|
57
|
+
|
|
58
|
+
| Option | Meaning |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `tenantBy` | `"host"` (`<key>.<baseDomain>`) or `"path"` with `tenantPathPrefix` (`/t/<key>/...` on the apex) |
|
|
61
|
+
| `baseDomain` | Apex hostname, lowercase, no port. `www.<baseDomain>` counts as apex |
|
|
62
|
+
| `apex` | `{ file, csp?, localeFiles? }` for the apex |
|
|
63
|
+
| `tenant` | `{ file, csp? }` for a known tenant and for the bare path prefix |
|
|
64
|
+
| `unknownTenant` | `{ file, csp? }` served with 404; omit for a bare 404 |
|
|
65
|
+
| `hosts` | Further fixed hostnames with their own surface, checked first |
|
|
66
|
+
| `apexAnonymousTenantId` | Tenant for anonymous API calls on the apex (e.g. `SYSTEM_TENANT_ID` for public signup); omit and the apex has none |
|
|
67
|
+
| `locales` | `{ default, prefixed }`: `/<default>/...` answers 301 to the unprefixed path, `/<prefixed>/...` serves `apex.localeFiles[locale]` |
|
|
68
|
+
|
|
69
|
+
A `csp` replaces runProdApp's default CSP for that surface; without it the
|
|
70
|
+
default applies. Options are validated when the feature or dispatch is built.
|
|
71
|
+
|
|
72
|
+
## Security
|
|
73
|
+
|
|
74
|
+
- Only plain DNS names (optional port) are routed. `X-Forwarded-Host` is never
|
|
75
|
+
read; userinfo, IPv6 literals, lists or nested subdomains fall to a bare 404
|
|
76
|
+
without a lookup.
|
|
77
|
+
- Redirect targets are same-origin paths; leading slashes and backslashes are
|
|
78
|
+
collapsed, so `/de//evil.example` never becomes a protocol-relative URL.
|
|
79
|
+
- The key query returns only `{ exists }`, which the 404 page makes public
|
|
80
|
+
anyway. Over its rate limit the dispatch serves the tenant shell; the API
|
|
81
|
+
behind it still resolves the tenant itself.
|
|
82
|
+
- In `tenantBy: "path"` no resolver is registered, so the client names its
|
|
83
|
+
tenant with `X-Tenant`; the existence check still rejects unknown, disabled
|
|
84
|
+
and destroyed tenants.
|
|
85
|
+
|
|
86
|
+
## Not covered
|
|
87
|
+
|
|
88
|
+
Custom domains per tenant, legacy host redirects and app-specific query
|
|
89
|
+
allowlists stay in the app: wrap the dispatch function and fall through to it.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.370.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "createHostRoutingFeature and createHostDispatch route tenants by host or path",
|
|
6
|
+
"detail": "One HostRoutingOptions object ({ tenantBy: \"host\" } or { tenantBy: \"path\", tenantPathPrefix }, plus baseDomain, apex, tenant, unknownTenant?, hosts?, locales?) drives both halves. createHostRoutingFeature registers an authoritative Host-header tenant resolver in host mode and, in both modes, an existence check that admits only enabled, active tenants. apexAnonymousTenantId gives anonymous apex calls a tenant (e.g. SYSTEM_TENANT_ID); without it the apex answers tenant_required. createHostDispatch is a runProdApp hostDispatch: HTML file and optional CSP per surface (without csp the runProdApp default applies), a 301 from the default-locale prefix to the unprefixed path, and 404 for unknown tenants and hosts. toDevHostDispatch(dispatch, { entries, staticDir }) from @cosmicdrift/kumiko-dev-server plugs the same decision into the dev server. Apps with their own routing feature and hostDispatch move to these; app-specific redirects or custom domains wrap the dispatch function."
|
|
7
|
+
}
|
|
8
|
+
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const HOST_ROUTING_FEATURE = "host-routing";
|
|
2
|
+
|
|
3
|
+
export const HostRoutingQueries = {
|
|
4
|
+
tenantKeyExists: `${HOST_ROUTING_FEATURE}:query:tenant-key-exists`,
|
|
5
|
+
} as const;
|
|
6
|
+
|
|
7
|
+
// Matches tenant:write:create's key limit; keeps lookups for absurd keys out
|
|
8
|
+
// of the database.
|
|
9
|
+
export const TENANT_KEY_MAX_LENGTH = 50;
|
|
10
|
+
// A subdomain is one lowercase DNS label, so tenant keys outside this shape
|
|
11
|
+
// are only reachable in path mode.
|
|
12
|
+
export const TENANT_KEY_PATTERN = /^[a-z0-9](?:[a-z0-9-]{0,48}[a-z0-9])?$/;
|
|
13
|
+
|
|
14
|
+
export function isTenantKeyCandidate(value: string): boolean {
|
|
15
|
+
return value.length <= TENANT_KEY_MAX_LENGTH && TENANT_KEY_PATTERN.test(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Path mode takes any key made of unreserved URL characters, since the tenant
|
|
19
|
+
// feature itself only limits the length.
|
|
20
|
+
const PATH_TENANT_KEY_PATTERN = /^[A-Za-z0-9._~-]+$/;
|
|
21
|
+
|
|
22
|
+
export function isPathTenantKeyCandidate(value: string): boolean {
|
|
23
|
+
return value.length <= TENANT_KEY_MAX_LENGTH && PATH_TENANT_KEY_PATTERN.test(value);
|
|
24
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
import { RateLimitError, ValidationError } from "@cosmicdrift/kumiko-framework/errors";
|
|
3
|
+
import type { PageHeadSystemQuery } from "@cosmicdrift/kumiko-headless/apex";
|
|
4
|
+
import * as z from "zod";
|
|
5
|
+
import { HostRoutingQueries, isPathTenantKeyCandidate, isTenantKeyCandidate } from "./constants.ts";
|
|
6
|
+
import { classifyHost } from "./host.ts";
|
|
7
|
+
import type { HostRoutingOptions, HostRoutingSurface } from "./options.ts";
|
|
8
|
+
import { validateHostRoutingOptions } from "./validate-options.ts";
|
|
9
|
+
|
|
10
|
+
// Structurally identical to server-runtime's HostDispatchResult. Defined here
|
|
11
|
+
// because server-runtime depends on bundled-features, not the other way round;
|
|
12
|
+
// dev-server pins the compatibility with a type test.
|
|
13
|
+
export type HostRoutingDispatchResult =
|
|
14
|
+
| { readonly kind: "html"; readonly file: string; readonly csp?: string }
|
|
15
|
+
| { readonly kind: "redirect"; readonly to: string; readonly status?: 301 | 302 }
|
|
16
|
+
| { readonly kind: "not-found"; readonly file?: string; readonly csp?: string };
|
|
17
|
+
|
|
18
|
+
export type HostRoutingRequest = {
|
|
19
|
+
readonly host: string;
|
|
20
|
+
readonly path: string;
|
|
21
|
+
// Query string incl. leading "?", "" if none.
|
|
22
|
+
readonly search: string;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type HostRoutingDispatchFn = (
|
|
26
|
+
req: HostRoutingRequest,
|
|
27
|
+
deps: { readonly systemQuery: PageHeadSystemQuery },
|
|
28
|
+
) => Promise<HostRoutingDispatchResult>;
|
|
29
|
+
|
|
30
|
+
const tenantKeyExistsResultSchema = z.object({ exists: z.boolean() });
|
|
31
|
+
|
|
32
|
+
async function isTenantKeyKnown(systemQuery: PageHeadSystemQuery, key: string): Promise<boolean> {
|
|
33
|
+
let result: unknown;
|
|
34
|
+
try {
|
|
35
|
+
result = await systemQuery(HostRoutingQueries.tenantKeyExists, { key }, SYSTEM_TENANT_ID);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error instanceof ValidationError) return false;
|
|
38
|
+
// Over the rate limit every key looks the same: serve the tenant shell,
|
|
39
|
+
// which leaks nothing; the API behind it still resolves the tenant itself.
|
|
40
|
+
if (error instanceof RateLimitError) return true;
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
return tenantKeyExistsResultSchema.parse(result).exists;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function serve(
|
|
47
|
+
surface: HostRoutingSurface,
|
|
48
|
+
file: string = surface.file,
|
|
49
|
+
): HostRoutingDispatchResult {
|
|
50
|
+
return surface.csp === undefined
|
|
51
|
+
? { kind: "html", file }
|
|
52
|
+
: { kind: "html", file, csp: surface.csp };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function notFound(surface: HostRoutingSurface | undefined): HostRoutingDispatchResult {
|
|
56
|
+
if (surface === undefined) return { kind: "not-found" };
|
|
57
|
+
return surface.csp === undefined
|
|
58
|
+
? { kind: "not-found", file: surface.file }
|
|
59
|
+
: { kind: "not-found", file: surface.file, csp: surface.csp };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Redirect targets are always same-origin paths. Collapsing leading slashes
|
|
63
|
+
// and backslashes keeps "/de//evil.example" from turning into the
|
|
64
|
+
// protocol-relative "//evil.example".
|
|
65
|
+
function sameOriginPath(path: string): string {
|
|
66
|
+
return `/${path.replace(/^[/\\]+/, "")}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function splitFirstSegment(path: string): { readonly segment: string; readonly rest: string } {
|
|
70
|
+
const withoutLeading = path.replace(/^\/+/, "");
|
|
71
|
+
const slash = withoutLeading.indexOf("/");
|
|
72
|
+
if (slash === -1) return { segment: withoutLeading, rest: "/" };
|
|
73
|
+
return { segment: withoutLeading.slice(0, slash), rest: withoutLeading.slice(slash) };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function apexPage(options: HostRoutingOptions, req: HostRoutingRequest): HostRoutingDispatchResult {
|
|
77
|
+
const { apex, locales } = options;
|
|
78
|
+
if (locales === undefined) return serve(apex);
|
|
79
|
+
const { segment, rest } = splitFirstSegment(req.path);
|
|
80
|
+
if (segment === locales.default) {
|
|
81
|
+
return { kind: "redirect", to: `${sameOriginPath(rest)}${req.search}`, status: 301 };
|
|
82
|
+
}
|
|
83
|
+
const locale = locales.prefixed.includes(segment) ? segment : locales.default;
|
|
84
|
+
return serve(apex, apex.localeFiles?.[locale] ?? apex.file);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function tenantPage(
|
|
88
|
+
options: HostRoutingOptions,
|
|
89
|
+
key: string | null,
|
|
90
|
+
systemQuery: PageHeadSystemQuery,
|
|
91
|
+
): Promise<HostRoutingDispatchResult> {
|
|
92
|
+
// No key (bare tenant prefix): the shell handles login and tenant choice.
|
|
93
|
+
if (key === null) return serve(options.tenant);
|
|
94
|
+
const isCandidate = options.tenantBy === "path" ? isPathTenantKeyCandidate : isTenantKeyCandidate;
|
|
95
|
+
if (!isCandidate(key)) return notFound(options.unknownTenant);
|
|
96
|
+
return (await isTenantKeyKnown(systemQuery, key))
|
|
97
|
+
? serve(options.tenant)
|
|
98
|
+
: notFound(options.unknownTenant);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function tenantKeyFromPath(prefix: string, path: string): string | null | undefined {
|
|
102
|
+
if (path !== prefix && !path.startsWith(`${prefix}/`)) return undefined;
|
|
103
|
+
const { segment } = splitFirstSegment(path.slice(prefix.length));
|
|
104
|
+
return segment === "" ? null : segment;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// The routing decision for runProdApp's `hostDispatch` (and, via
|
|
108
|
+
// toDevHostDispatch, the dev server). Unknown hosts fail closed with 404.
|
|
109
|
+
export function createHostDispatch(options: HostRoutingOptions): HostRoutingDispatchFn {
|
|
110
|
+
validateHostRoutingOptions(options);
|
|
111
|
+
return async (req, { systemQuery }) => {
|
|
112
|
+
const host = classifyHost(req.host, options);
|
|
113
|
+
switch (host.kind) {
|
|
114
|
+
case "fixed":
|
|
115
|
+
return serve(host.surface);
|
|
116
|
+
case "unknown":
|
|
117
|
+
return notFound(undefined);
|
|
118
|
+
case "subdomain":
|
|
119
|
+
if (options.tenantBy !== "host") return notFound(undefined);
|
|
120
|
+
return tenantPage(options, host.key, systemQuery);
|
|
121
|
+
case "apex": {
|
|
122
|
+
if (options.tenantBy === "path") {
|
|
123
|
+
const key = tenantKeyFromPath(options.tenantPathPrefix, req.path);
|
|
124
|
+
if (key !== undefined) return tenantPage(options, key, systemQuery);
|
|
125
|
+
}
|
|
126
|
+
return apexPage(options, req);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { DbConnection, TenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
2
|
+
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
3
|
+
import {
|
|
4
|
+
defineFeature,
|
|
5
|
+
defineQueryHandler,
|
|
6
|
+
type FeatureDefinition,
|
|
7
|
+
isSystemTenant,
|
|
8
|
+
type TenantId,
|
|
9
|
+
} from "@cosmicdrift/kumiko-framework/engine";
|
|
10
|
+
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
11
|
+
import * as z from "zod";
|
|
12
|
+
import {
|
|
13
|
+
EXT_TENANT_EXISTENCE,
|
|
14
|
+
EXT_TENANT_RESOLVER,
|
|
15
|
+
type TenantExistenceProvider,
|
|
16
|
+
type TenantResolverProvider,
|
|
17
|
+
} from "../auth-foundation/index.ts";
|
|
18
|
+
import {
|
|
19
|
+
isTenantServingPublicContent,
|
|
20
|
+
type TenantLifecycleStatus,
|
|
21
|
+
tenantTable,
|
|
22
|
+
} from "../tenant/index.ts";
|
|
23
|
+
import { HOST_ROUTING_FEATURE, TENANT_KEY_MAX_LENGTH } from "./constants.ts";
|
|
24
|
+
import { classifyHost } from "./host.ts";
|
|
25
|
+
import type { HostRoutingOptions } from "./options.ts";
|
|
26
|
+
import { validateHostRoutingOptions } from "./validate-options.ts";
|
|
27
|
+
|
|
28
|
+
type TenantRow = {
|
|
29
|
+
readonly id: TenantId;
|
|
30
|
+
readonly isEnabled: boolean;
|
|
31
|
+
readonly status: TenantLifecycleStatus;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Disabled tenants and tenants in any destroy phase are not routable, the same
|
|
35
|
+
// rule public files and pages follow.
|
|
36
|
+
async function servingTenantIdByKey(
|
|
37
|
+
db: DbConnection | TenantDb,
|
|
38
|
+
key: string,
|
|
39
|
+
): Promise<TenantId | null> {
|
|
40
|
+
const row = await fetchOne<TenantRow>(db, tenantTable, { key });
|
|
41
|
+
return row !== undefined && isTenantServingPublicContent(row) ? row.id : null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function isTenantServing(db: DbConnection, id: TenantId): Promise<boolean> {
|
|
45
|
+
const row = await fetchOne<TenantRow>(db, tenantTable, { id });
|
|
46
|
+
return row !== undefined && isTenantServingPublicContent(row);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type HostHeaderReader = { readonly req: { readonly header: (name: string) => string | undefined } };
|
|
50
|
+
|
|
51
|
+
// auth-foundation types the Hono context as unknown to stay free of a hono dep.
|
|
52
|
+
function isHostHeaderReader(c: unknown): c is HostHeaderReader {
|
|
53
|
+
return (
|
|
54
|
+
typeof c === "object" &&
|
|
55
|
+
c !== null &&
|
|
56
|
+
"req" in c &&
|
|
57
|
+
typeof c.req === "object" &&
|
|
58
|
+
c.req !== null &&
|
|
59
|
+
"header" in c.req &&
|
|
60
|
+
typeof c.req.header === "function"
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Returns only { exists }: the same fact the tenant 404 page already makes
|
|
65
|
+
// public, never other tenant fields. Rate-limited so it is no cheap oracle.
|
|
66
|
+
const tenantKeyExistsQuery = defineQueryHandler({
|
|
67
|
+
name: "tenant-key-exists",
|
|
68
|
+
schema: z.object({ key: z.string().min(1).max(TENANT_KEY_MAX_LENGTH) }),
|
|
69
|
+
access: { roles: ["anonymous"] },
|
|
70
|
+
rateLimit: { per: "ip+handler", limit: 120, windowSeconds: 60 },
|
|
71
|
+
// Page-routing plumbing, not a task an agent performs.
|
|
72
|
+
agent: { expose: false },
|
|
73
|
+
description:
|
|
74
|
+
"Anonymous existence check for a tenant key, backing the unknown-tenant 404 of the host-routing hostDispatch. Returns only { exists }.",
|
|
75
|
+
handler: async (query, ctx) => {
|
|
76
|
+
if (!ctx.systemDb) {
|
|
77
|
+
throw new InternalError({
|
|
78
|
+
message: "host-routing:query:tenant-key-exists requires ctx.systemDb (r.systemScope())",
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const db = ctx.systemDb.acknowledgeCrossTenant(
|
|
82
|
+
"tenant-key existence check for the host-routing 404 — publicly observable via the 404 itself",
|
|
83
|
+
);
|
|
84
|
+
return { exists: (await servingTenantIdByKey(db, query.payload.key)) !== null };
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
function tenantResolverFor(options: HostRoutingOptions): TenantResolverProvider | undefined {
|
|
89
|
+
const apexTenantId = options.apexAnonymousTenantId ?? null;
|
|
90
|
+
if (options.tenantBy === "host") {
|
|
91
|
+
return {
|
|
92
|
+
trust: "authoritative",
|
|
93
|
+
build:
|
|
94
|
+
({ db }) =>
|
|
95
|
+
async (c: unknown): Promise<TenantId | null> => {
|
|
96
|
+
if (!isHostHeaderReader(c)) return null;
|
|
97
|
+
const host = classifyHost(c.req.header("Host") ?? "", options);
|
|
98
|
+
if (host.kind === "subdomain") return servingTenantIdByKey(db, host.key);
|
|
99
|
+
// Fixed and unknown hosts have no anonymous tenant: an authoritative
|
|
100
|
+
// null answers tenant_required, whatever X-Tenant says.
|
|
101
|
+
return host.kind === "apex" ? apexTenantId : null;
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (apexTenantId === null) return undefined;
|
|
106
|
+
// Path mode: the client names its tenant; the apex default only fills in
|
|
107
|
+
// when it does not.
|
|
108
|
+
return {
|
|
109
|
+
trust: "fallback-only",
|
|
110
|
+
build: () => async (c: unknown) => {
|
|
111
|
+
if (!isHostHeaderReader(c)) return null;
|
|
112
|
+
return classifyHost(c.req.header("Host") ?? "", options).kind === "apex"
|
|
113
|
+
? apexTenantId
|
|
114
|
+
: null;
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Server half of host routing: the tenant for anonymous API requests comes
|
|
120
|
+
// from the Host header only (never from X-Tenant), and a client-named tenant
|
|
121
|
+
// must exist, be enabled and be active. The page half is createHostDispatch.
|
|
122
|
+
export function createHostRoutingFeature(options: HostRoutingOptions): FeatureDefinition {
|
|
123
|
+
validateHostRoutingOptions(options);
|
|
124
|
+
return defineFeature(HOST_ROUTING_FEATURE, (r) => {
|
|
125
|
+
r.describe(
|
|
126
|
+
"Host- and path-based tenant routing: an authoritative tenant resolver from the subdomain (tenantBy host), a tenant existence check against enabled, active tenants, and the tenant-key query behind createHostDispatch, which picks the HTML file, CSP, locale redirect or 404 per host for runProdApp's hostDispatch.",
|
|
127
|
+
);
|
|
128
|
+
r.requires({ features: ["auth-foundation", "tenant"] });
|
|
129
|
+
r.systemScope();
|
|
130
|
+
r.queryHandler(tenantKeyExistsQuery);
|
|
131
|
+
|
|
132
|
+
const resolver = tenantResolverFor(options);
|
|
133
|
+
if (resolver !== undefined) {
|
|
134
|
+
// biome-ignore lint/correctness/useHookAtTopLevel: r.useExtension is a registrar method, not a React hook; path mode without an apex tenant must leave the resolver slot free.
|
|
135
|
+
r.useExtension(EXT_TENANT_RESOLVER, "host", resolver);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const existence: TenantExistenceProvider = {
|
|
139
|
+
build:
|
|
140
|
+
({ db }) =>
|
|
141
|
+
(tenantId: string) =>
|
|
142
|
+
isSystemTenant(tenantId) ? true : isTenantServing(db, tenantId),
|
|
143
|
+
};
|
|
144
|
+
r.useExtension(EXT_TENANT_EXISTENCE, "active-tenant", existence);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { isTenantKeyCandidate } from "./constants.ts";
|
|
2
|
+
import type { HostRoutingOptions, HostRoutingSurface } from "./options.ts";
|
|
3
|
+
|
|
4
|
+
// Only plain DNS names (plus an optional port) are routable. Anything else,
|
|
5
|
+
// e.g. userinfo ("a@b"), IPv6 literals or stray characters, never matches a
|
|
6
|
+
// configured domain and must not reach URL parsing or a DB lookup.
|
|
7
|
+
const HOST_HEADER_PATTERN = /^[a-z0-9.-]+(?::[0-9]{1,5})?$/;
|
|
8
|
+
|
|
9
|
+
export function normalizeHostname(host: string): string | null {
|
|
10
|
+
const lower = host.trim().toLowerCase();
|
|
11
|
+
if (!HOST_HEADER_PATTERN.test(lower)) return null;
|
|
12
|
+
const colon = lower.indexOf(":");
|
|
13
|
+
const hostname = colon === -1 ? lower : lower.slice(0, colon);
|
|
14
|
+
const withoutTrailingDot = hostname.endsWith(".") ? hostname.slice(0, -1) : hostname;
|
|
15
|
+
return withoutTrailingDot === "" ? null : withoutTrailingDot;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type HostClass =
|
|
19
|
+
| { readonly kind: "fixed"; readonly surface: HostRoutingSurface }
|
|
20
|
+
| { readonly kind: "apex" }
|
|
21
|
+
| { readonly kind: "subdomain"; readonly key: string }
|
|
22
|
+
| { readonly kind: "unknown" };
|
|
23
|
+
|
|
24
|
+
export function classifyHost(host: string, options: HostRoutingOptions): HostClass {
|
|
25
|
+
const hostname = normalizeHostname(host);
|
|
26
|
+
if (hostname === null) return { kind: "unknown" };
|
|
27
|
+
// Own-property check: the Host header is attacker-controlled, and a plain
|
|
28
|
+
// "constructor" would otherwise resolve through Object.prototype.
|
|
29
|
+
const fixed =
|
|
30
|
+
options.hosts !== undefined && Object.hasOwn(options.hosts, hostname)
|
|
31
|
+
? options.hosts[hostname]
|
|
32
|
+
: undefined;
|
|
33
|
+
if (fixed !== undefined) return { kind: "fixed", surface: fixed };
|
|
34
|
+
const baseDomain = options.baseDomain.toLowerCase();
|
|
35
|
+
if (hostname === baseDomain || hostname === `www.${baseDomain}`) return { kind: "apex" };
|
|
36
|
+
const suffix = `.${baseDomain}`;
|
|
37
|
+
if (!hostname.endsWith(suffix)) return { kind: "unknown" };
|
|
38
|
+
const label = hostname.slice(0, -suffix.length);
|
|
39
|
+
// Exactly one label: "a.b.<baseDomain>" is not a tenant host.
|
|
40
|
+
if (!isTenantKeyCandidate(label)) return { kind: "unknown" };
|
|
41
|
+
return { kind: "subdomain", key: label };
|
|
42
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export {
|
|
2
|
+
HOST_ROUTING_FEATURE,
|
|
3
|
+
HostRoutingQueries,
|
|
4
|
+
isTenantKeyCandidate,
|
|
5
|
+
TENANT_KEY_MAX_LENGTH,
|
|
6
|
+
} from "./constants.ts";
|
|
7
|
+
export {
|
|
8
|
+
createHostDispatch,
|
|
9
|
+
type HostRoutingDispatchFn,
|
|
10
|
+
type HostRoutingDispatchResult,
|
|
11
|
+
type HostRoutingRequest,
|
|
12
|
+
} from "./dispatch.ts";
|
|
13
|
+
export { createHostRoutingFeature } from "./feature.ts";
|
|
14
|
+
export { normalizeHostname } from "./host.ts";
|
|
15
|
+
export type {
|
|
16
|
+
HostRoutingApexSurface,
|
|
17
|
+
HostRoutingLocales,
|
|
18
|
+
HostRoutingOptions,
|
|
19
|
+
HostRoutingSurface,
|
|
20
|
+
HostRoutingTenantMode,
|
|
21
|
+
} from "./options.ts";
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
|
+
|
|
3
|
+
// What a host (or a tenant) gets served on the HTML fallback.
|
|
4
|
+
export type HostRoutingSurface = {
|
|
5
|
+
// HTML file relative to the prod staticDir, e.g. "index.html" or "admin.html".
|
|
6
|
+
readonly file: string;
|
|
7
|
+
// Replaces the default CSP for this surface. Omit to keep runProdApp's default.
|
|
8
|
+
readonly csp?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type HostRoutingApexSurface = HostRoutingSurface & {
|
|
12
|
+
// Per-locale file for the apex, keyed by locale; falls back to `file`.
|
|
13
|
+
readonly localeFiles?: Readonly<Record<string, string>>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type HostRoutingLocales = {
|
|
17
|
+
// Served unprefixed; "/<default>/..." answers 301 to the unprefixed path.
|
|
18
|
+
readonly default: string;
|
|
19
|
+
// Served under "/<locale>/...".
|
|
20
|
+
readonly prefixed: readonly string[];
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type HostRoutingTenantMode =
|
|
24
|
+
// <key>.<baseDomain> names the tenant.
|
|
25
|
+
| { readonly tenantBy: "host" }
|
|
26
|
+
// <baseDomain><tenantPathPrefix>/<key>/... names the tenant.
|
|
27
|
+
| { readonly tenantBy: "path"; readonly tenantPathPrefix: string };
|
|
28
|
+
|
|
29
|
+
export type HostRoutingOptions = HostRoutingTenantMode & {
|
|
30
|
+
// Apex host without port, e.g. "example.com". "www.<baseDomain>" counts as apex.
|
|
31
|
+
readonly baseDomain: string;
|
|
32
|
+
readonly apex: HostRoutingApexSurface;
|
|
33
|
+
// Served for a known, enabled tenant (and for the bare tenant path prefix).
|
|
34
|
+
readonly tenant: HostRoutingSurface;
|
|
35
|
+
// Served with status 404 for an unknown or disabled tenant. Omit for a bare 404.
|
|
36
|
+
readonly unknownTenant?: HostRoutingSurface;
|
|
37
|
+
// Further fixed hosts (full hostname, lowercase, without port), checked first.
|
|
38
|
+
readonly hosts?: Readonly<Record<string, HostRoutingSurface>>;
|
|
39
|
+
readonly locales?: HostRoutingLocales;
|
|
40
|
+
// Tenant for anonymous API calls on the apex (e.g. SYSTEM_TENANT_ID for
|
|
41
|
+
// public signup forms). Omit and the apex answers tenant_required.
|
|
42
|
+
readonly apexAnonymousTenantId?: TenantId;
|
|
43
|
+
};
|