@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
|
@@ -6,5 +6,5 @@ export type SwitchTenantMfaGateData = {
|
|
|
6
6
|
} | NonNullable<Awaited<ReturnType<typeof gateEnforceMfa>>>;
|
|
7
7
|
export declare function createSwitchTenantMfaGateHandler(opts: Pick<LoginHandlerOptions, "mfaStatusChecker">): import("@cosmicdrift/kumiko-types/define-handler").WriteHandlerDefinition<"switch-tenant-mfa-gate", z.ZodObject<{
|
|
8
8
|
userId: z.ZodString;
|
|
9
|
-
tenantId: z.
|
|
9
|
+
tenantId: z.ZodString;
|
|
10
10
|
}, z.core.$strip>, SwitchTenantMfaGateData, import("@cosmicdrift/kumiko-types/event-type-map").KumikoEventTypeMap, undefined>;
|
|
@@ -7,10 +7,7 @@ import { noMembership } from "../errors.js";
|
|
|
7
7
|
import { gateEnforceMfa } from "./login.write.js";
|
|
8
8
|
const SwitchTenantMfaGateSchema = z.object({
|
|
9
9
|
userId: z.string().min(1),
|
|
10
|
-
tenantId: z
|
|
11
|
-
.string()
|
|
12
|
-
.min(1)
|
|
13
|
-
.transform((id) => id),
|
|
10
|
+
tenantId: z.string().min(1),
|
|
14
11
|
});
|
|
15
12
|
// Dispatched by POST /auth/switch-tenant with the system identity. The handler
|
|
16
13
|
// resolves membership and roles itself, so the gate never trusts caller-supplied
|
|
@@ -9,11 +9,11 @@ export { BootstrapPlanError, BootstrapWriteError, bootstrapTenants } from "./boo
|
|
|
9
9
|
export { authEmailPasswordEnvSchema, createAuthEmailPasswordFeature } from "./feature.js";
|
|
10
10
|
export { AuthMailNotificationTypes } from "./mail-notifications.js";
|
|
11
11
|
export { AUTH_SELF_REGISTRATION_FEATURE, createAuthSelfRegistrationToggleFeature, } from "./self-registration-toggle.js";
|
|
12
|
-
// Generic HMAC-signed single-purpose token helpers. Re-exported
|
|
13
|
-
// app-
|
|
14
|
-
// invite-tokens)
|
|
15
|
-
//
|
|
16
|
-
//
|
|
12
|
+
// Generic HMAC-signed single-purpose token helpers. Re-exported so
|
|
13
|
+
// app-specific out-of-band flows (subscriber-confirm, magic-links,
|
|
14
|
+
// invite-tokens) can use the same battle-tested signer/verifier
|
|
15
|
+
// instead of duplicating HMAC logic. The purpose string prevents
|
|
16
|
+
// cross-replay between flows.
|
|
17
17
|
export { signToken, TokenPurpose, verifyToken } from "./signed-token.js";
|
|
18
18
|
export { issueSignupActivation, SIGNUP_ACTIVATION_NOTIFICATION_TYPE, } from "./signup-activation.js";
|
|
19
19
|
export { invalidateExistingSignupToken, normalizeEmail, SIGNUP_TOKEN_KEY_PREFIXES, storeSignupToken, } from "./signup-token-store.js";
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// semantics) live in shared/lockout-counter.ts — this file only wires the
|
|
18
18
|
// account-lockout key prefixes onto it. See that file for why a lock
|
|
19
19
|
// re-arms immediately after expiry, and why a successful login (or the
|
|
20
|
-
// account-unlock magic-link flow
|
|
20
|
+
// account-unlock magic-link flow in
|
|
21
21
|
// handlers/confirm-account-unlock.write.ts) is what resets the streak.
|
|
22
22
|
import { createLockoutCounter } from "../shared/index.js";
|
|
23
23
|
const COUNT_KEY_PREFIX = "kumiko:auth:lockout:count:";
|
|
@@ -8,53 +8,51 @@ export type SeedUserWithPasswordOptions = {
|
|
|
8
8
|
readonly password: string;
|
|
9
9
|
readonly displayName: string;
|
|
10
10
|
readonly locale?: string;
|
|
11
|
-
/**
|
|
11
|
+
/** Global roles — see SeedUserOptions.roles. */
|
|
12
12
|
readonly roles?: readonly string[];
|
|
13
|
-
/** Initial
|
|
14
|
-
* Magic-
|
|
15
|
-
*
|
|
13
|
+
/** Initial emailVerified flag. Defaults to false (the verification flow runs).
|
|
14
|
+
* Magic-link signup sets it to true because clicking the email proves
|
|
15
|
+
* ownership. See SeedUserOptions.emailVerified. */
|
|
16
16
|
readonly emailVerified?: boolean;
|
|
17
17
|
readonly by?: SessionUser;
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
|
-
* Seed a user
|
|
21
|
-
*
|
|
20
|
+
* Seed a user with a plaintext password (hashed with argon2 before insertion).
|
|
21
|
+
* Returns the userId and is idempotent by email.
|
|
22
22
|
*/
|
|
23
23
|
export declare function seedUserWithPassword(db: DbConnection, options: SeedUserWithPasswordOptions, hooks?: SeedTenantHooks): Promise<{
|
|
24
24
|
id: string;
|
|
25
25
|
}>;
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
26
|
+
/** Provisions a fresh tenant, admin user, and membership for self-signup
|
|
27
|
+
* confirmation in one operation. It uses the existing event-store pipeline
|
|
28
|
+
* (as seedAdmin), keeping it consistent with the regular create path:
|
|
29
|
+
* events are written, projections are populated, and MSPs/audit see the
|
|
30
|
+
* new rows.
|
|
31
31
|
*
|
|
32
|
-
* Naming
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* ist als dedizierter Cleanup-PR geplant — disproportional zum Wert
|
|
37
|
-
* innerhalb dieses Sprints, weil alle existing tests berührt würden.
|
|
32
|
+
* Naming note: internally uses `seedTenant` / `seedUser*`; these helpers are
|
|
33
|
+
* production-grade (event-store pipeline), and "seed" is historical because
|
|
34
|
+
* they were first built for tests and bootstrap before being exported as
|
|
35
|
+
* general-purpose helpers.
|
|
38
36
|
*
|
|
39
|
-
* Atomicity:
|
|
40
|
-
* (db.begin(tx => provisionSignupAccount(tx, ...))
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
37
|
+
* Atomicity: runs inside a Drizzle transaction when the caller provides one
|
|
38
|
+
* (db.begin(tx => provisionSignupAccount(tx, ...)); the seed helpers accept
|
|
39
|
+
* DbConnection|DbTx structurally. With a plain DbConnection, the three writes
|
|
40
|
+
* are not atomic; a failure between steps can leave an orphan tenant (tenant
|
|
41
|
+
* without a user → unused row; user without a membership → "no_membership"
|
|
42
|
+
* on first login).
|
|
45
43
|
*
|
|
46
|
-
* Create-only:
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
44
|
+
* Create-only: if a user with this email already exists (from seeding or an
|
|
45
|
+
* earlier signup), the function throws a ConflictError BEFORE creating a
|
|
46
|
+
* tenant. The self-signup path must not silently reuse an existing user —
|
|
47
|
+
* otherwise the confirmation step could mint a session for that user
|
|
48
|
+
* (account takeover). `seedUser` itself remains idempotent and add-only
|
|
49
|
+
* (for bootstrap/tests); the create-only guarantee belongs here.
|
|
50
|
+
* The caller resolves tenantKey collisions via generateUniqueName. */
|
|
53
51
|
/** Default membership roles for self-signup tenant owners. Shared between
|
|
54
|
-
* provisionSignupAccount (DB
|
|
55
|
-
* (SessionUser
|
|
56
|
-
*
|
|
57
|
-
*
|
|
52
|
+
* provisionSignupAccount (DB write) and signup-confirm-handler
|
|
53
|
+
* (SessionUser construction for JWT minting); otherwise two locations would
|
|
54
|
+
* independently hardcode "TenantAdmin" and a refactor could cause a role
|
|
55
|
+
* mismatch between the database and the session. */
|
|
58
56
|
export declare const INITIAL_SIGNUP_ROLES: readonly ["TenantAdmin", "Admin"];
|
|
59
57
|
export type ProvisionSignupAccountOptions = {
|
|
60
58
|
readonly email: string;
|
|
@@ -75,20 +73,19 @@ export type SeedAdminOptions = {
|
|
|
75
73
|
readonly email: string;
|
|
76
74
|
readonly password: string;
|
|
77
75
|
readonly displayName: string;
|
|
78
|
-
/** Tenants
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* Rollen-Listen zeigt. */
|
|
76
|
+
/** Tenants where the admin is added as a member. Each tenant can have
|
|
77
|
+
* its own role list, which lets the sample TenantSwitcher show different
|
|
78
|
+
* role lists for each tenant. */
|
|
82
79
|
readonly memberships: ReadonlyArray<{
|
|
83
80
|
readonly tenantId: TenantId;
|
|
84
81
|
readonly tenantKey: string;
|
|
85
82
|
readonly tenantName: string;
|
|
86
83
|
readonly roles: readonly string[];
|
|
87
84
|
}>;
|
|
88
|
-
/**
|
|
89
|
-
*
|
|
90
|
-
* membership
|
|
91
|
-
*
|
|
85
|
+
/** Global roles stored in users.roles, independent of the tenant.
|
|
86
|
+
* The login handler merges them into every session alongside the tenant
|
|
87
|
+
* membership roles. Typical use case: `["SystemAdmin"]` for a platform
|
|
88
|
+
* operator. Default: empty. */
|
|
92
89
|
readonly globalRoles?: readonly string[];
|
|
93
90
|
/** Initial emailVerified state — defaults to false (unverified). Same
|
|
94
91
|
* mechanism as seedUserWithPassword.emailVerified. Re-running the seed
|
|
@@ -98,9 +95,9 @@ export type SeedAdminOptions = {
|
|
|
98
95
|
readonly by?: SessionUser;
|
|
99
96
|
};
|
|
100
97
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* persistent-DB
|
|
98
|
+
* Seeding convenience for sample servers: an admin user with a hashed
|
|
99
|
+
* password, N tenants, and N memberships. Idempotent, so rerunning it in
|
|
100
|
+
* persistent-DB mode succeeds. Returns the userId.
|
|
104
101
|
*/
|
|
105
102
|
export declare function seedAdmin(db: DbConnection, options: SeedAdminOptions): Promise<{
|
|
106
103
|
id: string;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
// Stable seeding helpers
|
|
2
|
-
// `/seeding`
|
|
3
|
-
// non-test code
|
|
4
|
-
// Test-
|
|
5
|
-
// race-conditions)
|
|
6
|
-
//
|
|
1
|
+
// Stable seeding helpers for the auth-email-password feature. They live under
|
|
2
|
+
// `/seeding` rather than `/testing` to make the contract clear: this is
|
|
3
|
+
// non-test code that runs on every dev boot and integration test.
|
|
4
|
+
// Test-specific variations (account-locked setup, expired-token,
|
|
5
|
+
// race-conditions) are NOT added as options to these helpers —
|
|
6
|
+
// they belong in separate functions or inline in the test file.
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
// 1. argon2
|
|
10
|
-
// 2. seedUser()
|
|
11
|
-
// 3. seedTenant + seedTenantMembership
|
|
12
|
-
//
|
|
13
|
-
//
|
|
8
|
+
// Bundles three steps into one call:
|
|
9
|
+
// 1. argon2 hash of the plaintext password
|
|
10
|
+
// 2. seedUser() from user/seeding
|
|
11
|
+
// 3. seedTenant + seedTenantMembership from tenant/seeding
|
|
12
|
+
// This keeps sample servers and tests from having to assemble three
|
|
13
|
+
// sub-paths themselves.
|
|
14
14
|
import { configuredBlindIndexKey, configuredPiiSubjectKms, decryptPiiFieldValues, } from "@cosmicdrift/kumiko-framework/crypto";
|
|
15
15
|
import { fetchOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
16
16
|
import { ConflictError } from "@cosmicdrift/kumiko-framework/errors";
|
|
@@ -24,21 +24,21 @@ import { USER_STATUS, userTable } from "../user/schema/user.js";
|
|
|
24
24
|
// kumiko-lint-ignore cross-feature-import auth-tests need user+tenant seed-helpers
|
|
25
25
|
import { reconcileSeededUserEmailVerified, rewriteSeededUserEmail, seedUser, } from "../user/seeding.js";
|
|
26
26
|
const log = createFallbackLogger("auth-email-password-seeding");
|
|
27
|
-
// Re-export
|
|
28
|
-
//
|
|
29
|
-
// password + tenant + membership"
|
|
30
|
-
//
|
|
27
|
+
// Re-export for a convenient single import site in tests/seed-scripts.
|
|
28
|
+
// The auth feature is the natural caller for "seed admin user with
|
|
29
|
+
// password + tenant + membership", so consumers do not need to assemble
|
|
30
|
+
// these helpers from three different sub-paths.
|
|
31
31
|
// kumiko-lint-ignore cross-feature-import re-export of test-helpers
|
|
32
32
|
export { seedTenant, seedTenantMembership } from "../tenant/seeding.js";
|
|
33
33
|
// kumiko-lint-ignore cross-feature-import re-export of test-helpers
|
|
34
34
|
export { seedUser } from "../user/seeding.js";
|
|
35
35
|
/**
|
|
36
|
-
* Seed a user
|
|
37
|
-
*
|
|
36
|
+
* Seed a user with a plaintext password (hashed with argon2 before insertion).
|
|
37
|
+
* Returns the userId and is idempotent by email.
|
|
38
38
|
*/
|
|
39
39
|
export async function seedUserWithPassword(db, options,
|
|
40
40
|
// Optional, append-only — same rationale as provisionSignupAccount's
|
|
41
|
-
// hooks param
|
|
41
|
+
// hooks param: the self-signup path passes it through so `user`'s
|
|
42
42
|
// postSave hooks fire on self-signup same as on the regular create path.
|
|
43
43
|
hooks) {
|
|
44
44
|
const passwordHash = await hashPassword(options.password);
|
|
@@ -52,54 +52,52 @@ hooks) {
|
|
|
52
52
|
...(options.by !== undefined && { by: options.by }),
|
|
53
53
|
}, hooks);
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
55
|
+
/** Provisions a fresh tenant, admin user, and membership for self-signup
|
|
56
|
+
* confirmation in one operation. It uses the existing event-store pipeline
|
|
57
|
+
* (as seedAdmin), keeping it consistent with the regular create path:
|
|
58
|
+
* events are written, projections are populated, and MSPs/audit see the
|
|
59
|
+
* new rows.
|
|
60
60
|
*
|
|
61
|
-
* Naming
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* ist als dedizierter Cleanup-PR geplant — disproportional zum Wert
|
|
66
|
-
* innerhalb dieses Sprints, weil alle existing tests berührt würden.
|
|
61
|
+
* Naming note: internally uses `seedTenant` / `seedUser*`; these helpers are
|
|
62
|
+
* production-grade (event-store pipeline), and "seed" is historical because
|
|
63
|
+
* they were first built for tests and bootstrap before being exported as
|
|
64
|
+
* general-purpose helpers.
|
|
67
65
|
*
|
|
68
|
-
* Atomicity:
|
|
69
|
-
* (db.begin(tx => provisionSignupAccount(tx, ...))
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
66
|
+
* Atomicity: runs inside a Drizzle transaction when the caller provides one
|
|
67
|
+
* (db.begin(tx => provisionSignupAccount(tx, ...)); the seed helpers accept
|
|
68
|
+
* DbConnection|DbTx structurally. With a plain DbConnection, the three writes
|
|
69
|
+
* are not atomic; a failure between steps can leave an orphan tenant (tenant
|
|
70
|
+
* without a user → unused row; user without a membership → "no_membership"
|
|
71
|
+
* on first login).
|
|
74
72
|
*
|
|
75
|
-
* Create-only:
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
73
|
+
* Create-only: if a user with this email already exists (from seeding or an
|
|
74
|
+
* earlier signup), the function throws a ConflictError BEFORE creating a
|
|
75
|
+
* tenant. The self-signup path must not silently reuse an existing user —
|
|
76
|
+
* otherwise the confirmation step could mint a session for that user
|
|
77
|
+
* (account takeover). `seedUser` itself remains idempotent and add-only
|
|
78
|
+
* (for bootstrap/tests); the create-only guarantee belongs here.
|
|
79
|
+
* The caller resolves tenantKey collisions via generateUniqueName. */
|
|
82
80
|
/** Default membership roles for self-signup tenant owners. Shared between
|
|
83
|
-
* provisionSignupAccount (DB
|
|
84
|
-
* (SessionUser
|
|
85
|
-
*
|
|
86
|
-
*
|
|
81
|
+
* provisionSignupAccount (DB write) and signup-confirm-handler
|
|
82
|
+
* (SessionUser construction for JWT minting); otherwise two locations would
|
|
83
|
+
* independently hardcode "TenantAdmin" and a refactor could cause a role
|
|
84
|
+
* mismatch between the database and the session. */
|
|
87
85
|
// TenantAdmin is the canonical owner role; Admin stays for handlers that still
|
|
88
86
|
// gate on the legacy literal until those call sites move to access.admin.
|
|
89
87
|
export const INITIAL_SIGNUP_ROLES = ["TenantAdmin", "Admin"];
|
|
90
88
|
export async function provisionSignupAccount(db, options,
|
|
91
89
|
// Optional, append-only — existing callers (tests, seed scripts) that
|
|
92
90
|
// don't pass hooks keep today's behavior. The real signup-confirm
|
|
93
|
-
// handler DOES pass it
|
|
91
|
+
// handler DOES pass it so seedTenant/seedUserWithPassword/
|
|
94
92
|
// seedTenantMembership's postSave hooks (tier-engine's auto-default-tier,
|
|
95
93
|
// app auto-default-compliance, a Welcome-notification hook, ...) fire on
|
|
96
94
|
// self-signup for all three entities, same as they do on the regular
|
|
97
|
-
// create paths
|
|
95
|
+
// create paths — this was only wired for tenant before.
|
|
98
96
|
hooks) {
|
|
99
97
|
// Create-only guard BEFORE seedTenant: hard-abort on an already-registered
|
|
100
98
|
// email, otherwise an orphaned tenant would be created and seedUser
|
|
101
99
|
// (idempotent add-only) would silently return the existing userId ->
|
|
102
|
-
// confirm mints a session for the wrong account
|
|
100
|
+
// confirm mints a session for the wrong account.
|
|
103
101
|
// isDeleted: false — the partial bidx unique index only covers live rows,
|
|
104
102
|
// so a soft-deleted row must not block re-registering its email.
|
|
105
103
|
const existingUser = await fetchOne(db, userTable, { email: options.email, isDeleted: false });
|
|
@@ -126,9 +124,9 @@ hooks) {
|
|
|
126
124
|
return { userId, tenantId: options.tenantId };
|
|
127
125
|
}
|
|
128
126
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* persistent-DB
|
|
127
|
+
* Seeding convenience for sample servers: an admin user with a hashed
|
|
128
|
+
* password, N tenants, and N memberships. Idempotent, so rerunning it in
|
|
129
|
+
* persistent-DB mode succeeds. Returns the userId.
|
|
132
130
|
*/
|
|
133
131
|
export async function seedAdmin(db, options) {
|
|
134
132
|
const by = options.by ?? TestUsers.systemAdmin;
|
|
@@ -57,14 +57,14 @@ export async function deleteSignupToken(redis, args) {
|
|
|
57
57
|
/** Burn release for failed-confirm paths (DB error etc.) so a legitimate
|
|
58
58
|
* retry isn't blocked by a stale burn marker. */
|
|
59
59
|
export const unburnSignupToken = store.unburn;
|
|
60
|
-
// Cross-device try-first handover
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
60
|
+
// Cross-device try-first handover:
|
|
61
|
+
// signup-request binds a verified tenant-handover grant to its own signup token,
|
|
62
|
+
// in a SIBLING Redis namespace keyed the same way (sha256(token)) so it stays
|
|
63
|
+
// byte-compatible with the token store above without going through it — the
|
|
64
|
+
// binding has its own lifecycle (survives a resend, is read once by
|
|
65
|
+
// signup-confirm) that doesn't fit the token↔email pairing. Only
|
|
66
|
+
// {entityType, rowId, sourceTenantId} is ever stored — never the grant token
|
|
67
|
+
// or the email (see shared/signup-handover.ts).
|
|
68
68
|
const SIGNUP_HANDOVER_KEY_PREFIX = "signup:handover:";
|
|
69
69
|
const signupHandoverBindingSchema = z.object({
|
|
70
70
|
entityType: z.string().min(1),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// /testing re-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// /testing re-exports /seeding. See ../tenant/testing.ts for the reason:
|
|
2
|
+
// Helpers are shared between tests and Dev-Server bootstrap, so /seeding is
|
|
3
|
+
// the stable home.
|
|
4
4
|
export * from "./seeding.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export type TenantSummary = {
|
|
2
2
|
readonly tenantId: string;
|
|
3
3
|
readonly roles: readonly string[];
|
|
4
|
-
/** Display
|
|
5
|
-
*
|
|
4
|
+
/** Display name from /auth/tenants; absent only for app-owned membership
|
|
5
|
+
* queries without tenantName enrichment. */
|
|
6
6
|
readonly name?: string;
|
|
7
7
|
readonly key?: string;
|
|
8
8
|
};
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
// Browser-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// Browser-side wrappers around /api/auth/* using cookie transport: the JWT
|
|
2
|
+
// lives in the HttpOnly kumiko_auth cookie, while the Double-Submit CSRF
|
|
3
|
+
// token lives in the JS-readable kumiko_csrf cookie. Every state-changing
|
|
4
|
+
// request echoes the CSRF token via X-CSRF-Token; otherwise the server
|
|
5
|
+
// rejects it with csrf_token_missing.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// nicht divergieren.
|
|
7
|
+
// dispatcher-live uses the same readCsrfToken helper; reusing it here keeps
|
|
8
|
+
// the cookie and header constants from diverging.
|
|
10
9
|
import { parseRoles } from "@cosmicdrift/kumiko-framework/utils";
|
|
11
10
|
import { CSRF_HEADER_NAME, readCsrfToken } from "@cosmicdrift/kumiko-renderer/live";
|
|
12
11
|
export function csrfHeader() {
|
|
@@ -70,8 +69,8 @@ export async function login(req) {
|
|
|
70
69
|
return { kind: "success", data: toLoginResponse(body.token, body.user, body.landingPath) };
|
|
71
70
|
}
|
|
72
71
|
}
|
|
73
|
-
//
|
|
74
|
-
//
|
|
72
|
+
// The server sends error either as a string ("invalid_body") or as a
|
|
73
|
+
// structured object. Extract the most descriptive reason.
|
|
75
74
|
const err = body.error;
|
|
76
75
|
if (typeof err === "string") {
|
|
77
76
|
return { kind: "failure", error: { reason: err } };
|
|
@@ -87,10 +86,10 @@ export async function login(req) {
|
|
|
87
86
|
},
|
|
88
87
|
};
|
|
89
88
|
}
|
|
90
|
-
// POST /api/auth/logout.
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
//
|
|
89
|
+
// POST /api/auth/logout. The server revokes the session when
|
|
90
|
+
// sessionRevoker is wired and clears the cookies. A navigation refresh
|
|
91
|
+
// afterward ensures that all caches (React state, query cache) return to
|
|
92
|
+
// an unauthenticated state—the simplest way to restore a clean baseline.
|
|
94
93
|
export async function logout() {
|
|
95
94
|
await fetch("/api/auth/logout", {
|
|
96
95
|
method: "POST",
|
|
@@ -98,11 +97,11 @@ export async function logout() {
|
|
|
98
97
|
headers: { "Content-Type": "application/json", ...csrfHeader() },
|
|
99
98
|
});
|
|
100
99
|
}
|
|
101
|
-
// 4xx/5xx
|
|
102
|
-
//
|
|
100
|
+
// Parse 4xx/5xx responses into AuthTokenFailure. 429 uses a dedicated
|
|
101
|
+
// reason so the UI can display a retry hint.
|
|
103
102
|
async function parseTokenFailure(res) {
|
|
104
103
|
if (res.status === 429) {
|
|
105
|
-
// @cast-boundary engine-payload — server
|
|
104
|
+
// @cast-boundary engine-payload — the server sends details.retryAfterSeconds for 429
|
|
106
105
|
const body = (await res.json().catch(() => ({})));
|
|
107
106
|
const retry = body.error?.details?.retryAfterSeconds;
|
|
108
107
|
return { reason: "rate_limited", ...(retry !== undefined && { retryAfterSeconds: retry }) };
|
|
@@ -127,11 +126,12 @@ export async function requestPasswordReset(email) {
|
|
|
127
126
|
return { ok: true };
|
|
128
127
|
return { ok: false, error: await parseTokenFailure(res) };
|
|
129
128
|
}
|
|
130
|
-
// POST /api/auth/reset-password.
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
129
|
+
// POST /api/auth/reset-password. The token comes from the URL and the
|
|
130
|
+
// request includes the new password. On 422, the server collapses all
|
|
131
|
+
// token-verification errors (malformed, bad signature, expired) into the
|
|
132
|
+
// single code `invalid_reset_token` to prevent enumeration. Zod validation
|
|
133
|
+
// failures (newPassword < 8) use a separate 4xx code, "validation_failed".
|
|
134
|
+
// The UI maps reason to an i18n key.
|
|
135
135
|
export async function resetPassword(token, newPassword) {
|
|
136
136
|
const res = await fetch("/api/auth/reset-password", {
|
|
137
137
|
method: "POST",
|
|
@@ -156,9 +156,9 @@ export async function requestEmailVerification(email) {
|
|
|
156
156
|
return { ok: true };
|
|
157
157
|
return { ok: false, error: await parseTokenFailure(res) };
|
|
158
158
|
}
|
|
159
|
-
// POST /api/auth/verify-email.
|
|
160
|
-
//
|
|
161
|
-
// `invalid_verification_token`
|
|
159
|
+
// POST /api/auth/verify-email. VerifyEmailScreen submits this automatically
|
|
160
|
+
// after parsing `?token=...`. The server collapses all verification failures
|
|
161
|
+
// into `invalid_verification_token` to prevent enumeration, as with reset.
|
|
162
162
|
export async function verifyEmail(token) {
|
|
163
163
|
const res = await fetch("/api/auth/verify-email", {
|
|
164
164
|
method: "POST",
|
|
@@ -199,14 +199,13 @@ export async function confirmAccountUnlock(token) {
|
|
|
199
199
|
return { ok: true };
|
|
200
200
|
return { ok: false, error: await parseTokenFailure(res) };
|
|
201
201
|
}
|
|
202
|
-
// POST /api/auth/signup-request. Always
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
//
|
|
202
|
+
// POST /api/auth/signup-request. Always returns 200 to prevent enumeration;
|
|
203
|
+
// the response does not reveal whether the email is already registered. The
|
|
204
|
+
// server sends an activation email to the address; following its link takes
|
|
205
|
+
// the user to /signup/complete?token=… to set a password.
|
|
206
206
|
export async function requestSignup(email,
|
|
207
|
-
// Cross-device try-first handover
|
|
208
|
-
//
|
|
209
|
-
// server can verify + rebind it to the signup token. The grant never
|
|
207
|
+
// Cross-device try-first handover: forwards a row-bound tenant-handover
|
|
208
|
+
// grant so the server can verify + rebind it to the signup token. The grant never
|
|
210
209
|
// travels any further than this request — never in the URL, the mail,
|
|
211
210
|
// or the confirm response.
|
|
212
211
|
handover) {
|
|
@@ -243,8 +242,8 @@ export async function confirmSignup(token, password) {
|
|
|
243
242
|
}
|
|
244
243
|
return { ok: false, error: await parseTokenFailure(res) };
|
|
245
244
|
}
|
|
246
|
-
// GET /api/auth/tenants.
|
|
247
|
-
//
|
|
245
|
+
// GET /api/auth/tenants. Returns the current user's memberships; the server
|
|
246
|
+
// returns 401 when the cookie is missing or expired.
|
|
248
247
|
export async function fetchTenants() {
|
|
249
248
|
const res = await fetch("/api/auth/tenants", {
|
|
250
249
|
method: "GET",
|
|
@@ -258,9 +257,9 @@ export async function fetchTenants() {
|
|
|
258
257
|
// @cast-boundary engine-payload — HTTP-API contract, server-side schema-validated
|
|
259
258
|
return (await res.json());
|
|
260
259
|
}
|
|
261
|
-
// POST /api/auth/switch-tenant.
|
|
262
|
-
//
|
|
263
|
-
//
|
|
260
|
+
// POST /api/auth/switch-tenant. Mints a new JWT for the target tenant and
|
|
261
|
+
// rotates both cookies. Returns 400 for already_in_tenant or
|
|
262
|
+
// tenant_switch_not_available, and 403 for not_a_member.
|
|
264
263
|
export async function switchTenant(tenantId) {
|
|
265
264
|
const res = await fetch("/api/auth/switch-tenant", {
|
|
266
265
|
method: "POST",
|
|
@@ -25,21 +25,21 @@ export function useAuthShell() {
|
|
|
25
25
|
export function AuthCard({ title, subtitle, className, headerClassName, titleClassName, bodyClassName, children, }) {
|
|
26
26
|
const { Card } = usePrimitives();
|
|
27
27
|
const shell = useAuthShell() ?? defaultAuthShell;
|
|
28
|
-
// h1 (
|
|
29
|
-
//
|
|
28
|
+
// Keep an h1 (page heading) through the header slot; the Card's default
|
|
29
|
+
// header would be h3. padded:false keeps the form edge-to-edge as before
|
|
30
|
+
// (bare form).
|
|
30
31
|
const card = (_jsx(Card, { className: cn("w-full max-w-sm", className), options: { padded: false }, slots: {
|
|
31
32
|
header: title !== undefined || subtitle !== undefined ? (_jsxs("div", { className: cn("flex flex-col space-y-1.5 p-6 pb-4", headerClassName), children: [title !== undefined && (_jsx("h1", { className: cn("text-xl font-semibold tracking-tight", titleClassName), children: title })), subtitle !== undefined && (_jsx("p", { className: "text-sm text-muted-foreground", children: subtitle }))] })) : undefined,
|
|
32
33
|
}, children: _jsx(BareFormProvider, { children: _jsx("div", { className: cn("p-6 pt-0 flex flex-col gap-4", bodyClassName), children: children }) }) }));
|
|
33
34
|
return shell(card);
|
|
34
35
|
}
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
// Browser nicht da ist (SSR-safety) oder der Parameter fehlt.
|
|
36
|
+
// Reads `?<paramName>=<value>` from the current URL, as used by token-bearing
|
|
37
|
+
// pages (reset, verify). Returns "" during SSR or when the parameter is absent.
|
|
38
38
|
//
|
|
39
|
-
//
|
|
40
|
-
// pattern
|
|
41
|
-
//
|
|
42
|
-
//
|
|
39
|
+
// This is intentionally not read through useState/useEffect: that would be a
|
|
40
|
+
// read-once-on-mount pattern, while URL changes are irrelevant here because
|
|
41
|
+
// token pages reload for new tokens. Callers can use
|
|
42
|
+
// useState(() => parseUrlToken(...)) when needed.
|
|
43
43
|
export function parseUrlToken(paramName = "token") {
|
|
44
44
|
if (typeof window === "undefined")
|
|
45
45
|
return "";
|
|
@@ -47,7 +47,7 @@ export function parseUrlToken(paramName = "token") {
|
|
|
47
47
|
}
|
|
48
48
|
// Reads the magic-link token from `?<paramName>=` once on mount, then strips
|
|
49
49
|
// that param from the URL via history.replaceState so the single-use token
|
|
50
|
-
// doesn't linger in browser history / Referer
|
|
50
|
+
// doesn't linger in browser history / Referer. An explicit `override`
|
|
51
51
|
// (server-injected token) short-circuits both the URL read and the scrub.
|
|
52
52
|
export function useUrlToken(override, paramName = "token") {
|
|
53
53
|
const [token] = useState(() => override ?? parseUrlToken(paramName));
|