@cosmicdrift/kumiko-samples 0.386.0 → 0.388.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -57
- package/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +9 -2
- package/packages/bundled-features/src/agent-tools/changes.json +6 -0
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +9 -9
- package/packages/bundled-features/src/audit/changes.json +12 -0
- package/packages/bundled-features/src/audit/handlers/audit-events.ts +1 -1
- package/packages/bundled-features/src/audit/screens.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/auth-user-row.ts +10 -10
- package/packages/bundled-features/src/auth-email-password/feature.ts +6 -6
- package/packages/bundled-features/src/auth-email-password/handlers/change-password.write.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/handlers/confirm-token-flow.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept-with-login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-accept.write.ts +18 -18
- package/packages/bundled-features/src/auth-email-password/handlers/invite-create.write.ts +12 -12
- package/packages/bundled-features/src/auth-email-password/handlers/invite-info.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/invite-signup-complete.write.ts +24 -26
- package/packages/bundled-features/src/auth-email-password/handlers/login.write.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/self-registration-status.query.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/handlers/signup-confirm.write.ts +34 -37
- package/packages/bundled-features/src/auth-email-password/handlers/signup-request.write.ts +6 -7
- package/packages/bundled-features/src/auth-email-password/handlers/switch-tenant-mfa-gate.write.ts +1 -5
- package/packages/bundled-features/src/auth-email-password/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/lockout-store.ts +1 -1
- package/packages/bundled-features/src/auth-email-password/seeding.ts +63 -66
- package/packages/bundled-features/src/auth-email-password/signup-token-store.ts +8 -8
- package/packages/bundled-features/src/auth-email-password/testing.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/auth-client.ts +57 -57
- package/packages/bundled-features/src/auth-email-password/web/auth-form-primitives.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/auth-gate.tsx +15 -16
- package/packages/bundled-features/src/auth-email-password/web/client-plugin.ts +11 -12
- package/packages/bundled-features/src/auth-email-password/web/confirm-account-unlock-screen.tsx +1 -1
- package/packages/bundled-features/src/auth-email-password/web/constants.ts +3 -3
- package/packages/bundled-features/src/auth-email-password/web/default-topbar-actions.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/forgot-password-screen.tsx +11 -11
- package/packages/bundled-features/src/auth-email-password/web/index.ts +5 -5
- package/packages/bundled-features/src/auth-email-password/web/invite-accept-screen.tsx +17 -17
- package/packages/bundled-features/src/auth-email-password/web/login-screen.tsx +3 -4
- package/packages/bundled-features/src/auth-email-password/web/reset-password-screen.tsx +16 -17
- package/packages/bundled-features/src/auth-email-password/web/session.tsx +34 -34
- package/packages/bundled-features/src/auth-email-password/web/signup-complete-screen.tsx +3 -3
- package/packages/bundled-features/src/auth-email-password/web/signup-screen.tsx +14 -14
- package/packages/bundled-features/src/auth-email-password/web/tenant-switcher.tsx +26 -27
- package/packages/bundled-features/src/auth-email-password/web/use-shell-user.ts +12 -13
- package/packages/bundled-features/src/auth-email-password/web/user-menu.tsx +17 -18
- package/packages/bundled-features/src/auth-email-password/web/verify-email-screen.tsx +11 -12
- package/packages/bundled-features/src/auth-foundation/boot-checks.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/resolve-anonymous-access.ts +4 -4
- package/packages/bundled-features/src/auth-foundation/types.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/changes.json +6 -0
- package/packages/bundled-features/src/auth-mfa/feature-exports.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/feature.ts +6 -0
- package/packages/bundled-features/src/auth-mfa/handlers/disable.write.ts +3 -3
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm-preauth.write.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/handlers/enable-confirm.write.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/handlers/enable-start-preauth.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/reencrypt.job.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/handlers/regenerate-recovery.write.ts +5 -5
- package/packages/bundled-features/src/auth-mfa/handlers/verify.write.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/token-secrets.ts +1 -1
- package/packages/bundled-features/src/auth-mfa/web/client-plugin.ts +2 -2
- package/packages/bundled-features/src/auth-mfa/web/i18n.ts +9 -4
- package/packages/bundled-features/src/auth-mfa/web/index.ts +4 -4
- package/packages/bundled-features/src/auth-mfa/web/mfa-client.ts +17 -16
- package/packages/bundled-features/src/auth-mfa/web/mfa-code-or-recovery-field.tsx +68 -0
- package/packages/bundled-features/src/auth-mfa/web/mfa-disable-dialog.tsx +23 -13
- package/packages/bundled-features/src/auth-mfa/web/mfa-regenerate-recovery-dialog.tsx +23 -13
- package/packages/bundled-features/src/auth-mfa/web/mfa-setup-preauth-screen.tsx +15 -6
- package/packages/bundled-features/src/auth-mfa/web/mfa-verify-screen.tsx +71 -24
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/changes.json +55 -0
- package/packages/bundled-features/src/billing-foundation/checkout-core.ts +32 -42
- package/packages/bundled-features/src/billing-foundation/consumer-protection/confirmation-mail.ts +8 -2
- package/packages/bundled-features/src/billing-foundation/consumer-protection/consent-gate.ts +2 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/issue-confirmation.ts +14 -3
- package/packages/bundled-features/src/billing-foundation/consumer-protection/mail-notifications.ts +3 -4
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-receipt-limit.ts +12 -6
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-record.ts +35 -19
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-request.ts +12 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-revoke.ts +14 -8
- package/packages/bundled-features/src/billing-foundation/consumer-protection/termination-texts.ts +5 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/withdrawal-period.ts +8 -10
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +23 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +45 -44
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/billing-plans.query.ts +71 -6
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +19 -17
- package/packages/bundled-features/src/billing-foundation/handlers/create-portal-session.write.ts +11 -12
- package/packages/bundled-features/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -4
- package/packages/bundled-features/src/billing-foundation/handlers/plan-switch-preview.query.ts +65 -0
- package/packages/bundled-features/src/billing-foundation/handlers/process-event.write.ts +29 -22
- package/packages/bundled-features/src/billing-foundation/handlers/start-plan-checkout.write.ts +44 -8
- package/packages/bundled-features/src/billing-foundation/handlers/switch-plan.write.ts +72 -82
- package/packages/bundled-features/src/billing-foundation/handlers/sync-subscription.write.ts +14 -1
- package/packages/bundled-features/src/billing-foundation/i18n.ts +22 -0
- package/packages/bundled-features/src/billing-foundation/index.ts +2 -0
- package/packages/bundled-features/src/billing-foundation/plan-catalog.ts +62 -27
- package/packages/bundled-features/src/billing-foundation/plan-switch.ts +84 -0
- package/packages/bundled-features/src/billing-foundation/projection.ts +38 -37
- package/packages/bundled-features/src/billing-foundation/subscription-tier-sync.ts +3 -3
- package/packages/bundled-features/src/billing-foundation/tenant-destroy-hook.ts +7 -8
- package/packages/bundled-features/src/billing-foundation/types.ts +144 -66
- package/packages/bundled-features/src/billing-foundation/validate-options.ts +19 -0
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +123 -51
- package/packages/bundled-features/src/billing-foundation/web/checkout-consent-dialog.tsx +89 -42
- package/packages/bundled-features/src/billing-foundation/web/constants.ts +4 -0
- package/packages/bundled-features/src/billing-foundation/web/plan-price.ts +55 -0
- package/packages/bundled-features/src/billing-foundation/web/plan-switch-confirm-dialog.tsx +224 -0
- package/packages/bundled-features/src/billing-foundation/webhook-handler.ts +1 -1
- package/packages/bundled-features/src/cap-counter/aggregate-id.ts +8 -9
- package/packages/bundled-features/src/cap-counter/cap-reservation.ts +5 -1
- package/packages/bundled-features/src/cap-counter/changes.json +18 -0
- package/packages/bundled-features/src/cap-counter/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +66 -68
- package/packages/bundled-features/src/cap-counter/entity.ts +29 -29
- package/packages/bundled-features/src/cap-counter/feature.ts +34 -35
- package/packages/bundled-features/src/cap-counter/handlers/increment-rolling.write.ts +31 -31
- package/packages/bundled-features/src/cap-counter/handlers/mark-soft-warned.write.ts +4 -5
- package/packages/bundled-features/src/cap-counter/stock-cap-guard.ts +9 -2
- package/packages/bundled-features/src/cap-counter/with-cap-enforcement.ts +3 -5
- package/packages/bundled-features/src/cap-overview/handlers/caps-usage.query.ts +1 -3
- package/packages/bundled-features/src/cap-overview/handlers/tenant-caps-list.query.ts +1 -1
- package/packages/bundled-features/src/channel-email/changes.json +6 -0
- package/packages/bundled-features/src/channel-email/feature.ts +1 -1
- package/packages/bundled-features/src/channel-email/smtp-transport.ts +34 -31
- package/packages/bundled-features/src/channel-in-app/handlers/unread-count.query.ts +3 -4
- package/packages/bundled-features/src/compliance-profiles/feature.ts +15 -16
- package/packages/bundled-features/src/compliance-profiles/handlers/for-tenant.query.ts +3 -6
- package/packages/bundled-features/src/compliance-profiles/handlers/list-profiles.query.ts +5 -5
- package/packages/bundled-features/src/compliance-profiles/handlers/needs-profile.query.ts +4 -4
- package/packages/bundled-features/src/compliance-profiles/handlers/set-profile.write.ts +13 -14
- package/packages/bundled-features/src/compliance-profiles/handlers/sub-processors.query.ts +9 -11
- package/packages/bundled-features/src/compliance-profiles/resolve-for-tenant.ts +7 -7
- package/packages/bundled-features/src/compliance-profiles/schema/profile-selection.ts +18 -23
- package/packages/bundled-features/src/compliance-profiles/seeding.ts +14 -15
- package/packages/bundled-features/src/compliance-profiles-ops/handlers/tenants-missing-profile.query.ts +3 -3
- package/packages/bundled-features/src/compliance-profiles-ops/index.ts +2 -2
- package/packages/bundled-features/src/config/changes.json +12 -0
- package/packages/bundled-features/src/config/handlers/cascade.query.ts +4 -2
- package/packages/bundled-features/src/config/handlers/readiness.query.ts +7 -7
- package/packages/bundled-features/src/config/handlers/reencrypt.job.ts +4 -5
- package/packages/bundled-features/src/config/handlers/set.write.ts +4 -4
- package/packages/bundled-features/src/config/handlers/values.query.ts +4 -2
- package/packages/bundled-features/src/config/resolver.ts +4 -4
- package/packages/bundled-features/src/config/table.ts +10 -10
- package/packages/bundled-features/src/config/write-helpers.ts +28 -9
- package/packages/bundled-features/src/crypto-shredding/changes.json +6 -0
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +23 -21
- package/packages/bundled-features/src/custom-fields/aggregate-id.ts +16 -17
- package/packages/bundled-features/src/custom-fields/entity.ts +49 -47
- package/packages/bundled-features/src/custom-fields/events.ts +7 -8
- package/packages/bundled-features/src/custom-fields/feature.ts +70 -72
- package/packages/bundled-features/src/custom-fields/handlers/clear-custom-field.write.ts +9 -8
- package/packages/bundled-features/src/custom-fields/handlers/define-tenant-field.write.ts +28 -26
- package/packages/bundled-features/src/custom-fields/handlers/delete-system-field.write.ts +6 -7
- package/packages/bundled-features/src/custom-fields/handlers/delete-tenant-field.write.ts +12 -13
- package/packages/bundled-features/src/custom-fields/handlers/set-custom-field.write.ts +25 -28
- package/packages/bundled-features/src/custom-fields/handlers/update-tenant-field.write.ts +6 -6
- package/packages/bundled-features/src/custom-fields/lib/field-access.ts +2 -2
- package/packages/bundled-features/src/custom-fields/lib/parse-serialized-field.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/quota.ts +1 -1
- package/packages/bundled-features/src/custom-fields/lib/value-schema.ts +10 -12
- package/packages/bundled-features/src/custom-fields/run-retention.ts +3 -3
- package/packages/bundled-features/src/custom-fields/schemas.ts +14 -14
- package/packages/bundled-features/src/custom-fields/web/client-plugin.tsx +2 -5
- package/packages/bundled-features/src/custom-fields/web/constants.ts +2 -2
- package/packages/bundled-features/src/custom-fields/web/custom-fields-form-section.tsx +26 -26
- package/packages/bundled-features/src/custom-fields/wire-for-entity.ts +65 -67
- package/packages/bundled-features/src/custom-fields/wire-user-data-rights.ts +3 -3
- package/packages/bundled-features/src/data-retention/_internal/parse-override.ts +2 -3
- package/packages/bundled-features/src/data-retention/feature.ts +11 -18
- package/packages/bundled-features/src/data-retention/handlers/policy-for.query.ts +6 -6
- package/packages/bundled-features/src/data-retention/keep-for.ts +17 -17
- package/packages/bundled-features/src/data-retention/override-schema.ts +13 -15
- package/packages/bundled-features/src/data-retention/presets.ts +18 -23
- package/packages/bundled-features/src/data-retention/resolve-for-tenant.ts +1 -1
- package/packages/bundled-features/src/data-retention/resolve-tenant-preset.ts +17 -16
- package/packages/bundled-features/src/data-retention/resolver.ts +33 -32
- package/packages/bundled-features/src/data-retention/run-retention-cleanup.ts +71 -58
- package/packages/bundled-features/src/data-retention/schema/tenant-retention-override.ts +13 -11
- package/packages/bundled-features/src/delivery/changes.json +30 -0
- package/packages/bundled-features/src/delivery/channel-context.ts +9 -3
- package/packages/bundled-features/src/delivery/db/queries/preferences.ts +2 -2
- package/packages/bundled-features/src/delivery/delivery-service.ts +35 -5
- package/packages/bundled-features/src/delivery/feature.ts +3 -3
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
- package/packages/bundled-features/src/delivery/handlers/preferences.query.ts +20 -1
- package/packages/bundled-features/src/delivery/handlers/unsubscribe-page-chrome.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe-link.ts +3 -1
- package/packages/bundled-features/src/delivery/unsubscribe-page-strings.ts +1 -0
- package/packages/bundled-features/src/delivery/unsubscribe-page.ts +6 -0
- package/packages/bundled-features/src/delivery/unsubscribe.ts +40 -19
- package/packages/bundled-features/src/delivery/upsert-preference.ts +3 -4
- package/packages/bundled-features/src/document-ingest-foundation/entity.ts +5 -5
- package/packages/bundled-features/src/document-ingest-foundation/events.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/feature.ts +2 -2
- package/packages/bundled-features/src/document-ingest-foundation/pages.ts +1 -1
- package/packages/bundled-features/src/document-ingest-foundation/tenant-destroy-hook.ts +4 -4
- package/packages/bundled-features/src/feature-toggles/compose-tier-resolver.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/feature.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/global-feature-state-table.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/handlers/registered.query.ts +5 -5
- package/packages/bundled-features/src/feature-toggles/toggle-runtime.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/toggle-sync-signal.ts +1 -1
- package/packages/bundled-features/src/feature-toggles/web/constants.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/feature.ts +2 -2
- package/packages/bundled-features/src/file-derivatives/handlers/public-variant.query.ts +1 -1
- package/packages/bundled-features/src/file-derivatives/presets.ts +1 -1
- package/packages/bundled-features/src/file-foundation/feature.ts +6 -6
- package/packages/bundled-features/src/file-foundation/index.ts +1 -0
- package/packages/bundled-features/src/file-foundation/read-file-ref-content.ts +7 -1
- package/packages/bundled-features/src/file-provider-inmemory/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/env-named-feature.ts +0 -2
- package/packages/bundled-features/src/file-provider-s3/feature.ts +16 -16
- package/packages/bundled-features/src/file-provider-s3/lib/s3-provider.ts +6 -6
- package/packages/bundled-features/src/files/README.md +1 -1
- package/packages/bundled-features/src/files/feature.ts +6 -6
- package/packages/bundled-features/src/files-tenant-data/handlers/sweep-orphaned-derivatives.job.ts +5 -5
- package/packages/bundled-features/src/files-tenant-data/hooks.ts +24 -26
- package/packages/bundled-features/src/files-tenant-data/index.ts +1 -1
- package/packages/bundled-features/src/folders/feature.ts +1 -1
- package/packages/bundled-features/src/folders/web/folder-manager.tsx +2 -2
- package/packages/bundled-features/src/folders/web/tree.ts +5 -5
- package/packages/bundled-features/src/form-draft/changes.json +6 -0
- package/packages/bundled-features/src/form-draft/db/queries/cleanup.ts +3 -3
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -1
- package/packages/bundled-features/src/form-draft/decrypt-draft.ts +4 -1
- package/packages/bundled-features/src/form-draft/entity.ts +3 -3
- package/packages/bundled-features/src/form-draft/feature.ts +4 -5
- package/packages/bundled-features/src/form-draft/handlers/discard.write.ts +1 -1
- package/packages/bundled-features/src/form-draft/release-file-refs.ts +6 -6
- package/packages/bundled-features/src/form-draft/schemas.ts +3 -3
- package/packages/bundled-features/src/form-draft/web/constants.ts +0 -2
- package/packages/bundled-features/src/host-routing/README.md +1 -1
- package/packages/bundled-features/src/host-routing/changes.json +6 -0
- package/packages/bundled-features/src/host-routing/dispatch.ts +16 -17
- package/packages/bundled-features/src/host-routing/options.ts +2 -1
- package/packages/bundled-features/src/inbound-mail-foundation/aggregate-id.ts +19 -19
- package/packages/bundled-features/src/inbound-mail-foundation/changes.json +18 -0
- package/packages/bundled-features/src/inbound-mail-foundation/connect-routes.ts +4 -3
- package/packages/bundled-features/src/inbound-mail-foundation/constants.ts +30 -33
- package/packages/bundled-features/src/inbound-mail-foundation/entities.ts +47 -48
- package/packages/bundled-features/src/inbound-mail-foundation/events.ts +54 -50
- package/packages/bundled-features/src/inbound-mail-foundation/feature.ts +39 -39
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/account-state.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/connect-account.write.ts +25 -26
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/disconnect-account.write.ts +7 -7
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/ingest-message.write.ts +50 -51
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-accounts.query.ts +8 -8
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/list-messages.query.ts +10 -10
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/scope-visibility.ts +3 -4
- package/packages/bundled-features/src/inbound-mail-foundation/handlers/update-account.write.ts +27 -15
- package/packages/bundled-features/src/inbound-mail-foundation/i18n.ts +0 -1
- package/packages/bundled-features/src/inbound-mail-foundation/oauth-state.ts +16 -15
- package/packages/bundled-features/src/inbound-mail-foundation/projection.ts +31 -29
- package/packages/bundled-features/src/inbound-mail-foundation/provider-factory.ts +9 -9
- package/packages/bundled-features/src/inbound-mail-foundation/retention-sweep.ts +45 -41
- package/packages/bundled-features/src/inbound-mail-foundation/screens.ts +0 -3
- package/packages/bundled-features/src/inbound-mail-foundation/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +70 -70
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +101 -84
- package/packages/bundled-features/src/inbound-provider-imap/credential-document.ts +13 -13
- package/packages/bundled-features/src/inbound-provider-imap/feature.ts +42 -40
- package/packages/bundled-features/src/inbound-provider-imap/imap-client.ts +20 -19
- package/packages/bundled-features/src/inbound-provider-inmemory/feature.ts +21 -21
- package/packages/bundled-features/src/jobs/changes.json +13 -0
- package/packages/bundled-features/src/jobs/db/queries/retention.ts +2 -2
- package/packages/bundled-features/src/jobs/db/queries/stale-run-sweep.ts +3 -3
- package/packages/bundled-features/src/jobs/events.ts +1 -1
- package/packages/bundled-features/src/jobs/feature.ts +20 -11
- package/packages/bundled-features/src/jobs/handlers/detail.query.ts +4 -4
- package/packages/bundled-features/src/jobs/handlers/list.query.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/projection-rebuild.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/reindex-entity.job.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/retry.write.ts +1 -1
- package/packages/bundled-features/src/jobs/handlers/tenant-failures.query.ts +45 -40
- package/packages/bundled-features/src/jobs/handlers/tenant-runs.query.ts +63 -59
- package/packages/bundled-features/src/jobs/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +19 -19
- package/packages/bundled-features/src/jobs/job-run-table.ts +3 -3
- package/packages/bundled-features/src/jobs/screens.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-failure-table.ts +1 -1
- package/packages/bundled-features/src/jobs/tenant-job-run-table.ts +1 -1
- package/packages/bundled-features/src/ledger/entity.ts +5 -5
- package/packages/bundled-features/src/ledger/feature.ts +3 -3
- package/packages/bundled-features/src/ledger/handlers/confirm-schedule-period.write.ts +3 -3
- package/packages/bundled-features/src/ledger/recurring.ts +12 -12
- package/packages/bundled-features/src/ledger/schemas.ts +1 -1
- package/packages/bundled-features/src/ledger/web/constants.ts +2 -2
- package/packages/bundled-features/src/ledger/web/index.ts +7 -7
- package/packages/bundled-features/src/legal-pages/README.md +1 -1
- package/packages/bundled-features/src/legal-pages/feature.ts +40 -41
- package/packages/bundled-features/src/legal-pages/markdown.ts +3 -3
- package/packages/bundled-features/src/legal-pages/web/client-plugin.ts +23 -24
- package/packages/bundled-features/src/legal-pages/web/index.ts +0 -2
- package/packages/bundled-features/src/mail-foundation/changes.json +6 -0
- package/packages/bundled-features/src/mail-foundation/feature.ts +31 -30
- package/packages/bundled-features/src/mail-transport-inmemory/feature.ts +27 -28
- package/packages/bundled-features/src/mail-transport-smtp/feature.ts +20 -20
- package/packages/bundled-features/src/managed-pages/branding.ts +6 -6
- package/packages/bundled-features/src/managed-pages/feature.ts +62 -62
- package/packages/bundled-features/src/managed-pages/handlers/by-slug.query.ts +5 -6
- package/packages/bundled-features/src/managed-pages/handlers/by-tenant-published.query.ts +8 -8
- package/packages/bundled-features/src/managed-pages/handlers/set.write.ts +5 -7
- package/packages/bundled-features/src/managed-pages/screens/page-screens.ts +11 -11
- package/packages/bundled-features/src/managed-pages/seeding.ts +8 -8
- package/packages/bundled-features/src/managed-pages/table.ts +16 -15
- package/packages/bundled-features/src/managed-pages/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/managed-pages/web/i18n.ts +1 -1
- package/packages/bundled-features/src/notes-history/entity.ts +4 -4
- package/packages/bundled-features/src/notes-history/feature.ts +2 -2
- package/packages/bundled-features/src/notes-history-user-data/hooks.ts +1 -1
- package/packages/bundled-features/src/page-render/layout.ts +9 -9
- package/packages/bundled-features/src/page-render/markdown.ts +11 -11
- package/packages/bundled-features/src/page-render/security-headers.ts +7 -6
- package/packages/bundled-features/src/personal-access-tokens/feature.ts +9 -6
- package/packages/bundled-features/src/personal-access-tokens/roles.ts +2 -2
- package/packages/bundled-features/src/readiness/handlers/status.query.ts +3 -3
- package/packages/bundled-features/src/renderer-foundation/api.ts +12 -13
- package/packages/bundled-features/src/renderer-foundation/constants.ts +2 -2
- package/packages/bundled-features/src/renderer-foundation/feature.ts +7 -7
- package/packages/bundled-features/src/renderer-foundation/types.ts +11 -12
- package/packages/bundled-features/src/renderer-pdf/changes.json +6 -0
- package/packages/bundled-features/src/renderer-pdf/render-table-pdf.ts +27 -10
- package/packages/bundled-features/src/secrets/feature.ts +9 -9
- package/packages/bundled-features/src/secrets/web/constants.ts +2 -2
- package/packages/bundled-features/src/seo/feature.ts +3 -3
- package/packages/bundled-features/src/sessions/constants.ts +1 -1
- package/packages/bundled-features/src/sessions/feature.ts +16 -11
- package/packages/bundled-features/src/sessions/handlers/revoke-all-for-user.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke-all-others.write.ts +2 -2
- package/packages/bundled-features/src/sessions/handlers/revoke.write.ts +1 -1
- package/packages/bundled-features/src/sessions/schema/user-session.ts +4 -4
- package/packages/bundled-features/src/sessions/screens.ts +2 -2
- package/packages/bundled-features/src/sessions/session-callbacks.ts +2 -2
- package/packages/bundled-features/src/sessions/session-revoked-event.ts +2 -2
- package/packages/bundled-features/src/shared/assert-no-where-rule-in-ownership-write.ts +1 -1
- package/packages/bundled-features/src/shared/decrypt-stored-pii.ts +11 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- package/packages/bundled-features/src/shared/index.ts +1 -1
- package/packages/bundled-features/src/shared/mail-template-body.ts +10 -3
- package/packages/bundled-features/src/shared/map-with-concurrency.ts +5 -4
- package/packages/bundled-features/src/shared/parent-visibility.ts +2 -2
- package/packages/bundled-features/src/shared/password-hashing.ts +1 -1
- package/packages/bundled-features/src/shared/signup-handover.ts +1 -2
- package/packages/bundled-features/src/shared/single-use-token-store.ts +1 -1
- package/packages/bundled-features/src/step-dispatcher/changes.json +6 -0
- package/packages/bundled-features/src/step-dispatcher/feature.ts +1 -0
- package/packages/bundled-features/src/subscription-dodo/changes.json +14 -0
- package/packages/bundled-features/src/subscription-dodo/client.ts +45 -0
- package/packages/bundled-features/src/subscription-dodo/constants.ts +24 -0
- package/packages/bundled-features/src/subscription-dodo/feature.ts +207 -0
- package/packages/bundled-features/src/subscription-dodo/index.ts +16 -0
- package/packages/bundled-features/src/subscription-dodo/plugin-methods.ts +345 -0
- package/packages/bundled-features/src/subscription-dodo/runtime.ts +126 -0
- package/packages/bundled-features/src/subscription-dodo/verify-webhook.ts +262 -0
- package/packages/bundled-features/src/subscription-mollie/constants.ts +15 -17
- package/packages/bundled-features/src/subscription-mollie/feature.ts +41 -42
- package/packages/bundled-features/src/subscription-mollie/index.ts +3 -3
- package/packages/bundled-features/src/subscription-mollie/plugin-methods.ts +17 -16
- package/packages/bundled-features/src/subscription-mollie/verify-webhook.ts +34 -34
- package/packages/bundled-features/src/subscription-stripe/changes.json +12 -0
- package/packages/bundled-features/src/subscription-stripe/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +45 -43
- package/packages/bundled-features/src/subscription-stripe/index.ts +6 -6
- package/packages/bundled-features/src/subscription-stripe/plugin-methods.ts +22 -27
- package/packages/bundled-features/src/subscription-stripe/runtime.ts +9 -8
- package/packages/bundled-features/src/subscription-stripe/verify-webhook.ts +62 -64
- package/packages/bundled-features/src/tags/feature.ts +3 -3
- package/packages/bundled-features/src/tags/screens.ts +1 -1
- package/packages/bundled-features/src/template-resolver/api.ts +41 -14
- package/packages/bundled-features/src/template-resolver/changes.json +48 -0
- package/packages/bundled-features/src/template-resolver/compile-document-body.ts +1 -0
- package/packages/bundled-features/src/template-resolver/feature.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/bundle-import.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/copy-locale.write.ts +27 -5
- package/packages/bundled-features/src/template-resolver/handlers/diff-to-system.query.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/document-base.ts +3 -2
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +8 -7
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +19 -20
- package/packages/bundled-features/src/template-resolver/handlers/overview.query.ts +15 -5
- package/packages/bundled-features/src/template-resolver/handlers/shared.ts +2 -2
- package/packages/bundled-features/src/template-resolver/handlers/template-write.ts +3 -3
- package/packages/bundled-features/src/template-resolver/handlers/tenant-override-counts.query.ts +9 -5
- package/packages/bundled-features/src/template-resolver/handlers/tenant-override-selection.ts +8 -6
- package/packages/bundled-features/src/template-resolver/handlers/tenant-overrides.query.ts +44 -5
- package/packages/bundled-features/src/template-resolver/handlers/upsert-system.write.ts +3 -4
- package/packages/bundled-features/src/template-resolver/handlers/upsert-tenant.write.ts +4 -5
- package/packages/bundled-features/src/template-resolver/handlers/usage.query.ts +37 -26
- package/packages/bundled-features/src/template-resolver/handlers/validate.query.ts +7 -2
- package/packages/bundled-features/src/template-resolver/seeding.ts +36 -18
- package/packages/bundled-features/src/template-resolver/store-template-resource.ts +22 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/template-delivery-policy.ts +0 -11
- package/packages/bundled-features/src/template-resolver/template-meta.ts +12 -4
- package/packages/bundled-features/src/template-resolver/template-preview.ts +11 -3
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/template-resolver/web/constants.ts +7 -5
- package/packages/bundled-features/src/template-resolver/web/index.ts +7 -0
- package/packages/bundled-features/src/template-resolver/web/mail-layout-constants.ts +8 -0
- package/packages/bundled-features/src/tenant/changes.json +6 -0
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +10 -4
- package/packages/bundled-features/src/tenant/handlers/members.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/memberships.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/team-list.query.ts +1 -1
- package/packages/bundled-features/src/tenant/handlers/tenant-directory.query.ts +8 -5
- package/packages/bundled-features/src/tenant/invitation-table.ts +37 -40
- package/packages/bundled-features/src/tenant/membership-table.ts +3 -3
- package/packages/bundled-features/src/tenant/schema/tenant.ts +7 -9
- package/packages/bundled-features/src/tenant/screens.ts +1 -1
- package/packages/bundled-features/src/tenant/seeding.ts +19 -18
- package/packages/bundled-features/src/tenant/testing.ts +5 -6
- package/packages/bundled-features/src/tenant/web/constants.ts +2 -2
- package/packages/bundled-features/src/tenant-handover/events.ts +5 -7
- package/packages/bundled-features/src/tenant-handover/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/grant.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/handlers/claim.write.ts +1 -1
- package/packages/bundled-features/src/tenant-handover/move-entity-graph.ts +8 -9
- package/packages/bundled-features/src/tenant-handover/signup-handover-provider.ts +1 -2
- package/packages/bundled-features/src/tenant-handover/transfer-graph.ts +4 -5
- package/packages/bundled-features/src/tenant-lifecycle/boot-checks.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/changes.json +6 -0
- package/packages/bundled-features/src/tenant-lifecycle/constants.ts +5 -0
- package/packages/bundled-features/src/tenant-lifecycle/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +7 -3
- package/packages/bundled-features/src/tenant-lifecycle/stages.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/constants.ts +1 -1
- package/packages/bundled-features/src/tenant-settings/tenant-defaults.ts +12 -5
- package/packages/bundled-features/src/tier-engine/aggregate-id.ts +15 -16
- package/packages/bundled-features/src/tier-engine/changes.json +6 -0
- package/packages/bundled-features/src/tier-engine/compose-app.ts +14 -14
- package/packages/bundled-features/src/tier-engine/entity.ts +18 -19
- package/packages/bundled-features/src/tier-engine/feature.ts +88 -87
- package/packages/bundled-features/src/tier-engine/handlers/active-tier.query.ts +6 -7
- package/packages/bundled-features/src/tier-engine/handlers/get-tenant-tier.query.ts +4 -4
- package/packages/bundled-features/src/tier-engine/handlers/set-tenant-tier.write.ts +12 -9
- package/packages/bundled-features/src/tier-engine/tier-resolver.ts +2 -2
- package/packages/bundled-features/src/tier-engine/trial.ts +13 -13
- package/packages/bundled-features/src/tier-engine/web/constants.ts +3 -3
- package/packages/bundled-features/src/tier-engine/web/index.ts +4 -4
- package/packages/bundled-features/src/user/db/queries/stream-tenant-backfill.ts +8 -8
- package/packages/bundled-features/src/user/handlers/create.write.ts +4 -4
- package/packages/bundled-features/src/user/schema/user.ts +45 -44
- package/packages/bundled-features/src/user/seeding.ts +40 -40
- package/packages/bundled-features/src/user/testing.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/audit-download.ts +27 -28
- package/packages/bundled-features/src/user-data-rights/boot-checks.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/deletion-token.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/feature.ts +112 -113
- package/packages/bundled-features/src/user-data-rights/handlers/cancel-deletion.write.ts +9 -9
- package/packages/bundled-features/src/user-data-rights/handlers/confirm-deletion-by-token.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-job.query.ts +29 -30
- package/packages/bundled-features/src/user-data-rights/handlers/download-by-token.query.ts +40 -42
- package/packages/bundled-features/src/user-data-rights/handlers/export-status.query.ts +8 -9
- package/packages/bundled-features/src/user-data-rights/handlers/lift-restriction.write.ts +7 -8
- package/packages/bundled-features/src/user-data-rights/handlers/list-download-attempts.query.ts +2 -2
- package/packages/bundled-features/src/user-data-rights/handlers/my-audit-log.query.ts +4 -4
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion-by-email.write.ts +30 -29
- package/packages/bundled-features/src/user-data-rights/handlers/request-deletion.write.ts +15 -18
- package/packages/bundled-features/src/user-data-rights/handlers/request-export.write.ts +42 -41
- package/packages/bundled-features/src/user-data-rights/handlers/restrict-account.write.ts +22 -19
- package/packages/bundled-features/src/user-data-rights/handlers/run-forget-cleanup.write.ts +8 -8
- package/packages/bundled-features/src/user-data-rights/index.ts +8 -10
- package/packages/bundled-features/src/user-data-rights/lib/default-mailers.ts +3 -3
- package/packages/bundled-features/src/user-data-rights/lib/update-user-lifecycle.ts +24 -27
- package/packages/bundled-features/src/user-data-rights/run-export-jobs.ts +169 -280
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +87 -108
- package/packages/bundled-features/src/user-data-rights/run-user-export.ts +67 -69
- package/packages/bundled-features/src/user-data-rights/schema/download-attempt.ts +11 -11
- package/packages/bundled-features/src/user-data-rights/schema/download-token.ts +37 -41
- package/packages/bundled-features/src/user-data-rights/schema/export-job.ts +65 -67
- package/packages/bundled-features/src/user-data-rights/token-helpers.ts +21 -25
- package/packages/bundled-features/src/user-data-rights/web/client-plugin.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/web/confirm-deletion-screen.tsx +6 -5
- package/packages/bundled-features/src/user-data-rights/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-data-rights/web/index.ts +5 -5
- package/packages/bundled-features/src/user-data-rights/web/privacy-center-screen.tsx +14 -13
- package/packages/bundled-features/src/user-data-rights/web/public-deletion-gate.tsx +13 -12
- package/packages/bundled-features/src/user-data-rights/web/request-deletion-screen.tsx +6 -6
- package/packages/bundled-features/src/user-data-rights/zip-path.ts +41 -40
- package/packages/bundled-features/src/user-data-rights-defaults/feature.ts +15 -15
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/delivery-attempt.userdata-hook.ts +3 -5
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +45 -51
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/job-run.userdata-hook.ts +2 -2
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/notification-preference.userdata-hook.ts +1 -1
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user-session.userdata-hook.ts +3 -3
- package/packages/bundled-features/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +32 -31
- package/packages/bundled-features/src/user-profile/handlers/change-email.write.ts +13 -13
- package/packages/bundled-features/src/user-profile/index.ts +3 -3
- package/packages/bundled-features/src/user-profile/web/client-plugin.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/constants.ts +1 -1
- package/packages/bundled-features/src/user-profile/web/profile-screen.tsx +1 -1
- package/packages/bundled-features/src/waitlist/changes.json +18 -0
- package/packages/bundled-features/src/waitlist/handlers/export-purge.write.ts +2 -1
- package/packages/bundled-features/src/waitlist/handlers/submit.write.ts +5 -5
- package/packages/bundled-features/src/waitlist/import.ts +5 -0
- package/packages/bundled-features/src/waitlist/legacy-migrate.ts +22 -3
- package/packages/bundled-features/src/waitlist/link-on-signup.ts +20 -10
- package/packages/bundled-features/src/waitlist/options.ts +3 -0
- package/packages/bundled-features/src/workflow-runner/aggregate-id.ts +1 -1
- package/packages/bundled-features/src/workflow-runner/event-subscriber.ts +4 -5
- package/packages/bundled-features/src/workflow-runner/event-trigger.ts +4 -15
- package/packages/bundled-features/src/workflow-runner/feature.ts +2 -2
- package/packages/bundled-features/src/workflow-runner/handlers/resume-run.write.ts +4 -4
- package/packages/bundled-features/src/workflow-runner/pending-projection.ts +6 -7
- package/packages/bundled-features/src/workflow-runner/runner.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/tables.ts +6 -6
- package/packages/bundled-features/src/workflow-runner/workflow-registry.ts +1 -1
- package/samples/apps/styleguide/src/features/widgets/i18n.ts +11 -0
- package/samples/apps/styleguide/src/features/widgets/web/Widgets.tsx +24 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-constants.ts +5 -0
- package/samples/apps/use-all-bundled/e2e-billing-gallery/gallery-features.ts +90 -15
- package/samples/apps/use-all-bundled/e2e-billing-gallery/server.ts +16 -6
- package/samples/apps/use-all-bundled/feature-manifest.json +120 -3
- package/samples/apps/use-all-bundled/src/run-config.ts +9 -3
- package/samples/recipes/auth-mfa/README.md +5 -0
- package/samples/recipes/auth-mfa/package.json +5 -2
- package/samples/recipes/auth-mfa/src/web/confirmation-code-step.tsx +49 -0
- package/samples/recipes/auth-mfa/tsconfig.json +8 -0
- package/samples/recipes/env-composition/README.md +3 -1
- package/samples/recipes/env-composition/src/env.ts +2 -0
- package/samples/recipes/legal-pages/README.md +1 -1
- package/samples/recipes/rate-limiting/README.md +18 -0
- package/samples/recipes/rate-limiting/src/feature.ts +12 -0
- package/packages/bundled-features/src/billing-foundation/consumer-protection/stored-user-email.ts +0 -12
|
@@ -1,35 +1,34 @@
|
|
|
1
|
-
// verifyAndParseStripeWebhook — Stripe-
|
|
2
|
-
// event
|
|
3
|
-
// `verifyAndParseWebhook
|
|
1
|
+
// verifyAndParseStripeWebhook — Stripe-specific signature verification +
|
|
2
|
+
// event mapping. Registered by the plugin build (feature.ts) as
|
|
3
|
+
// `verifyAndParseWebhook`.
|
|
4
4
|
//
|
|
5
5
|
// **Steps:**
|
|
6
|
-
// 1.
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// 1. Verify the signature via stripe.webhooks.constructEvent (HMAC-SHA-256
|
|
7
|
+
// against rawBody + Stripe-Signature header). Throws on mismatch or
|
|
8
|
+
// timestamps older than 5 minutes (replay protection).
|
|
9
9
|
// 1b. checkout.session.completed / .async_payment_succeeded branch off
|
|
10
10
|
// here into a PaymentEvent (one-off-payment, own aggregate) — see
|
|
11
|
-
// "One-off-payment" section below. Everything else falls through.
|
|
12
|
-
// 2. Event-type
|
|
13
|
-
// SubscriptionEventTypes
|
|
14
|
-
//
|
|
15
|
-
// 3. Stripe
|
|
16
|
-
// (status
|
|
11
|
+
// the "One-off-payment" section below. Everything else falls through.
|
|
12
|
+
// 2. Event-type filter: only the 5 event types mapped to
|
|
13
|
+
// SubscriptionEventTypes continue; everything else returns null
|
|
14
|
+
// (the foundation responds with 200 ignored).
|
|
15
|
+
// 3. Normalize the Stripe payload into a SubscriptionEvent
|
|
16
|
+
// (status mapping, tenant ID from metadata, price-to-tier lookup).
|
|
17
17
|
//
|
|
18
|
-
// **Runtime
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// sig-verify, kein split-brain.
|
|
18
|
+
// **Runtime keys (pre-tenant):** the API key and webhook secret no longer
|
|
19
|
+
// come from a mount-time closure; they are resolved from `StripeWebhookRuntime`
|
|
20
|
+
// at webhook time. The foundation webhook handler passes a system-scoped
|
|
21
|
+
// SecretsContext as the third argument; the runtime reads both keys from it
|
|
22
|
+
// (unaudited, system-internal), falling back to the factory options. This
|
|
23
|
+
// allows key rotation without a redeploy, and the invoice lazy-fetch below
|
|
24
|
+
// uses the same rotated client as signature verification, avoiding split-brain.
|
|
26
25
|
//
|
|
27
26
|
// **Invoice-event lazy-fetch:**
|
|
28
|
-
// Invoice payloads carry only the subscription
|
|
29
|
-
//
|
|
27
|
+
// Invoice payloads carry only the subscription ID (Stripe does not expand
|
|
28
|
+
// subscriptions in webhooks), so the plugin lazy-fetches via
|
|
30
29
|
// `stripe.subscriptions.retrieve(subId)` to get the full subscription for
|
|
31
30
|
// status/tier/period-end mapping. resource_missing (deleted between webhook
|
|
32
|
-
// and
|
|
31
|
+
// and retrieval) returns null; any other Stripe error becomes 503 so Stripe
|
|
33
32
|
// redelivers.
|
|
34
33
|
|
|
35
34
|
import type {
|
|
@@ -77,18 +76,18 @@ function transientProviderRejection(error: unknown): ExtraRouteRejection {
|
|
|
77
76
|
// =============================================================================
|
|
78
77
|
|
|
79
78
|
export type StripeWebhookOptions = {
|
|
80
|
-
/** Price-to-tier
|
|
81
|
-
*
|
|
82
|
-
*
|
|
79
|
+
/** Price-to-tier map. The plugin reads the price ID from the event and
|
|
80
|
+
* maps it to a tier name. Returns null when the price ID is not mapped.
|
|
81
|
+
* App-specific and remains a factory option, not a secret. */
|
|
83
82
|
readonly priceToTier: Readonly<Record<string, string>>;
|
|
84
83
|
};
|
|
85
84
|
|
|
86
85
|
/**
|
|
87
|
-
* Stripe
|
|
88
|
-
* `verifyAndParseWebhook`. **Pre-tenant
|
|
89
|
-
* HandlerContext;
|
|
90
|
-
* Stripe
|
|
91
|
-
* system
|
|
86
|
+
* Stripe webhook handler implementing the plugin contract
|
|
87
|
+
* `verifyAndParseWebhook`. **Pre-tenant resolution** — there is no
|
|
88
|
+
* HandlerContext; instead of using a mount-time client, `runtime` resolves
|
|
89
|
+
* the Stripe client and webhook secret at call time from the optional
|
|
90
|
+
* system SecretsContext (third argument).
|
|
92
91
|
*/
|
|
93
92
|
export function verifyAndParseStripeWebhook(
|
|
94
93
|
runtime: StripeWebhookRuntime,
|
|
@@ -104,16 +103,16 @@ export function verifyAndParseStripeWebhook(
|
|
|
104
103
|
throw new Error("subscription-stripe: stripe-signature header missing");
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
// 0.
|
|
108
|
-
// secret (
|
|
109
|
-
// options.
|
|
106
|
+
// 0. Resolve at runtime: obtain the API key (for the client and lazy fetch)
|
|
107
|
+
// and webhook secret (for signature verification) from system secrets,
|
|
108
|
+
// falling back to the factory options. Throws if neither is configured.
|
|
110
109
|
const { stripe, webhookSecret } = await runtime.resolve(systemSecrets);
|
|
111
110
|
|
|
112
|
-
// 1.
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
// payment
|
|
116
|
-
// path
|
|
111
|
+
// 1. Verify the signature. constructEvent throws on a mismatch (invalid
|
|
112
|
+
// signature) or timestamp-tolerance violation (default: 5 minutes).
|
|
113
|
+
// The foundation maps the thrown error to HTTP 401. This applies to
|
|
114
|
+
// BOTH branches below: the payment branch is selected only AFTER this
|
|
115
|
+
// check, so no path bypasses signature verification.
|
|
117
116
|
let event: Stripe.Event;
|
|
118
117
|
try {
|
|
119
118
|
event = await stripe.webhooks.constructEventAsync(rawBody, sigHeader, webhookSecret);
|
|
@@ -131,30 +130,29 @@ export function verifyAndParseStripeWebhook(
|
|
|
131
130
|
return await parsePaymentEvent(event, stripe);
|
|
132
131
|
}
|
|
133
132
|
|
|
134
|
-
// 2. Event-type
|
|
133
|
+
// 2. Event-type filter — only 5 event types are supported.
|
|
135
134
|
const normalizedType = mapStripeEventType(event.type);
|
|
136
135
|
if (!normalizedType) {
|
|
137
136
|
return null; // foundation returnt 200 ignored
|
|
138
137
|
}
|
|
139
138
|
|
|
140
|
-
// 3.
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
// oder via lazy-fetch (invoice-events).
|
|
139
|
+
// 3. Extract the payload. Stripe uses different data.object shapes
|
|
140
|
+
// depending on event.type. Extract subscription data either directly
|
|
141
|
+
// (subscription events) or through a lazy fetch (invoice events).
|
|
144
142
|
const sub = await extractSubscriptionFromEvent(event, stripe);
|
|
145
143
|
if (!sub) {
|
|
146
|
-
// event
|
|
147
|
-
//
|
|
144
|
+
// The event type passed the 5-item filter, but its payload shape did not
|
|
145
|
+
// match — treat this as Stripe SDK schema drift and return null defensively.
|
|
148
146
|
return null;
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
// 4.
|
|
152
|
-
// `metadata.tenantId`
|
|
149
|
+
// 4. Resolve the tenant from metadata. The app builder sets
|
|
150
|
+
// `metadata.tenantId` when calling createCheckoutSession.
|
|
153
151
|
const tenantId = sub.metadata?.["tenantId"];
|
|
154
152
|
if (!tenantId || tenantId.length === 0) {
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
153
|
+
// A subscription without tenant metadata cannot be created without tenant
|
|
154
|
+
// resolution. Drop the event silently (the foundation responds with 200
|
|
155
|
+
// ignored). This is an app-owner error, not a foundation error.
|
|
158
156
|
return null;
|
|
159
157
|
}
|
|
160
158
|
|
|
@@ -218,7 +216,7 @@ export function mapStripeSubscriptionState(
|
|
|
218
216
|
const periodEndUnixSec = sub.items.data[0]?.current_period_end ?? 0;
|
|
219
217
|
// Stripe returns Unix-seconds; Temporal.Instant.fromEpochMilliseconds
|
|
220
218
|
// expects ms. Multiply, then ISO. (No-Date-API-Guard forbids
|
|
221
|
-
// `new Date()` — static import above, not the ambient global
|
|
219
|
+
// `new Date()` — static import above, not the ambient global.)
|
|
222
220
|
const currentPeriodEnd = Temporal.Instant.fromEpochMilliseconds(
|
|
223
221
|
periodEndUnixSec * 1000,
|
|
224
222
|
).toString();
|
|
@@ -264,9 +262,9 @@ export function mapStripeEventType(stripeType: string): SubscriptionEventType |
|
|
|
264
262
|
}
|
|
265
263
|
}
|
|
266
264
|
|
|
267
|
-
/** Stripe
|
|
268
|
-
* incomplete
|
|
269
|
-
*
|
|
265
|
+
/** Maps Stripe statuses to normalized statuses. Unknown statuses are
|
|
266
|
+
* mapped defensively to incomplete; the plugin should not receive them, but
|
|
267
|
+
* an invalid status string must not be stored in the database. */
|
|
270
268
|
export function mapStripeStatus(stripeStatus: Stripe.Subscription.Status): SubscriptionStatus {
|
|
271
269
|
switch (stripeStatus) {
|
|
272
270
|
case "active":
|
|
@@ -293,9 +291,9 @@ export function mapStripeStatus(stripeStatus: Stripe.Subscription.Status): Subsc
|
|
|
293
291
|
}
|
|
294
292
|
}
|
|
295
293
|
|
|
296
|
-
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
294
|
+
/** Gets the subscription from the event. Subscription events include it
|
|
295
|
+
* directly in data.object; invoice events include only the subscription ID
|
|
296
|
+
* and require a lazy fetch via stripe.subscriptions.retrieve. */
|
|
299
297
|
// @wrapper-known semantic-alias
|
|
300
298
|
async function extractSubscriptionFromEvent(
|
|
301
299
|
event: Stripe.Event,
|
|
@@ -308,16 +306,16 @@ async function extractSubscriptionFromEvent(
|
|
|
308
306
|
return event.data.object as Stripe.Subscription; // @cast-boundary engine-bridge
|
|
309
307
|
case StripeEventTypes.invoicePaid:
|
|
310
308
|
case StripeEventTypes.invoicePaymentFailed: {
|
|
311
|
-
// Lazy-fetch
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
//
|
|
309
|
+
// Lazy-fetch the subscription. invoice.subscription is a string ID because
|
|
310
|
+
// Stripe webhooks do not expand it automatically. Fetch the full
|
|
311
|
+
// subscription so downstream status, tier via priceId, and period-end
|
|
312
|
+
// mapping remain consistent.
|
|
315
313
|
const invoice = event.data.object as Stripe.Invoice; // @cast-boundary engine-bridge
|
|
316
314
|
const subRef = (invoice as { subscription?: string | Stripe.Subscription | null }) // @cast-boundary engine-payload
|
|
317
315
|
.subscription;
|
|
318
316
|
if (!subRef) {
|
|
319
|
-
//
|
|
320
|
-
// recurring
|
|
317
|
+
// An invoice without a subscription reference is a one-shot invoice, not a
|
|
318
|
+
// recurring invoice. It is outside this domain and should be ignored.
|
|
321
319
|
return null;
|
|
322
320
|
}
|
|
323
321
|
const subId = typeof subRef === "string" ? subRef : subRef.id;
|
|
@@ -150,9 +150,9 @@ export type TagsFeatureOptions = {
|
|
|
150
150
|
/** Row-level ownership on the tag-assignment rows themselves — orthogonal to
|
|
151
151
|
* `access`, which only gates whether a caller may dispatch assign/remove/list
|
|
152
152
|
* at all. `ownership.read` is no longer what keeps a caller from reading
|
|
153
|
-
* assignments on host entities they can't see: that gate is default-on
|
|
154
|
-
*
|
|
155
|
-
*
|
|
153
|
+
* assignments on host entities they can't see: that gate is default-on and
|
|
154
|
+
* derives from the entity's `parentRef`. Use `ownership.read` for an
|
|
155
|
+
* ADDITIONAL row rule on the assignment row itself; it is AND-ed with the
|
|
156
156
|
* host-visibility gate, never a replacement for it. Applies only to
|
|
157
157
|
* `tag-assignment`; the `tag` catalog stays tenant-wide by design.
|
|
158
158
|
*
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
import { DEFAULT_TAG_ACCESS, TAGS_EDIT_SCREEN_ID, TAGS_SCREEN_ID } from "./web/constants.ts";
|
|
8
8
|
|
|
9
|
-
// Declarative catalog screens
|
|
9
|
+
// Declarative catalog screens. Access matches create/update/
|
|
10
10
|
// delete so createTagsFeature({ access|roles }) stays consistent. TagManager
|
|
11
11
|
// remains for TagPicker/TagSection — only the standalone admin screen moved.
|
|
12
12
|
|
|
@@ -158,12 +158,14 @@ export function createTemplateResolverApi(
|
|
|
158
158
|
};
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
type DeliveredRowKey = Pick<TemplateResourceRow, "tenantId" | "kind" | "slug">;
|
|
162
|
+
|
|
161
163
|
// The one delivery rule for a stored row: unlocked, and a collection entry never shadows a system
|
|
162
164
|
// template of the same slug that the app did not unlock.
|
|
163
165
|
export async function isRowDelivered(
|
|
164
166
|
db: DbRunner | TenantDb,
|
|
165
167
|
policy: TemplateDeliveryPolicy,
|
|
166
|
-
row:
|
|
168
|
+
row: DeliveredRowKey,
|
|
167
169
|
): Promise<boolean> {
|
|
168
170
|
if (!isRowServed(policy, row)) return false;
|
|
169
171
|
if (row.tenantId === SYSTEM_TENANT_ID || !isServedByCollectionOnly(policy, row)) return true;
|
|
@@ -174,19 +176,44 @@ export async function isRowDeliveredTo(
|
|
|
174
176
|
db: DbRunner | TenantDb,
|
|
175
177
|
policy: TemplateDeliveryPolicy,
|
|
176
178
|
user: { readonly roles: readonly string[] },
|
|
177
|
-
row:
|
|
179
|
+
row: DeliveredRowKey,
|
|
178
180
|
): Promise<boolean> {
|
|
179
181
|
return isSystemAdmin(user) || (await isRowDelivered(db, policy, row));
|
|
180
182
|
}
|
|
181
183
|
|
|
184
|
+
// One system-slug lookup per kind instead of one query per row, because by-tenant is anonymous.
|
|
182
185
|
export async function filterDeliveredTo(
|
|
183
186
|
db: DbRunner | TenantDb,
|
|
184
187
|
policy: TemplateDeliveryPolicy,
|
|
185
188
|
user: { readonly roles: readonly string[] },
|
|
186
189
|
rows: readonly TemplateResourceRow[],
|
|
187
190
|
): Promise<TemplateResourceRow[]> {
|
|
188
|
-
|
|
189
|
-
|
|
191
|
+
if (isSystemAdmin(user)) return [...rows];
|
|
192
|
+
const served = rows.filter((row) => isRowServed(policy, row));
|
|
193
|
+
const shadowable = served.filter(
|
|
194
|
+
(row) => row.tenantId !== SYSTEM_TENANT_ID && isServedByCollectionOnly(policy, row),
|
|
195
|
+
);
|
|
196
|
+
const slugsByKind = new Map<string, Set<string>>();
|
|
197
|
+
for (const row of shadowable) {
|
|
198
|
+
const slugs = slugsByKind.get(row.kind) ?? new Set<string>();
|
|
199
|
+
slugs.add(row.slug);
|
|
200
|
+
slugsByKind.set(row.kind, slugs);
|
|
201
|
+
}
|
|
202
|
+
const systemKeys = new Set<string>();
|
|
203
|
+
for (const [kind, slugs] of slugsByKind) {
|
|
204
|
+
const systemRows = await selectMany<TemplateResourceRow>(db, templateResourcesTable, {
|
|
205
|
+
tenantId: SYSTEM_TENANT_ID,
|
|
206
|
+
kind,
|
|
207
|
+
slug: [...slugs],
|
|
208
|
+
});
|
|
209
|
+
for (const systemRow of systemRows) systemKeys.add(`${kind}|${systemRow.slug}`);
|
|
210
|
+
}
|
|
211
|
+
return served.filter(
|
|
212
|
+
(row) =>
|
|
213
|
+
row.tenantId === SYSTEM_TENANT_ID ||
|
|
214
|
+
!isServedByCollectionOnly(policy, row) ||
|
|
215
|
+
!systemKeys.has(`${row.kind}|${row.slug}`),
|
|
216
|
+
);
|
|
190
217
|
}
|
|
191
218
|
|
|
192
219
|
export async function systemTemplateExists(
|
|
@@ -232,20 +259,20 @@ async function fetchTemplate(
|
|
|
232
259
|
{ limit: 1 },
|
|
233
260
|
);
|
|
234
261
|
// @cast-boundary db-row — db.select returnt unbenanntes unknown[],
|
|
235
|
-
//
|
|
262
|
+
// The row shape is guaranteed by templateResourcesTable + buildBaseColumns.
|
|
236
263
|
return (rows[0] as TemplateResourceRow | undefined) ?? null;
|
|
237
264
|
}
|
|
238
265
|
|
|
239
266
|
function toPublic(row: TemplateResourceRow): TemplateResource {
|
|
240
267
|
// @cast-boundary db-row — Drizzle-Schema typisiert kind/contentFormat/
|
|
241
|
-
// scope/status
|
|
242
|
-
//
|
|
268
|
+
// scope/status as generic text. Database CHECK constraints restrict
|
|
269
|
+
// them to the union types; the cast asserts that schema knowledge.
|
|
243
270
|
const kind = row.kind as TemplateKind;
|
|
244
|
-
// @cast-boundary db-row —
|
|
271
|
+
// @cast-boundary db-row — see kind.
|
|
245
272
|
const contentFormat = row.contentFormat as ContentFormat;
|
|
246
|
-
// @cast-boundary db-row —
|
|
273
|
+
// @cast-boundary db-row — see kind.
|
|
247
274
|
const scope = row.scope as "system" | "tenant";
|
|
248
|
-
// @cast-boundary db-row —
|
|
275
|
+
// @cast-boundary db-row — see kind.
|
|
249
276
|
const status = row.status as "draft" | "active" | "archived";
|
|
250
277
|
const linkedEntries = parseLinkedResourceEntries(row.linkedResources);
|
|
251
278
|
return {
|
|
@@ -286,7 +313,7 @@ function parseJson(raw: string | null): Record<string, unknown> {
|
|
|
286
313
|
try {
|
|
287
314
|
const parsed = JSON.parse(raw);
|
|
288
315
|
// @cast-boundary engine-payload — JSON.parse returnt unknown, typeof-Guard
|
|
289
|
-
//
|
|
316
|
+
// narrows it to object; Record<string, unknown> is the minimal common shape.
|
|
290
317
|
return typeof parsed === "object" && parsed !== null ? (parsed as Record<string, unknown>) : {};
|
|
291
318
|
} catch {
|
|
292
319
|
return {};
|
|
@@ -302,14 +329,14 @@ export class TemplateNotFoundError extends Error {
|
|
|
302
329
|
}
|
|
303
330
|
}
|
|
304
331
|
|
|
305
|
-
// Single
|
|
306
|
-
// Pattern
|
|
332
|
+
// Single source of truth for "this handler requires template-resolver".
|
|
333
|
+
// Pattern symmetric with requireTextContent.
|
|
307
334
|
export function requireTemplateResolver(
|
|
308
335
|
ctx: { readonly templateResolver?: TemplateResolverApi } | object,
|
|
309
336
|
callerName: string,
|
|
310
337
|
): TemplateResolverApi {
|
|
311
338
|
// @cast-boundary engine-bridge — templateResolver kommt per extraContext
|
|
312
|
-
//
|
|
339
|
+
// from App-Bootstrap; the framework container does not know this field on its own.
|
|
313
340
|
const api = (ctx as { templateResolver?: TemplateResolverApi }).templateResolver;
|
|
314
341
|
if (!api) {
|
|
315
342
|
throw new InternalError({
|
|
@@ -1,4 +1,52 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.388.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Template overrides, key collisions and by-tenant queries",
|
|
6
|
+
"detail": "link-pdf refuses a key that already holds an inline image (key_in_use). by-tenant no longer runs a query per row, tenant-override-counts selects only the needed columns, and tenant-overrides resolves names beyond the first 200 tenants or users through the new ids filter of the tenant and member directories. Notification preference and form-draft cleanup queries bind array parameters as Postgres array literals."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.388.0",
|
|
10
|
+
"type": "fix",
|
|
11
|
+
"title": "Re-seeding keeps archived system templates, drops stale drafts and adds only missing bundle locales",
|
|
12
|
+
"detail": "A boot-time re-seed no longer reactivates an archived system template and clears an open system draft when the seeded content changes. A bundle with resources seeded with ifExists skip imports only the missing locales instead of overwriting existing system rows. copy-locale fails with version_conflict when its source changed between the upload and the transaction, and releases the uploaded files."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"version": "0.388.0",
|
|
16
|
+
"type": "fix",
|
|
17
|
+
"title": "isCollectionRefusedKind is a type predicate",
|
|
18
|
+
"detail": "isCollectionRefusedKind accepts unknown and narrows to the refused kinds; tier-engine's isTierAssignmentSource shares the isOneOf implementation. Behavior is unchanged."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"version": "0.388.0",
|
|
22
|
+
"type": "fix",
|
|
23
|
+
"title": "Layout usage list matches the overview",
|
|
24
|
+
"detail": "The usage query of a mail layout filters the mail rows by the caller's visibility like the overview and logs a warning when the 5000-row limit cuts the result."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"version": "0.388.0",
|
|
28
|
+
"type": "fix",
|
|
29
|
+
"title": "Admin views follow the delivery rule of rendering",
|
|
30
|
+
"detail": "List, find-by-id, diff-to-system, validate, preview and the document base hide a collection row that a locked system template of the same slug shadows, as mail, PDF and the resolver already do."
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"version": "0.388.0",
|
|
34
|
+
"type": "fix",
|
|
35
|
+
"title": "Seeded title key must look like a namespace:key",
|
|
36
|
+
"detail": "seedSystemTemplate rejects a titleI18nKey without a namespace prefix or with whitespace, so free text cannot pass as a key and show up raw in the UI."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"version": "0.388.0",
|
|
40
|
+
"type": "fix",
|
|
41
|
+
"title": "Failing release keeps the upload error",
|
|
42
|
+
"detail": "When releasing already uploaded files fails after a refused upload in copy-locale or bundle import, the release error is logged and the original error is returned, and the releases run once."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"version": "0.388.0",
|
|
46
|
+
"type": "fix",
|
|
47
|
+
"title": "Mail layout enums and hex color pattern are exported client-side",
|
|
48
|
+
"detail": "The layout editor imports the width, font, accent line and button style lists plus the hex pattern from the template-resolver web barrel instead of keeping copies, so editor and server validation cannot drift."
|
|
49
|
+
},
|
|
2
50
|
{
|
|
3
51
|
"version": "0.384.0",
|
|
4
52
|
"type": "improvement",
|
|
@@ -432,6 +432,7 @@ export function compileDocumentBodyToHandlebars(
|
|
|
432
432
|
for (const element of Array.from(root.querySelectorAll("div[data-images]"))) {
|
|
433
433
|
rewriteImagesBlock(element, state, options);
|
|
434
434
|
}
|
|
435
|
+
// Order matters: the conditional wraps first so the row's #each lands inside the #if (evaluated once per list).
|
|
435
436
|
for (const block of Array.from(root.querySelectorAll(`[${DOCUMENT_CONDITION_ATTRIBUTE}]`))) {
|
|
436
437
|
rewriteConditionalBlock(block, state);
|
|
437
438
|
}
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "./handlers/toggle-status.write.ts";
|
|
42
42
|
import { upsertSystemWrite } from "./handlers/upsert-system.write.ts";
|
|
43
43
|
import { makeUpsertTenantWrite } from "./handlers/upsert-tenant.write.ts";
|
|
44
|
-
import {
|
|
44
|
+
import { makeUsageQuery } from "./handlers/usage.query.ts";
|
|
45
45
|
import { validateQuery } from "./handlers/validate.query.ts";
|
|
46
46
|
import { TEMPLATE_RESOLVER_I18N } from "./i18n.ts";
|
|
47
47
|
import { templateResourceEntity } from "./table.ts";
|
|
@@ -181,7 +181,7 @@ export function createTemplateResolverFeature(opts: TemplateResolverOptions = {}
|
|
|
181
181
|
list: r.queryHandler(listQuery),
|
|
182
182
|
bySlug: r.queryHandler(bySlugQuery),
|
|
183
183
|
byTenant: r.queryHandler(byTenantQuery),
|
|
184
|
-
usage: r.queryHandler(
|
|
184
|
+
usage: r.queryHandler(makeUsageQuery(policy)),
|
|
185
185
|
overview: r.queryHandler(makeOverviewQuery(policy)),
|
|
186
186
|
layoutSource: r.queryHandler(layoutSourceQuery),
|
|
187
187
|
tenantOverrides: r.queryHandler(tenantOverridesQuery),
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
prepareTemplateResourceBeforeTransaction,
|
|
24
24
|
type Release,
|
|
25
25
|
readTemplateResourceMaxBytes,
|
|
26
|
+
releaseAfterFailure,
|
|
26
27
|
releaseAll,
|
|
27
28
|
} from "../store-template-resource.ts";
|
|
28
29
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
@@ -152,14 +153,14 @@ export async function prepareTemplateBundleBeforeTransaction(
|
|
|
152
153
|
})
|
|
153
154
|
: await prepareTemplateResourceBeforeTransaction(common);
|
|
154
155
|
if (!result.isSuccess) {
|
|
155
|
-
await
|
|
156
|
+
await releaseAfterFailure(args.ctx, releases);
|
|
156
157
|
return result;
|
|
157
158
|
}
|
|
158
159
|
if (result.release) releases.push(result.release);
|
|
159
160
|
prepared.set(key, result.data);
|
|
160
161
|
}
|
|
161
162
|
} catch (cause) {
|
|
162
|
-
await
|
|
163
|
+
await releaseAfterFailure(args.ctx, releases);
|
|
163
164
|
throw cause;
|
|
164
165
|
}
|
|
165
166
|
return { isSuccess: true, data: prepared, release: () => releaseAll(releases) };
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
AccessDeniedError,
|
|
12
12
|
NotFoundError,
|
|
13
13
|
ValidationError,
|
|
14
|
+
VersionConflictError,
|
|
14
15
|
writeFailure,
|
|
15
16
|
} from "@cosmicdrift/kumiko-framework/errors";
|
|
16
17
|
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
@@ -172,13 +173,17 @@ export function makeCopyLocaleWrite(policy: TemplateEditPolicy) {
|
|
|
172
173
|
beforeTransaction: async (event, ctx) => {
|
|
173
174
|
const request = await checkCopyRequest(ctx, policy, event);
|
|
174
175
|
if (!request.isSuccess) return request;
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
const { source, tenantId, sourceIsForeign, sourceResources } = request.data;
|
|
177
|
+
const sourceStamp = { sourceId: source.id, sourceVersion: source.version };
|
|
178
|
+
if (!sourceIsForeign) return { isSuccess: true, data: { ...sourceStamp, copies: [] } };
|
|
179
|
+
const prepared = await prepareLinkedResourceCopiesBeforeTransaction({
|
|
177
180
|
ctx,
|
|
178
181
|
user: event.user,
|
|
179
|
-
tenantId
|
|
180
|
-
resources:
|
|
182
|
+
tenantId,
|
|
183
|
+
resources: sourceResources,
|
|
181
184
|
});
|
|
185
|
+
if (!prepared.isSuccess) return prepared;
|
|
186
|
+
return { ...prepared, data: { ...sourceStamp, copies: prepared.data } };
|
|
182
187
|
},
|
|
183
188
|
handler: async (event, ctx) => {
|
|
184
189
|
const { slug, kind, toLocale } = event.payload;
|
|
@@ -186,6 +191,20 @@ export function makeCopyLocaleWrite(policy: TemplateEditPolicy) {
|
|
|
186
191
|
if (!request.isSuccess) return request;
|
|
187
192
|
const { scope, tenantId, source, contentFormat, sourceResources, sourceIsForeign } =
|
|
188
193
|
request.data;
|
|
194
|
+
// The uploads were prepared for the source as it was before the transaction; a source that
|
|
195
|
+
// changed since (own row created or deleted, edited) no longer matches them.
|
|
196
|
+
if (
|
|
197
|
+
event.prepared.sourceId !== source.id ||
|
|
198
|
+
event.prepared.sourceVersion !== source.version
|
|
199
|
+
) {
|
|
200
|
+
return writeFailure(
|
|
201
|
+
new VersionConflictError({
|
|
202
|
+
entityId: source.id,
|
|
203
|
+
expectedVersion: event.prepared.sourceVersion,
|
|
204
|
+
currentVersion: source.version,
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
207
|
+
}
|
|
189
208
|
|
|
190
209
|
const variableSchema = storedRecord(source.variableSchema);
|
|
191
210
|
const written = await writeTemplateRow({
|
|
@@ -209,7 +228,10 @@ export function makeCopyLocaleWrite(policy: TemplateEditPolicy) {
|
|
|
209
228
|
});
|
|
210
229
|
if (!written.isSuccess) return written;
|
|
211
230
|
const resources = sourceIsForeign
|
|
212
|
-
? await createLinkedResourceCopies(
|
|
231
|
+
? await createLinkedResourceCopies(
|
|
232
|
+
{ ctx, user: event.user, tenantId },
|
|
233
|
+
event.prepared.copies,
|
|
234
|
+
)
|
|
213
235
|
: { isSuccess: true as const, data: sourceResources };
|
|
214
236
|
if (!resources.isSuccess) return resources;
|
|
215
237
|
const attached = await attachTemplateResources(ctx, {
|
|
@@ -2,8 +2,9 @@ import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
|
2
2
|
import { defineQueryHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import { NotFoundError } from "@cosmicdrift/kumiko-framework/errors";
|
|
4
4
|
import * as z from "zod";
|
|
5
|
+
import { isRowDeliveredTo } from "../api.ts";
|
|
5
6
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
6
|
-
import { deliveryPolicyOf
|
|
7
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.ts";
|
|
7
8
|
import { isHiddenSystemDraft } from "../template-draft.ts";
|
|
8
9
|
import { buildOverrideDiff } from "./override-diff.ts";
|
|
9
10
|
|
|
@@ -21,7 +22,7 @@ export const diffToSystemQuery = defineQueryHandler({
|
|
|
21
22
|
!tenantRow ||
|
|
22
23
|
tenantRow.tenantId !== query.user.tenantId ||
|
|
23
24
|
tenantRow.scope !== "tenant" ||
|
|
24
|
-
!
|
|
25
|
+
!(await isRowDeliveredTo(ctx.db, deliveryPolicyOf(ctx.registry), query.user, tenantRow))
|
|
25
26
|
) {
|
|
26
27
|
throw new NotFoundError("template-resource", query.payload.id);
|
|
27
28
|
}
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
SYSTEM_TENANT_ID,
|
|
6
6
|
} from "@cosmicdrift/kumiko-framework/engine";
|
|
7
7
|
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
8
|
+
import { isRowDeliveredTo } from "../api.ts";
|
|
8
9
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
9
|
-
import { deliveryPolicyOf
|
|
10
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.ts";
|
|
10
11
|
import { isHiddenSystemDraft, toWorkingRow } from "../template-draft.ts";
|
|
11
12
|
import { isSystemOnlyTemplateHiddenFrom } from "../template-system-only.ts";
|
|
12
13
|
import type { DocumentHtmlKind } from "../web/constants.ts";
|
|
@@ -50,7 +51,7 @@ export async function loadDocumentBase(
|
|
|
50
51
|
const ownIsVisible =
|
|
51
52
|
own !== undefined &&
|
|
52
53
|
!isSystemOnlyTemplateHiddenFrom(user, ctx.registry, own) &&
|
|
53
|
-
|
|
54
|
+
(await isRowDeliveredTo(ctx.db, deliveryPolicyOf(ctx.registry), user, own));
|
|
54
55
|
if (own !== undefined && ownIsVisible) {
|
|
55
56
|
const working = toWorkingRow(own, user.tenantId);
|
|
56
57
|
return {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { fetchOne } from "@cosmicdrift/kumiko-framework/db";
|
|
2
2
|
import { defineQueryHandler } from "@cosmicdrift/kumiko-framework/engine";
|
|
3
3
|
import * as z from "zod";
|
|
4
|
+
import { isRowDeliveredTo } from "../api.ts";
|
|
4
5
|
import { type TemplateResourceRow, templateResourcesTable } from "../table.ts";
|
|
5
|
-
import { deliveryPolicyOf
|
|
6
|
+
import { deliveryPolicyOf } from "../template-delivery-policy.ts";
|
|
6
7
|
import { draftViewerTenantId, isHiddenSystemDraft, toWorkingRow } from "../template-draft.ts";
|
|
7
8
|
import { isSystemOnlyTemplateHiddenFrom } from "../template-system-only.ts";
|
|
8
9
|
|
|
9
|
-
// Admin
|
|
10
|
-
// archived
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
10
|
+
// Admin lookup for the UI editing flow. Returns the raw template, including draft/
|
|
11
|
+
// archived status. Tenant isolation: users see only templates belonging to their own
|
|
12
|
+
// tenant or SYSTEM_TENANT (system defaults are publicly readable); ctx.db is tenant-
|
|
13
|
+
// scoped for every role, so the check below is defense in depth. Anonymous access is
|
|
14
|
+
// excluded—public reads go through resolveTemplate in the API, not here.
|
|
14
15
|
export const findByIdQuery = defineQueryHandler({
|
|
15
16
|
name: "find-by-id",
|
|
16
17
|
schema: z.object({ id: z.string().min(1) }),
|
|
@@ -25,7 +26,7 @@ export const findByIdQuery = defineQueryHandler({
|
|
|
25
26
|
!stored ||
|
|
26
27
|
isHiddenSystemDraft(query.user, stored) ||
|
|
27
28
|
isSystemOnlyTemplateHiddenFrom(query.user, ctx.registry, stored) ||
|
|
28
|
-
!
|
|
29
|
+
!(await isRowDeliveredTo(ctx.db, deliveryPolicyOf(ctx.registry), query.user, stored))
|
|
29
30
|
) {
|
|
30
31
|
return null;
|
|
31
32
|
}
|