@cosmicdrift/kumiko-bundled-features 0.386.0 → 0.387.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/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/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 +3 -3
- 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-verify-screen.js +6 -6
- package/dist/billing-foundation/aggregate-id.d.ts +5 -5
- package/dist/billing-foundation/aggregate-id.js +10 -11
- package/dist/billing-foundation/entities.js +27 -27
- package/dist/billing-foundation/events.js +18 -17
- package/dist/billing-foundation/feature.js +42 -43
- 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/create-checkout-session.write.js +18 -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/process-event.write.js +20 -20
- 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 +40 -41
- package/dist/billing-foundation/types.js +20 -20
- package/dist/billing-foundation/web/billing-plans-panel.js +4 -4
- package/dist/cap-counter/aggregate-id.js +8 -9
- 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 +47 -48
- 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 +1 -1
- package/dist/cap-counter/with-cap-enforcement.d.ts +3 -5
- 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/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/resolver.js +4 -4
- package/dist/config/table.js +10 -10
- package/dist/config/write-helpers.js +1 -1
- package/dist/crypto-shredding/handlers/forget-subject.write.d.ts +2 -2
- package/dist/crypto-shredding/handlers/forget-subject.write.js +12 -11
- 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/feature.js +2 -2
- package/dist/delivery/handlers/log.query.js +1 -1
- package/dist/delivery/tables.js +9 -8
- package/dist/delivery/unsubscribe.js +4 -4
- 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-provider-inmemory/feature.d.ts +1 -1
- package/dist/file-provider-inmemory/feature.js +16 -16
- 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 +1 -1
- package/dist/form-draft/db/queries/owned-file-refs.js +1 -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/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.js +11 -11
- 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/tenant-destroy-hook.js +14 -16
- package/dist/inbound-mail-foundation/types.d.ts +45 -46
- 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 +57 -56
- 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.js +5 -6
- 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/job-instant.js +1 -1
- package/dist/jobs/job-run-logger.js +10 -11
- 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 +2 -2
- package/dist/mail-foundation/feature.js +24 -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.js +5 -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/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.js +8 -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.js +1 -1
- package/dist/shared/encrypt-for-direct-write.js +1 -1
- 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/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 +35 -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 +1 -1
- 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.js +10 -10
- package/dist/template-resolver/handlers/find-by-id.query.js +5 -5
- package/dist/template-resolver/handlers/list.query.js +1 -1
- package/dist/template-resolver/handlers/shared.js +2 -2
- package/dist/template-resolver/handlers/template-write.js +3 -3
- 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/seeding.js +4 -4
- package/dist/template-resolver/table.js +10 -11
- package/dist/template-resolver/web/client-plugin.js +2 -2
- package/dist/tenant/feature.js +7 -7
- package/dist/tenant/handlers/member-directory.query.js +1 -1
- 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.js +1 -1
- 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/feature.js +1 -1
- 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 +5 -5
- package/dist/tier-engine/handlers/set-tenant-tier.write.js +3 -3
- package/dist/tier-engine/tier-resolver.js +2 -2
- package/dist/tier-engine/trial.js +8 -8
- 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 +127 -233
- package/dist/user-data-rights/run-forget-cleanup.d.ts +16 -20
- package/dist/user-data-rights/run-forget-cleanup.js +63 -82
- 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/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 +10 -10
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
// kumiko-feature-version: 3
|
|
2
2
|
//
|
|
3
|
-
// subscription-stripe — Stripe
|
|
4
|
-
//
|
|
3
|
+
// subscription-stripe — Stripe plugin for the billing-foundation
|
|
4
|
+
// plugin API.
|
|
5
5
|
//
|
|
6
|
-
// **Runtime
|
|
7
|
-
//
|
|
8
|
-
// mount-time
|
|
9
|
-
//
|
|
6
|
+
// **Runtime config (v3):** Stripe credentials and the billing-live master
|
|
7
|
+
// switch come from the config feature AT RUNTIME, no longer from a
|
|
8
|
+
// mount-time closure. This allows keys to rotate and production to go live
|
|
9
|
+
// without a redeploy — and the input form is generated automatically.
|
|
10
10
|
// - `subscription-stripe:config:api-key` + `:webhook-secret` → system
|
|
11
|
-
// config keys
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
11
|
+
// config keys with **backing:"secrets"**: the value is envelope-encrypted
|
|
12
|
+
// in the secrets store under SYSTEM_TENANT_ID and addressed as a
|
|
13
|
+
// config key. `mask` derives the sysadmin configEdit screen +
|
|
14
|
+
// Settings-Hub navigation — the app no longer needs handwritten
|
|
15
|
+
// r.screen/r.nav entries (v2 used `r.secret` keys + an app-owned form).
|
|
16
16
|
// - `subscription-stripe:config:billing-live` (shortKey `billingLive`,
|
|
17
|
-
// kebab-
|
|
18
|
-
// (boolean, default false).
|
|
19
|
-
//
|
|
20
|
-
//
|
|
17
|
+
// kebab-qualified by r.config) → **system config**
|
|
18
|
+
// (boolean, default false). The master switch: without it, checkout may
|
|
19
|
+
// not create a Stripe session; this is enforced in the
|
|
20
|
+
// createCheckoutSession gate.
|
|
21
21
|
//
|
|
22
|
-
// **Factory
|
|
23
|
-
// apiKey, webhookSecret, priceToTier })`
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
// (Stripe
|
|
27
|
-
//
|
|
22
|
+
// **Factory options as fallback:** `createSubscriptionStripeFeature({
|
|
23
|
+
// apiKey, webhookSecret, priceToTier })` remains — apiKey/webhookSecret
|
|
24
|
+
// are now OPTIONAL and serve only as fallbacks during the env→secrets
|
|
25
|
+
// bridge phase and in tests that do not wire a secrets context. `priceToTier`
|
|
26
|
+
// (Stripe price ID → app tier name) remains a factory option: it is
|
|
27
|
+
// app-specific, is not a secret, and changes infrequently.
|
|
28
28
|
//
|
|
29
|
-
// **Webhook + system
|
|
30
|
-
// (
|
|
31
|
-
//
|
|
32
|
-
// webhook
|
|
29
|
+
// **Webhook + system secrets:** verifyAndParseWebhook is pre-tenant
|
|
30
|
+
// (no ctx). The billing-foundation webhook handler passes a system-scoped
|
|
31
|
+
// SecretsContext as the third argument, from which the plugin reads the
|
|
32
|
+
// api key + webhook secret without auditing (a sanctioned framework-internal
|
|
33
|
+
// read).
|
|
33
34
|
import { access, createSystemConfig, defineFeature, } from "@cosmicdrift/kumiko-framework/engine";
|
|
34
35
|
import { featureWithEnvSchema } from "@cosmicdrift/kumiko-framework/env";
|
|
35
36
|
import * as z from "zod";
|
|
@@ -92,11 +93,11 @@ function validateOneOffPriceIds(priceIds) {
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
/**
|
|
95
|
-
* Factory
|
|
96
|
-
* key-presence
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* extension
|
|
96
|
+
* Factory for the subscription-stripe feature. Always mounts (no
|
|
97
|
+
* key-presence guard) — activity is gated at runtime through config/secrets
|
|
98
|
+
* (following the feature-toggles pattern). The returned FeatureDefinition
|
|
99
|
+
* registers the plugin under billing-foundation's "subscriptionProvider"
|
|
100
|
+
* extension with entityName "stripe".
|
|
100
101
|
*/
|
|
101
102
|
export function createSubscriptionStripeFeature(options = {}) {
|
|
102
103
|
validateOneOffPriceIds(options.oneOffPriceIds ?? []);
|
|
@@ -118,15 +119,15 @@ export function createSubscriptionStripeFeature(options = {}) {
|
|
|
118
119
|
// the value lives envelope-encrypted in the secrets store under
|
|
119
120
|
// SYSTEM_TENANT_ID, while `mask` derives the sysadmin settings screen +
|
|
120
121
|
// Settings-Hub nav (no hand-written r.screen/r.nav in the consuming app).
|
|
121
|
-
// billingLive is the
|
|
122
|
+
// billingLive is the master switch. The factory-fallback
|
|
122
123
|
// (options.apiKey/.webhookSecret) covers the env→secrets bridge + tests.
|
|
123
124
|
const configKeys = r.config({
|
|
124
125
|
keys: {
|
|
125
126
|
[STRIPE_API_KEY_CONFIG]: createSystemConfig("text", {
|
|
126
127
|
backing: "secrets",
|
|
127
|
-
// Prefix
|
|
128
|
-
//
|
|
129
|
-
// base62
|
|
128
|
+
// Prefix guard, matching subscriptionStripeEnvSchema:
|
|
129
|
+
// catches the wrong-field paste error (pk_/price_) without
|
|
130
|
+
// constraining the base62 body. Anchored, with no backtracking → no ReDoS.
|
|
130
131
|
pattern: { regex: "^(sk|rk)_(test|live)_" },
|
|
131
132
|
write: access.systemAdmin,
|
|
132
133
|
read: access.admin,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// Public API of the subscription-stripe bundled
|
|
1
|
+
// Public API of the subscription-stripe bundled feature.
|
|
2
2
|
//
|
|
3
|
-
// **Internal-only** (
|
|
4
|
-
// - StripeWebhookOptions / verifyAndParseStripeWebhook (
|
|
5
|
-
// feature.ts factory
|
|
6
|
-
// - mapStripeEventType / mapStripeStatus (pure helpers,
|
|
7
|
-
//
|
|
3
|
+
// **Internal-only** (not in the public barrel — the App Builder never uses it directly):
|
|
4
|
+
// - StripeWebhookOptions / verifyAndParseStripeWebhook (called internally by the
|
|
5
|
+
// feature.ts factory)
|
|
6
|
+
// - mapStripeEventType / mapStripeStatus (pure helpers, for tests only;
|
|
7
|
+
// import directly from the file only if truly needed externally)
|
|
8
8
|
export { STRIPE_PROVIDER_NAME, StripeEventTypes, SUBSCRIPTION_STRIPE_FEATURE, } from "./constants.js";
|
|
9
9
|
export { createSubscriptionStripeFeature, stripeEnvSchema, subscriptionStripeEnvSchema, } from "./feature.js";
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
// Stripe
|
|
1
|
+
// Stripe plugin methods for the POST-tenant-resolution phase:
|
|
2
2
|
// createCheckoutSession, createPortalSession, cancelSubscription,
|
|
3
|
-
// retrieveSubscription, retrievePrices, planSwitchSession.
|
|
3
|
+
// retrieveSubscription, retrievePrices, and planSwitchSession.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
// SubscriptionProviderPlugin
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
5
|
+
// The plugin build (`feature.ts`) registers these as methods on
|
|
6
|
+
// `SubscriptionProviderPlugin`. Unlike verifyAndParseWebhook (= pre-tenant),
|
|
7
|
+
// they receive the full HandlerContext and resolve the Stripe client from
|
|
8
|
+
// the runtime at call time (using the audited api-key from system-secrets),
|
|
9
|
+
// rather than from a mount-time closure. Key rotation therefore works
|
|
10
|
+
// without a redeploy.
|
|
11
11
|
//
|
|
12
|
-
// **Type
|
|
13
|
-
//
|
|
14
|
-
// <SubscriptionProviderPlugin["...method"]>>[1]`).
|
|
15
|
-
//
|
|
16
|
-
//
|
|
12
|
+
// **Type derivation:** method option shapes are derived **directly from the
|
|
13
|
+
// plugin contract** (`Parameters<NonNullable
|
|
14
|
+
// <SubscriptionProviderPlugin["...method"]>>[1]`). If Foundation extends the
|
|
15
|
+
// contract (for example, with a new optional field), the Stripe plugin detects
|
|
16
|
+
// it at TypeScript compile time rather than at runtime.
|
|
17
17
|
import { createHash } from "node:crypto";
|
|
18
18
|
import { KNOWN_RECURRING_INTERVALS, SubscriptionCancelTimings, } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
|
|
19
19
|
import { ConflictError, UnprocessableError } from "@cosmicdrift/kumiko-framework/errors";
|
|
@@ -79,11 +79,11 @@ function isUnknownCustomerStripeError(error) {
|
|
|
79
79
|
}
|
|
80
80
|
export function createStripeCheckoutSession(runtime, { paymentInvoiceCreation = true } = {}) {
|
|
81
81
|
return async (ctx, options) => {
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
// billing-live-config-key write
|
|
82
|
+
// Invariant: without billing-live, no Stripe session may be created
|
|
83
|
+
// (sk_test_-keys in production would otherwise create a test-mode checkout).
|
|
84
|
+
// Throw before every Stripe call. The guard used to be provided by the
|
|
85
|
+
// unmounted plugin; Stripe is now always mounted, so the
|
|
86
|
+
// billing-live-config-key gates the write side.
|
|
87
87
|
await runtime.assertBillingLive(ctx);
|
|
88
88
|
const stripe = await runtime.clientForCtx(ctx);
|
|
89
89
|
const mode = options.mode ?? "subscription";
|
|
@@ -19,7 +19,7 @@ export type StripeRuntimeDeps = {
|
|
|
19
19
|
export type StripeCtxRuntime = {
|
|
20
20
|
readonly clientForCtx: (ctx: HandlerContext) => Promise<Stripe>;
|
|
21
21
|
/** Throws FeatureDisabledError unless `billing-live` config is true. The
|
|
22
|
-
*
|
|
22
|
+
* invariant: no Stripe session may be created while billing is not
|
|
23
23
|
* live (sk_test_ keys in prod must not produce a live checkout).
|
|
24
24
|
* `handlerName` names the write-handler in the thrown error — defaults to
|
|
25
25
|
* "create-checkout-session" for existing callers, but plan-switch/portal
|
|
@@ -41,7 +41,7 @@ export function createStripeClientCache() {
|
|
|
41
41
|
if (cached)
|
|
42
42
|
return cached;
|
|
43
43
|
// No apiVersion pin — a string literal breaks consumers' typecheck on newer
|
|
44
|
-
// stripe SDKs
|
|
44
|
+
// stripe SDKs; the SDK's own default keeps wire-version and types aligned.
|
|
45
45
|
const client = new Stripe(apiKey);
|
|
46
46
|
cache.set(apiKey, client);
|
|
47
47
|
return client;
|
|
@@ -5,17 +5,17 @@ import Stripe from "stripe";
|
|
|
5
5
|
import type { StripeWebhookRuntime } from "./runtime.ts";
|
|
6
6
|
export declare function isResourceMissingStripeError(error: unknown): error is Stripe.errors.StripeInvalidRequestError;
|
|
7
7
|
export type StripeWebhookOptions = {
|
|
8
|
-
/** Price-to-tier
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
/** Price-to-tier map. The plugin reads the price ID from the event and
|
|
9
|
+
* maps it to a tier name. Returns null when the price ID is not mapped.
|
|
10
|
+
* App-specific and remains a factory option, not a secret. */
|
|
11
11
|
readonly priceToTier: Readonly<Record<string, string>>;
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
* Stripe
|
|
15
|
-
* `verifyAndParseWebhook`. **Pre-tenant
|
|
16
|
-
* HandlerContext;
|
|
17
|
-
* Stripe
|
|
18
|
-
* system
|
|
14
|
+
* Stripe webhook handler implementing the plugin contract
|
|
15
|
+
* `verifyAndParseWebhook`. **Pre-tenant resolution** — there is no
|
|
16
|
+
* HandlerContext; instead of using a mount-time client, `runtime` resolves
|
|
17
|
+
* the Stripe client and webhook secret at call time from the optional
|
|
18
|
+
* system SecretsContext (third argument).
|
|
19
19
|
*/
|
|
20
20
|
export declare function verifyAndParseStripeWebhook(runtime: StripeWebhookRuntime, options: StripeWebhookOptions): (rawBody: string, headers: Record<string, string>, systemSecrets?: SecretsContext) => Promise<SubscriptionEvent | PaymentEvent | null>;
|
|
21
21
|
export type MappedStripeSubscriptionState = {
|
|
@@ -37,7 +37,7 @@ export declare function mapStripeSubscriptionState(sub: Pick<Stripe.Subscription
|
|
|
37
37
|
export declare function stripeCancelAtIso(sub: Pick<Stripe.Subscription, "cancel_at" | "cancel_at_period_end">, currentPeriodEndIso: string): string | null;
|
|
38
38
|
/** Stripe-event-type → normalisiert. null = ignore. */
|
|
39
39
|
export declare function mapStripeEventType(stripeType: string): SubscriptionEventType | null;
|
|
40
|
-
/** Stripe
|
|
41
|
-
* incomplete
|
|
42
|
-
*
|
|
40
|
+
/** Maps Stripe statuses to normalized statuses. Unknown statuses are
|
|
41
|
+
* mapped defensively to incomplete; the plugin should not receive them, but
|
|
42
|
+
* an invalid status string must not be stored in the database. */
|
|
43
43
|
export declare function mapStripeStatus(stripeStatus: Stripe.Subscription.Status): SubscriptionStatus;
|
|
@@ -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
|
import { BillingEventKinds, parseProviderConsentId, SubscriptionEventTypes, SubscriptionStatuses, } from "@cosmicdrift/kumiko-bundled-features/billing-foundation";
|
|
35
34
|
import { ExtraRouteRejection } from "@cosmicdrift/kumiko-framework/api";
|
|
@@ -47,11 +46,11 @@ function transientProviderRejection(error) {
|
|
|
47
46
|
return new ExtraRouteRejection(503, { error: { code: "subscription_provider_transient" } }, `stripe retrieve failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
48
47
|
}
|
|
49
48
|
/**
|
|
50
|
-
* Stripe
|
|
51
|
-
* `verifyAndParseWebhook`. **Pre-tenant
|
|
52
|
-
* HandlerContext;
|
|
53
|
-
* Stripe
|
|
54
|
-
* system
|
|
49
|
+
* Stripe webhook handler implementing the plugin contract
|
|
50
|
+
* `verifyAndParseWebhook`. **Pre-tenant resolution** — there is no
|
|
51
|
+
* HandlerContext; instead of using a mount-time client, `runtime` resolves
|
|
52
|
+
* the Stripe client and webhook secret at call time from the optional
|
|
53
|
+
* system SecretsContext (third argument).
|
|
55
54
|
*/
|
|
56
55
|
export function verifyAndParseStripeWebhook(runtime, options) {
|
|
57
56
|
return async (rawBody, headers, systemSecrets) => {
|
|
@@ -59,15 +58,15 @@ export function verifyAndParseStripeWebhook(runtime, options) {
|
|
|
59
58
|
if (!sigHeader) {
|
|
60
59
|
throw new Error("subscription-stripe: stripe-signature header missing");
|
|
61
60
|
}
|
|
62
|
-
// 0.
|
|
63
|
-
// secret (
|
|
64
|
-
// options.
|
|
61
|
+
// 0. Resolve at runtime: obtain the API key (for the client and lazy fetch)
|
|
62
|
+
// and webhook secret (for signature verification) from system secrets,
|
|
63
|
+
// falling back to the factory options. Throws if neither is configured.
|
|
65
64
|
const { stripe, webhookSecret } = await runtime.resolve(systemSecrets);
|
|
66
|
-
// 1.
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
// payment
|
|
70
|
-
// path
|
|
65
|
+
// 1. Verify the signature. constructEvent throws on a mismatch (invalid
|
|
66
|
+
// signature) or timestamp-tolerance violation (default: 5 minutes).
|
|
67
|
+
// The foundation maps the thrown error to HTTP 401. This applies to
|
|
68
|
+
// BOTH branches below: the payment branch is selected only AFTER this
|
|
69
|
+
// check, so no path bypasses signature verification.
|
|
71
70
|
let event;
|
|
72
71
|
try {
|
|
73
72
|
event = await stripe.webhooks.constructEventAsync(rawBody, sigHeader, webhookSecret);
|
|
@@ -84,28 +83,27 @@ export function verifyAndParseStripeWebhook(runtime, options) {
|
|
|
84
83
|
if (isCheckoutSessionEventType(event.type)) {
|
|
85
84
|
return await parsePaymentEvent(event, stripe);
|
|
86
85
|
}
|
|
87
|
-
// 2. Event-type
|
|
86
|
+
// 2. Event-type filter — only 5 event types are supported.
|
|
88
87
|
const normalizedType = mapStripeEventType(event.type);
|
|
89
88
|
if (!normalizedType) {
|
|
90
89
|
return null; // foundation returnt 200 ignored
|
|
91
90
|
}
|
|
92
|
-
// 3.
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
// oder via lazy-fetch (invoice-events).
|
|
91
|
+
// 3. Extract the payload. Stripe uses different data.object shapes
|
|
92
|
+
// depending on event.type. Extract subscription data either directly
|
|
93
|
+
// (subscription events) or through a lazy fetch (invoice events).
|
|
96
94
|
const sub = await extractSubscriptionFromEvent(event, stripe);
|
|
97
95
|
if (!sub) {
|
|
98
|
-
// event
|
|
99
|
-
//
|
|
96
|
+
// The event type passed the 5-item filter, but its payload shape did not
|
|
97
|
+
// match — treat this as Stripe SDK schema drift and return null defensively.
|
|
100
98
|
return null;
|
|
101
99
|
}
|
|
102
|
-
// 4.
|
|
103
|
-
// `metadata.tenantId`
|
|
100
|
+
// 4. Resolve the tenant from metadata. The app builder sets
|
|
101
|
+
// `metadata.tenantId` when calling createCheckoutSession.
|
|
104
102
|
const tenantId = sub.metadata?.["tenantId"];
|
|
105
103
|
if (!tenantId || tenantId.length === 0) {
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
104
|
+
// A subscription without tenant metadata cannot be created without tenant
|
|
105
|
+
// resolution. Drop the event silently (the foundation responds with 200
|
|
106
|
+
// ignored). This is an app-owner error, not a foundation error.
|
|
109
107
|
return null;
|
|
110
108
|
}
|
|
111
109
|
// 5+6. Price-to-tier-Mapping + status/period-end/cancel_at — shared with
|
|
@@ -151,7 +149,7 @@ export function mapStripeSubscriptionState(sub, priceToTier) {
|
|
|
151
149
|
const periodEndUnixSec = sub.items.data[0]?.current_period_end ?? 0;
|
|
152
150
|
// Stripe returns Unix-seconds; Temporal.Instant.fromEpochMilliseconds
|
|
153
151
|
// expects ms. Multiply, then ISO. (No-Date-API-Guard forbids
|
|
154
|
-
// `new Date()` — static import above, not the ambient global
|
|
152
|
+
// `new Date()` — static import above, not the ambient global.)
|
|
155
153
|
const currentPeriodEnd = Temporal.Instant.fromEpochMilliseconds(periodEndUnixSec * 1000).toString();
|
|
156
154
|
const cancelAt = stripeCancelAtIso(sub, currentPeriodEnd);
|
|
157
155
|
return { status, tier, currentPeriodEnd, cancelAt };
|
|
@@ -187,9 +185,9 @@ export function mapStripeEventType(stripeType) {
|
|
|
187
185
|
return null;
|
|
188
186
|
}
|
|
189
187
|
}
|
|
190
|
-
/** Stripe
|
|
191
|
-
* incomplete
|
|
192
|
-
*
|
|
188
|
+
/** Maps Stripe statuses to normalized statuses. Unknown statuses are
|
|
189
|
+
* mapped defensively to incomplete; the plugin should not receive them, but
|
|
190
|
+
* an invalid status string must not be stored in the database. */
|
|
193
191
|
export function mapStripeStatus(stripeStatus) {
|
|
194
192
|
switch (stripeStatus) {
|
|
195
193
|
case "active":
|
|
@@ -215,9 +213,9 @@ export function mapStripeStatus(stripeStatus) {
|
|
|
215
213
|
return SubscriptionStatuses.incomplete;
|
|
216
214
|
}
|
|
217
215
|
}
|
|
218
|
-
/**
|
|
219
|
-
*
|
|
220
|
-
*
|
|
216
|
+
/** Gets the subscription from the event. Subscription events include it
|
|
217
|
+
* directly in data.object; invoice events include only the subscription ID
|
|
218
|
+
* and require a lazy fetch via stripe.subscriptions.retrieve. */
|
|
221
219
|
// @wrapper-known semantic-alias
|
|
222
220
|
async function extractSubscriptionFromEvent(event, stripe) {
|
|
223
221
|
switch (event.type) {
|
|
@@ -227,16 +225,16 @@ async function extractSubscriptionFromEvent(event, stripe) {
|
|
|
227
225
|
return event.data.object; // @cast-boundary engine-bridge
|
|
228
226
|
case StripeEventTypes.invoicePaid:
|
|
229
227
|
case StripeEventTypes.invoicePaymentFailed: {
|
|
230
|
-
// Lazy-fetch
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
228
|
+
// Lazy-fetch the subscription. invoice.subscription is a string ID because
|
|
229
|
+
// Stripe webhooks do not expand it automatically. Fetch the full
|
|
230
|
+
// subscription so downstream status, tier via priceId, and period-end
|
|
231
|
+
// mapping remain consistent.
|
|
234
232
|
const invoice = event.data.object; // @cast-boundary engine-bridge
|
|
235
233
|
const subRef = invoice // @cast-boundary engine-payload
|
|
236
234
|
.subscription;
|
|
237
235
|
if (!subRef) {
|
|
238
|
-
//
|
|
239
|
-
// recurring
|
|
236
|
+
// An invoice without a subscription reference is a one-shot invoice, not a
|
|
237
|
+
// recurring invoice. It is outside this domain and should be ignored.
|
|
240
238
|
return null;
|
|
241
239
|
}
|
|
242
240
|
const subId = typeof subRef === "string" ? subRef : subRef.id;
|
package/dist/tags/feature.d.ts
CHANGED
|
@@ -21,9 +21,9 @@ export type TagsFeatureOptions = {
|
|
|
21
21
|
/** Row-level ownership on the tag-assignment rows themselves — orthogonal to
|
|
22
22
|
* `access`, which only gates whether a caller may dispatch assign/remove/list
|
|
23
23
|
* at all. `ownership.read` is no longer what keeps a caller from reading
|
|
24
|
-
* assignments on host entities they can't see: that gate is default-on
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* assignments on host entities they can't see: that gate is default-on and
|
|
25
|
+
* derives from the entity's `parentRef`. Use `ownership.read` for an
|
|
26
|
+
* ADDITIONAL row rule on the assignment row itself; it is AND-ed with the
|
|
27
27
|
* host-visibility gate, never a replacement for it. Applies only to
|
|
28
28
|
* `tag-assignment`; the `tag` catalog stays tenant-wide by design.
|
|
29
29
|
*
|
package/dist/tags/screens.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i18nKey, } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import { DEFAULT_TAG_ACCESS, TAGS_EDIT_SCREEN_ID, TAGS_SCREEN_ID } from "./web/constants.js";
|
|
3
|
-
// Declarative catalog screens
|
|
3
|
+
// Declarative catalog screens. Access matches create/update/
|
|
4
4
|
// delete so createTagsFeature({ access|roles }) stays consistent. TagManager
|
|
5
5
|
// remains for TagPicker/TagSection — only the standalone admin screen moved.
|
|
6
6
|
export function createTagListScreen(access = DEFAULT_TAG_ACCESS) {
|
|
@@ -89,19 +89,19 @@ function pickActiveLayoutRow(rows, locale) {
|
|
|
89
89
|
async function fetchTemplate(db, tenantId, slug, kind, locale) {
|
|
90
90
|
const rows = await selectMany(db, templateResourcesTable, { tenantId, slug, kind, locale }, { limit: 1 });
|
|
91
91
|
// @cast-boundary db-row — db.select returnt unbenanntes unknown[],
|
|
92
|
-
//
|
|
92
|
+
// The row shape is guaranteed by templateResourcesTable + buildBaseColumns.
|
|
93
93
|
return rows[0] ?? null;
|
|
94
94
|
}
|
|
95
95
|
function toPublic(row) {
|
|
96
96
|
// @cast-boundary db-row — Drizzle-Schema typisiert kind/contentFormat/
|
|
97
|
-
// scope/status
|
|
98
|
-
//
|
|
97
|
+
// scope/status as generic text. Database CHECK constraints restrict
|
|
98
|
+
// them to the union types; the cast asserts that schema knowledge.
|
|
99
99
|
const kind = row.kind;
|
|
100
|
-
// @cast-boundary db-row —
|
|
100
|
+
// @cast-boundary db-row — see kind.
|
|
101
101
|
const contentFormat = row.contentFormat;
|
|
102
|
-
// @cast-boundary db-row —
|
|
102
|
+
// @cast-boundary db-row — see kind.
|
|
103
103
|
const scope = row.scope;
|
|
104
|
-
// @cast-boundary db-row —
|
|
104
|
+
// @cast-boundary db-row — see kind.
|
|
105
105
|
const status = row.status;
|
|
106
106
|
const linkedEntries = parseLinkedResourceEntries(row.linkedResources);
|
|
107
107
|
return {
|
|
@@ -143,7 +143,7 @@ function parseJson(raw) {
|
|
|
143
143
|
try {
|
|
144
144
|
const parsed = JSON.parse(raw);
|
|
145
145
|
// @cast-boundary engine-payload — JSON.parse returnt unknown, typeof-Guard
|
|
146
|
-
//
|
|
146
|
+
// narrows it to object; Record<string, unknown> is the minimal common shape.
|
|
147
147
|
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
148
148
|
}
|
|
149
149
|
catch {
|
|
@@ -158,11 +158,11 @@ export class TemplateNotFoundError extends Error {
|
|
|
158
158
|
this.name = "TemplateNotFoundError";
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
|
-
// Single
|
|
162
|
-
// Pattern
|
|
161
|
+
// Single source of truth for "this handler requires template-resolver".
|
|
162
|
+
// Pattern symmetric with requireTextContent.
|
|
163
163
|
export function requireTemplateResolver(ctx, callerName) {
|
|
164
164
|
// @cast-boundary engine-bridge — templateResolver kommt per extraContext
|
|
165
|
-
//
|
|
165
|
+
// from App-Bootstrap; the framework container does not know this field on its own.
|
|
166
166
|
const api = ctx.templateResolver;
|
|
167
167
|
if (!api) {
|
|
168
168
|
throw new InternalError({
|
|
@@ -5,11 +5,11 @@ import { templateResourcesTable } from "../table.js";
|
|
|
5
5
|
import { deliveryPolicyOf, isRowServedTo } from "../template-delivery-policy.js";
|
|
6
6
|
import { draftViewerTenantId, isHiddenSystemDraft, toWorkingRow } from "../template-draft.js";
|
|
7
7
|
import { isSystemOnlyTemplateHiddenFrom } from "../template-system-only.js";
|
|
8
|
-
// Admin
|
|
9
|
-
// archived
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
8
|
+
// Admin lookup for the UI editing flow. Returns the raw template, including draft/
|
|
9
|
+
// archived status. Tenant isolation: users see only templates belonging to their own
|
|
10
|
+
// tenant or SYSTEM_TENANT (system defaults are publicly readable); ctx.db is tenant-
|
|
11
|
+
// scoped for every role, so the check below is defense in depth. Anonymous access is
|
|
12
|
+
// excluded—public reads go through resolveTemplate in the API, not here.
|
|
13
13
|
export const findByIdQuery = defineQueryHandler({
|
|
14
14
|
name: "find-by-id",
|
|
15
15
|
schema: z.object({ id: z.string().min(1) }),
|
|
@@ -35,7 +35,7 @@ export const listQuery = defineQueryHandler({
|
|
|
35
35
|
if (query.payload.status) {
|
|
36
36
|
where["status"] = query.payload.status;
|
|
37
37
|
}
|
|
38
|
-
// @cast-boundary db-row — selectMany
|
|
38
|
+
// @cast-boundary db-row — selectMany returns unknown[]; Row shape is
|
|
39
39
|
// durch templateResourcesTable + buildBaseColumns garantiert.
|
|
40
40
|
const rows = (await selectMany(ctx.db, templateResourcesTable, where, {
|
|
41
41
|
limit: 500,
|
|
@@ -30,8 +30,8 @@ export const folderSchema = z
|
|
|
30
30
|
export const titleSchema = z.string().min(1).max(200);
|
|
31
31
|
export const contentFormatSchema = z.enum(CONTENT_FORMATS);
|
|
32
32
|
export const statusSchema = z.enum(TEMPLATE_STATUSES);
|
|
33
|
-
// Common
|
|
34
|
-
//
|
|
33
|
+
// Common upsert payload shared by upsertSystem and upsertTenant.
|
|
34
|
+
// Only ACL and tenantId determination differ.
|
|
35
35
|
export const upsertPayloadSchema = z.object({
|
|
36
36
|
slug: templateSlugSchema,
|
|
37
37
|
kind: kindSchema,
|
|
@@ -148,9 +148,9 @@ export async function writeTemplateRow(args) {
|
|
|
148
148
|
}, user, db, { streamTenantId });
|
|
149
149
|
if (!result.isSuccess)
|
|
150
150
|
return result;
|
|
151
|
-
// @cast-boundary db-row — executor.create
|
|
152
|
-
// INSERT RETURNING;
|
|
153
|
-
//
|
|
151
|
+
// @cast-boundary db-row — executor.create returns a row from
|
|
152
|
+
// INSERT RETURNING; the { id } shape is guaranteed because the primary key is in the
|
|
153
|
+
// RETURNING clause.
|
|
154
154
|
const createdRow = result.data;
|
|
155
155
|
return {
|
|
156
156
|
isSuccess: true,
|
|
@@ -2,10 +2,9 @@ import { defineWriteHandler, SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framew
|
|
|
2
2
|
import { resolveTemplateVariables } from "../template-validation.js";
|
|
3
3
|
import { upsertPayloadSchema } from "./shared.js";
|
|
4
4
|
import { writeTemplateRow } from "./template-write.js";
|
|
5
|
-
//
|
|
6
|
-
// scope='system'.
|
|
7
|
-
//
|
|
8
|
-
// Overrides.
|
|
5
|
+
// Creates or updates a system template under SYSTEM_TENANT_ID with
|
|
6
|
+
// scope='system'. Only SystemAdmin can change these global defaults;
|
|
7
|
+
// TenantAdmin uses upsertTenant for overrides instead.
|
|
9
8
|
export const upsertSystemWrite = defineWriteHandler({
|
|
10
9
|
name: "upsert-system",
|
|
11
10
|
schema: upsertPayloadSchema,
|
|
@@ -4,11 +4,10 @@ import { refuseTemplateEdit, templateEditAccess, } from "../template-edit-policy
|
|
|
4
4
|
import { resolveTemplateVariables } from "../template-validation.js";
|
|
5
5
|
import { upsertPayloadSchema } from "./shared.js";
|
|
6
6
|
import { writeTemplateRow } from "./template-write.js";
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// Tenant-Templates kuratiert).
|
|
7
|
+
// Creates or updates a tenant override under event.user.tenantId with scope='tenant'.
|
|
8
|
+
// The default status is 'draft'; users must publish explicitly via the publish handler.
|
|
9
|
+
// SystemAdmin can write for another tenant through tenantIdOverride, typically to
|
|
10
|
+
// curate tenant templates from a platform admin UI.
|
|
12
11
|
export function makeUpsertTenantWrite(policy) {
|
|
13
12
|
return defineWriteHandler({
|
|
14
13
|
name: "upsert-tenant",
|