@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
|
@@ -4,10 +4,10 @@ import { eventsTable } from "@cosmicdrift/kumiko-framework/event-store";
|
|
|
4
4
|
import { Temporal } from "@cosmicdrift/kumiko-types/temporal";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
import { redactPiiCiphertext } from "../../shared/index.js";
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
7
|
+
// GDPR Art. 15 self-disclosure: users may read only their own audit log.
|
|
8
|
+
// `createdBy = ctx.user.id` is hard-coded to prevent cross-user snooping;
|
|
9
|
+
// no `tenantId` filter is applied because the user is entitled to an
|
|
10
|
+
// account-wide view across all memberships, as in the forget path.
|
|
11
11
|
const MAX_LIMIT = 100;
|
|
12
12
|
const MY_AUDIT_LOG_REASON = "reads the caller's own events across all tenant memberships, bounded by createdBy = caller";
|
|
13
13
|
export const myAuditLogQuery = defineQueryHandler({
|
|
@@ -5,12 +5,12 @@ export type SendDeletionVerificationEmailFn = (args: {
|
|
|
5
5
|
readonly expiresAt: string;
|
|
6
6
|
}) => Promise<void>;
|
|
7
7
|
export type RequestDeletionByEmailOptions = {
|
|
8
|
-
/** HMAC
|
|
9
|
-
*
|
|
8
|
+
/** HMAC secret used to sign the verification token. Without a secret, the flow
|
|
9
|
+
* is disabled (the handler silently responds with success and no link). */
|
|
10
10
|
readonly deletionTokenSecret?: string;
|
|
11
|
-
/**
|
|
12
|
-
* "https://app.example.com/delete-account/confirm".
|
|
13
|
-
*
|
|
11
|
+
/** Base URL of the Apex confirmation screen, e.g.
|
|
12
|
+
* "https://app.example.com/delete-account/confirm". The handler appends the
|
|
13
|
+
* token as a URL fragment (`#token=<token>`). Without a URL, no link is sent. */
|
|
14
14
|
readonly deletionVerifyUrl?: string;
|
|
15
15
|
readonly sendDeletionVerificationEmail?: SendDeletionVerificationEmailFn;
|
|
16
16
|
};
|
|
@@ -3,13 +3,13 @@ import * as z from "zod";
|
|
|
3
3
|
import { USER_STATUS, userTable } from "../../user/index.js";
|
|
4
4
|
import { signDeletionToken } from "../deletion-token.js";
|
|
5
5
|
import { updateUserLifecycle } from "../lib/update-user-lifecycle.js";
|
|
6
|
-
// TTL
|
|
7
|
-
//
|
|
6
|
+
// Verification-link TTL: 60 minutes — long enough for an email round trip,
|
|
7
|
+
// but short enough that an intercepted link does not remain valid indefinitely.
|
|
8
8
|
const DELETION_VERIFY_TTL_MINUTES = 60;
|
|
9
9
|
// Token goes in the URL fragment, not a query param — fragments never leave
|
|
10
10
|
// the browser (not sent to the server, so they never land in proxy/access
|
|
11
11
|
// logs, unlike `?token=`). Same convention as the export-download link
|
|
12
|
-
// (feature.ts
|
|
12
|
+
// (feature.ts). Preserves any existing query params on `base`
|
|
13
13
|
// (`?lang=de` stays a query param; only the token is a fragment).
|
|
14
14
|
const APPEND_LIFECYCLE_EVENT_REASON = "appends the user lifecycle event on the SYSTEM_TENANT_ID user stream";
|
|
15
15
|
export function buildDeletionVerifyUrl(base, token) {
|
|
@@ -17,14 +17,14 @@ export function buildDeletionVerifyUrl(base, token) {
|
|
|
17
17
|
url.hash = `token=${encodeURIComponent(token)}`;
|
|
18
18
|
return url.toString();
|
|
19
19
|
}
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
// (
|
|
20
|
+
// Anonymous Apex flow step 1: request account deletion by email.
|
|
21
|
+
// This is especially relevant for GDPR when the user can no longer log in
|
|
22
|
+
// (lockout). Email → magic link → confirm-deletion-by-token.
|
|
23
23
|
//
|
|
24
|
-
// Enumeration-safe (content):
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
// Timing
|
|
24
|
+
// Enumeration-safe (content): always returns the same success shape,
|
|
25
|
+
// regardless of whether the email exists, the user is active, or the flow is
|
|
26
|
+
// configured. A link is generated only for an existing, active user.
|
|
27
|
+
// Timing safety depends on the non-blocking callback (see the type doc above).
|
|
28
28
|
export function createRequestDeletionByEmailHandler(opts = {}) {
|
|
29
29
|
return defineWriteHandler({
|
|
30
30
|
name: "request-deletion-by-email",
|
|
@@ -33,7 +33,7 @@ export function createRequestDeletionByEmailHandler(opts = {}) {
|
|
|
33
33
|
description: "Mails an account-deletion verification link to the given address, for a user who wants to be erased but can no longer log in; it answers identically whether or not the address belongs to an active account and never returns the link.",
|
|
34
34
|
// Mails a deletion link to any address the caller names.
|
|
35
35
|
agent: { risk: "high" },
|
|
36
|
-
// Defense
|
|
36
|
+
// Defense in depth against email probing on the anonymous endpoint.
|
|
37
37
|
rateLimit: { per: "ip+handler", limit: 10, windowSeconds: 60 },
|
|
38
38
|
escapeHatch: {
|
|
39
39
|
grants: ["unsafeRaw", "globalWrites"],
|
|
@@ -41,7 +41,8 @@ export function createRequestDeletionByEmailHandler(opts = {}) {
|
|
|
41
41
|
},
|
|
42
42
|
handler: async (event, ctx) => {
|
|
43
43
|
const success = { isSuccess: true, data: { kind: "requested" } };
|
|
44
|
-
// not
|
|
44
|
+
// Safe when not configured: without a secret or URL, no link is sent, but the response is
|
|
45
|
+
// unchanged.
|
|
45
46
|
if (!opts.deletionTokenSecret || !opts.deletionVerifyUrl)
|
|
46
47
|
return success;
|
|
47
48
|
const userRow = await ctx.db
|
|
@@ -53,9 +54,9 @@ export function createRequestDeletionByEmailHandler(opts = {}) {
|
|
|
53
54
|
if (!userRow || userRow["status"] !== USER_STATUS.Active || !userRow["email"]) {
|
|
54
55
|
return success;
|
|
55
56
|
}
|
|
56
|
-
// Replay
|
|
57
|
-
// user
|
|
58
|
-
//
|
|
57
|
+
// Replay protection: each request gets a fresh requestId, which is stored on
|
|
58
|
+
// the user row and incorporated into the token HMAC purpose. cancel
|
|
59
|
+
// nulls it, so a token replayed after cancellation no longer verifies.
|
|
59
60
|
const requestId = crypto.randomUUID();
|
|
60
61
|
await updateUserLifecycle(ctx.db.unsafeRaw(), userRow["id"], {
|
|
61
62
|
pendingDeletionRequestId: requestId,
|
|
@@ -11,8 +11,8 @@ export type SendDeletionRequestedEmailFn = (args: {
|
|
|
11
11
|
}) => Promise<void>;
|
|
12
12
|
export type RequestDeletionOptions = {
|
|
13
13
|
readonly sendDeletionRequestedEmail?: SendDeletionRequestedEmailFn;
|
|
14
|
-
/** Branding
|
|
15
|
-
*
|
|
14
|
+
/** Branding for the default email when sendDeletionRequestedEmail is not set
|
|
15
|
+
* and mail-foundation is mounted. */
|
|
16
16
|
readonly mailDefaults?: GdprMailDefaults;
|
|
17
17
|
};
|
|
18
18
|
export declare function createRequestDeletionHandler(opts?: RequestDeletionOptions): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"request-deletion", z.ZodObject<{}, z.core.$strip>, {
|
|
@@ -4,11 +4,10 @@ import * as z from "zod";
|
|
|
4
4
|
import { USER_STATUS } from "../../user/index.js";
|
|
5
5
|
import { isGdprMailDeliveryAvailable, makeDefaultDeletionRequestedEmail, } from "../lib/default-mailers.js";
|
|
6
6
|
import { resolveGracePeriod, startDeletionGracePeriod } from "./deletion-grace-period.js";
|
|
7
|
-
// POST /api/user/request-deletion
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// user-data-rights.md "Cross-Tenant-Semantik".
|
|
7
|
+
// POST /api/user/request-deletion — GDPR Art. 17 erasure request.
|
|
8
|
+
// Changes status=Active → deletionRequested and sets gracePeriodEnd from the compliance
|
|
9
|
+
// profile using the shared startDeletionGracePeriod logic. The operation applies to the
|
|
10
|
+
// account-wide user row, so the user identity is global across tenants.
|
|
12
11
|
export function createRequestDeletionHandler(opts = {}) {
|
|
13
12
|
return defineWriteHandler({
|
|
14
13
|
name: "request-deletion",
|
|
@@ -39,8 +38,7 @@ export function createRequestDeletionHandler(opts = {}) {
|
|
|
39
38
|
(ctx.notify !== undefined && isGdprMailDeliveryAvailable(ctx.registry)
|
|
40
39
|
? makeDefaultDeletionRequestedEmail(ctx.notify, opts.mailDefaults)
|
|
41
40
|
: undefined);
|
|
42
|
-
// Best-effort
|
|
43
|
-
// killen — siehe Type-Doc oben.
|
|
41
|
+
// Best-effort email notification: a send failure must not abort the write.
|
|
44
42
|
if (send && userEmail.length > 0) {
|
|
45
43
|
try {
|
|
46
44
|
await send({
|
|
@@ -56,8 +54,8 @@ export function createRequestDeletionHandler(opts = {}) {
|
|
|
56
54
|
console.warn(`[user-data-rights:request-deletion] sendDeletionRequestedEmail failed userId=${event.user.id} tenantId=${event.user.tenantId} err=${err instanceof Error ? err.message : String(err)}`);
|
|
57
55
|
}
|
|
58
56
|
}
|
|
59
|
-
//
|
|
60
|
-
//
|
|
57
|
+
// Returns the absolute gracePeriodEnd timestamp so the frontend, audit, and cleanup
|
|
58
|
+
// runner all use the same value.
|
|
61
59
|
return {
|
|
62
60
|
isSuccess: true,
|
|
63
61
|
data: {
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
// POST /api/user/request-export
|
|
1
|
+
// POST /api/user/request-export — GDPR Art. 15 and 20 trigger.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
// (
|
|
3
|
+
// The user triggers an export job, persisted through
|
|
4
|
+
// createEventStoreExecutor (event-sourced pattern; ES has no CRUD).
|
|
5
|
+
// Idempotency uses two stages:
|
|
5
6
|
//
|
|
6
|
-
// 1) **App-side-
|
|
7
|
-
// (status pending|running)
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// 1) **App-side pre-check (primary path):** fetch active jobs with
|
|
8
|
+
// (status pending|running) for the userId. If one exists, return
|
|
9
|
+
// `{jobId, isExisting: true}` without creating an event, so a click
|
|
10
|
+
// storm produces one audit event rather than N.
|
|
10
11
|
//
|
|
11
|
-
// 2) **DB
|
|
12
|
-
//
|
|
13
|
-
// constraint_name === "read_export_jobs_one_active_per_user".
|
|
14
|
-
// Catch
|
|
15
|
-
// Window <1ms, in Production extrem selten.
|
|
12
|
+
// 2) **DB constraint as race protection (secondary path):** if a parallel
|
|
13
|
+
// click occurs between fetchOne and crud.create, the transaction raises
|
|
14
|
+
// 23505 with constraint_name === "read_export_jobs_one_active_per_user".
|
|
15
|
+
// Catch, re-fetch, and return the existing job with isExisting=true.
|
|
16
16
|
//
|
|
17
|
-
// **Cross-
|
|
18
|
-
// across all memberships)
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
17
|
+
// **Cross-tenant semantics:** ExportJob is tenant-agnostic (one job per
|
|
18
|
+
// userId across all memberships), so the pre-check uses ctx.db.unsafeRaw
|
|
19
|
+
// (no TenantDb filter) and a click from tenant B can find the job from tenant
|
|
20
|
+
// A. `requestedFromTenantId` persists the tenant from the first click; the
|
|
21
|
+
// worker reads its compliance profile from this tenant for job TTL, stale
|
|
22
|
+
// handling, and cleanup.
|
|
22
23
|
import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
23
24
|
import { defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
24
25
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
@@ -29,11 +30,11 @@ const crud = createEventStoreExecutor(exportJobsTable, exportJobEntity, {
|
|
|
29
30
|
});
|
|
30
31
|
const REQUEST_EXPORT_REASON = "export jobs are keyed by userId across all of the user's tenant memberships, not the caller's current tenant";
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* `createEventStoreExecutor.create` catches 23505 internally and returns
|
|
34
|
+
* `WriteFailure(UniqueViolationError)` rather than throwing. Check the
|
|
35
|
+
* failure code and constraintName to distinguish the app-side and race
|
|
36
|
+
* paths; propagate other failures (validation, version conflicts, ...)
|
|
37
|
+
* unchanged.
|
|
37
38
|
*/
|
|
38
39
|
function isActiveJobConflict(failure) {
|
|
39
40
|
const error = failure.error; // @cast-boundary error-details
|
|
@@ -62,9 +63,9 @@ export const requestExportWrite = defineWriteHandler({
|
|
|
62
63
|
// TenantDb-Wrapper would hide cross-tenant jobs.
|
|
63
64
|
const existing = await findActiveJob(exportJobRunner, userId);
|
|
64
65
|
if (existing) {
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
66
|
+
// The returned status is a snapshot and can become stale between fetchOne
|
|
67
|
+
// and the response if the worker changes the state concurrently. The
|
|
68
|
+
// window is minimal; clients poll export-status.query for live status.
|
|
68
69
|
return {
|
|
69
70
|
isSuccess: true,
|
|
70
71
|
data: {
|
|
@@ -74,9 +75,9 @@ export const requestExportWrite = defineWriteHandler({
|
|
|
74
75
|
},
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
78
|
+
// No active job exists, so create one through crud.create. Persist the
|
|
79
|
+
// user's current tenant in requestedFromTenantId so the worker reads the
|
|
80
|
+
// compliance profile from that tenant.
|
|
80
81
|
const result = await crud.create({
|
|
81
82
|
userId,
|
|
82
83
|
requestedFromTenantId: event.user.tenantId,
|
|
@@ -84,16 +85,16 @@ export const requestExportWrite = defineWriteHandler({
|
|
|
84
85
|
tenantId: event.user.tenantId,
|
|
85
86
|
}, event.user, ctx.db);
|
|
86
87
|
if (!result.isSuccess) {
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
88
|
+
// A parallel click may create an active job between findActiveJob and
|
|
89
|
+
// crud.create, causing UniqueViolationError for our constraint. Re-fetch
|
|
90
|
+
// and return the existing job with isExisting=true. Propagate other
|
|
91
|
+
// failures (validation, version conflicts, ...) unchanged.
|
|
91
92
|
if (isActiveJobConflict(result)) {
|
|
92
93
|
const winner = await findActiveJob(exportJobRunner, userId);
|
|
93
94
|
if (!winner) {
|
|
94
|
-
//
|
|
95
|
-
// active
|
|
96
|
-
//
|
|
95
|
+
// This should be impossible: a constraint violation without an existing
|
|
96
|
+
// active job would mean the constraint matched something else.
|
|
97
|
+
// Return the original failure so the inconsistency is visible.
|
|
97
98
|
return result;
|
|
98
99
|
}
|
|
99
100
|
return {
|
|
@@ -107,17 +108,17 @@ export const requestExportWrite = defineWriteHandler({
|
|
|
107
108
|
}
|
|
108
109
|
return result;
|
|
109
110
|
}
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
111
|
+
// SaveContext.id is EntityId (number | string), while exportJobEntity has
|
|
112
|
+
// idType:"uuid" and therefore guarantees a string. String() protects
|
|
113
|
+
// against drift if the entity is migrated to serial.
|
|
113
114
|
const created = result.data; // @cast-boundary engine-payload
|
|
114
115
|
return {
|
|
115
116
|
isSuccess: true,
|
|
116
117
|
data: {
|
|
117
118
|
jobId: String(created.id),
|
|
118
|
-
//
|
|
119
|
-
// export-status.query
|
|
120
|
-
// initial UI
|
|
119
|
+
// This is a snapshot: a just-created job is pending. Live status comes
|
|
120
|
+
// from export-status.query; this value is only a convenience for the
|
|
121
|
+
// initial UI render ("Anfrage angenommen, currently pending").
|
|
121
122
|
status: EXPORT_JOB_STATUS.Pending,
|
|
122
123
|
isExisting: false,
|
|
123
124
|
},
|
|
@@ -5,15 +5,16 @@ import { USER_STATUS, userTable } from "../../user/index.js";
|
|
|
5
5
|
import { denyIfTargetOutsideAdminTenant } from "../lib/deny-if-target-outside-admin-tenant.js";
|
|
6
6
|
import { isAdminActor } from "../lib/is-admin-actor.js";
|
|
7
7
|
import { updateUserLifecycle } from "../lib/update-user-lifecycle.js";
|
|
8
|
-
// POST /api/user/restrict
|
|
9
|
-
//
|
|
10
|
-
//
|
|
8
|
+
// POST /api/user/restrict — GDPR Art. 18 account freeze.
|
|
9
|
+
// Flips status=Active → Restricted and revokes all live sessions
|
|
10
|
+
// for the user via cross-feature ctx.writeAs(sessions.revokeAllForUser).
|
|
11
11
|
//
|
|
12
|
-
//
|
|
13
|
-
// - Login
|
|
14
|
-
// - Active sessions
|
|
15
|
-
//
|
|
16
|
-
//
|
|
12
|
+
// Write API behaviour:
|
|
13
|
+
// - Login is blocked: login.write.ts checks status=Restricted (Atom 3).
|
|
14
|
+
// - Active sessions are revoked through a cross-feature call (the
|
|
15
|
+
// sessions feature must be mounted). An app author without the
|
|
16
|
+
// sessions feature gets a boot resolver error via
|
|
17
|
+
// r.usesApi("sessions.revokeAllForUser").
|
|
17
18
|
//
|
|
18
19
|
// Self-service by default (userId omitted → event.user.id). An admin can
|
|
19
20
|
// also target someone else's account — needed once a user is already
|
|
@@ -22,14 +23,16 @@ import { updateUserLifecycle } from "../lib/update-user-lifecycle.js";
|
|
|
22
23
|
// themselves; only an operator path reaches it at that point.
|
|
23
24
|
//
|
|
24
25
|
// Tenant scope: `isAdminActor` accepts access.admin, which includes TenantAdmin
|
|
25
|
-
// (tenant-scoped) even though the User
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
26
|
+
// (tenant-scoped) even though the User entity is global — see user-data-rights.md
|
|
27
|
+
// "Cross-Tenant-Semantik". Without a membership check, a TenantAdmin from tenant A
|
|
28
|
+
// could restrict or unrestrict a user who has never been a member of tenant A.
|
|
29
|
+
// Only SystemAdmin (platform-wide) skips the check; the target must have a
|
|
30
|
+
// membership row in the acting admin's `event.user.tenantId` (row existence only —
|
|
31
|
+
// no active-status field).
|
|
29
32
|
//
|
|
30
|
-
// State
|
|
31
|
-
// Active → Restricted ✓ (
|
|
32
|
-
// Restricted → Restricted ✗ 422 already_restricted (
|
|
33
|
+
// State transitions:
|
|
34
|
+
// Active → Restricted ✓ (this handler)
|
|
35
|
+
// Restricted → Restricted ✗ 422 already_restricted (idempotency guard)
|
|
33
36
|
// DeletionRequested → ... ✗ 422 user_not_in_active_state
|
|
34
37
|
// Deleted → ... ✗ 422 user_not_in_active_state
|
|
35
38
|
export const restrictAccountWrite = defineWriteHandler({
|
|
@@ -83,10 +86,10 @@ export const restrictAccountWrite = defineWriteHandler({
|
|
|
83
86
|
}));
|
|
84
87
|
}
|
|
85
88
|
await updateUserLifecycle(ctx.db.unsafeRaw(), targetUserId, { status: USER_STATUS.Restricted });
|
|
86
|
-
// Cross-
|
|
87
|
-
//
|
|
88
|
-
// ctx.writeAs(systemUser, ...)
|
|
89
|
-
// System
|
|
89
|
+
// Cross-feature: all live sessions are revoked; otherwise the user could
|
|
90
|
+
// continue writing with an existing JWT until token expiry.
|
|
91
|
+
// ctx.writeAs(systemUser, ...) gives the privileged handler the
|
|
92
|
+
// System user roles required by its access gate.
|
|
90
93
|
const systemUser = createSystemUser(event.user.tenantId);
|
|
91
94
|
await ctx.writeAs(systemUser, "sessions:write:user-session:revoke-all-for-user", {
|
|
92
95
|
userId: targetUserId,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
// POST /userDataRights/run-forget-cleanup
|
|
1
|
+
// POST /userDataRights/run-forget-cleanup.
|
|
2
2
|
//
|
|
3
|
-
// Cron
|
|
4
|
-
// `runForgetCleanup`
|
|
5
|
-
//
|
|
6
|
-
// `run-forget-cleanup.ts
|
|
3
|
+
// Cron trigger for the forget-cleanup pipeline. The handler only wraps
|
|
4
|
+
// `runForgetCleanup` so the dispatcher can invoke it as the system user;
|
|
5
|
+
// the pipeline logic itself lives in the pure-function module
|
|
6
|
+
// `run-forget-cleanup.ts`, which can be tested without the dispatcher.
|
|
7
7
|
//
|
|
8
|
-
// Access: privileged —
|
|
9
|
-
//
|
|
8
|
+
// Access: privileged — only system callers (cron, ops script). In the cron
|
|
9
|
+
// setup, the job runs with `createSystemUser(...)` as executor.
|
|
10
10
|
//
|
|
11
|
-
//
|
|
11
|
+
// Returns stats for operator monitoring (processed count, error list).
|
|
12
12
|
import { access, defineWriteHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
13
13
|
import { InternalError, writeFailure } from "@cosmicdrift/kumiko-framework/errors";
|
|
14
14
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
@@ -2,17 +2,15 @@ export { deletionTokenSecretEnvSchema } from "./env.js";
|
|
|
2
2
|
export { createUserDataRightsFeature } from "./feature.js";
|
|
3
3
|
export { denyIfTargetOutsideAdminTenant, TARGET_USER_NOT_IN_ADMIN_TENANT, } from "./lib/deny-if-target-outside-admin-tenant.js";
|
|
4
4
|
export { isSystemAdminActor } from "./lib/is-admin-actor.js";
|
|
5
|
-
//
|
|
6
|
-
//
|
|
5
|
+
// Reconcile existing data once before re-enabling read_users rebuilds.
|
|
6
|
+
// See the library documentation for the required procedure.
|
|
7
7
|
export { backfillUserLifecycleEvents, updateUserLifecycle } from "./lib/update-user-lifecycle.js";
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
// host-entity check) reuse this instead of re-deriving the anonymize/delete
|
|
15
|
-
// split.
|
|
8
|
+
// Exported so app tests can run export/forget deterministically instead of
|
|
9
|
+
// waiting for the job cron.
|
|
10
|
+
// Shared retention-to-strategy mapping: other EXT_USER_DATA delete hooks that
|
|
11
|
+
// independently consult a DIFFERENT entity's retention (for example,
|
|
12
|
+
// notes-history-user-data's host-entity check) reuse this instead of
|
|
13
|
+
// re-deriving the anonymize/delete split.
|
|
16
14
|
export { policyToStrategy, runForgetCleanup } from "./run-forget-cleanup.js";
|
|
17
15
|
export { runUserExport } from "./run-user-export.js";
|
|
18
16
|
export { downloadAttemptEntity, downloadAttemptsTable } from "./schema/download-attempt.js";
|
|
@@ -93,9 +93,9 @@ function emailChannelOf(registry) {
|
|
|
93
93
|
}
|
|
94
94
|
export function makeDefaultDeletionExecutedEmail(deps, defaults = {}) {
|
|
95
95
|
return async (args) => {
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
96
|
+
// The user is global, but the mail transport is tenant-specific, so use the
|
|
97
|
+
// first membership's transport. An orphan user has no tenant identity, so no
|
|
98
|
+
// transport can be resolved and the mail is omitted.
|
|
99
99
|
const tenantId = args.tenantIds[0];
|
|
100
100
|
if (tenantId === undefined) {
|
|
101
101
|
// skip: orphan user has no tenant whose transport could send the mail
|
|
@@ -2,20 +2,17 @@ import { createEventStoreExecutor, createTenantDb, selectMany, } from "@cosmicdr
|
|
|
2
2
|
import { createSystemUser, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { InternalError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import { USER_STATUS, userEntity, userTable } from "../../user/index.js";
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// gracePeriodEnd/pendingDeletionRequestId/Deleted
|
|
9
|
-
// Datenverlust).
|
|
5
|
+
// Lifecycle mutations of the user entity MUST be emitted as `user.updated` events.
|
|
6
|
+
// Writing them directly with updateMany causes a read_users rebuild to erase them
|
|
7
|
+
// (it replays only `user.created`, so status falls back to its default;
|
|
8
|
+
// gracePeriodEnd/pendingDeletionRequestId/Deleted are lost, causing GDPR data loss).
|
|
10
9
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
// NICHT `event.user.tenantId` (das ist der aktive Tenant zur Lifecycle-Zeit und
|
|
18
|
-
// kann abweichen).
|
|
10
|
+
// The event MUST use the same (tenant_id, aggregate_id) stream as `user.created`,
|
|
11
|
+
// otherwise the aggregate is split across tenants and cannot be reconstructed.
|
|
12
|
+
// The user entity runs under `r.systemScope()`, but its events use a concrete
|
|
13
|
+
// tenant stream (see auth-email-password/stream-tenant.ts). Therefore, rescope to
|
|
14
|
+
// the user's stream tenant—the tenant of the `user.created` event—not
|
|
15
|
+
// `event.user.tenantId`, which is the active tenant at lifecycle time and may differ.
|
|
19
16
|
const userExecutor = createEventStoreExecutor(userTable, userEntity, { entityName: "user" });
|
|
20
17
|
// `conn` is ctx.db.unsafeRaw() (regular handlers) or the open tx
|
|
21
18
|
// (forget-cleanup sub-tx) — keeps the event append atomic with the write.
|
|
@@ -29,10 +26,10 @@ const userExecutor = createEventStoreExecutor(userTable, userEntity, { entityNam
|
|
|
29
26
|
// throws — those callers never checked a return value, so silently dropping
|
|
30
27
|
// their write would be silent data loss.
|
|
31
28
|
export async function updateUserLifecycle(conn, userId, changes, options) {
|
|
32
|
-
// user
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
29
|
+
// The user is a system stream: the executor choke point always addresses the
|
|
30
|
+
// stream through SYSTEM_TENANT_ID; rescoping to row-tenant_id would have no
|
|
31
|
+
// effect. Use "system" mode so loadById also finds legacy rows whose tenant_id
|
|
32
|
+
// predates the backfill rebuild.
|
|
36
33
|
// skipOptimisticLock: every caller is a server-side business transition
|
|
37
34
|
// (restrict/lift-restriction/grace-period/cancel/forget) that holds no row
|
|
38
35
|
// version to pass as `payload.version`, which update() requires otherwise.
|