@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.388.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/dist/agent-tools/tool-catalog.js +1 -1
- package/dist/agent-tools/tool-dispatch.d.ts +7 -7
- package/dist/agent-tools/tool-dispatch.js +9 -9
- package/dist/audit/handlers/audit-events.js +1 -1
- package/dist/audit/screens.js +1 -1
- package/dist/auth-email-password/feature.js +1 -1
- package/dist/auth-email-password/handlers/change-password.write.js +3 -3
- package/dist/auth-email-password/handlers/confirm-token-flow.js +5 -5
- package/dist/auth-email-password/handlers/invite-accept-with-login.write.js +1 -1
- package/dist/auth-email-password/handlers/invite-accept.write.js +18 -18
- package/dist/auth-email-password/handlers/invite-create.write.d.ts +2 -2
- package/dist/auth-email-password/handlers/invite-create.write.js +10 -10
- package/dist/auth-email-password/handlers/invite-info.query.js +1 -1
- package/dist/auth-email-password/handlers/invite-signup-complete.write.js +24 -26
- package/dist/auth-email-password/handlers/login.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/login.write.js +1 -1
- package/dist/auth-email-password/handlers/self-registration-status.query.js +1 -1
- package/dist/auth-email-password/handlers/signup-confirm.write.js +34 -37
- package/dist/auth-email-password/handlers/signup-request.write.js +6 -7
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.d.ts +1 -1
- package/dist/auth-email-password/handlers/switch-tenant-mfa-gate.write.js +1 -4
- package/dist/auth-email-password/index.js +5 -5
- package/dist/auth-email-password/lockout-store.js +1 -1
- package/dist/auth-email-password/seeding.d.ts +42 -45
- package/dist/auth-email-password/seeding.js +51 -53
- package/dist/auth-email-password/signup-token-store.js +8 -8
- package/dist/auth-email-password/testing.js +3 -3
- package/dist/auth-email-password/web/auth-client.d.ts +2 -2
- package/dist/auth-email-password/web/auth-client.js +36 -37
- package/dist/auth-email-password/web/auth-form-primitives.js +10 -10
- package/dist/auth-email-password/web/auth-gate.js +15 -16
- package/dist/auth-email-password/web/client-plugin.d.ts +7 -7
- package/dist/auth-email-password/web/client-plugin.js +4 -5
- package/dist/auth-email-password/web/confirm-account-unlock-screen.js +1 -1
- package/dist/auth-email-password/web/constants.js +3 -3
- package/dist/auth-email-password/web/default-topbar-actions.d.ts +8 -8
- package/dist/auth-email-password/web/default-topbar-actions.js +6 -6
- package/dist/auth-email-password/web/forgot-password-screen.d.ts +2 -2
- package/dist/auth-email-password/web/forgot-password-screen.js +9 -9
- package/dist/auth-email-password/web/index.js +5 -5
- package/dist/auth-email-password/web/invite-accept-screen.d.ts +1 -1
- package/dist/auth-email-password/web/invite-accept-screen.js +16 -16
- package/dist/auth-email-password/web/login-screen.d.ts +1 -1
- package/dist/auth-email-password/web/login-screen.js +2 -3
- package/dist/auth-email-password/web/reset-password-screen.d.ts +4 -4
- package/dist/auth-email-password/web/reset-password-screen.js +12 -13
- package/dist/auth-email-password/web/session.d.ts +10 -9
- package/dist/auth-email-password/web/session.js +28 -29
- package/dist/auth-email-password/web/signup-complete-screen.js +3 -3
- package/dist/auth-email-password/web/signup-screen.d.ts +1 -1
- package/dist/auth-email-password/web/signup-screen.js +13 -13
- package/dist/auth-email-password/web/tenant-switcher.d.ts +4 -4
- package/dist/auth-email-password/web/tenant-switcher.js +21 -22
- package/dist/auth-email-password/web/use-shell-user.js +12 -13
- package/dist/auth-email-password/web/user-menu.d.ts +4 -4
- package/dist/auth-email-password/web/user-menu.js +12 -13
- package/dist/auth-email-password/web/verify-email-screen.d.ts +2 -2
- package/dist/auth-email-password/web/verify-email-screen.js +9 -10
- package/dist/auth-foundation/boot-checks.js +4 -4
- package/dist/auth-foundation/resolve-anonymous-access.d.ts +1 -1
- package/dist/auth-foundation/resolve-anonymous-access.js +3 -3
- package/dist/auth-foundation/types.js +2 -2
- package/dist/auth-mfa/feature-exports.d.ts +2 -2
- package/dist/auth-mfa/feature.js +8 -0
- package/dist/auth-mfa/handlers/disable.write.js +3 -3
- package/dist/auth-mfa/handlers/enable-confirm-preauth.write.js +4 -4
- package/dist/auth-mfa/handlers/enable-confirm.write.js +2 -2
- package/dist/auth-mfa/handlers/enable-start-preauth.write.js +1 -1
- package/dist/auth-mfa/handlers/reencrypt.job.js +1 -1
- package/dist/auth-mfa/handlers/regenerate-recovery.write.js +5 -5
- package/dist/auth-mfa/handlers/verify.write.js +1 -1
- package/dist/auth-mfa/token-secrets.js +1 -1
- package/dist/auth-mfa/web/client-plugin.d.ts +1 -1
- package/dist/auth-mfa/web/client-plugin.js +1 -1
- package/dist/auth-mfa/web/i18n.js +8 -4
- package/dist/auth-mfa/web/index.js +4 -4
- package/dist/auth-mfa/web/mfa-client.js +17 -16
- package/dist/auth-mfa/web/mfa-code-or-recovery-field.d.ts +11 -0
- package/dist/auth-mfa/web/mfa-code-or-recovery-field.js +12 -0
- package/dist/auth-mfa/web/mfa-disable-dialog.js +14 -3
- package/dist/auth-mfa/web/mfa-regenerate-recovery-dialog.js +14 -3
- package/dist/auth-mfa/web/mfa-setup-preauth-screen.js +10 -5
- package/dist/auth-mfa/web/mfa-verify-screen.js +32 -11
- package/dist/billing-foundation/aggregate-id.d.ts +5 -5
- package/dist/billing-foundation/aggregate-id.js +10 -11
- package/dist/billing-foundation/checkout-core.d.ts +9 -14
- package/dist/billing-foundation/checkout-core.js +24 -39
- package/dist/billing-foundation/consumer-protection/confirmation-mail.js +8 -2
- package/dist/billing-foundation/consumer-protection/consent-gate.d.ts +1 -0
- package/dist/billing-foundation/consumer-protection/consent-gate.js +1 -0
- package/dist/billing-foundation/consumer-protection/issue-confirmation.js +9 -3
- package/dist/billing-foundation/consumer-protection/mail-notifications.js +3 -1
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.d.ts +4 -2
- package/dist/billing-foundation/consumer-protection/termination-receipt-limit.js +6 -5
- package/dist/billing-foundation/consumer-protection/termination-record.d.ts +5 -1
- package/dist/billing-foundation/consumer-protection/termination-record.js +27 -17
- package/dist/billing-foundation/consumer-protection/termination-request.js +12 -7
- package/dist/billing-foundation/consumer-protection/termination-revoke.js +12 -7
- package/dist/billing-foundation/consumer-protection/termination-texts.d.ts +1 -1
- package/dist/billing-foundation/consumer-protection/termination-texts.js +3 -0
- package/dist/billing-foundation/consumer-protection/withdrawal-period.d.ts +5 -2
- package/dist/billing-foundation/consumer-protection/withdrawal-period.js +8 -9
- package/dist/billing-foundation/entities.js +27 -27
- package/dist/billing-foundation/events.d.ts +1 -0
- package/dist/billing-foundation/events.js +19 -17
- package/dist/billing-foundation/feature.js +45 -44
- package/dist/billing-foundation/get-subscription-for-tenant.d.ts +3 -3
- package/dist/billing-foundation/get-subscription-for-tenant.js +3 -5
- package/dist/billing-foundation/handlers/billing-plans.query.js +35 -5
- package/dist/billing-foundation/handlers/create-checkout-session.write.js +19 -17
- package/dist/billing-foundation/handlers/create-portal-session.write.js +11 -12
- package/dist/billing-foundation/handlers/list-subscriptions.query.js +4 -4
- package/dist/billing-foundation/handlers/plan-switch-preview.query.d.ts +13 -0
- package/dist/billing-foundation/handlers/plan-switch-preview.query.js +48 -0
- package/dist/billing-foundation/handlers/process-event.write.d.ts +6 -0
- package/dist/billing-foundation/handlers/process-event.write.js +28 -22
- package/dist/billing-foundation/handlers/start-plan-checkout.write.js +32 -5
- package/dist/billing-foundation/handlers/switch-plan.write.d.ts +2 -2
- package/dist/billing-foundation/handlers/switch-plan.write.js +56 -64
- package/dist/billing-foundation/handlers/sync-subscription.write.js +12 -1
- package/dist/billing-foundation/i18n.js +22 -0
- package/dist/billing-foundation/index.d.ts +1 -1
- package/dist/billing-foundation/plan-catalog.d.ts +21 -5
- package/dist/billing-foundation/plan-catalog.js +25 -16
- package/dist/billing-foundation/plan-switch.d.ts +12 -0
- package/dist/billing-foundation/plan-switch.js +60 -0
- package/dist/billing-foundation/projection.d.ts +15 -11
- package/dist/billing-foundation/projection.js +38 -37
- package/dist/billing-foundation/subscription-tier-sync.js +3 -3
- package/dist/billing-foundation/tenant-destroy-hook.d.ts +2 -2
- package/dist/billing-foundation/tenant-destroy-hook.js +7 -7
- package/dist/billing-foundation/types.d.ts +97 -42
- package/dist/billing-foundation/types.js +29 -20
- package/dist/billing-foundation/validate-options.js +17 -0
- package/dist/billing-foundation/web/billing-plans-panel.js +82 -36
- package/dist/billing-foundation/web/checkout-consent-dialog.d.ts +17 -3
- package/dist/billing-foundation/web/checkout-consent-dialog.js +14 -10
- package/dist/billing-foundation/web/constants.d.ts +4 -0
- package/dist/billing-foundation/web/constants.js +4 -0
- package/dist/billing-foundation/web/plan-price.d.ts +15 -0
- package/dist/billing-foundation/web/plan-price.js +32 -0
- package/dist/billing-foundation/web/plan-switch-confirm-dialog.d.ts +15 -0
- package/dist/billing-foundation/web/plan-switch-confirm-dialog.js +66 -0
- package/dist/cap-counter/aggregate-id.js +8 -9
- package/dist/cap-counter/cap-reservation.js +5 -1
- package/dist/cap-counter/constants.js +11 -12
- package/dist/cap-counter/enforce-cap.d.ts +59 -62
- package/dist/cap-counter/enforce-cap.js +49 -49
- package/dist/cap-counter/entity.js +29 -29
- package/dist/cap-counter/feature.js +34 -35
- package/dist/cap-counter/handlers/increment-rolling.write.d.ts +2 -2
- package/dist/cap-counter/handlers/increment-rolling.write.js +31 -31
- package/dist/cap-counter/handlers/mark-soft-warned.write.js +4 -5
- package/dist/cap-counter/stock-cap-guard.js +8 -2
- package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
- package/dist/channel-email/feature.js +1 -1
- package/dist/channel-email/smtp-transport.d.ts +18 -17
- package/dist/channel-email/smtp-transport.js +24 -21
- package/dist/channel-in-app/handlers/unread-count.query.js +3 -4
- package/dist/compliance-profiles/feature.js +4 -4
- package/dist/compliance-profiles/handlers/for-tenant.query.js +3 -6
- package/dist/compliance-profiles/handlers/list-profiles.query.js +5 -5
- package/dist/compliance-profiles/handlers/needs-profile.query.js +4 -4
- package/dist/compliance-profiles/handlers/set-profile.write.js +13 -14
- package/dist/compliance-profiles/handlers/sub-processors.query.js +9 -11
- package/dist/compliance-profiles/resolve-for-tenant.js +7 -7
- package/dist/compliance-profiles/schema/profile-selection.js +18 -23
- package/dist/compliance-profiles/seeding.js +14 -15
- package/dist/compliance-profiles-ops/handlers/tenants-missing-profile.query.js +3 -3
- package/dist/compliance-profiles-ops/index.js +2 -2
- package/dist/config/handlers/cascade.query.d.ts +5 -0
- package/dist/config/handlers/cascade.query.js +4 -3
- package/dist/config/handlers/readiness.query.d.ts +4 -4
- package/dist/config/handlers/readiness.query.js +1 -1
- package/dist/config/handlers/reencrypt.job.js +4 -5
- package/dist/config/handlers/set.write.js +4 -4
- package/dist/config/handlers/values.query.d.ts +5 -0
- package/dist/config/handlers/values.query.js +4 -3
- package/dist/config/resolver.js +4 -4
- package/dist/config/table.js +10 -10
- package/dist/config/write-helpers.d.ts +1 -0
- package/dist/config/write-helpers.js +19 -10
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
- package/dist/crypto-shredding/handlers/forget-subject.write.js +25 -21
- package/dist/custom-fields/aggregate-id.d.ts +12 -13
- package/dist/custom-fields/aggregate-id.js +16 -17
- package/dist/custom-fields/entity.js +49 -47
- package/dist/custom-fields/events.js +7 -8
- package/dist/custom-fields/feature.d.ts +14 -14
- package/dist/custom-fields/feature.js +53 -54
- package/dist/custom-fields/handlers/clear-custom-field.write.d.ts +3 -2
- package/dist/custom-fields/handlers/clear-custom-field.write.js +9 -8
- package/dist/custom-fields/handlers/define-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/define-tenant-field.write.js +2 -2
- package/dist/custom-fields/handlers/delete-system-field.write.js +6 -7
- package/dist/custom-fields/handlers/delete-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/delete-tenant-field.write.js +3 -3
- package/dist/custom-fields/handlers/set-custom-field.write.d.ts +3 -3
- package/dist/custom-fields/handlers/set-custom-field.write.js +25 -28
- package/dist/custom-fields/handlers/update-tenant-field.write.d.ts +1 -1
- package/dist/custom-fields/handlers/update-tenant-field.write.js +1 -1
- package/dist/custom-fields/lib/field-access.js +2 -2
- package/dist/custom-fields/lib/parse-serialized-field.js +1 -1
- package/dist/custom-fields/lib/quota.js +1 -1
- package/dist/custom-fields/lib/value-schema.js +10 -12
- package/dist/custom-fields/run-retention.js +3 -3
- package/dist/custom-fields/schemas.js +14 -14
- package/dist/custom-fields/web/client-plugin.js +2 -5
- package/dist/custom-fields/web/constants.js +2 -2
- package/dist/custom-fields/web/custom-fields-form-section.d.ts +4 -4
- package/dist/custom-fields/web/custom-fields-form-section.js +22 -22
- package/dist/custom-fields/wire-for-entity.js +65 -67
- package/dist/custom-fields/wire-user-data-rights.js +3 -3
- package/dist/data-retention/_internal/parse-override.js +2 -3
- package/dist/data-retention/feature.js +11 -18
- package/dist/data-retention/handlers/policy-for.query.js +6 -6
- package/dist/data-retention/keep-for.d.ts +7 -7
- package/dist/data-retention/keep-for.js +15 -15
- package/dist/data-retention/override-schema.d.ts +3 -4
- package/dist/data-retention/override-schema.js +13 -15
- package/dist/data-retention/presets.d.ts +4 -5
- package/dist/data-retention/presets.js +18 -23
- package/dist/data-retention/resolve-tenant-preset.js +17 -16
- package/dist/data-retention/resolver.d.ts +12 -12
- package/dist/data-retention/resolver.js +24 -23
- package/dist/data-retention/run-retention-cleanup.d.ts +8 -3
- package/dist/data-retention/run-retention-cleanup.js +61 -51
- package/dist/data-retention/schema/tenant-retention-override.js +13 -11
- package/dist/delivery/channel-context.js +6 -3
- package/dist/delivery/db/queries/preferences.js +2 -2
- package/dist/delivery/delivery-service.js +22 -7
- package/dist/delivery/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/handlers/preferences.query.d.ts +1 -1
- package/dist/delivery/handlers/preferences.query.js +20 -1
- package/dist/delivery/handlers/unsubscribe-page-chrome.query.js +1 -1
- package/dist/delivery/tables.js +9 -8
- package/dist/delivery/unsubscribe-link.d.ts +3 -1
- package/dist/delivery/unsubscribe-page-strings.d.ts +1 -0
- package/dist/delivery/unsubscribe-page-strings.js +1 -0
- package/dist/delivery/unsubscribe-page.d.ts +2 -0
- package/dist/delivery/unsubscribe-page.js +5 -0
- package/dist/delivery/unsubscribe.js +29 -11
- package/dist/document-ingest-foundation/entity.js +4 -4
- package/dist/document-ingest-foundation/events.js +2 -2
- package/dist/document-ingest-foundation/feature.js +2 -2
- package/dist/document-ingest-foundation/pages.js +1 -1
- package/dist/document-ingest-foundation/tenant-destroy-hook.js +4 -4
- package/dist/feature-toggles/compose-tier-resolver.js +1 -1
- package/dist/feature-toggles/feature.js +1 -1
- package/dist/feature-toggles/global-feature-state-table.js +1 -1
- package/dist/feature-toggles/handlers/registered.query.js +5 -5
- package/dist/feature-toggles/toggle-sync-signal.js +1 -1
- package/dist/feature-toggles/web/constants.js +1 -1
- package/dist/file-derivatives/feature.d.ts +1 -1
- package/dist/file-derivatives/feature.js +1 -1
- package/dist/file-derivatives/handlers/public-variant.query.js +1 -1
- package/dist/file-derivatives/presets.js +1 -1
- package/dist/file-foundation/feature.js +6 -6
- package/dist/file-foundation/index.d.ts +1 -1
- package/dist/file-foundation/index.js +1 -1
- package/dist/file-foundation/read-file-ref-content.d.ts +3 -0
- package/dist/file-foundation/read-file-ref-content.js +6 -1
- package/dist/file-provider-inmemory/feature.d.ts +1 -1
- package/dist/file-provider-inmemory/feature.js +16 -16
- package/dist/file-provider-s3/env-named-feature.d.ts +0 -2
- package/dist/file-provider-s3/feature.js +16 -16
- package/dist/file-provider-s3/lib/s3-provider.js +6 -6
- package/dist/files/feature.js +6 -6
- package/dist/files-tenant-data/handlers/sweep-orphaned-derivatives.job.js +4 -4
- package/dist/files-tenant-data/hooks.js +24 -26
- package/dist/files-tenant-data/index.js +1 -1
- package/dist/folders/feature.d.ts +1 -1
- package/dist/folders/web/folder-manager.js +2 -2
- package/dist/folders/web/tree.js +5 -5
- package/dist/form-draft/db/queries/cleanup.js +3 -3
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -1
- package/dist/form-draft/decrypt-draft.js +5 -1
- package/dist/form-draft/entity.js +3 -3
- package/dist/form-draft/feature.js +4 -5
- package/dist/form-draft/handlers/discard.write.js +1 -1
- package/dist/form-draft/release-file-refs.js +6 -6
- package/dist/form-draft/schemas.js +3 -3
- package/dist/form-draft/web/constants.js +0 -2
- package/dist/host-routing/dispatch.js +11 -20
- package/dist/inbound-mail-foundation/aggregate-id.d.ts +13 -13
- package/dist/inbound-mail-foundation/aggregate-id.js +19 -19
- package/dist/inbound-mail-foundation/connect-routes.js +4 -3
- package/dist/inbound-mail-foundation/constants.d.ts +22 -24
- package/dist/inbound-mail-foundation/constants.js +30 -33
- package/dist/inbound-mail-foundation/entities.d.ts +12 -12
- package/dist/inbound-mail-foundation/entities.js +47 -48
- package/dist/inbound-mail-foundation/events.d.ts +4 -3
- package/dist/inbound-mail-foundation/events.js +50 -47
- package/dist/inbound-mail-foundation/feature.js +39 -39
- package/dist/inbound-mail-foundation/handlers/account-state.js +8 -8
- package/dist/inbound-mail-foundation/handlers/connect-account.write.js +25 -26
- package/dist/inbound-mail-foundation/handlers/disconnect-account.write.js +7 -7
- package/dist/inbound-mail-foundation/handlers/ingest-message.write.js +50 -51
- package/dist/inbound-mail-foundation/handlers/list-accounts.query.js +8 -8
- package/dist/inbound-mail-foundation/handlers/list-messages.query.js +10 -10
- package/dist/inbound-mail-foundation/handlers/scope-visibility.js +3 -4
- package/dist/inbound-mail-foundation/handlers/update-account.write.d.ts +2 -2
- package/dist/inbound-mail-foundation/handlers/update-account.write.js +22 -14
- package/dist/inbound-mail-foundation/i18n.js +0 -1
- package/dist/inbound-mail-foundation/oauth-state.d.ts +5 -5
- package/dist/inbound-mail-foundation/oauth-state.js +11 -10
- package/dist/inbound-mail-foundation/projection.d.ts +4 -4
- package/dist/inbound-mail-foundation/projection.js +31 -29
- package/dist/inbound-mail-foundation/provider-factory.d.ts +4 -4
- package/dist/inbound-mail-foundation/provider-factory.js +9 -9
- package/dist/inbound-mail-foundation/retention-sweep.d.ts +5 -3
- package/dist/inbound-mail-foundation/retention-sweep.js +38 -36
- package/dist/inbound-mail-foundation/screens.js +0 -3
- package/dist/inbound-mail-foundation/tenant-destroy-hook.js +14 -16
- package/dist/inbound-mail-foundation/types.d.ts +49 -49
- package/dist/inbound-mail-foundation/types.js +21 -21
- package/dist/inbound-mail-foundation/watch-supervisor.d.ts +10 -10
- package/dist/inbound-mail-foundation/watch-supervisor.js +85 -67
- package/dist/inbound-provider-imap/credential-document.js +13 -13
- package/dist/inbound-provider-imap/feature.d.ts +2 -2
- package/dist/inbound-provider-imap/feature.js +42 -40
- package/dist/inbound-provider-imap/imap-client.d.ts +12 -11
- package/dist/inbound-provider-imap/imap-client.js +20 -19
- package/dist/inbound-provider-inmemory/feature.d.ts +9 -9
- package/dist/inbound-provider-inmemory/feature.js +19 -19
- package/dist/jobs/db/queries/retention.js +2 -2
- package/dist/jobs/db/queries/stale-run-sweep.js +3 -3
- package/dist/jobs/events.js +1 -1
- package/dist/jobs/feature.d.ts +1 -0
- package/dist/jobs/feature.js +13 -10
- package/dist/jobs/handlers/detail.query.js +4 -4
- package/dist/jobs/handlers/list.query.js +1 -1
- package/dist/jobs/handlers/projection-rebuild.job.js +1 -1
- package/dist/jobs/handlers/reindex-entity.job.js +1 -1
- package/dist/jobs/handlers/retry.write.js +1 -1
- package/dist/jobs/handlers/tenant-failures.query.d.ts +1 -1
- package/dist/jobs/handlers/tenant-failures.query.js +45 -41
- package/dist/jobs/handlers/tenant-runs.query.d.ts +1 -1
- package/dist/jobs/handlers/tenant-runs.query.js +54 -50
- package/dist/jobs/job-instant.js +1 -1
- package/dist/jobs/job-run-logger.js +15 -15
- package/dist/jobs/job-run-table.js +3 -3
- package/dist/jobs/screens.js +1 -1
- package/dist/jobs/tenant-job-failure-table.js +1 -1
- package/dist/jobs/tenant-job-run-table.js +1 -1
- package/dist/ledger/entity.js +5 -5
- package/dist/ledger/feature.js +3 -3
- package/dist/ledger/handlers/confirm-schedule-period.write.js +3 -3
- package/dist/ledger/recurring.js +12 -12
- package/dist/ledger/schemas.js +1 -1
- package/dist/ledger/web/constants.js +2 -2
- package/dist/ledger/web/index.js +7 -7
- package/dist/legal-pages/feature.d.ts +4 -4
- package/dist/legal-pages/feature.js +25 -26
- package/dist/legal-pages/markdown.js +3 -3
- package/dist/legal-pages/web/client-plugin.js +23 -24
- package/dist/legal-pages/web/index.js +0 -1
- package/dist/mail-foundation/feature.d.ts +5 -5
- package/dist/mail-foundation/feature.js +27 -25
- package/dist/mail-transport-inmemory/feature.d.ts +4 -4
- package/dist/mail-transport-inmemory/feature.js +27 -28
- package/dist/mail-transport-smtp/feature.js +20 -20
- package/dist/managed-pages/branding.js +6 -6
- package/dist/managed-pages/feature.d.ts +26 -26
- package/dist/managed-pages/feature.js +34 -34
- package/dist/managed-pages/handlers/by-slug.query.js +5 -6
- package/dist/managed-pages/handlers/by-tenant-published.query.js +2 -2
- package/dist/managed-pages/handlers/set.write.js +5 -7
- package/dist/managed-pages/screens/page-screens.js +11 -11
- package/dist/managed-pages/seeding.js +8 -8
- package/dist/managed-pages/table.js +13 -12
- package/dist/managed-pages/web/client-plugin.d.ts +1 -1
- package/dist/managed-pages/web/client-plugin.js +5 -5
- package/dist/managed-pages/web/i18n.js +1 -1
- package/dist/notes-history/entity.js +4 -4
- package/dist/notes-history/feature.d.ts +2 -2
- package/dist/notes-history-user-data/hooks.js +1 -1
- package/dist/page-render/layout.js +9 -9
- package/dist/page-render/markdown.js +11 -11
- package/dist/page-render/security-headers.js +7 -6
- package/dist/personal-access-tokens/feature.d.ts +1 -1
- package/dist/personal-access-tokens/feature.js +9 -5
- package/dist/personal-access-tokens/roles.js +2 -2
- package/dist/readiness/handlers/status.query.js +3 -3
- package/dist/renderer-foundation/api.js +12 -13
- package/dist/renderer-foundation/constants.js +2 -2
- package/dist/renderer-foundation/feature.js +7 -7
- package/dist/renderer-pdf/render-table-pdf.d.ts +1 -1
- package/dist/renderer-pdf/render-table-pdf.js +22 -10
- package/dist/secrets/feature.js +9 -9
- package/dist/secrets/web/constants.js +2 -2
- package/dist/seo/feature.js +3 -3
- package/dist/sessions/constants.d.ts +1 -1
- package/dist/sessions/constants.js +1 -1
- package/dist/sessions/feature.d.ts +2 -2
- package/dist/sessions/feature.js +12 -8
- package/dist/sessions/handlers/revoke-all-for-user.write.js +2 -2
- package/dist/sessions/handlers/revoke-all-others.write.js +2 -2
- package/dist/sessions/handlers/revoke.write.js +1 -1
- package/dist/sessions/schema/user-session.js +4 -4
- package/dist/sessions/screens.js +2 -2
- package/dist/sessions/session-callbacks.js +2 -2
- package/dist/sessions/session-revoked-event.js +2 -2
- package/dist/shared/assert-no-where-rule-in-ownership-write.js +1 -1
- package/dist/shared/decrypt-stored-pii.d.ts +1 -0
- package/dist/shared/decrypt-stored-pii.js +7 -2
- package/dist/shared/encrypt-for-direct-write.js +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/mail-template-body.d.ts +6 -2
- package/dist/shared/mail-template-body.js +7 -4
- package/dist/shared/map-with-concurrency.js +5 -4
- package/dist/shared/parent-visibility.js +2 -2
- package/dist/shared/password-hashing.js +1 -1
- package/dist/shared/signup-handover.js +1 -2
- package/dist/shared/single-use-token-store.js +1 -1
- package/dist/step-dispatcher/feature.js +1 -0
- package/dist/subscription-dodo/client.d.ts +17 -0
- package/dist/subscription-dodo/client.js +31 -0
- package/dist/subscription-dodo/constants.d.ts +12 -0
- package/dist/subscription-dodo/constants.js +19 -0
- package/dist/subscription-dodo/feature.d.ts +37 -0
- package/dist/subscription-dodo/feature.js +144 -0
- package/dist/subscription-dodo/index.d.ts +2 -0
- package/dist/subscription-dodo/index.js +4 -0
- package/dist/subscription-dodo/plugin-methods.d.ts +23 -0
- package/dist/subscription-dodo/plugin-methods.js +260 -0
- package/dist/subscription-dodo/runtime.d.ts +27 -0
- package/dist/subscription-dodo/runtime.js +89 -0
- package/dist/subscription-dodo/verify-webhook.d.ts +37 -0
- package/dist/subscription-dodo/verify-webhook.js +189 -0
- package/dist/subscription-mollie/constants.js +15 -17
- package/dist/subscription-mollie/feature.d.ts +17 -18
- package/dist/subscription-mollie/feature.js +24 -24
- package/dist/subscription-mollie/index.js +3 -3
- package/dist/subscription-mollie/plugin-methods.d.ts +2 -2
- package/dist/subscription-mollie/plugin-methods.js +15 -14
- package/dist/subscription-mollie/verify-webhook.d.ts +10 -10
- package/dist/subscription-mollie/verify-webhook.js +27 -27
- package/dist/subscription-stripe/constants.js +4 -6
- package/dist/subscription-stripe/feature.d.ts +14 -14
- package/dist/subscription-stripe/feature.js +36 -34
- package/dist/subscription-stripe/index.js +6 -6
- package/dist/subscription-stripe/plugin-methods.js +18 -18
- package/dist/subscription-stripe/runtime.d.ts +1 -1
- package/dist/subscription-stripe/runtime.js +8 -7
- package/dist/subscription-stripe/verify-webhook.d.ts +11 -11
- package/dist/subscription-stripe/verify-webhook.js +59 -61
- package/dist/tags/feature.d.ts +3 -3
- package/dist/tags/screens.js +1 -1
- package/dist/template-resolver/api.d.ts +3 -2
- package/dist/template-resolver/api.js +34 -12
- package/dist/template-resolver/compile-document-body.js +1 -0
- package/dist/template-resolver/feature.js +2 -2
- package/dist/template-resolver/handlers/bundle-import.js +3 -3
- package/dist/template-resolver/handlers/copy-locale.write.d.ts +5 -1
- package/dist/template-resolver/handlers/copy-locale.write.js +22 -7
- package/dist/template-resolver/handlers/diff-to-system.query.js +3 -2
- package/dist/template-resolver/handlers/document-base.js +3 -2
- package/dist/template-resolver/handlers/find-by-id.query.js +8 -7
- package/dist/template-resolver/handlers/list.query.js +6 -7
- package/dist/template-resolver/handlers/overview.query.d.ts +3 -0
- package/dist/template-resolver/handlers/overview.query.js +6 -3
- package/dist/template-resolver/handlers/shared.js +2 -2
- package/dist/template-resolver/handlers/template-write.js +3 -3
- package/dist/template-resolver/handlers/tenant-override-counts.query.js +1 -3
- package/dist/template-resolver/handlers/tenant-override-selection.d.ts +2 -1
- package/dist/template-resolver/handlers/tenant-overrides.query.js +28 -5
- package/dist/template-resolver/handlers/upsert-system.write.js +3 -4
- package/dist/template-resolver/handlers/upsert-tenant.write.js +4 -5
- package/dist/template-resolver/handlers/usage.query.d.ts +2 -1
- package/dist/template-resolver/handlers/usage.query.js +26 -16
- package/dist/template-resolver/handlers/validate.query.js +7 -2
- package/dist/template-resolver/seeding.js +30 -14
- package/dist/template-resolver/store-template-resource.d.ts +1 -0
- package/dist/template-resolver/store-template-resource.js +19 -4
- package/dist/template-resolver/table.js +10 -11
- package/dist/template-resolver/template-delivery-policy.d.ts +0 -5
- package/dist/template-resolver/template-delivery-policy.js +0 -6
- package/dist/template-resolver/template-meta.js +7 -4
- package/dist/template-resolver/template-preview.js +4 -3
- package/dist/template-resolver/web/client-plugin.js +2 -2
- package/dist/template-resolver/web/constants.d.ts +2 -2
- package/dist/template-resolver/web/constants.js +3 -3
- package/dist/template-resolver/web/index.d.ts +1 -0
- package/dist/template-resolver/web/index.js +1 -0
- package/dist/template-resolver/web/mail-layout-constants.d.ts +5 -0
- package/dist/template-resolver/web/mail-layout-constants.js +7 -0
- package/dist/tenant/feature.js +7 -7
- package/dist/tenant/handlers/member-directory.query.d.ts +1 -0
- package/dist/tenant/handlers/member-directory.query.js +11 -4
- package/dist/tenant/handlers/members.query.js +1 -1
- package/dist/tenant/handlers/team-list.query.js +1 -1
- package/dist/tenant/handlers/tenant-directory.query.d.ts +1 -0
- package/dist/tenant/handlers/tenant-directory.query.js +9 -5
- package/dist/tenant/invitation-table.js +37 -40
- package/dist/tenant/membership-table.js +3 -3
- package/dist/tenant/schema/tenant.js +7 -9
- package/dist/tenant/screens.js +1 -1
- package/dist/tenant/seeding.d.ts +6 -5
- package/dist/tenant/seeding.js +12 -12
- package/dist/tenant/testing.js +5 -6
- package/dist/tenant/web/constants.js +2 -2
- package/dist/tenant-handover/events.js +5 -7
- package/dist/tenant-handover/feature.js +1 -1
- package/dist/tenant-handover/grant.js +1 -1
- package/dist/tenant-handover/handlers/claim.write.js +1 -1
- package/dist/tenant-handover/move-entity-graph.js +8 -9
- package/dist/tenant-handover/signup-handover-provider.js +1 -2
- package/dist/tenant-handover/transfer-graph.js +4 -5
- package/dist/tenant-lifecycle/boot-checks.js +1 -1
- package/dist/tenant-lifecycle/constants.d.ts +1 -0
- package/dist/tenant-lifecycle/constants.js +4 -0
- package/dist/tenant-lifecycle/feature.js +1 -1
- package/dist/tenant-lifecycle/run-tenant-destroy.js +2 -2
- package/dist/tenant-settings/constants.js +1 -1
- package/dist/tenant-settings/tenant-defaults.d.ts +1 -1
- package/dist/tenant-settings/tenant-defaults.js +9 -2
- package/dist/tier-engine/aggregate-id.d.ts +11 -11
- package/dist/tier-engine/aggregate-id.js +15 -16
- package/dist/tier-engine/compose-app.d.ts +14 -14
- package/dist/tier-engine/compose-app.js +1 -1
- package/dist/tier-engine/entity.js +18 -19
- package/dist/tier-engine/feature.d.ts +19 -17
- package/dist/tier-engine/feature.js +68 -69
- package/dist/tier-engine/handlers/active-tier.query.js +6 -7
- package/dist/tier-engine/handlers/get-tenant-tier.query.js +4 -4
- package/dist/tier-engine/handlers/set-tenant-tier.write.d.ts +7 -8
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +7 -4
- package/dist/tier-engine/tier-resolver.js +2 -2
- package/dist/tier-engine/trial.js +8 -8
- package/dist/tier-engine/web/constants.js +2 -2
- package/dist/tier-engine/web/index.js +4 -4
- package/dist/user/db/queries/stream-tenant-backfill.js +8 -8
- package/dist/user/handlers/create.write.js +4 -4
- package/dist/user/schema/user.d.ts +11 -11
- package/dist/user/schema/user.js +45 -44
- package/dist/user/seeding.d.ts +15 -15
- package/dist/user/seeding.js +28 -28
- package/dist/user/testing.js +3 -3
- package/dist/user-data-rights/audit-download.d.ts +8 -8
- package/dist/user-data-rights/audit-download.js +19 -20
- package/dist/user-data-rights/boot-checks.js +1 -1
- package/dist/user-data-rights/deletion-token.js +1 -1
- package/dist/user-data-rights/feature.d.ts +49 -50
- package/dist/user-data-rights/feature.js +54 -53
- package/dist/user-data-rights/handlers/cancel-deletion.write.js +9 -9
- package/dist/user-data-rights/handlers/confirm-deletion-by-token.write.js +8 -8
- package/dist/user-data-rights/handlers/download-by-job.query.js +29 -30
- package/dist/user-data-rights/handlers/download-by-token.query.js +40 -42
- package/dist/user-data-rights/handlers/export-status.query.js +8 -9
- package/dist/user-data-rights/handlers/lift-restriction.write.js +7 -8
- package/dist/user-data-rights/handlers/list-download-attempts.query.js +2 -2
- package/dist/user-data-rights/handlers/my-audit-log.query.js +4 -4
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.d.ts +5 -5
- package/dist/user-data-rights/handlers/request-deletion-by-email.write.js +16 -15
- package/dist/user-data-rights/handlers/request-deletion.write.d.ts +2 -2
- package/dist/user-data-rights/handlers/request-deletion.write.js +7 -9
- package/dist/user-data-rights/handlers/request-export.write.js +42 -41
- package/dist/user-data-rights/handlers/restrict-account.write.js +22 -19
- package/dist/user-data-rights/handlers/run-forget-cleanup.write.js +8 -8
- package/dist/user-data-rights/index.js +8 -10
- package/dist/user-data-rights/lib/default-mailers.js +3 -3
- package/dist/user-data-rights/lib/update-user-lifecycle.js +14 -17
- package/dist/user-data-rights/run-export-jobs.d.ts +38 -42
- package/dist/user-data-rights/run-export-jobs.js +130 -237
- package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
- package/dist/user-data-rights/run-forget-cleanup.js +65 -83
- package/dist/user-data-rights/run-user-export.d.ts +34 -33
- package/dist/user-data-rights/run-user-export.js +55 -57
- package/dist/user-data-rights/schema/download-attempt.js +11 -11
- package/dist/user-data-rights/schema/download-token.js +37 -41
- package/dist/user-data-rights/schema/export-job.d.ts +4 -4
- package/dist/user-data-rights/schema/export-job.js +65 -67
- package/dist/user-data-rights/token-helpers.d.ts +8 -9
- package/dist/user-data-rights/token-helpers.js +21 -25
- package/dist/user-data-rights/web/client-plugin.d.ts +5 -5
- package/dist/user-data-rights/web/client-plugin.js +1 -1
- package/dist/user-data-rights/web/confirm-deletion-screen.js +6 -5
- package/dist/user-data-rights/web/constants.js +1 -1
- package/dist/user-data-rights/web/index.js +5 -5
- package/dist/user-data-rights/web/privacy-center-screen.js +14 -13
- package/dist/user-data-rights/web/public-deletion-gate.d.ts +4 -4
- package/dist/user-data-rights/web/request-deletion-screen.js +6 -6
- package/dist/user-data-rights/zip-path.d.ts +15 -15
- package/dist/user-data-rights/zip-path.js +41 -40
- package/dist/user-data-rights-defaults/feature.js +15 -15
- package/dist/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.js +3 -5
- package/dist/user-data-rights-defaults/hooks/file-ref.userdata-hook.js +45 -51
- package/dist/user-data-rights-defaults/hooks/job-run.userdata-hook.js +2 -2
- package/dist/user-data-rights-defaults/hooks/notification-preference.userdata-hook.js +1 -1
- package/dist/user-data-rights-defaults/hooks/user-session.userdata-hook.js +3 -3
- package/dist/user-data-rights-defaults/hooks/user.userdata-hook.js +32 -31
- package/dist/user-profile/handlers/change-email.write.js +13 -13
- package/dist/user-profile/index.js +3 -3
- package/dist/user-profile/web/client-plugin.js +1 -1
- package/dist/user-profile/web/constants.js +1 -1
- package/dist/user-profile/web/profile-screen.js +1 -1
- package/dist/waitlist/handlers/export-purge.write.js +2 -1
- package/dist/waitlist/handlers/submit.write.js +5 -5
- package/dist/waitlist/import.d.ts +1 -0
- package/dist/waitlist/import.js +4 -0
- package/dist/waitlist/legacy-migrate.js +17 -6
- package/dist/waitlist/link-on-signup.js +18 -6
- package/dist/waitlist/options.d.ts +3 -0
- package/dist/workflow-runner/aggregate-id.d.ts +1 -1
- package/dist/workflow-runner/aggregate-id.js +1 -1
- package/dist/workflow-runner/event-subscriber.js +4 -5
- package/dist/workflow-runner/event-trigger.js +4 -17
- package/dist/workflow-runner/feature.js +2 -2
- package/dist/workflow-runner/handlers/resume-run.write.js +4 -4
- package/dist/workflow-runner/pending-projection.js +6 -7
- package/dist/workflow-runner/runner.js +6 -6
- package/dist/workflow-runner/tables.js +6 -6
- package/dist/workflow-runner/workflow-registry.js +1 -1
- package/package.json +20 -10
- package/src/agent-tools/changes.json +6 -0
- package/src/audit/changes.json +12 -0
- package/src/auth-mfa/changes.json +6 -0
- package/src/billing-foundation/changes.json +55 -0
- package/src/cap-counter/changes.json +18 -0
- package/src/channel-email/changes.json +6 -0
- package/src/config/changes.json +12 -0
- package/src/crypto-shredding/changes.json +6 -0
- package/src/delivery/changes.json +30 -0
- package/src/form-draft/changes.json +6 -0
- package/src/host-routing/changes.json +6 -0
- package/src/inbound-mail-foundation/changes.json +18 -0
- package/src/jobs/changes.json +13 -0
- package/src/mail-foundation/changes.json +6 -0
- package/src/renderer-pdf/changes.json +6 -0
- package/src/step-dispatcher/changes.json +6 -0
- package/src/subscription-dodo/changes.json +14 -0
- package/src/subscription-stripe/changes.json +12 -0
- package/src/template-resolver/changes.json +48 -0
- package/src/tenant/changes.json +6 -0
- package/src/tenant-lifecycle/changes.json +6 -0
- package/src/tier-engine/changes.json +6 -0
- package/src/waitlist/changes.json +18 -0
- package/dist/billing-foundation/consumer-protection/stored-user-email.d.ts +0 -1
- package/dist/billing-foundation/consumer-protection/stored-user-email.js +0 -8
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
// Test
|
|
2
|
-
//
|
|
3
|
-
// set-profile
|
|
4
|
-
// minimal-no-region
|
|
5
|
-
//
|
|
1
|
+
// Test helper for compliance-profiles. Creates a profile entry directly
|
|
2
|
+
// through the Event Store executor—the same path as the real
|
|
3
|
+
// set-profile handler, but without Zod schema restrictions (accepts
|
|
4
|
+
// minimal-no-region for migration edge-case tests) and without an access
|
|
5
|
+
// check. Default ifExists="skip": creates only missing profiles.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// user-data-rights uses this for test setup ("user can export data with
|
|
8
|
+
// profile X": a fresh tenant and profile selection per test in one helper
|
|
9
|
+
// call).
|
|
10
10
|
//
|
|
11
|
-
//
|
|
11
|
+
// The pattern matches seedTextBlock in template-resolver/seeding.ts.
|
|
12
12
|
import { createEventStoreExecutor, createTenantDb, fetchOne, } from "@cosmicdrift/kumiko-framework/db";
|
|
13
13
|
import { runEventStoreSeed, TestUsers, } from "@cosmicdrift/kumiko-framework/seeding";
|
|
14
14
|
import { tenantComplianceProfileEntity, tenantComplianceProfileTable, } from "./schema/profile-selection.js";
|
|
15
15
|
const executor = createEventStoreExecutor(tenantComplianceProfileTable, tenantComplianceProfileEntity, { entityName: "tenant-compliance-profile" });
|
|
16
16
|
export async function seedComplianceProfile(db, opts) {
|
|
17
|
-
// user.tenantId
|
|
18
|
-
//
|
|
19
|
-
// feedback_event_store_tenant_consistency).
|
|
17
|
+
// user.tenantId must equal opts.tenantId so the Event Store stream
|
|
18
|
+
// and projection remain in the same tenant bucket.
|
|
20
19
|
const by = opts.by ?? { ...TestUsers.systemAdmin, tenantId: opts.tenantId };
|
|
21
20
|
const tdb = createTenantDb({ db, tenantId: opts.tenantId, mode: "system" });
|
|
22
21
|
const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
|
|
@@ -35,9 +34,9 @@ export async function seedComplianceProfile(db, opts) {
|
|
|
35
34
|
if (!result.isSuccess) {
|
|
36
35
|
throw new Error(`seedComplianceProfile create failed: ${JSON.stringify(result)}`);
|
|
37
36
|
}
|
|
38
|
-
// @cast-boundary db-row: executor.create result.data
|
|
39
|
-
// inserted
|
|
40
|
-
// INSERT
|
|
37
|
+
// @cast-boundary db-row: executor.create result.data is the
|
|
38
|
+
// inserted projection row (Record<string, unknown>); id is guaranteed
|
|
39
|
+
// after INSERT (runtime check directly below).
|
|
41
40
|
const data = result.data;
|
|
42
41
|
if (data.id === undefined) {
|
|
43
42
|
throw new Error("seedComplianceProfile: executor.create did not return an id");
|
|
@@ -4,12 +4,12 @@ import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
|
4
4
|
import * as z from "zod";
|
|
5
5
|
import { tenantComplianceProfileTable } from "../../compliance-profiles/index.js";
|
|
6
6
|
import { decryptTenantNames, tenantTable } from "../../tenant/index.js";
|
|
7
|
-
// SystemAdmin platform-wide counterpart to needs-profile
|
|
7
|
+
// SystemAdmin platform-wide counterpart to needs-profile.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
9
|
+
// The change stopped needs-profile from nagging a TenantAdmin who can no longer
|
|
10
10
|
// reach a picker narrowed to access.systemAdmin — correct, but it left no
|
|
11
11
|
// one else able to notice: needs-profile stays TenantAdmin-only on purpose
|
|
12
|
-
// (widening its call-access was explicitly rejected
|
|
12
|
+
// (widening its call-access was explicitly rejected), so a
|
|
13
13
|
// SystemAdmin who owns the platform-only picker has no way to see which
|
|
14
14
|
// tenants still run on minimal-no-region. This query fills that gap
|
|
15
15
|
// instead of touching needs-profile: every enabled tenant that has no row
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// compliance-profiles-ops — platform-wide SystemAdmin visibility into
|
|
2
|
-
// tenants missing a compliance-profile selection
|
|
2
|
+
// tenants missing a compliance-profile selection.
|
|
3
3
|
//
|
|
4
4
|
// needs-profile (compliance-profiles) tells a TenantAdmin they must pick a
|
|
5
|
-
// profile, but stays TenantAdmin-only by design
|
|
5
|
+
// profile, but stays TenantAdmin-only by design — a SystemAdmin who
|
|
6
6
|
// owns a picker narrowed to access.systemAdmin has no query at all. Kept as
|
|
7
7
|
// a separate feature (mirrors folders-user-data/notes-history-user-data)
|
|
8
8
|
// rather than folded into compliance-profiles: this is the one genuinely
|
|
@@ -2,4 +2,9 @@ import { type ConfigCascade } from "@cosmicdrift/kumiko-framework/engine";
|
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
export declare const cascadeQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"cascade", z.ZodObject<{
|
|
4
4
|
keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
5
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
6
|
+
system: "system";
|
|
7
|
+
tenant: "tenant";
|
|
8
|
+
user: "user";
|
|
9
|
+
}>>;
|
|
5
10
|
}, z.core.$strip>, Record<string, ConfigCascade>, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap>;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
|
|
1
|
+
import { ConfigScopes, defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { requireConfigResolver, requireSystemDb } from "../feature.js";
|
|
4
4
|
import { MASKED, redactInheritedCascade, shouldRedactInherited } from "../read-redaction.js";
|
|
5
|
-
import { hasConfigAccess } from "../write-helpers.js";
|
|
5
|
+
import { hasConfigAccess, keyDefAtScope } from "../write-helpers.js";
|
|
6
6
|
export const cascadeQuery = defineQueryHandler({
|
|
7
7
|
name: "cascade",
|
|
8
8
|
description: "Shows, per config key the caller may read, the value at every cascade level (user, tenant, system, app override, default) and which level won; use it to explain where a setting's current value comes from.",
|
|
9
9
|
schema: z.object({
|
|
10
10
|
keys: z.array(z.string()).optional(),
|
|
11
|
+
scope: z.enum([ConfigScopes.system, ConfigScopes.tenant, ConfigScopes.user]).optional(),
|
|
11
12
|
}),
|
|
12
13
|
access: {
|
|
13
14
|
openToAll: {
|
|
@@ -34,7 +35,7 @@ export const cascadeQuery = defineQueryHandler({
|
|
|
34
35
|
continue;
|
|
35
36
|
if (!hasConfigAccess(keyDef.access.read, query.user.roles))
|
|
36
37
|
continue;
|
|
37
|
-
keyDefs.set(key, keyDef);
|
|
38
|
+
keyDefs.set(key, keyDefAtScope(keyDef, query.payload.scope, query.user.roles));
|
|
38
39
|
filteredKeys.push(key);
|
|
39
40
|
}
|
|
40
41
|
const cascades = await resolver.getCascadeBatch(filteredKeys, keyDefs, query.user.tenantId, query.user.id, db, ctx.secrets);
|
|
@@ -9,10 +9,10 @@ export type ReadinessMissingKey = {
|
|
|
9
9
|
export type RequiredKeyGate = (qualifiedName: string) => boolean;
|
|
10
10
|
export declare function buildProviderSelectionGate(ctx: HandlerContext, callerQn: string, user: SessionUser, db: TenantDb): Promise<RequiredKeyGate>;
|
|
11
11
|
export declare function collectMissingRequiredConfig(ctx: HandlerContext, callerQn: string, user: SessionUser, db: TenantDb, gate?: RequiredKeyGate, options?: {
|
|
12
|
-
/** Verdict
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
/** Verdict paths (rollup, themselves role-gated) MUST count without filtering:
|
|
13
|
+
* the per-key read filter protects the openToAll handler from information
|
|
14
|
+
* disclosure, but in the verdict it dropped SystemAdmin-gated required keys
|
|
15
|
+
* and incorrectly reported ready:true despite the gap. */
|
|
16
16
|
readonly skipAccessFilter?: boolean;
|
|
17
17
|
}): Promise<ReadinessMissingKey[]>;
|
|
18
18
|
export declare const readinessQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"readiness", z.ZodObject<{}, z.core.$strip>, {
|
|
@@ -95,7 +95,7 @@ export const readinessQuery = defineQueryHandler({
|
|
|
95
95
|
const db = requireSystemDb(ctx, "config:query:readiness", query.user.tenantId);
|
|
96
96
|
const missing = await collectMissingRequiredConfig(ctx, "config:query:readiness", query.user, db);
|
|
97
97
|
// Additive, display-ready fields for the admin-shell dashboard stat
|
|
98
|
-
// panel
|
|
98
|
+
// panel — `missing` itself stays untouched for existing
|
|
99
99
|
// consumers that read the array directly.
|
|
100
100
|
return {
|
|
101
101
|
missing,
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
// the NEW envelope: after a full run even a from-scratch rebuild only
|
|
17
17
|
// ever sees the current-KEK envelope.
|
|
18
18
|
//
|
|
19
|
-
// systemScope() fail-closed pattern
|
|
20
|
-
//
|
|
19
|
+
// systemScope() fail-closed pattern: the initial scan is intentionally
|
|
20
|
+
// cross-tenant (system-wide key rotation), acknowledged via
|
|
21
21
|
// UncheckedSystemDb.acknowledgeCrossTenant(). Rows are bucketed by tenant,
|
|
22
22
|
// and assertRowsTenant() re-verifies each row against its bucket's tenant
|
|
23
23
|
// right before the write — both checks are built locally from the exported
|
|
@@ -163,9 +163,8 @@ export const reencryptJob = async (rawPayload, ctx) => {
|
|
|
163
163
|
return "failed";
|
|
164
164
|
}
|
|
165
165
|
// Re-verify the row's own tenantId against the bucket it was scanned
|
|
166
|
-
// into, right before the write
|
|
167
|
-
//
|
|
168
|
-
// whole job.
|
|
166
|
+
// into, right before the write — a mismatch here fails this row only
|
|
167
|
+
// (via onRowError below), it does not abort the whole job.
|
|
169
168
|
sdbFor(tenantId).assertRowsTenant([row], "tenantId");
|
|
170
169
|
const plaintext = await cipher.decrypt(row.value, { tenantId });
|
|
171
170
|
const reencrypted = await cipher.encrypt(plaintext, { tenantId });
|
|
@@ -45,7 +45,8 @@ export const setWrite = defineWriteHandler({
|
|
|
45
45
|
// rejected), but an admin override write can still target scope=
|
|
46
46
|
// "system" for a tenant/user-scoped key (validateScope allows any
|
|
47
47
|
// requestedScope <= definedScope) — system-row has no subject.
|
|
48
|
-
|
|
48
|
+
const piiScope = keyDef.piiEncrypted && scope !== ConfigScopes.system ? scope : undefined;
|
|
49
|
+
if (keyDef.piiEncrypted && piiScope === undefined) {
|
|
49
50
|
return writeFailure(new UnprocessableError("invalid_scope", {
|
|
50
51
|
i18nKey: "config.errors.invalidScope",
|
|
51
52
|
details: { key: event.payload.key, definedScope: keyDef.scope, requestedScope: scope },
|
|
@@ -110,7 +111,7 @@ export const setWrite = defineWriteHandler({
|
|
|
110
111
|
const cipher = requireConfigEncryption(ctx, "config:write:set");
|
|
111
112
|
serialized = await cipher.encrypt(serialized, { tenantId });
|
|
112
113
|
}
|
|
113
|
-
else if (
|
|
114
|
+
else if (piiScope !== undefined) {
|
|
114
115
|
const kms = configuredPiiSubjectKms();
|
|
115
116
|
if (!kms) {
|
|
116
117
|
throw new InternalError({
|
|
@@ -119,8 +120,7 @@ export const setWrite = defineWriteHandler({
|
|
|
119
120
|
`configurePiiSubjectKms(adapter) at boot.`,
|
|
120
121
|
});
|
|
121
122
|
}
|
|
122
|
-
|
|
123
|
-
const subject = resolvePiiSubject(scope, tenantId, userId);
|
|
123
|
+
const subject = resolvePiiSubject(piiScope, tenantId, userId);
|
|
124
124
|
const kmsCtx = {
|
|
125
125
|
requestId: requestContext.get()?.requestId ?? "config:write:set",
|
|
126
126
|
tenantId,
|
|
@@ -2,6 +2,11 @@ import { type ConfigScope, type ConfigValueSource } from "@cosmicdrift/kumiko-fr
|
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
export declare const valuesQuery: import("@cosmicdrift/kumiko-types/define-handler").QueryHandlerDefinition<"values", z.ZodObject<{
|
|
4
4
|
keys: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
5
|
+
scope: z.ZodOptional<z.ZodEnum<{
|
|
6
|
+
system: "system";
|
|
7
|
+
tenant: "tenant";
|
|
8
|
+
user: "user";
|
|
9
|
+
}>>;
|
|
5
10
|
}, z.core.$strip>, Record<string, {
|
|
6
11
|
value: string | number | boolean | undefined;
|
|
7
12
|
scope: ConfigScope;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
|
|
1
|
+
import { ConfigScopes, defineQueryHandler, isEncryptedAtRest, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { requireConfigResolver, requireSystemDb } from "../feature.js";
|
|
4
4
|
import { MASKED, redactInheritedCascade, shouldRedactInherited } from "../read-redaction.js";
|
|
5
|
-
import { hasConfigAccess } from "../write-helpers.js";
|
|
5
|
+
import { hasConfigAccess, keyDefAtScope } from "../write-helpers.js";
|
|
6
6
|
export const valuesQuery = defineQueryHandler({
|
|
7
7
|
name: "values",
|
|
8
8
|
description: "Returns the effective value, scope and winning source for every config key the caller may read (optionally narrowed to `keys`), with encrypted and secret-backed values masked; use it to inspect the current settings.",
|
|
9
9
|
schema: z.object({
|
|
10
10
|
keys: z.array(z.string()).optional(),
|
|
11
|
+
scope: z.enum([ConfigScopes.system, ConfigScopes.tenant, ConfigScopes.user]).optional(),
|
|
11
12
|
}),
|
|
12
13
|
// Per-key read access enforced via hasConfigAccess inside the handler.
|
|
13
14
|
access: {
|
|
@@ -34,7 +35,7 @@ export const valuesQuery = defineQueryHandler({
|
|
|
34
35
|
continue;
|
|
35
36
|
if (!hasConfigAccess(keyDef.access.read, query.user.roles))
|
|
36
37
|
continue;
|
|
37
|
-
keyDefs.set(qualifiedKey, keyDef);
|
|
38
|
+
keyDefs.set(qualifiedKey, keyDefAtScope(keyDef, query.payload.scope, query.user.roles));
|
|
38
39
|
filteredKeys.push(qualifiedKey);
|
|
39
40
|
}
|
|
40
41
|
// Resolve through the full cascade (rows → app-override → computed →
|
package/dist/config/resolver.js
CHANGED
|
@@ -402,10 +402,10 @@ export function validateAppOverrides(registry, overrides) {
|
|
|
402
402
|
if (keyDef.computed) {
|
|
403
403
|
throw new Error(`App-Boot-Override for "${key}": this key has a computed resolver (plan-based / derived). App-overrides would silently bypass that logic — remove the override, or remove the computed resolver if a flat deploy-default is intended.`);
|
|
404
404
|
}
|
|
405
|
-
//
|
|
406
|
-
// `typeof value !== typeForKey(...)
|
|
407
|
-
//
|
|
408
|
-
//
|
|
405
|
+
// Narrow by keyDef.type inline because TypeScript cannot narrow through
|
|
406
|
+
// `typeof value !== typeForKey(...)`, whose return type is string rather
|
|
407
|
+
// than a discriminator. This avoids `value as string|number` casts below;
|
|
408
|
+
// value is correctly typed within each branch.
|
|
409
409
|
if (keyDef.type === "number") {
|
|
410
410
|
if (typeof value !== "number") {
|
|
411
411
|
throw new Error(`App-Boot-Override for "${key}": expected number, got ${typeof value}`);
|
package/dist/config/table.js
CHANGED
|
@@ -2,19 +2,19 @@ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
|
|
|
2
2
|
import { createEntity, createTextField } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
// Config values are event-sourced. Each (key, scope) is its own aggregate
|
|
4
4
|
// stream — lifecycle events `configValue.created / .updated / .deleted`
|
|
5
|
-
// flow through createEventStoreExecutor, which writes the stream
|
|
6
|
-
// projection in one TX. Reads
|
|
5
|
+
// flow through createEventStoreExecutor, which writes the stream and this
|
|
6
|
+
// projection in one TX. Reads remain O(1) against the projection.
|
|
7
7
|
//
|
|
8
8
|
// System-scope rows use SYSTEM_TENANT_ID (not null) — buildBaseColumns
|
|
9
|
-
// (via buildEntityTable) forces tenant_id NOT NULL, so
|
|
10
|
-
// means system" convention is replaced with a fixed sentinel.
|
|
11
|
-
// index
|
|
12
|
-
// level —
|
|
9
|
+
// (via buildEntityTable) forces tenant_id NOT NULL, so the pre-ES "NULL
|
|
10
|
+
// means system" convention is replaced with a fixed sentinel. The unique
|
|
11
|
+
// index on (key, tenant_id, user_id) prevents duplicate writes at the DB
|
|
12
|
+
// level — declared via entity.indexes.
|
|
13
13
|
//
|
|
14
|
-
// Single
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
14
|
+
// Single source of truth: `configValueEntity`. The DB table is derived from
|
|
15
|
+
// the EntityDefinition through buildEntityTable, and the unique index is
|
|
16
|
+
// declared via entity.indexes. The plural re-export `configValuesTable`
|
|
17
|
+
// provides handlers (`reset.write.ts` etc.) with a typed Drizzle table ref.
|
|
18
18
|
export const configValueEntity = createEntity({
|
|
19
19
|
table: "read_config_values",
|
|
20
20
|
fields: {
|
|
@@ -35,6 +35,7 @@ export declare function checkWriteAccess(keyDef: ConfigKeyDefinition, userRoles:
|
|
|
35
35
|
*/
|
|
36
36
|
export declare function checkScopeWriteAccess(scope: ConfigScope, userRoles: readonly string[]): KumikoError | null;
|
|
37
37
|
export declare function validateScope(requestedScope: ConfigScope, definedScope: ConfigScope, key: string): KumikoError | null;
|
|
38
|
+
export declare function keyDefAtScope(keyDef: ConfigKeyDefinition, readScope: ConfigScope | undefined, roles: readonly string[]): ConfigKeyDefinition;
|
|
38
39
|
export declare function resolveScopeIds(scope: ConfigScope, tenantId: TenantId, userId: string): {
|
|
39
40
|
tenantId: TenantId;
|
|
40
41
|
userId: string | null;
|
|
@@ -33,10 +33,9 @@ export async function findConfigRow(db, key, tenantId, userId) {
|
|
|
33
33
|
export async function configRowHoldsValue(row, keyDef, cipher, qualifiedKey, serializedValue) {
|
|
34
34
|
if (row?.value === null || row?.value === undefined)
|
|
35
35
|
return false;
|
|
36
|
-
if (!keyDef
|
|
36
|
+
if (keyDef === undefined || (!keyDef.encrypted && !keyDef.piiEncrypted)) {
|
|
37
37
|
return row.value === serializedValue;
|
|
38
|
-
|
|
39
|
-
return false;
|
|
38
|
+
}
|
|
40
39
|
try {
|
|
41
40
|
return (await decryptStoredValue(row.value, keyDef, cipher, qualifiedKey)) === serializedValue;
|
|
42
41
|
}
|
|
@@ -112,12 +111,7 @@ export function checkScopeWriteAccess(scope, userRoles) {
|
|
|
112
111
|
});
|
|
113
112
|
}
|
|
114
113
|
export function validateScope(requestedScope, definedScope, key) {
|
|
115
|
-
|
|
116
|
-
[ConfigScopes.system]: 0,
|
|
117
|
-
[ConfigScopes.tenant]: 1,
|
|
118
|
-
[ConfigScopes.user]: 2,
|
|
119
|
-
};
|
|
120
|
-
if (levels[requestedScope] > levels[definedScope]) {
|
|
114
|
+
if (SCOPE_LEVEL[requestedScope] > SCOPE_LEVEL[definedScope]) {
|
|
121
115
|
return new UnprocessableError("invalid_scope", {
|
|
122
116
|
i18nKey: "config.errors.invalidScope",
|
|
123
117
|
details: { key, definedScope, requestedScope },
|
|
@@ -125,6 +119,21 @@ export function validateScope(requestedScope, definedScope, key) {
|
|
|
125
119
|
}
|
|
126
120
|
return null;
|
|
127
121
|
}
|
|
122
|
+
const SCOPE_LEVEL = {
|
|
123
|
+
[ConfigScopes.system]: 0,
|
|
124
|
+
[ConfigScopes.tenant]: 1,
|
|
125
|
+
[ConfigScopes.user]: 2,
|
|
126
|
+
};
|
|
127
|
+
// Reads a tenant/user key at a narrower scope, e.g. system for a system-level screen.
|
|
128
|
+
// Only a SystemAdmin may widen the read to the platform level; everyone else keeps the normal cascade.
|
|
129
|
+
export function keyDefAtScope(keyDef, readScope, roles) {
|
|
130
|
+
if (readScope === undefined ||
|
|
131
|
+
!roles.includes("SystemAdmin") ||
|
|
132
|
+
SCOPE_LEVEL[readScope] >= SCOPE_LEVEL[keyDef.scope]) {
|
|
133
|
+
return keyDef;
|
|
134
|
+
}
|
|
135
|
+
return { ...keyDef, scope: readScope };
|
|
136
|
+
}
|
|
128
137
|
export function resolveScopeIds(scope, tenantId, userId) {
|
|
129
138
|
switch (scope) {
|
|
130
139
|
case ConfigScopes.system:
|
|
@@ -138,7 +147,7 @@ export function resolveScopeIds(scope, tenantId, userId) {
|
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
// The subject a piiEncrypted config value is encrypted under, for the scope
|
|
141
|
-
// actually written to
|
|
150
|
+
// actually written to. Pure — no I/O — so a bug
|
|
142
151
|
// here (e.g. picking the writer's identity instead of the row's target,
|
|
143
152
|
// see entity fields' explicit userOwned.ownerField for why that
|
|
144
153
|
// distinction matters) is caught by a fast unit test, not only the DB-
|
|
@@ -7,7 +7,7 @@ export declare const forgetSubjectSchema: z.ZodObject<{
|
|
|
7
7
|
userId: z.ZodUUID;
|
|
8
8
|
}, z.core.$strip>, z.ZodObject<{
|
|
9
9
|
kind: z.ZodLiteral<"tenant">;
|
|
10
|
-
tenantId: z.
|
|
10
|
+
tenantId: z.ZodUUID;
|
|
11
11
|
}, z.core.$strip>, z.ZodObject<{
|
|
12
12
|
kind: z.ZodLiteral<"record">;
|
|
13
13
|
entity: z.ZodString;
|
|
@@ -39,7 +39,7 @@ export declare const forgetSubjectWrite: import("@cosmicdrift/kumiko-types/defin
|
|
|
39
39
|
userId: z.ZodUUID;
|
|
40
40
|
}, z.core.$strip>, z.ZodObject<{
|
|
41
41
|
kind: z.ZodLiteral<"tenant">;
|
|
42
|
-
tenantId: z.
|
|
42
|
+
tenantId: z.ZodUUID;
|
|
43
43
|
}, z.core.$strip>, z.ZodObject<{
|
|
44
44
|
kind: z.ZodLiteral<"record">;
|
|
45
45
|
entity: z.ZodString;
|
|
@@ -54,7 +54,7 @@ function subjectAggregateId(raw) {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
// The record subject names its own entity — resolve it against the registry
|
|
57
|
-
// instead of trusting the payload straight into resolveTableName/SQL
|
|
57
|
+
// instead of trusting the payload straight into resolveTableName/SQL.
|
|
58
58
|
function findRegisteredEntity(features, entityName) {
|
|
59
59
|
for (const feature of features.values()) {
|
|
60
60
|
const entity = feature.entities?.[entityName];
|
|
@@ -63,7 +63,7 @@ function findRegisteredEntity(features, entityName) {
|
|
|
63
63
|
}
|
|
64
64
|
return undefined;
|
|
65
65
|
}
|
|
66
|
-
// Tenant-scope guard
|
|
66
|
+
// Tenant-scope guard: DataProtectionOfficer is a tenant-scoped role,
|
|
67
67
|
// but the handler otherwise erases ANY subject cross-tenant on a raw
|
|
68
68
|
// (un-scoped) client — a Tenant-A DPO who learns a Tenant-B subject id
|
|
69
69
|
// (export, support ticket, log line) could destroy it. SystemAdmin
|
|
@@ -111,7 +111,7 @@ async function resolveTenantScopeDenial(db, features, user, raw) {
|
|
|
111
111
|
const ownedInTenant = await subjectRowExistsInTenant(db, features, raw.userId, user.tenantId);
|
|
112
112
|
return ownedInTenant ? undefined : memberDenied;
|
|
113
113
|
}
|
|
114
|
-
//
|
|
114
|
+
// blockDelete (legally mandated physical retention, e.g.
|
|
115
115
|
// ledger/invoice text) means this command must refuse, not silently
|
|
116
116
|
// anonymize or proceed. Refused when the host entity itself declares
|
|
117
117
|
// blockDelete OR the owning tenant's effective data-retention policy
|
|
@@ -162,8 +162,8 @@ function denialReasonOf(failure) {
|
|
|
162
162
|
}
|
|
163
163
|
return failure.error.code;
|
|
164
164
|
}
|
|
165
|
-
// Denied cross-tenant probes must still leave an audit trail
|
|
166
|
-
// Appended outside the handler tx
|
|
165
|
+
// Denied cross-tenant probes must still leave an audit trail.
|
|
166
|
+
// Appended outside the handler tx: the caller's
|
|
167
167
|
// `return tenantScopeDenial` rolls that tx back.
|
|
168
168
|
async function appendDenialAuditEvent(ctx, event, subjectKey, subjectKind, denialCode, denialAuditRunner) {
|
|
169
169
|
if (!denialAuditRunner) {
|
|
@@ -195,7 +195,7 @@ async function appendDenialAuditEvent(ctx, event, subjectKey, subjectKind, denia
|
|
|
195
195
|
registry: ctx.registry,
|
|
196
196
|
db: denialAuditRunner,
|
|
197
197
|
// MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw
|
|
198
|
-
// bypasses TenantDb's scoping, so this is the only guard against a cross-tenant denial event
|
|
198
|
+
// bypasses TenantDb's scoping, so this is the only guard against a cross-tenant denial event.
|
|
199
199
|
tenantId: event.user.tenantId,
|
|
200
200
|
userId: String(event.user.id),
|
|
201
201
|
callSiteLabel: "forget-subject denial audit",
|
|
@@ -224,7 +224,6 @@ function sweepErrorLabel(err) {
|
|
|
224
224
|
// Each step runs in its own savepoint: a database error must not abort the handler
|
|
225
225
|
// transaction, and one failing step must not skip or roll back the others.
|
|
226
226
|
async function sweepDerivedSubjectData(ctx, subject, subjectKey, crossTenantRunner, audit, rawSubject) {
|
|
227
|
-
const recordTenantId = await owningTenantOfRecordSubject(crossTenantRunner, ctx.registry.features, rawSubject);
|
|
228
227
|
const failureLabels = [];
|
|
229
228
|
const runStep = async (step) => {
|
|
230
229
|
try {
|
|
@@ -235,10 +234,10 @@ async function sweepDerivedSubjectData(ctx, subject, subjectKey, crossTenantRunn
|
|
|
235
234
|
}
|
|
236
235
|
};
|
|
237
236
|
await runStep(async (crossTenantSubjectRunner) => {
|
|
238
|
-
// Blind-index sweep
|
|
237
|
+
// Blind-index sweep: nulls bidx columns now so the deterministic
|
|
239
238
|
// HMAC doesn't stay equality-matchable; raw because the ciphertext prefix addresses the subject across tenants.
|
|
240
239
|
await nullBlindIndexesForSubject(crossTenantSubjectRunner, ctx.registry.features, subjectKey);
|
|
241
|
-
// Derived search index still holds plaintext
|
|
240
|
+
// Derived search index still holds plaintext — purge next to the
|
|
242
241
|
// blind-index sweep. No adapter → no-op (apps without search).
|
|
243
242
|
if (ctx.searchAdapter) {
|
|
244
243
|
await purgeSearchDocumentsForSubject(crossTenantSubjectRunner, ctx.registry.features, ctx.searchAdapter, subjectKey, subject);
|
|
@@ -254,15 +253,19 @@ async function sweepDerivedSubjectData(ctx, subject, subjectKey, crossTenantRunn
|
|
|
254
253
|
}
|
|
255
254
|
});
|
|
256
255
|
// File columns hold only the fileRef id, so the key erase never reaches the bytes.
|
|
257
|
-
await runStep((crossTenantSubjectRunner) =>
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
256
|
+
await runStep(async (crossTenantSubjectRunner) => {
|
|
257
|
+
// Inside the step: a failing owner lookup must land in the audit label, not abort the handler.
|
|
258
|
+
const recordTenantId = await owningTenantOfRecordSubject(crossTenantSubjectRunner, ctx.registry.features, rawSubject);
|
|
259
|
+
await purgeFilesReachingSubject({
|
|
260
|
+
registry: ctx.registry,
|
|
261
|
+
db: crossTenantSubjectRunner,
|
|
262
|
+
subject,
|
|
263
|
+
subjectKey,
|
|
264
|
+
...(recordTenantId !== undefined && { recordTenantId }),
|
|
265
|
+
resolveDeleteBytes: resolveFileBytesDeleter(ctx),
|
|
266
|
+
missingStorage: { mode: "fail" },
|
|
267
|
+
});
|
|
268
|
+
});
|
|
266
269
|
return failureLabels[0];
|
|
267
270
|
}
|
|
268
271
|
// Email subscribers and other non-user entities use user-style subject keys
|
|
@@ -310,7 +313,8 @@ async function appendSubjectForgotten(ctx, event, aggregateId, payload, outsideR
|
|
|
310
313
|
await appendDomainEventCore({
|
|
311
314
|
registry: ctx.registry,
|
|
312
315
|
db: outsideRunner,
|
|
313
|
-
// MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw bypasses TenantDb's
|
|
316
|
+
// MUST be event.user.tenantId, never SYSTEM_TENANT_ID — unsafeRaw bypasses TenantDb's
|
|
317
|
+
// scoping.
|
|
314
318
|
tenantId: event.user.tenantId,
|
|
315
319
|
userId: String(event.user.id),
|
|
316
320
|
callSiteLabel: "forget-subject audit",
|
|
@@ -331,7 +335,7 @@ async function appendSubjectForgotten(ctx, event, aggregateId, payload, outsideR
|
|
|
331
335
|
// The automated Art.-17 path (user-data-rights forget-cleanup) calls
|
|
332
336
|
// kms.eraseKey directly inside its per-user sub-tx; this command is the
|
|
333
337
|
// standalone trigger for cases outside that pipeline (authority requests,
|
|
334
|
-
// tenant-destroy
|
|
338
|
+
// tenant-destroy, operator recovery).
|
|
335
339
|
export const forgetSubjectWrite = defineWriteHandler({
|
|
336
340
|
name: "forget-subject",
|
|
337
341
|
schema: forgetSubjectSchema,
|
|
@@ -393,7 +397,7 @@ export const forgetSubjectWrite = defineWriteHandler({
|
|
|
393
397
|
// callable. Mirror of the automated Art.-17 path (userDeleteHook:
|
|
394
398
|
// status=Deleted; apiTokenDeleteHook: revoke):
|
|
395
399
|
// - user.updated as lifecycle event (updateUserLifecycle), so a
|
|
396
|
-
// read_users rebuild doesn't wipe the flip
|
|
400
|
+
// read_users rebuild doesn't wipe the flip
|
|
397
401
|
// - sessions don't need active revocation — session-callbacks
|
|
398
402
|
// re-validate user.status on every request (isPrincipalBlocked
|
|
399
403
|
// blocks Deleted).
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Deterministic aggregate
|
|
3
|
-
*
|
|
4
|
-
* FieldKey)
|
|
2
|
+
* Deterministic aggregate ID for a fieldDefinition aggregate from the tuple
|
|
3
|
+
* (tenantId, entityName, fieldKey). Exactly one aggregate exists per
|
|
4
|
+
* (Tenant|System, Entity, FieldKey).
|
|
5
5
|
*
|
|
6
|
-
* **Scope
|
|
7
|
-
* - System
|
|
8
|
-
*
|
|
9
|
-
* - Tenant
|
|
6
|
+
* **Scope semantics:**
|
|
7
|
+
* - System scope: `tenantId = SYSTEM_TENANT_ID` → the fieldDefinition applies
|
|
8
|
+
* to all tenants (vendor-defined).
|
|
9
|
+
* - Tenant scope: `tenantId = <tenant-uuid>` → each tenant has its own
|
|
10
10
|
* fieldDefinition.
|
|
11
11
|
*
|
|
12
|
-
* **Conflict
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* beim Read.
|
|
12
|
+
* **Conflict rule** (enforced in the write handler, NOT via a DB constraint):
|
|
13
|
+
* Only ONE definition may exist per (entityName, fieldKey)—system or tenant,
|
|
14
|
+
* but not both. If system defines `customer.internalNumber`, a tenant cannot
|
|
15
|
+
* define its own `customer.internalNumber` (422 `fieldKey_conflict`). This
|
|
16
|
+
* prevents ambiguity when resolving the field during reads.
|
|
18
17
|
*/
|
|
19
18
|
export declare function fieldDefinitionAggregateId(tenantId: string, entityName: string, fieldKey: string): string;
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import { v5 as uuidv5 } from "uuid";
|
|
2
|
-
// Fixed UUID
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
2
|
+
// Fixed UUID namespace for deriving custom-field definition aggregate IDs.
|
|
3
|
+
// Generated once; changing it would re-key every existing fieldDefinition stream,
|
|
4
|
+
// breaking event replay and definition history. Drift is pinned in
|
|
5
|
+
// __tests__/drift.test.ts.
|
|
6
6
|
const FIELD_DEFINITION_NAMESPACE = "f1d3b2c7-4e5a-4b9c-8d1f-2a3b4c5d6e7f";
|
|
7
7
|
/**
|
|
8
|
-
* Deterministic aggregate
|
|
9
|
-
*
|
|
10
|
-
* FieldKey)
|
|
8
|
+
* Deterministic aggregate ID for a fieldDefinition aggregate from the tuple
|
|
9
|
+
* (tenantId, entityName, fieldKey). Exactly one aggregate exists per
|
|
10
|
+
* (Tenant|System, Entity, FieldKey).
|
|
11
11
|
*
|
|
12
|
-
* **Scope
|
|
13
|
-
* - System
|
|
14
|
-
*
|
|
15
|
-
* - Tenant
|
|
12
|
+
* **Scope semantics:**
|
|
13
|
+
* - System scope: `tenantId = SYSTEM_TENANT_ID` → the fieldDefinition applies
|
|
14
|
+
* to all tenants (vendor-defined).
|
|
15
|
+
* - Tenant scope: `tenantId = <tenant-uuid>` → each tenant has its own
|
|
16
16
|
* fieldDefinition.
|
|
17
17
|
*
|
|
18
|
-
* **Conflict
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* beim Read.
|
|
18
|
+
* **Conflict rule** (enforced in the write handler, NOT via a DB constraint):
|
|
19
|
+
* Only ONE definition may exist per (entityName, fieldKey)—system or tenant,
|
|
20
|
+
* but not both. If system defines `customer.internalNumber`, a tenant cannot
|
|
21
|
+
* define its own `customer.internalNumber` (422 `fieldKey_conflict`). This
|
|
22
|
+
* prevents ambiguity when resolving the field during reads.
|
|
24
23
|
*/
|
|
25
24
|
// @wrapper-known uuid-domain
|
|
26
25
|
export function fieldDefinitionAggregateId(tenantId, entityName, fieldKey) {
|