@cosmicdrift/kumiko-samples 0.386.0 → 0.388.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +9 -2
- package/packages/bundled-features/src/agent-tools/changes.json +6 -0
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +9 -9
- package/packages/bundled-features/src/audit/changes.json +12 -0
- package/packages/bundled-features/src/audit/handlers/audit-events.ts +1 -1
- package/packages/bundled-features/src/audit/screens.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
- 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 +34 -37
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
- package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
- package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
- package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
- package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
- package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
- package/packages/bundled-features/src/auth-mfa/feature-exports.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/feature.ts +6 -0
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +9 -4
- package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
- package/packages/bundled-features/src/auth-mfa/web/mfa-code-or-recovery-field.tsx +68 -0
- package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +23 -13
- package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +23 -13
- package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +15 -6
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +71 -24
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/changes.json +55 -0
- package/packages/bundled-features/src/billing-foundation/checkout-core.ts +32 -42
- package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +8 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +2 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +14 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +3 -4
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +12 -6
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +35 -19
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +14 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +5 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +8 -10
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +23 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +45 -44
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +71 -6
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +19 -17
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
- package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/plan-switch-preview.query.ts +65 -0
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +29 -22
- package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +44 -8
- package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +72 -82
- package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +14 -1
- package/packages/bundled-features/src/billing-foundation/i18n.ts +22 -0
- package/packages/bundled-features/src/billing-foundation/index.ts +2 -0
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +62 -27
- package/packages/bundled-features/src/billing-foundation/plan-switch.ts +84 -0
- package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
- package/packages/bundled-features/src/billing-foundation/types.ts +144 -66
- package/packages/bundled-features/src/billing-foundation/validate-options.ts +19 -0
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +123 -51
- package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +89 -42
- package/packages/bundled-features/src/billing-foundation/web/constants.ts +4 -0
- package/packages/bundled-features/src/billing-foundation/web/plan-price.ts +55 -0
- package/packages/bundled-features/src/billing-foundation/web/plan-switch-confirm-dialog.tsx +224 -0
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
- package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
- package/packages/bundled-features/src/cap-counter/cap-reservation.ts +5 -1
- package/packages/bundled-features/src/cap-counter/changes.json +18 -0
- package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +66 -68
- package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
- package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
- package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -2
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/changes.json +6 -0
- package/packages/bundled-features/src/channel-email/feature.ts +1 -1
- package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
- package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
- package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
- package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
- package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
- package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
- package/packages/bundled-features/src/config/changes.json +12 -0
- package/packages/bundled-features/src/config/handlers/cascade.query.ts +4 -2
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/handlers/values.query.ts +4 -2
- package/packages/bundled-features/src/config/resolver.ts +4 -4
- package/packages/bundled-features/src/config/table.ts +10 -10
- package/packages/bundled-features/src/config/write-helpers.ts +28 -9
- package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +23 -21
- package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
- package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
- package/packages/bundled-features/src/custom-fields/events.ts +7 -8
- package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.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 +10 -12
- package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
- package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
- package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
- package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
- package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
- package/packages/bundled-features/src/data-retention/feature.ts +11 -18
- package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
- package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
- package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
- package/packages/bundled-features/src/data-retention/presets.ts +18 -23
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
- package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
- package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
- package/packages/bundled-features/src/delivery/changes.json +30 -0
- package/packages/bundled-features/src/delivery/channel-context.ts +9 -3
- package/packages/bundled-features/src/delivery/db/queries/preferences.ts +2 -2
- package/packages/bundled-features/src/delivery/delivery-service.ts +35 -5
- package/packages/bundled-features/src/delivery/feature.ts +3 -3
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
- package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +20 -1
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe-link.ts +3 -1
- package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +1 -0
- package/packages/bundled-features/src/delivery/unsubscribe-page.ts +6 -0
- package/packages/bundled-features/src/delivery/unsubscribe.ts +40 -19
- package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
- package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.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 +1 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
- package/packages/bundled-features/src/file-foundation/index.ts +1 -0
- package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -1
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/env-named-feature.ts +0 -2
- package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
- package/packages/bundled-features/src/files/README.md +1 -1
- package/packages/bundled-features/src/files/feature.ts +6 -6
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
- package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
- package/packages/bundled-features/src/folders/web/tree.ts +5 -5
- package/packages/bundled-features/src/form-draft/changes.json +6 -0
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +3 -3
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/decrypt-draft.ts +4 -1
- package/packages/bundled-features/src/form-draft/entity.ts +3 -3
- package/packages/bundled-features/src/form-draft/feature.ts +4 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
- package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
- package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
- package/packages/bundled-features/src/host-routing/README.md +1 -1
- package/packages/bundled-features/src/host-routing/changes.json +6 -0
- package/packages/bundled-features/src/host-routing/dispatch.ts +16 -17
- package/packages/bundled-features/src/host-routing/options.ts +2 -1
- package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
- package/packages/bundled-features/src/inbound-mail-foundation/changes.json +18 -0
- package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
- package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
- package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +27 -15
- package/packages/bundled-features/src/inbound-mail-foundation/i18n.ts +0 -1
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
- package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
- package/packages/bundled-features/src/inbound-mail-foundation/screens.ts +0 -3
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +70 -70
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +101 -84
- package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
- package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
- package/packages/bundled-features/src/jobs/changes.json +13 -0
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
- package/packages/bundled-features/src/jobs/events.ts +1 -1
- package/packages/bundled-features/src/jobs/feature.ts +20 -11
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +45 -40
- package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +63 -59
- package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +19 -19
- package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
- package/packages/bundled-features/src/jobs/screens.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
- package/packages/bundled-features/src/ledger/entity.ts +5 -5
- package/packages/bundled-features/src/ledger/feature.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
- package/packages/bundled-features/src/ledger/recurring.ts +12 -12
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
- package/packages/bundled-features/src/ledger/web/index.ts +7 -7
- package/packages/bundled-features/src/legal-pages/README.md +1 -1
- package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
- package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
- package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
- package/packages/bundled-features/src/mail-foundation/feature.ts +31 -30
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
- package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
- package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
- package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
- package/packages/bundled-features/src/managed-pages/table.ts +16 -15
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
- package/packages/bundled-features/src/notes-history/entity.ts +4 -4
- package/packages/bundled-features/src/notes-history/feature.ts +2 -2
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/page-render/layout.ts +9 -9
- package/packages/bundled-features/src/page-render/markdown.ts +11 -11
- package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +9 -6
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
- package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
- package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
- package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
- package/packages/bundled-features/src/renderer-pdf/changes.json +6 -0
- package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +27 -10
- package/packages/bundled-features/src/secrets/feature.ts +9 -9
- package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
- package/packages/bundled-features/src/seo/feature.ts +3 -3
- package/packages/bundled-features/src/sessions/constants.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +16 -11
- 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 +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
- package/packages/bundled-features/src/sessions/screens.ts +2 -2
- package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
- package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
- package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
- package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +11 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- package/packages/bundled-features/src/shared/index.ts +1 -1
- package/packages/bundled-features/src/shared/mail-template-body.ts +10 -3
- package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
- package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
- package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
- package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
- package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
- package/packages/bundled-features/src/step-dispatcher/changes.json +6 -0
- package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -0
- package/packages/bundled-features/src/subscription-dodo/changes.json +14 -0
- package/packages/bundled-features/src/subscription-dodo/client.ts +45 -0
- package/packages/bundled-features/src/subscription-dodo/constants.ts +24 -0
- package/packages/bundled-features/src/subscription-dodo/feature.ts +207 -0
- package/packages/bundled-features/src/subscription-dodo/index.ts +16 -0
- package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +345 -0
- package/packages/bundled-features/src/subscription-dodo/runtime.ts +126 -0
- package/packages/bundled-features/src/subscription-dodo/verify-webhook.ts +262 -0
- package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
- package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
- package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
- package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
- package/packages/bundled-features/src/subscription-stripe/changes.json +12 -0
- package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +45 -43
- package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +9 -8
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
- package/packages/bundled-features/src/tags/feature.ts +3 -3
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +41 -14
- package/packages/bundled-features/src/template-resolver/changes.json +48 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -0
- package/packages/bundled-features/src/template-resolver/feature.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +27 -5
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +8 -7
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -20
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +15 -5
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/tenant-override-counts.query.ts +9 -5
- package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +8 -6
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +44 -5
- package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +37 -26
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +7 -2
- package/packages/bundled-features/src/template-resolver/seeding.ts +36 -18
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +22 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +0 -11
- package/packages/bundled-features/src/template-resolver/template-meta.ts +12 -4
- package/packages/bundled-features/src/template-resolver/template-preview.ts +11 -3
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/template-resolver/web/constants.ts +7 -5
- package/packages/bundled-features/src/template-resolver/web/index.ts +7 -0
- package/packages/bundled-features/src/template-resolver/web/mail-layout-constants.ts +8 -0
- package/packages/bundled-features/src/tenant/changes.json +6 -0
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +10 -4
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +8 -5
- package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
- package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
- package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
- package/packages/bundled-features/src/tenant/screens.ts +1 -1
- package/packages/bundled-features/src/tenant/seeding.ts +19 -18
- package/packages/bundled-features/src/tenant/testing.ts +5 -6
- package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
- package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
- package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
- package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
- package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
- package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/changes.json +6 -0
- package/packages/bundled-features/src/tenant-lifecycle/constants.ts +5 -0
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +7 -3
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
- package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
- package/packages/bundled-features/src/tier-engine/changes.json +6 -0
- package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
- package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
- package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
- package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +12 -9
- package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
- package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
- package/packages/bundled-features/src/tier-engine/web/constants.ts +3 -3
- package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
- package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
- package/packages/bundled-features/src/user/schema/user.ts +45 -44
- package/packages/bundled-features/src/user/seeding.ts +40 -40
- package/packages/bundled-features/src/user/testing.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
- package/packages/bundled-features/src/user-data-rights/boot-checks.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 +112 -113
- package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
- package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
- 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 +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +169 -280
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +87 -108
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
- package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
- package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
- package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
- package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
- package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
- package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
- 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 +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
- package/packages/bundled-features/src/user-profile/index.ts +3 -3
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
- package/packages/bundled-features/src/waitlist/changes.json +18 -0
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +2 -1
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
- package/packages/bundled-features/src/waitlist/import.ts +5 -0
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +22 -3
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +20 -10
- package/packages/bundled-features/src/waitlist/options.ts +3 -0
- package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
- package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
- package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
- package/samples/apps/styleguide/src/features/widgets/i18n.ts +11 -0
- package/samples/apps/styleguide/src/features/widgets/web/Widgets.tsx +24 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-constants.ts +5 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +90 -15
- package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +16 -6
- package/samples/apps/use-all-bundled/feature-manifest.json +120 -3
- package/samples/apps/use-all-bundled/src/run-config.ts +9 -3
- package/samples/recipes/auth-mfa/README.md +5 -0
- package/samples/recipes/auth-mfa/package.json +5 -2
- package/samples/recipes/auth-mfa/src/web/confirmation-code-step.tsx +49 -0
- package/samples/recipes/auth-mfa/tsconfig.json +8 -0
- package/samples/recipes/env-composition/README.md +3 -1
- package/samples/recipes/env-composition/src/env.ts +2 -0
- package/samples/recipes/legal-pages/README.md +1 -1
- package/samples/recipes/rate-limiting/README.md +18 -0
- package/samples/recipes/rate-limiting/src/feature.ts +12 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +0 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// Test
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Test/seed helper for managed-pages. Creates a page directly through the
|
|
2
|
+
// event-store executor—the same path as the real set handler, but without an
|
|
3
|
+
// access check. Default ifExists="skip".
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
createEventStoreExecutor,
|
|
@@ -33,9 +33,9 @@ export type SeedPageOptions = {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export async function seedPage(db: DbConnection, opts: SeedPageOptions): Promise<{ id: string }> {
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
36
|
+
// The default user must have user.tenantId === opts.tenantId; otherwise the
|
|
37
|
+
// event-store stream ends up in the wrong tenant bucket → version_conflict
|
|
38
|
+
// on subsequent real writes. TestUsers.systemAdmin is testTenantId(1).
|
|
39
39
|
const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
|
|
40
40
|
const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
|
|
41
41
|
|
|
@@ -70,8 +70,8 @@ export async function seedPage(db: DbConnection, opts: SeedPageOptions): Promise
|
|
|
70
70
|
if (!result.isSuccess) {
|
|
71
71
|
throw new Error(`seedPage create failed: ${JSON.stringify(result)}`);
|
|
72
72
|
}
|
|
73
|
-
// @cast-boundary db-row: executor.create result.data
|
|
74
|
-
// Drizzle
|
|
73
|
+
// @cast-boundary db-row: executor.create result.data is the inserted
|
|
74
|
+
// Drizzle row (Record<string, unknown>), projected from RETURNING.
|
|
75
75
|
const data = result.data as Partial<PageRow>;
|
|
76
76
|
if (data.id === undefined) {
|
|
77
77
|
throw new Error("seedPage: executor.create did not return an id");
|
|
@@ -5,12 +5,13 @@ import {
|
|
|
5
5
|
createTextField,
|
|
6
6
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
|
|
8
|
-
// Page —
|
|
9
|
-
//
|
|
10
|
-
// Markdown
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
8
|
+
// Page — a tenant-editable, server-rendered public page (landing,
|
|
9
|
+
// about, custom). Exactly one row per (tenantId, slug, lang). The body is
|
|
10
|
+
// Markdown, rendered securely on the server via page-render. `published`
|
|
11
|
+
// gates delivery to anonymous visitors: drafts return 404. description and
|
|
12
|
+
// ogImage support SEO and social previews. SYSTEM_TENANT_ID is used for
|
|
13
|
+
// app-wide pages; otherwise the page belongs to the tenant resolved from the
|
|
14
|
+
// host via resolveApexTenant during rendering.
|
|
14
15
|
export const pageEntity = createEntity({
|
|
15
16
|
table: "read_pages",
|
|
16
17
|
description:
|
|
@@ -38,12 +39,12 @@ export const pageEntity = createEntity({
|
|
|
38
39
|
personal: false,
|
|
39
40
|
reason: "is_business_data",
|
|
40
41
|
}),
|
|
41
|
-
// Body
|
|
42
|
-
// (Markdown),
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
// maxLengths
|
|
46
|
-
//
|
|
42
|
+
// Body and description are tenant-admin-authored business content
|
|
43
|
+
// (Markdown), not user-generated PII. `multiline` makes the entityEdit
|
|
44
|
+
// renderer output a <textarea> (createLongTextField currently has a
|
|
45
|
+
// rendering gap: edit.ts/render-field.tsx only gates on type==="text").
|
|
46
|
+
// maxLengths mirror the handler schemas (set.write and convention CRUD
|
|
47
|
+
// derive their zod caps from these field maxLengths).
|
|
47
48
|
body: createTextField({
|
|
48
49
|
multiline: { rows: 16 },
|
|
49
50
|
maxLength: 100_000,
|
|
@@ -59,9 +60,9 @@ export const pageEntity = createEntity({
|
|
|
59
60
|
|
|
60
61
|
export const pagesTable = buildEntityTable("page", pageEntity);
|
|
61
62
|
|
|
62
|
-
// Concrete
|
|
63
|
-
// `row["x"] as Y
|
|
64
|
-
// (id, version, tenantId, createdAt, updatedAt, createdBy, updatedBy).
|
|
63
|
+
// Concrete row type — the single source of truth for named values instead
|
|
64
|
+
// of `row["x"] as Y` casts in handlers. Includes entity.fields and standard
|
|
65
|
+
// columns (id, version, tenantId, createdAt, updatedAt, createdBy, updatedBy).
|
|
65
66
|
export type PageRow = {
|
|
66
67
|
readonly id: string;
|
|
67
68
|
readonly version: number;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
// Client
|
|
2
|
-
//
|
|
3
|
-
// (entityList/entityEdit/configEdit),
|
|
4
|
-
//
|
|
5
|
-
// [managedPagesClient()] })
|
|
1
|
+
// Client feature factory for managed-pages. It provides ONLY translations —
|
|
2
|
+
// the screens (page-list/page-edit/branding-settings) are schema-driven
|
|
3
|
+
// (entityList/entityEdit/configEdit), so no custom React components are
|
|
4
|
+
// registered. Apps mount it in createKumikoApp({ clientFeatures:
|
|
5
|
+
// [managedPagesClient()] }) so the admin labels render translated.
|
|
6
6
|
|
|
7
7
|
import { mergeTranslations, type TranslationsByLocale } from "@cosmicdrift/kumiko-renderer";
|
|
8
8
|
import type { ClientFeatureDefinition } from "@cosmicdrift/kumiko-renderer/web";
|
|
9
9
|
import { defaultTranslations } from "./default-translations.ts";
|
|
10
10
|
|
|
11
11
|
export type ManagedPagesClientOptions = {
|
|
12
|
-
/** Key-wise
|
|
12
|
+
/** Key-wise overrides of the default bundles (de/en). */
|
|
13
13
|
readonly translations?: TranslationsByLocale;
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -56,7 +56,7 @@ export const MANAGED_PAGES_I18N: Readonly<Record<string, LocalizedString>> = {
|
|
|
56
56
|
en: "Delete this page?",
|
|
57
57
|
},
|
|
58
58
|
|
|
59
|
-
//
|
|
59
|
+
// Only used when allowCustomCss:true in the screen; supplied unconditionally
|
|
60
60
|
"managed-pages:entity:__config-edit__:field:customCss": { en: "Custom CSS" },
|
|
61
61
|
"managed-pages:branding.section.custom-css": { en: "Custom CSS" },
|
|
62
62
|
};
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
// Strictly append-only by design: no update/delete write-handler is
|
|
16
16
|
// registered (see feature.ts). A correction is a new entry, not an edit —
|
|
17
17
|
// that is the whole point of a note *history* instead of the single
|
|
18
|
-
// overwritable textarea this bundle replaces
|
|
18
|
+
// overwritable textarea this bundle replaces.
|
|
19
19
|
//
|
|
20
20
|
// `body` is about the HOST entity (entityType/entityId), not the author — the
|
|
21
21
|
// author is never the data subject of a note's content, so it is deliberately
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
// employee leaving triggers a forget), garbling unrelated business notes
|
|
25
25
|
// about customers/projects/etc. — data loss, not privacy.
|
|
26
26
|
//
|
|
27
|
-
// `body` is instead `personal: { of: "id" }` (Row-Subject
|
|
27
|
+
// `body` is instead `personal: { of: "id" }` (Row-Subject):
|
|
28
28
|
// the note's OWN row is its content's subject, so `body` is encrypted under a
|
|
29
29
|
// per-note key that nothing else shares. That key gets erased only when the
|
|
30
30
|
// note is reached by a forgotten subject: `note-mention` (below) names the
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
// shreds `authorName` (`personal: { of: "authorId" }`, the name as stamped at
|
|
35
35
|
// write time); the two erasures are independent.
|
|
36
36
|
//
|
|
37
|
-
// Known gap (
|
|
37
|
+
// Known gap (not fixed by this entity): prose that names a third
|
|
38
38
|
// party without a structured @-mention is not tracked — regex/NLP over
|
|
39
39
|
// free text is unreliable. An operator must erase such a note's own record
|
|
40
40
|
// subject (`forget-subject` kind "record", entity "note-entry") to cover it.
|
|
@@ -86,7 +86,7 @@ export function createNoteEntryEntity(
|
|
|
86
86
|
body: createLongTextField({
|
|
87
87
|
required: true,
|
|
88
88
|
maxLength: 20_000,
|
|
89
|
-
// Row-Subject
|
|
89
|
+
// Row-Subject: the note itself is the subject, so its
|
|
90
90
|
// key is erased per-note via `note-mention` lookups, not tied to any
|
|
91
91
|
// user's own forget.
|
|
92
92
|
personal: { of: "id" },
|
|
@@ -78,8 +78,8 @@ export type NotesHistoryFeatureOptions = {
|
|
|
78
78
|
/** Row-level ownership on the note-entry rows themselves — orthogonal to
|
|
79
79
|
* `access`, which only gates whether a caller may dispatch create/list at
|
|
80
80
|
* all. `ownership.read` is no longer what keeps a caller from reading notes
|
|
81
|
-
* on host entities they can't see: that gate is default-on
|
|
82
|
-
*
|
|
81
|
+
* on host entities they can't see: that gate is default-on and derives from
|
|
82
|
+
* the entity's `parentRef`. Use `ownership.read` for an
|
|
83
83
|
* ADDITIONAL row rule on the note row itself (e.g. author-only visibility);
|
|
84
84
|
* it is AND-ed with the host-visibility gate, never a replacement for it.
|
|
85
85
|
*
|
|
@@ -74,7 +74,7 @@ async function selectNotesReachingSubject(
|
|
|
74
74
|
// (entity.ts), so forgetting the AUTHOR already crypto-shreds that field on
|
|
75
75
|
// its own. `body` is Row-Subject (`personal: { of: "id" }`): its key is per
|
|
76
76
|
// note, so forgetting a subject only reaches a body when the note structurally
|
|
77
|
-
// @-mentions the subject (`note-mention
|
|
77
|
+
// @-mentions the subject (`note-mention`) or hangs on it as host.
|
|
78
78
|
// Free-text mentions are NOT detected — the documented gap in entity.ts.
|
|
79
79
|
//
|
|
80
80
|
// Reached bodies are shredded regardless of the host entity's retention strategy:
|
|
@@ -51,19 +51,19 @@ const TENANT_CLIP = `${TENANT_SCOPE}{overflow:hidden}`;
|
|
|
51
51
|
export function tenantStyleBlock(customCss: string): string {
|
|
52
52
|
const sanitized = sanitizeTenantCss(customCss, TENANT_SCOPE);
|
|
53
53
|
if (!sanitized) return "";
|
|
54
|
-
// html-ok: sanitizeTenantCss
|
|
54
|
+
// html-ok: sanitizeTenantCss is the escaping boundary (allowlist, strips `<`).
|
|
55
55
|
return `\n<style data-tenant-css>${TENANT_CONTAINMENT}\n${TENANT_CLIP}\n${sanitized}</style>`;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
//
|
|
59
|
-
// server-
|
|
60
|
-
//
|
|
61
|
-
//
|
|
58
|
+
// Minimal HTML5 skeleton with inline CSS — the default `wrapLayout` for
|
|
59
|
+
// server-rendered public pages, so they look clean without an app layout.
|
|
60
|
+
// Apps that want to wrap the body in their own marketing layout
|
|
61
|
+
// (header/footer/theme) pass their own render function.
|
|
62
62
|
//
|
|
63
|
-
// Branding (optional):
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
63
|
+
// Branding (optional): emits a scoped `:root` override after the base
|
|
64
|
+
// `<style>` (accent color, layout preset → max-width) and a logo/title header.
|
|
65
|
+
// All branding values are tenant-supplied and untrusted; branding.ts
|
|
66
|
+
// revalidates/escapes them before they enter the markup.
|
|
67
67
|
export function wrapInLayout(opts: {
|
|
68
68
|
title: string;
|
|
69
69
|
bodyHtml: string;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { escapeHtml, isSafeHref } from "@cosmicdrift/kumiko-renderer/headless";
|
|
2
2
|
import { Marked } from "marked";
|
|
3
3
|
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// Raw
|
|
7
|
-
//
|
|
8
|
-
// (
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// 'none'`). GFM
|
|
12
|
-
//
|
|
4
|
+
// Shared, hardened Markdown→HTML core for server-rendered public
|
|
5
|
+
// pages (legal-pages, managed-pages). Assumption: untrusted tenant authors.
|
|
6
|
+
// Raw HTML tokens are escaped as text (no <script>/<img onerror>-
|
|
7
|
+
// passthrough), and link/image hrefs are restricted to http(s)/mailto/relative
|
|
8
|
+
// (no javascript:/data:). Markdown structure (headings, lists, links,
|
|
9
|
+
// code) remains intact—this neutralizes XSS vectors without a sanitizer
|
|
10
|
+
// dependency. Defense in depth complements `securePageHeaders` (`script-src
|
|
11
|
+
// 'none'`). GFM and breaks are disabled—structured pages do not need
|
|
12
|
+
// tables/strikethrough/task lists.
|
|
13
13
|
const safeRenderer = new Marked({ gfm: false, breaks: false });
|
|
14
14
|
safeRenderer.use({
|
|
15
15
|
walkTokens(token) {
|
|
@@ -25,7 +25,7 @@ safeRenderer.use({
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
export function renderSafeMarkdown(markdown: string): string {
|
|
28
|
-
// @cast-boundary third-party-type-gap marked.parse return
|
|
29
|
-
// `{ async: false }`
|
|
28
|
+
// @cast-boundary third-party-type-gap marked.parse return type is `string | Promise<string>`;
|
|
29
|
+
// `{ async: false }` guarantees synchronous output (string)—the cast only fixes the API contract.
|
|
30
30
|
return safeRenderer.parse(markdown, { async: false }) as string;
|
|
31
31
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
// Security
|
|
2
|
-
// managed-pages). `script-src 'none'`
|
|
3
|
-
// HTML
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
1
|
+
// Security headers for server-rendered public HTML pages (legal-pages,
|
|
2
|
+
// managed-pages). `script-src 'none'` provides defense in depth: even if
|
|
3
|
+
// HTML injection gets through, no script can run. Deliberately omit
|
|
4
|
+
// `default-src` so styles, images, and fonts remain unrestricted for
|
|
5
|
+
// backward compatibility with inline-<style> layouts such as
|
|
6
|
+
// publicstatus' renderLegalLayout.
|
|
7
|
+
// nosniff/SAMEORIGIN/Referrer-Policy are broadly safe defaults.
|
|
7
8
|
const PUBLIC_PAGE_SECURITY_HEADERS = {
|
|
8
9
|
"content-security-policy": "script-src 'none'; object-src 'none'; base-uri 'none'",
|
|
9
10
|
"x-content-type-options": "nosniff",
|
|
@@ -36,7 +36,7 @@ const PAT_REVOKE_TRIGGERING_FIELDS = ["passwordHash"] as const;
|
|
|
36
36
|
|
|
37
37
|
export type BindPatAutoRevokeOnPasswordChange = (
|
|
38
38
|
revoker: (userId: string) => Promise<number>,
|
|
39
|
-
) => void;
|
|
39
|
+
) => () => void;
|
|
40
40
|
|
|
41
41
|
// Reads the late-bind setter off a mounted personal-access-tokens feature's
|
|
42
42
|
// exports — run{Prod,Dev}App call this once a concrete db is available,
|
|
@@ -123,12 +123,12 @@ export function createPersonalAccessTokensFeature(
|
|
|
123
123
|
} satisfies AuthProviderPlugin);
|
|
124
124
|
// Direct-write store like store_user_sessions: create/revoke write it, the
|
|
125
125
|
// resolver point-reads it. r.entity would make it a rebuildable projection
|
|
126
|
-
// whose replay (no token events) would wipe every live token
|
|
126
|
+
// whose replay (no token events) would wipe every live token.
|
|
127
127
|
r.storeTable(
|
|
128
128
|
deriveEntityTableMeta(API_TOKEN_ENTITY_NAME, apiTokenEntity, { source: "unmanaged" }),
|
|
129
129
|
{
|
|
130
130
|
reason: "read_side.api_tokens_direct_write",
|
|
131
|
-
// create.write encrypts `name` via encryptForDirectWrite
|
|
131
|
+
// create.write encrypts `name` via encryptForDirectWrite.
|
|
132
132
|
piiEncryptedOnWrite: true,
|
|
133
133
|
},
|
|
134
134
|
);
|
|
@@ -145,9 +145,9 @@ export function createPersonalAccessTokensFeature(
|
|
|
145
145
|
// Password-change auto-revoke — mirrors sessions' own
|
|
146
146
|
// autoRevokeOnPasswordChange postSave hook, including WHY it's a
|
|
147
147
|
// late-bind callback rather than direct ctx.db use: user:write:user:update
|
|
148
|
-
// is r.systemScope()'d (the user aggregate is a systemStream,
|
|
149
|
-
//
|
|
150
|
-
//
|
|
148
|
+
// is r.systemScope()'d (the user aggregate is a systemStream), so a postSave hook
|
|
149
|
+
// on "user" gets a poisoned ctx.db here. The concrete revoker is bound once
|
|
150
|
+
// run{Prod,Dev}App has a real db handle.
|
|
151
151
|
// Explicit option wins; the runtime binding is replaceable so a second boot of the same
|
|
152
152
|
// feature instance binds its own database.
|
|
153
153
|
let boundAutoRevoke: ((userId: string) => Promise<number>) | undefined;
|
|
@@ -169,6 +169,9 @@ export function createPersonalAccessTokensFeature(
|
|
|
169
169
|
});
|
|
170
170
|
const bindAutoRevokeOnPasswordChange: BindPatAutoRevokeOnPasswordChange = (revoker) => {
|
|
171
171
|
boundAutoRevoke = revoker;
|
|
172
|
+
return () => {
|
|
173
|
+
if (boundAutoRevoke === revoker) boundAutoRevoke = undefined;
|
|
174
|
+
};
|
|
172
175
|
};
|
|
173
176
|
|
|
174
177
|
const handlers = {
|
|
@@ -12,8 +12,8 @@ import { isPrincipalRowBlocked, type UserStatus, userTable } from "../user/index
|
|
|
12
12
|
// time would keep a since-revoked admin role for the token's whole (months-long)
|
|
13
13
|
// life. Returns null when the user has no membership in that tenant: removed
|
|
14
14
|
// from the tenant → the PAT stops authenticating there. Also null when the
|
|
15
|
-
// user's lifecycle status blocks them
|
|
16
|
-
//
|
|
15
|
+
// user's lifecycle status blocks them — collapsed onto the same "no roles"
|
|
16
|
+
// outcome as missing-membership so a blocked user's PAT
|
|
17
17
|
// gets an identical 401 to an unknown token (no status oracle).
|
|
18
18
|
export async function resolvePatRoles(
|
|
19
19
|
db: DbConnection,
|
|
@@ -22,9 +22,9 @@ export const statusQuery = defineQueryHandler({
|
|
|
22
22
|
// One gate for both halves: required keys/secrets of provider-features
|
|
23
23
|
// count only while their provider is the selected one (r.extensionSelector).
|
|
24
24
|
const gate = await buildProviderSelectionGate(ctx, ReadinessQueries.status, query.user, ctx.db);
|
|
25
|
-
// skipAccessFilter:
|
|
26
|
-
// Handler
|
|
27
|
-
//
|
|
25
|
+
// skipAccessFilter: the verdict must count ALL required keys—the
|
|
26
|
+
// Handler itself is TenantAdmin-gated; the per-key filter would falsely
|
|
27
|
+
// report ready:true for SystemAdmin-gated keys.
|
|
28
28
|
const missingConfig = await collectMissingRequiredConfig(
|
|
29
29
|
ctx,
|
|
30
30
|
ReadinessQueries.status,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// RendererFoundationApi —
|
|
2
|
-
// (delivery, mail
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// RendererFoundationApi — cross-feature interface. Consumers
|
|
2
|
+
// (delivery, mail sender, Solon NKA PDF generator) retrieve the appropriate
|
|
3
|
+
// plugin for each render call via `createRendererForTenant`.
|
|
4
|
+
// The pattern mirrors ai-foundation's `createLLMProviderForTenant`.
|
|
5
5
|
|
|
6
6
|
import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
@@ -32,10 +32,9 @@ export type RendererFoundationApi = {
|
|
|
32
32
|
}) => RendererPlugin;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
// Result in extraContext.
|
|
35
|
+
// The plugin pool is built at boot time from extension usages.
|
|
36
|
+
// The registry provides all registered plugins. The foundation feature builds
|
|
37
|
+
// the pool via `collectRendererPlugins(registry)` and puts it in extraContext.
|
|
39
38
|
export function createRendererFoundationApi(
|
|
40
39
|
plugins: ReadonlyArray<RendererPlugin>,
|
|
41
40
|
tenantConfigLookup: (tenantId: TenantId) => Record<string, string> | null = () => null,
|
|
@@ -50,7 +49,7 @@ export function createRendererFoundationApi(
|
|
|
50
49
|
if (tenantPluginName) {
|
|
51
50
|
const plugin = plugins.find((p) => p.name === tenantPluginName && p.kinds.includes(kind));
|
|
52
51
|
if (plugin) return plugin;
|
|
53
|
-
//
|
|
52
|
+
// The tenant configuration points to an unregistered plugin; fall through to the default.
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
// 2. Default-Plugin
|
|
@@ -60,7 +59,7 @@ export function createRendererFoundationApi(
|
|
|
60
59
|
if (plugin) return plugin;
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
// 3.
|
|
62
|
+
// 3. First plugin in the pool that serves the kind
|
|
64
63
|
const first = byKind.get(kind)?.[0];
|
|
65
64
|
if (first) return first;
|
|
66
65
|
|
|
@@ -85,14 +84,14 @@ function indexByKind(plugins: ReadonlyArray<RendererPlugin>): Map<RenderKind, Re
|
|
|
85
84
|
return map;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
// Single
|
|
89
|
-
//
|
|
87
|
+
// Single source of truth for handlers that require renderer-foundation.
|
|
88
|
+
// The pattern mirrors requireTemplateResolver + requireTextContent.
|
|
90
89
|
export function requireRendererFoundation(
|
|
91
90
|
ctx: { readonly rendererFoundation?: RendererFoundationApi } | object,
|
|
92
91
|
callerName: string,
|
|
93
92
|
): RendererFoundationApi {
|
|
94
93
|
// @cast-boundary engine-bridge — rendererFoundation kommt per extraContext
|
|
95
|
-
//
|
|
94
|
+
// from the app bootstrap.
|
|
96
95
|
const api = (ctx as { rendererFoundation?: RendererFoundationApi }).rendererFoundation;
|
|
97
96
|
if (!api) {
|
|
98
97
|
throw new InternalError({
|
|
@@ -14,8 +14,8 @@ export {
|
|
|
14
14
|
type RenderKind,
|
|
15
15
|
} from "../template-resolver/index.ts";
|
|
16
16
|
|
|
17
|
-
// Standard
|
|
18
|
-
//
|
|
17
|
+
// Standard default plugin for each kind when the tenant has not set explicit configuration.
|
|
18
|
+
// App bootstrap can override this through TenantConfigKey.
|
|
19
19
|
export const DEFAULT_PLUGIN_BY_KIND: Readonly<Record<RenderKindLocal, string>> = {
|
|
20
20
|
mail: "mail-html",
|
|
21
21
|
"document-pdf": "puppeteer",
|
|
@@ -24,9 +24,9 @@ export function createRendererFoundationFeature() {
|
|
|
24
24
|
|
|
25
25
|
r.extendsRegistrar(RENDERER_EXTENSION, {
|
|
26
26
|
onRegister: () => {
|
|
27
|
-
// Plugin
|
|
28
|
-
// options (kinds, render
|
|
29
|
-
//
|
|
27
|
+
// Plugin conformance check could go here: validate the shape of
|
|
28
|
+
// options (kinds, render function present). No shape check currently —
|
|
29
|
+
// the caller's TypeScript type safety applies.
|
|
30
30
|
},
|
|
31
31
|
});
|
|
32
32
|
|
|
@@ -34,11 +34,11 @@ export function createRendererFoundationFeature() {
|
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
37
|
+
// Build the plugin pool at boot time. App bootstrap calls this after
|
|
38
|
+
// feature registration, builds the pool, and passes it to handlers via
|
|
39
|
+
// extraContext.
|
|
40
40
|
//
|
|
41
|
-
//
|
|
41
|
+
// Symmetric to collectChannels / collectRenderers in delivery-service.
|
|
42
42
|
export function collectRendererPlugins(registry: Registry): RendererPlugin[] {
|
|
43
43
|
const usages = registry.getExtensionUsages(RENDERER_EXTENSION);
|
|
44
44
|
return usages.map((usage) => {
|
|
@@ -10,9 +10,9 @@ import type {
|
|
|
10
10
|
} from "../template-resolver/index.ts";
|
|
11
11
|
import { type ContentFormat, RENDERER_EXTENSION, type RenderKind } from "./constants.ts";
|
|
12
12
|
|
|
13
|
-
// RenderRequest —
|
|
14
|
-
// (renderer-foundation
|
|
15
|
-
//
|
|
13
|
+
// RenderRequest — plugins receive this. The caller selects resource mode
|
|
14
|
+
// (renderer-foundation API) by kind or explicitly. Plugins do not decide this;
|
|
15
|
+
// they receive an already-resolved form.
|
|
16
16
|
export type RenderRequest =
|
|
17
17
|
| { kind: "mail"; payload: MailPayload }
|
|
18
18
|
| { kind: "document-pdf"; payload: DocumentPdfPayload; options?: PdfOptions }
|
|
@@ -157,13 +157,12 @@ export type ImageOptions = {
|
|
|
157
157
|
readonly quality?: number;
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
// RendererContext —
|
|
161
|
-
// + ChannelContext). Plugins
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
// Function-Factories statt App-ctx zu casten.
|
|
160
|
+
// RendererContext — a narrow surface (Kumiko-style, matching FileProviderContext
|
|
161
|
+
// + ChannelContext). Plugins that need services obtain templateResolver/etc. via
|
|
162
|
+
// direct bundle imports + ctx.db (cross-feature public API). No extraContext
|
|
163
|
+
// pass-through: plugins import pure function factories instead of casting App-ctx.
|
|
165
164
|
//
|
|
166
|
-
// **
|
|
165
|
+
// **Example renderer-mail-html:**
|
|
167
166
|
// import { createTemplateResolverApi } from "@cosmicdrift/kumiko-bundled-features/template-resolver";
|
|
168
167
|
// const tplApi = createTemplateResolverApi(ctx.db, ctx.registry);
|
|
169
168
|
// const layout = await tplApi.resolveTemplate({ tenantId: ctx.tenantId, slug, kind });
|
|
@@ -178,9 +177,9 @@ export type RendererContext = {
|
|
|
178
177
|
readonly filesForTenant?: (tenantId: string) => FileContext | undefined;
|
|
179
178
|
};
|
|
180
179
|
|
|
181
|
-
// RendererPlugin
|
|
182
|
-
// renderer-puppeteer-client).
|
|
183
|
-
//
|
|
180
|
+
// RendererPlugin contract — per plugin (renderer-mail-html,
|
|
181
|
+
// renderer-puppeteer-client). The plugin declares which kinds it can handle;
|
|
182
|
+
// the Foundation resolver selects one based on tenant config + kind.
|
|
184
183
|
//
|
|
185
184
|
// Plugin invariants:
|
|
186
185
|
// - `kinds` has at least one entry, otherwise the plugin is never picked.
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.388.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "renderTablePdf validates the document for direct callers",
|
|
6
|
+
"detail": "renderTablePdf parses the document against pdfTableDocumentSchema and throws RendererError invalid_payload above the row, column and cell caps. Title, subtitle, meta entries, headers, empty text, footer text and page label now have length caps and meta at most 500 entries."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.364.0",
|
|
4
10
|
"type": "fix",
|
|
@@ -7,10 +7,13 @@ import type { PdfPageFormat } from "../template-resolver/index.ts";
|
|
|
7
7
|
const PDF_TABLE_MAX_ROWS = 10_000;
|
|
8
8
|
const PDF_TABLE_MAX_COLUMNS = 30;
|
|
9
9
|
const PDF_TABLE_MAX_CELL_LENGTH = 5_000;
|
|
10
|
+
const PDF_TABLE_MAX_META_ENTRIES = 500;
|
|
11
|
+
const PDF_TABLE_MAX_TEXT_LENGTH = 20_000;
|
|
12
|
+
const PDF_TABLE_MAX_PAGE_LABEL_LENGTH = 100;
|
|
10
13
|
|
|
11
14
|
const pdfTableColumnSchema = z
|
|
12
15
|
.object({
|
|
13
|
-
header: z.string(),
|
|
16
|
+
header: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH),
|
|
14
17
|
weight: z.number().positive().optional(),
|
|
15
18
|
align: z.enum(["left", "right"]).optional(),
|
|
16
19
|
})
|
|
@@ -18,10 +21,18 @@ const pdfTableColumnSchema = z
|
|
|
18
21
|
|
|
19
22
|
export const pdfTableDocumentSchema = z
|
|
20
23
|
.object({
|
|
21
|
-
title: z.string(),
|
|
22
|
-
subtitle: z.string().optional(),
|
|
24
|
+
title: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH),
|
|
25
|
+
subtitle: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH).optional(),
|
|
23
26
|
meta: z
|
|
24
|
-
.array(
|
|
27
|
+
.array(
|
|
28
|
+
z
|
|
29
|
+
.object({
|
|
30
|
+
label: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH),
|
|
31
|
+
value: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH),
|
|
32
|
+
})
|
|
33
|
+
.readonly(),
|
|
34
|
+
)
|
|
35
|
+
.max(PDF_TABLE_MAX_META_ENTRIES)
|
|
25
36
|
.readonly()
|
|
26
37
|
.optional(),
|
|
27
38
|
columns: z.array(pdfTableColumnSchema).min(1).max(PDF_TABLE_MAX_COLUMNS).readonly(),
|
|
@@ -29,10 +40,10 @@ export const pdfTableDocumentSchema = z
|
|
|
29
40
|
.array(z.array(z.string().max(PDF_TABLE_MAX_CELL_LENGTH)).readonly())
|
|
30
41
|
.max(PDF_TABLE_MAX_ROWS)
|
|
31
42
|
.readonly(),
|
|
32
|
-
emptyText: z.string().optional(),
|
|
33
|
-
footerText: z.string().optional(),
|
|
43
|
+
emptyText: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH).optional(),
|
|
44
|
+
footerText: z.string().max(PDF_TABLE_MAX_TEXT_LENGTH).optional(),
|
|
34
45
|
// Template with `{page}` and `{pages}`; default `"{page} / {pages}"`.
|
|
35
|
-
pageLabel: z.string().optional(),
|
|
46
|
+
pageLabel: z.string().max(PDF_TABLE_MAX_PAGE_LABEL_LENGTH).optional(),
|
|
36
47
|
})
|
|
37
48
|
.readonly();
|
|
38
49
|
|
|
@@ -235,12 +246,18 @@ function resolveTableLayout(
|
|
|
235
246
|
}
|
|
236
247
|
|
|
237
248
|
export async function renderTablePdf(
|
|
238
|
-
|
|
249
|
+
untrustedDoc: PdfTableDocument,
|
|
239
250
|
options?: PdfTableOptions,
|
|
240
251
|
): Promise<PdfTableResult> {
|
|
241
|
-
|
|
242
|
-
|
|
252
|
+
// Direct callers bypass renderTablePdfRequest, so the size caps are enforced here too.
|
|
253
|
+
const parsed = pdfTableDocumentSchema.safeParse(untrustedDoc);
|
|
254
|
+
if (!parsed.success) {
|
|
255
|
+
throw new RendererError(
|
|
256
|
+
`table document is invalid: ${parsed.error.message}`,
|
|
257
|
+
"invalid_payload",
|
|
258
|
+
);
|
|
243
259
|
}
|
|
260
|
+
const doc = parsed.data;
|
|
244
261
|
assertRowShape(doc);
|
|
245
262
|
|
|
246
263
|
const pdf = await PDFDocument.create({ updateMetadata: false });
|
|
@@ -71,15 +71,15 @@ export const JOIN_REQUEST_TRANSACTION_REASON =
|
|
|
71
71
|
"the secret write runs on the request transaction so a failing batch rolls it back together with the config writes";
|
|
72
72
|
|
|
73
73
|
// AppContext carries ctx.secrets via extraContext. requireSecretsContext
|
|
74
|
-
// wraps that raw context so every `.get(...)` call
|
|
75
|
-
// current user
|
|
76
|
-
//
|
|
74
|
+
// wraps that raw context so every `.get(...)` call automatically includes
|
|
75
|
+
// the current user and handler as audit metadata, preventing feature code
|
|
76
|
+
// from silently bypassing read auditing.
|
|
77
77
|
//
|
|
78
|
-
//
|
|
79
|
-
// FileProviderContext
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
78
|
+
// The context shape stays minimal: HandlerContext paths (Set/Delete handlers)
|
|
79
|
+
// and FileProviderContext paths (the S3 plugin in the worker) provide the same
|
|
80
|
+
// two fields, so importing the full HandlerContext is unnecessary.
|
|
81
|
+
// Handler contexts carry the caller as ctx.user; provider contexts set
|
|
82
|
+
// auditUserId, which takes precedence.
|
|
83
83
|
export function requireSecretsContext(
|
|
84
84
|
ctx: {
|
|
85
85
|
readonly secrets?: SecretsContext;
|
|
@@ -181,7 +181,7 @@ export function createSecretsFeature(
|
|
|
181
181
|
// Backing table: envelope/metadata/last_rotated_at + the (tenant,key)
|
|
182
182
|
// uniqueIndex are not expressible via the field-DSL (jsonb-without-default,
|
|
183
183
|
// now()-default), so the physical table is the DDL truth. Without this the
|
|
184
|
-
// generated migration omitted those columns → prod-500
|
|
184
|
+
// generated migration omitted those columns → prod-500.
|
|
185
185
|
r.entity({ name: "tenant-secret", ...tenantSecretEntity, backingTable: tenantSecretsTable });
|
|
186
186
|
|
|
187
187
|
// Read-audit domain-event. Registered here so ops tools + MSPs can
|