@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,9 +1,9 @@
|
|
|
1
|
-
// secrets bundle constants — default RBAC for set/delete/list
|
|
1
|
+
// secrets bundle constants — default RBAC for set/delete/list.
|
|
2
2
|
|
|
3
3
|
import type { AccessRule } from "@cosmicdrift/kumiko-framework/engine";
|
|
4
4
|
|
|
5
5
|
// Default-RBAC of the set/delete/list handlers, hard-wired to ["TenantAdmin"]
|
|
6
|
-
// before
|
|
6
|
+
// before this default was established. Apps with their own role vocabulary override via
|
|
7
7
|
// createSecretsFeature({ roles }) or createSecretsFeature({ access }) — the
|
|
8
8
|
// rotate job stays untouched, it's a manual/ops path across all tenants by
|
|
9
9
|
// design, not a per-tenant RBAC surface.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// kumiko-lint-ignore app-feature-structure
|
|
1
|
+
// kumiko-lint-ignore app-feature-structure feature.ts is over 300 lines and not yet split
|
|
2
2
|
import { computeRevisionEtag } from "@cosmicdrift/kumiko-framework/api";
|
|
3
3
|
import {
|
|
4
4
|
defineFeature,
|
|
@@ -274,8 +274,8 @@ export function createSeoFeature(opts: SeoOptions): FeatureDefinition {
|
|
|
274
274
|
});
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
// Boot-
|
|
278
|
-
//
|
|
277
|
+
// Boot-check body extracted as a named function—directly unit-testable,
|
|
278
|
+
// following the same "thin job-shell calls testable function" pattern as
|
|
279
279
|
// legal-pages' runLegalPagesBootCheck.
|
|
280
280
|
r.job(
|
|
281
281
|
"seo-boot-check",
|
|
@@ -9,7 +9,7 @@ export const SessionHandlers = {
|
|
|
9
9
|
revoke: "sessions:write:user-session:revoke",
|
|
10
10
|
revokeAllOthers: "sessions:write:user-session:revoke-all-others",
|
|
11
11
|
/** Privileged: System-Caller (cross-feature) revokes ALL live sessions
|
|
12
|
-
*
|
|
12
|
+
* for a user. Used by user-data-rights:restrict-account
|
|
13
13
|
* (DSGVO Art. 18 Account-Freeze). */
|
|
14
14
|
revokeAllForUser: "sessions:write:user-session:revoke-all-for-user",
|
|
15
15
|
} as const;
|
|
@@ -51,7 +51,7 @@ export type SessionsFeatureOptions = {
|
|
|
51
51
|
// runtime binding.
|
|
52
52
|
readonly autoRevokeOnPasswordChange?: SessionMassRevoker;
|
|
53
53
|
// Session JWT / store_user_sessions TTL. Was previously auth.sessions.expiresInMs
|
|
54
|
-
//
|
|
54
|
+
// — lives on the sessions feature now that sessionStore is the wiring.
|
|
55
55
|
readonly expiresInMs?: number;
|
|
56
56
|
// Access preset for the admin list/detail queries and screens; they expose decrypted
|
|
57
57
|
// IP/user-agent of every session in the tenant. A preset name, not a role array, because
|
|
@@ -59,8 +59,10 @@ export type SessionsFeatureOptions = {
|
|
|
59
59
|
readonly adminAccess?: "admin" | "systemAdmin";
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
// The returned unbind only clears the binding while it is still this revoker, so a stack that
|
|
63
|
+
// stops later cannot unbind a newer stack sharing the same feature instance.
|
|
64
|
+
export type BindAutoRevokeOnPasswordChange = (revoker: SessionMassRevoker) => () => void;
|
|
65
|
+
export type BindRevokeAllOtherSessions = (revoker: SessionAllOthersRevoker) => () => void;
|
|
64
66
|
|
|
65
67
|
// Reads the late-bind setter off a mounted sessions feature's exports.
|
|
66
68
|
// run{Prod,Dev}App call it once the DB connection is concrete — the feature
|
|
@@ -119,23 +121,23 @@ export function createSessionsFeature(options?: SessionsFeatureOptions): Feature
|
|
|
119
121
|
// events (the row columns ARE the audit trail). Registering it as
|
|
120
122
|
// r.entity would make it a rebuildable implicit projection whose replay
|
|
121
123
|
// finds zero session events and swaps an empty shadow over the live
|
|
122
|
-
// table — wiping every active session on the next projection rebuild
|
|
123
|
-
//
|
|
124
|
+
// table — wiping every active session on the next projection rebuild.
|
|
125
|
+
// r.storeTable keeps the migration DDL but opts the
|
|
124
126
|
// table out of implicit rebuild, like jobs/channel-in-app/feature-toggles
|
|
125
127
|
// which are direct-write stores too.
|
|
126
128
|
r.storeTable(
|
|
127
129
|
deriveEntityTableMeta(USER_SESSION_ENTITY_NAME, userSessionEntity, { source: "unmanaged" }),
|
|
128
130
|
{
|
|
129
131
|
reason: "read_side.user_sessions_direct_write",
|
|
130
|
-
// sessionCreator encrypts ip/userAgent via encryptForDirectWrite
|
|
132
|
+
// sessionCreator encrypts ip/userAgent via encryptForDirectWrite.
|
|
131
133
|
piiEncryptedOnWrite: true,
|
|
132
134
|
},
|
|
133
135
|
);
|
|
134
136
|
|
|
135
|
-
// Self-registers as auth-foundation's sessionStore provider
|
|
137
|
+
// Self-registers as auth-foundation's sessionStore provider —
|
|
136
138
|
// wraps the same createSessionCallbacks() used by the manual
|
|
137
|
-
// buildServer({ auth: { ... } }) wiring above;
|
|
138
|
-
//
|
|
139
|
+
// buildServer({ auth: { ... } }) wiring above; removes that manual
|
|
140
|
+
// wiring once the middleware resolves generically
|
|
139
141
|
// via resolveSessionStore().
|
|
140
142
|
r.useExtension(EXT_SESSION_STORE, "default", {
|
|
141
143
|
build: (deps): SessionStore => {
|
|
@@ -153,7 +155,7 @@ export function createSessionsFeature(options?: SessionsFeatureOptions): Feature
|
|
|
153
155
|
},
|
|
154
156
|
} satisfies SessionStoreProvider);
|
|
155
157
|
|
|
156
|
-
// Custom domain-event for cross-instance access-invalidation
|
|
158
|
+
// Custom domain-event for cross-instance access-invalidation.
|
|
157
159
|
// r.defineEvent registers the schema so ctx.unsafeAppendEvent (revoke,
|
|
158
160
|
// revoke-all-others) enforces it at append time. revoke-all-for-user
|
|
159
161
|
// appends via the low-level append() instead (needs to anchor on
|
|
@@ -161,7 +163,7 @@ export function createSessionsFeature(options?: SessionsFeatureOptions): Feature
|
|
|
161
163
|
// consult the registry, so that callsite parses against
|
|
162
164
|
// sessionRevokedSchema explicitly, same guarantee via a different path.
|
|
163
165
|
// No projection: the payload IS the read, consumed directly off the
|
|
164
|
-
// event-store NOTIFY
|
|
166
|
+
// event-store NOTIFY.
|
|
165
167
|
r.defineEvent(SESSION_REVOKED_EVENT_SHORT, sessionRevokedSchema, { piiFields: "none" });
|
|
166
168
|
|
|
167
169
|
const handlers = {
|
|
@@ -236,6 +238,9 @@ export function createSessionsFeature(options?: SessionsFeatureOptions): Feature
|
|
|
236
238
|
|
|
237
239
|
const bindAutoRevokeOnPasswordChange: BindAutoRevokeOnPasswordChange = (revoker) => {
|
|
238
240
|
boundAutoRevoke = revoker;
|
|
241
|
+
return () => {
|
|
242
|
+
if (boundAutoRevoke === revoker) boundAutoRevoke = undefined;
|
|
243
|
+
};
|
|
239
244
|
};
|
|
240
245
|
|
|
241
246
|
r.translations({ keys: SESSIONS_I18N });
|
|
@@ -64,8 +64,8 @@ export const revokeAllForUserWrite = defineWriteHandler({
|
|
|
64
64
|
},
|
|
65
65
|
);
|
|
66
66
|
|
|
67
|
-
// Lightweight append alongside the direct-write above
|
|
68
|
-
//
|
|
67
|
+
// Lightweight append alongside the direct-write above; see revoke.write.ts
|
|
68
|
+
// for why this isn't a lifecycle event on
|
|
69
69
|
// store_user_sessions. Uses the low-level append() (not
|
|
70
70
|
// ctx.unsafeAppendEvent) because this handler is deliberately
|
|
71
71
|
// cross-tenant: the privileged caller's own tenantId (what
|
|
@@ -46,8 +46,8 @@ export const revokeAllOthersWrite = defineWriteHandler({
|
|
|
46
46
|
{ userId: event.user.id, revokedAt: null, id: { ne: keepSid } },
|
|
47
47
|
);
|
|
48
48
|
|
|
49
|
-
// Lightweight append alongside the direct-write above
|
|
50
|
-
//
|
|
49
|
+
// Lightweight append alongside the direct-write above; see revoke.write.ts
|
|
50
|
+
// for why this isn't a lifecycle event on
|
|
51
51
|
// store_user_sessions. Skipped when nothing was revoked (no other
|
|
52
52
|
// live sessions) — a spurious invalidation would be the failure mode.
|
|
53
53
|
if (updated.length > 0) {
|
|
@@ -50,7 +50,7 @@ export const revokeWrite = defineWriteHandler({
|
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
if (updated.length > 0) {
|
|
53
|
-
// Lightweight append alongside the direct-write above
|
|
53
|
+
// Lightweight append alongside the direct-write above — NOT a
|
|
54
54
|
// lifecycle event for store_user_sessions (that table stays an
|
|
55
55
|
// unmanaged direct-write store, see feature.ts). Own aggregate id per
|
|
56
56
|
// revoke, no predecessor to satisfy, no version_conflict against a
|
|
@@ -18,9 +18,9 @@ import { USER_SESSION_ENTITY_NAME } from "../constants.ts";
|
|
|
18
18
|
// mutate them via ctx.db inside a transaction, but no user request can bypass
|
|
19
19
|
// the revocation flow by poking the column directly.
|
|
20
20
|
export const userSessionEntity = createEntity({
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
21
|
+
// The entity key is "user-session"; snake-casing it would produce
|
|
22
|
+
// "read_user-sessions", which is invalid SQL without quoting. Use an explicit
|
|
23
|
+
// override with a valid read_-prefixed table name.
|
|
24
24
|
table: "store_user_sessions",
|
|
25
25
|
// sid-as-PK: the sessionCreator callback generates the UUID, returns it to
|
|
26
26
|
// the framework; the framework stamps it as `jti`; here the same value is
|
|
@@ -84,7 +84,7 @@ export const userSessionEntity = createEntity({
|
|
|
84
84
|
// Unmanaged direct-write store (r.storeTable in feature.ts, no event stream —
|
|
85
85
|
// revocation is a column write, not an aggregate). Handlers write via ctx.db;
|
|
86
86
|
// source: "unmanaged" makes the meta Writable so those writes compile. See
|
|
87
|
-
// feature.ts for the rebuild-exclusion rationale
|
|
87
|
+
// feature.ts for the rebuild-exclusion rationale.
|
|
88
88
|
export const userSessionTable = deriveEntityTableMeta(USER_SESSION_ENTITY_NAME, userSessionEntity, {
|
|
89
89
|
source: "unmanaged",
|
|
90
90
|
});
|
|
@@ -28,7 +28,7 @@ export const createSessionListScreen = (
|
|
|
28
28
|
pageSize: MAX_LIST_LIMIT,
|
|
29
29
|
// Mirrors list.query's own fallback (unrecognised/absent sort → createdAt
|
|
30
30
|
// desc) — kept in sync by hand, boot-validator only requires the field
|
|
31
|
-
// be present once the query accepts `sort
|
|
31
|
+
// be present once the query accepts `sort`.
|
|
32
32
|
defaultSort: { field: "createdAt", dir: "desc" },
|
|
33
33
|
columns: [
|
|
34
34
|
{ field: "id", label: i18nKey("sessions.list.col.id") },
|
|
@@ -90,7 +90,7 @@ export const createSessionDetailScreen = (
|
|
|
90
90
|
// The shim (projection-detail-shim.ts) stamps every field as
|
|
91
91
|
// type:"text" — field.renderer is the only way this screen
|
|
92
92
|
// type reaches real per-type formatting instead of a raw ISO
|
|
93
|
-
// string
|
|
93
|
+
// string.
|
|
94
94
|
{ field: "createdAt", renderer: { format: "timestamp" } },
|
|
95
95
|
{ field: "expiresAt", renderer: { format: "timestamp" } },
|
|
96
96
|
{ field: "revokedAt", renderer: { format: "timestamp" } },
|
|
@@ -256,11 +256,11 @@ export function createSessionCallbacks(opts: SessionCallbacksOptions): SessionCa
|
|
|
256
256
|
);
|
|
257
257
|
|
|
258
258
|
// Lightweight append alongside the direct-write above, same pattern
|
|
259
|
-
// as revoke.write.ts
|
|
259
|
+
// as revoke.write.ts — this callback is the password-change
|
|
260
260
|
// auto-revoke path (sessions/feature.ts postSave hook) and has no
|
|
261
261
|
// dispatcher ctx to call unsafeAppendEvent from, so it uses the raw
|
|
262
262
|
// append() like revoke-all-for-user.write.ts does. Without this, the
|
|
263
|
-
// access-invalidation consumer
|
|
263
|
+
// access-invalidation consumer never hears about a password
|
|
264
264
|
// change and an already-open SSE stream survives it — the exact
|
|
265
265
|
// "stale JWT mid-stream" gap this feature exists to close.
|
|
266
266
|
if (result.length > 0) {
|
|
@@ -2,11 +2,11 @@ import * as z from "zod";
|
|
|
2
2
|
|
|
3
3
|
// Lightweight custom event appended alongside the direct-write
|
|
4
4
|
// updateMany() in revoke.write.ts / revoke-all-others.write.ts /
|
|
5
|
-
// revoke-all-for-user.write.ts
|
|
5
|
+
// revoke-all-for-user.write.ts. store_user_sessions itself stays
|
|
6
6
|
// an unmanaged direct-write store (see feature.ts) — the row columns are
|
|
7
7
|
// the audit trail, this event is NOT a CRUD/lifecycle event for that
|
|
8
8
|
// table and carries no projection. Its only job is to give cross-instance
|
|
9
|
-
// consumers (access-invalidation
|
|
9
|
+
// consumers (access-invalidation) something to LISTEN for via the
|
|
10
10
|
// existing event-store NOTIFY, keyed by the affected userId.
|
|
11
11
|
//
|
|
12
12
|
// _SHORT/_QN pair mirrors cap-counter's rolling-incremented event:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OwnershipMap } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
|
|
3
|
-
// Boot validation rejects `{ kind: "where" }` in access.write too
|
|
3
|
+
// Boot validation rejects `{ kind: "where" }` in access.write too;
|
|
4
4
|
// failing at factory time names the option instead of an entity scope.
|
|
5
5
|
export function assertNoWhereRuleInOwnershipWrite(
|
|
6
6
|
factoryName: string,
|
|
@@ -2,13 +2,14 @@ import { requestContext } from "@cosmicdrift/kumiko-framework/api";
|
|
|
2
2
|
import {
|
|
3
3
|
configuredPiiSubjectKms,
|
|
4
4
|
decryptPiiFieldValues,
|
|
5
|
+
PII_ERASED_SENTINEL,
|
|
5
6
|
} from "@cosmicdrift/kumiko-framework/crypto";
|
|
6
7
|
|
|
7
8
|
// Raw reads (fetchOne/selectMany) return the stored column value — with an
|
|
8
9
|
// active KMS that is ciphertext (self-describing: it names its own subject,
|
|
9
10
|
// so no entity/field context is needed for key selection). `field` must
|
|
10
11
|
// still match the field name used at encrypt time — it is part of the
|
|
11
|
-
// AAD
|
|
12
|
+
// AAD, so a mismatch fails decrypt loud rather than silently
|
|
12
13
|
// letting ciphertext cut-and-pasted from another field decrypt. An erased
|
|
13
14
|
// subject yields the sentinel, which matches no real value.
|
|
14
15
|
export async function decryptStoredPii(
|
|
@@ -24,3 +25,12 @@ export async function decryptStoredPii(
|
|
|
24
25
|
const decrypted = out[field];
|
|
25
26
|
return typeof decrypted === "string" ? decrypted : value;
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
// Null for an erased subject: the sentinel must never be mailed or shown as an address.
|
|
30
|
+
export async function decryptStoredUserEmail(
|
|
31
|
+
stored: string,
|
|
32
|
+
fallbackRequestId: string,
|
|
33
|
+
): Promise<string | null> {
|
|
34
|
+
const email = await decryptStoredPii(stored, "email", fallbackRequestId);
|
|
35
|
+
return email === PII_ERASED_SENTINEL ? null : email;
|
|
36
|
+
}
|
|
@@ -11,7 +11,7 @@ import { subjectErasedConflict } from "@cosmicdrift/kumiko-framework/errors";
|
|
|
11
11
|
// Unmanaged direct-write stores (r.unmanagedTable) skip the executor, so its
|
|
12
12
|
// PII encryption never runs — every insert of subject-annotated fields must
|
|
13
13
|
// go through this instead, and the feature declares { piiEncryptedOnWrite:
|
|
14
|
-
// true } at the registration site (enforced by the registry
|
|
14
|
+
// true } at the registration site (enforced by the registry).
|
|
15
15
|
export async function encryptForDirectWrite(
|
|
16
16
|
entity: EntityDefinition,
|
|
17
17
|
entityName: string,
|
|
@@ -15,7 +15,7 @@ export {
|
|
|
15
15
|
classifyStoredEnvelope,
|
|
16
16
|
type StoredEnvelopeClassification,
|
|
17
17
|
} from "./classify-stored-envelope.ts";
|
|
18
|
-
export { decryptStoredPii } from "./decrypt-stored-pii.ts";
|
|
18
|
+
export { decryptStoredPii, decryptStoredUserEmail } from "./decrypt-stored-pii.ts";
|
|
19
19
|
export { encryptForDirectWrite } from "./encrypt-for-direct-write.ts";
|
|
20
20
|
export { entitiesOf } from "./entities-of.ts";
|
|
21
21
|
export { isWithinGracePeriod } from "./grace-period.ts";
|
|
@@ -11,8 +11,14 @@ export function mailTextWithSlotsHtml(text: string): string {
|
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
type MailParagraphOptions = { readonly showIf?: string };
|
|
15
|
+
|
|
16
|
+
function paragraphOpenTag(options: MailParagraphOptions | undefined): string {
|
|
17
|
+
return options?.showIf === undefined ? "<p>" : `<p data-if="${escapeHtmlAttr(options.showIf)}">`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function mailParagraph(text: string, options?: MailParagraphOptions): string {
|
|
21
|
+
return `${paragraphOpenTag(options)}${mailTextWithSlotsHtml(text)}</p>`;
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
export function mailHeading(text: string): string {
|
|
@@ -27,8 +33,9 @@ export function mailParagraphWithLink(
|
|
|
27
33
|
text: string,
|
|
28
34
|
linkLabel: string,
|
|
29
35
|
linkVariable: string,
|
|
36
|
+
options?: MailParagraphOptions,
|
|
30
37
|
): string {
|
|
31
|
-
return
|
|
38
|
+
return `${paragraphOpenTag(options)}${mailTextWithSlotsHtml(text)} <a href="{{${escapeHtmlAttr(linkVariable)}}}">${escapeHtml(linkLabel)}</a></p>`;
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
// One table row per list entry; the cell shows the entry's `field`.
|
|
@@ -16,17 +16,18 @@ export async function mapWithConcurrency<T, R>(
|
|
|
16
16
|
fn: (item: T, index: number) => Promise<R>,
|
|
17
17
|
): Promise<R[]> {
|
|
18
18
|
const results: R[] = new Array(items.length);
|
|
19
|
-
|
|
19
|
+
const unclaimed = items.entries();
|
|
20
20
|
let failed = false;
|
|
21
21
|
async function worker(): Promise<void> {
|
|
22
22
|
for (;;) {
|
|
23
23
|
// skip: another worker already failed — stop claiming new items.
|
|
24
24
|
if (failed) return;
|
|
25
|
-
const
|
|
25
|
+
const claimed = unclaimed.next();
|
|
26
26
|
// skip: cursor exhausted, normal worker-loop exit
|
|
27
|
-
if (
|
|
27
|
+
if (claimed.done) return;
|
|
28
|
+
const [index, item] = claimed.value;
|
|
28
29
|
try {
|
|
29
|
-
results[index] = await fn(
|
|
30
|
+
results[index] = await fn(item, index);
|
|
30
31
|
} catch (err) {
|
|
31
32
|
failed = true;
|
|
32
33
|
throw err;
|
|
@@ -91,7 +91,7 @@ export async function hostRowIsGone(
|
|
|
91
91
|
return row === undefined || row["isDeleted"] === true;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
// Write-path half of the parentRef gate
|
|
94
|
+
// Write-path half of the parentRef gate. Resolves the join entity's
|
|
95
95
|
// own `parentRef` declaration from the registry — the same object the read
|
|
96
96
|
// path's SQL gate reads — so the field names and the allowedTypes allowlist
|
|
97
97
|
// exist in exactly one place instead of once per path.
|
|
@@ -104,7 +104,7 @@ export async function joinRowParentIsVisible(
|
|
|
104
104
|
): Promise<boolean> {
|
|
105
105
|
const parentRef = registry.getEntity(joinEntityName)?.parentRef;
|
|
106
106
|
// A mount whose join entity lost its declaration can't derive a gate —
|
|
107
|
-
// deny rather than silently fall back to the
|
|
107
|
+
// deny rather than silently fall back to the open behaviour.
|
|
108
108
|
if (parentRef === undefined) return false;
|
|
109
109
|
|
|
110
110
|
const entityType = payload[parentRef.entityTypeField];
|
|
@@ -43,7 +43,7 @@ export async function verifyPassword(hashString: string, password: string): Prom
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// Anti-enumeration timing equaliser
|
|
46
|
+
// Anti-enumeration timing equaliser. The login handler runs this on
|
|
47
47
|
// the no-user / no-hash path so a missing account costs the same argon2
|
|
48
48
|
// latency as a real verify — otherwise response timing leaks whether an
|
|
49
49
|
// email is registered. Derived from hashPassword once and cached, so it
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
// Cross-device try-first handover
|
|
2
|
-
// offlot-app#454): signup-request runs in whichever browser the activation
|
|
1
|
+
// Cross-device try-first handover: signup-request runs in whichever browser the activation
|
|
3
2
|
// link ends up opened in, which may not be the one holding the anonymous
|
|
4
3
|
// visitor's tenant-handover grant. This extension point lets
|
|
5
4
|
// auth-email-password bind a verified grant to the signup token server-side
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
//
|
|
26
26
|
// Every key is derived from sha256(token), never the raw token — Redis key
|
|
27
27
|
// names, MONITOR output, replica traffic, and memory/backup dumps never
|
|
28
|
-
// carry the bearer secret in the clear
|
|
28
|
+
// carry the bearer secret in the clear. The by-subject entry stores
|
|
29
29
|
// the *hash* of the live token, not the token itself, so it can only be
|
|
30
30
|
// used to invalidate (delete the matching forward entry) — never to
|
|
31
31
|
// recover or resend the original token. A resend therefore always mints a
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.388.0",
|
|
4
|
+
"type": "fix",
|
|
5
|
+
"title": "Deliver job validates its payload at the trigger",
|
|
6
|
+
"detail": "The deliver job now declares its payload schema, so a manual trigger with an invalid payload is rejected up front instead of throwing inside the handler and consuming all retries."
|
|
7
|
+
},
|
|
2
8
|
{
|
|
3
9
|
"version": "0.365.1",
|
|
4
10
|
"type": "fix",
|
|
@@ -75,6 +75,7 @@ export function createStepDispatcherFeature(): FeatureDefinition {
|
|
|
75
75
|
retries: DELIVER_RETRIES,
|
|
76
76
|
backoff: "exponential",
|
|
77
77
|
maxPerTenant: { limit: DELIVER_MAX_PER_TENANT, onLimit: "defer" },
|
|
78
|
+
schema: deliverJobPayloadSchema,
|
|
78
79
|
escapeHatch: { reason: DELIVER_ESCAPE_HATCH_REASON },
|
|
79
80
|
},
|
|
80
81
|
async (payload, ctx) => {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"version": "0.388.0",
|
|
4
|
+
"type": "improvement",
|
|
5
|
+
"title": "New subscription provider for Dodo Payments",
|
|
6
|
+
"detail": "createSubscriptionDodoFeature() registers the \"dodo\" subscription provider (Merchant of Record). It verifies Standard Webhooks signatures, maps Dodo events to the foundation events, creates hosted checkouts and portal sessions, and switches plans in the app through previewPlanSwitch and applyPlanSwitch. Config keys are api-key, webhook-secret, billing-live and environment. Plan switches need a Product Collection in Dodo."
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"version": "0.388.0",
|
|
10
|
+
"type": "improvement",
|
|
11
|
+
"title": "dodoEnvSchema declares the Dodo product id slots",
|
|
12
|
+
"detail": "dodoEnvSchema({ prices: [\"PRO\"] }) adds one optional DODO_PRODUCT_PRO slot per plan next to the API key and webhook key, and checks the pdt_ prefix. It is the counterpart to stripeEnvSchema."
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Thin JSON-over-fetch client for the Dodo Payments REST API. All traffic goes
|
|
2
|
+
// through the injected `send`, which defaults to the SSRF-safe egress in
|
|
3
|
+
// feature.ts and is replaced by a mock in tests.
|
|
4
|
+
|
|
5
|
+
import { parseJsonOrThrow } from "@cosmicdrift/kumiko-framework/utils";
|
|
6
|
+
|
|
7
|
+
export type DodoSend = (url: string, init?: RequestInit) => Promise<Response>;
|
|
8
|
+
|
|
9
|
+
export type DodoRequest = {
|
|
10
|
+
readonly method: "GET" | "POST" | "PATCH";
|
|
11
|
+
/** Path segments interpolated into it must already be encodeURIComponent'ed. */
|
|
12
|
+
readonly path: string;
|
|
13
|
+
readonly query?: Readonly<Record<string, string>>;
|
|
14
|
+
readonly body?: unknown;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type DodoTarget = { readonly baseUrl: string; readonly apiKey: string };
|
|
18
|
+
|
|
19
|
+
// Never carries the response body or the key: both can hold customer data or secrets.
|
|
20
|
+
export class DodoHttpError extends Error {
|
|
21
|
+
readonly status: number;
|
|
22
|
+
constructor(request: DodoRequest, status: number) {
|
|
23
|
+
super(`subscription-dodo: ${request.method} ${request.path} failed with status ${status}`);
|
|
24
|
+
this.name = "DodoHttpError";
|
|
25
|
+
this.status = status;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createDodoHttp(send: DodoSend) {
|
|
30
|
+
return async (target: DodoTarget, request: DodoRequest): Promise<unknown> => {
|
|
31
|
+
const query = request.query ? `?${new URLSearchParams(request.query).toString()}` : "";
|
|
32
|
+
const response = await send(`${target.baseUrl}${request.path}${query}`, {
|
|
33
|
+
method: request.method,
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${target.apiKey}`,
|
|
36
|
+
Accept: "application/json",
|
|
37
|
+
...(request.body !== undefined && { "Content-Type": "application/json" }),
|
|
38
|
+
},
|
|
39
|
+
...(request.body !== undefined && { body: JSON.stringify(request.body) }),
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) throw new DodoHttpError(request, response.status);
|
|
42
|
+
const text = await response.text();
|
|
43
|
+
return text.length === 0 ? null : parseJsonOrThrow<unknown>(text, "subscription-dodo response");
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const SUBSCRIPTION_DODO_FEATURE = "subscription-dodo" as const;
|
|
2
|
+
|
|
3
|
+
// Must match the path segment in the webhook URL `/api/subscription/webhook/dodo`.
|
|
4
|
+
export const DODO_PROVIDER_NAME = "dodo" as const;
|
|
5
|
+
|
|
6
|
+
// Config-key short-names, qualified to `subscription-dodo:config:<name>` at
|
|
7
|
+
// registry-build. api-key + webhook-secret are backing:"secrets".
|
|
8
|
+
export const DODO_API_KEY_CONFIG = "api-key" as const;
|
|
9
|
+
export const DODO_WEBHOOK_SECRET_CONFIG = "webhook-secret" as const;
|
|
10
|
+
export const DODO_BILLING_LIVE_CONFIG = "billingLive" as const;
|
|
11
|
+
export const DODO_ENVIRONMENT_CONFIG = "environment" as const;
|
|
12
|
+
|
|
13
|
+
// Separate from billingLive on purpose: staging runs Dodo's test API with
|
|
14
|
+
// billingLive on, production flips both.
|
|
15
|
+
export const DodoEnvironments = {
|
|
16
|
+
test: "test",
|
|
17
|
+
live: "live",
|
|
18
|
+
} as const;
|
|
19
|
+
export type DodoEnvironment = (typeof DodoEnvironments)[keyof typeof DodoEnvironments];
|
|
20
|
+
|
|
21
|
+
export const DODO_BASE_URLS: Readonly<Record<DodoEnvironment, string>> = {
|
|
22
|
+
test: "https://test.dodopayments.com",
|
|
23
|
+
live: "https://live.dodopayments.com",
|
|
24
|
+
};
|