@cosmicdrift/kumiko-samples 0.385.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/README.md +1 -1
- package/package.json +2 -2
- package/packages/bundled-features/package.json +2 -2
- package/packages/bundled-features/src/agent-tools/tool-catalog.ts +1 -1
- package/packages/bundled-features/src/agent-tools/tool-dispatch.ts +0 -2
- 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/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 +3 -3
- 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-verify-screen.tsx +6 -6
- package/packages/bundled-features/src/billing-foundation/aggregate-id.ts +10 -11
- package/packages/bundled-features/src/billing-foundation/entities.ts +27 -27
- package/packages/bundled-features/src/billing-foundation/events.ts +22 -21
- package/packages/bundled-features/src/billing-foundation/feature.ts +42 -43
- package/packages/bundled-features/src/billing-foundation/get-subscription-for-tenant.ts +3 -5
- package/packages/bundled-features/src/billing-foundation/handlers/create-checkout-session.write.ts +18 -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/process-event.write.ts +20 -20
- 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 +64 -65
- package/packages/bundled-features/src/billing-foundation/web/billing-plans-panel.tsx +4 -4
- 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/constants.ts +11 -12
- package/packages/bundled-features/src/cap-counter/enforce-cap.ts +64 -67
- 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 +1 -1
- 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/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/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/resolver.ts +4 -4
- package/packages/bundled-features/src/config/table.ts +10 -10
- package/packages/bundled-features/src/config/write-helpers.ts +1 -1
- package/packages/bundled-features/src/crypto-shredding/handlers/forget-subject.write.ts +13 -12
- 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/feature.ts +3 -3
- package/packages/bundled-features/src/delivery/handlers/log.query.ts +1 -1
- package/packages/bundled-features/src/delivery/tables.ts +9 -8
- package/packages/bundled-features/src/delivery/unsubscribe.ts +4 -4
- 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-provider-inmemory/feature.ts +16 -16
- 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/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/db/queries/cleanup.ts +1 -1
- package/packages/bundled-features/src/form-draft/db/queries/owned-file-refs.ts +1 -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/inbound-mail-foundation/aggregate-id.ts +19 -19
- 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 +11 -11
- 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/tenant-destroy-hook.ts +14 -16
- package/packages/bundled-features/src/inbound-mail-foundation/types.ts +66 -67
- package/packages/bundled-features/src/inbound-mail-foundation/watch-supervisor.ts +69 -68
- 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/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 +6 -7
- 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/job-instant.ts +1 -1
- package/packages/bundled-features/src/jobs/job-run-logger.ts +14 -15
- 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/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/feature.ts +26 -27
- 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 +5 -5
- 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/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 +9 -9
- 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 +1 -1
- package/packages/bundled-features/src/shared/encrypt-for-direct-write.ts +1 -1
- 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/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/constants.ts +4 -6
- package/packages/bundled-features/src/subscription-stripe/feature.ts +44 -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 +2 -2
- 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 +10 -10
- package/packages/bundled-features/src/template-resolver/handlers/find-by-id.query.ts +5 -5
- package/packages/bundled-features/src/template-resolver/handlers/list.query.ts +1 -1
- 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/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/seeding.ts +4 -4
- package/packages/bundled-features/src/template-resolver/table.ts +13 -14
- package/packages/bundled-features/src/template-resolver/web/client-plugin.tsx +2 -2
- package/packages/bundled-features/src/tenant/feature.ts +7 -7
- package/packages/bundled-features/src/tenant/handlers/member-directory.query.ts +1 -1
- 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 +1 -1
- 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/feature.ts +1 -1
- package/packages/bundled-features/src/tenant-lifecycle/run-tenant-destroy.ts +2 -2
- 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/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 +8 -8
- 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/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 +166 -276
- package/packages/bundled-features/src/user-data-rights/run-forget-cleanup.ts +85 -107
- 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/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
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
// ResetPasswordScreen
|
|
2
|
-
// new
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// ResetPasswordScreen reads `?token=...` from the URL and shows fields for
|
|
2
|
+
// a new and confirmed password. Submission calls /api/auth/reset-password
|
|
3
|
+
// with the token. The server collapses all token-verification failures into
|
|
4
|
+
// one code (anti-enumeration), so the UI shows the unified "link invalid or
|
|
5
|
+
// expired" message.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// durch — dann bleibt die URL unangetastet.
|
|
7
|
+
// The token is read once via useUrlToken(): `?token=...` is read on mount and
|
|
8
|
+
// then scrubbed from the URL. Apps that need different behavior can pass a
|
|
9
|
+
// server-injected token through the `token` prop; the URL is then left intact.
|
|
11
10
|
|
|
12
11
|
import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
13
12
|
import { type FormEvent, type ReactNode, useState } from "react";
|
|
@@ -17,11 +16,11 @@ import { AuthCard, useUrlToken } from "./auth-form-primitives.tsx";
|
|
|
17
16
|
|
|
18
17
|
export type ResetPasswordScreenProps = {
|
|
19
18
|
readonly title?: string;
|
|
20
|
-
/** Override
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
/** Override for the token from the URL. Apps that pass a token during
|
|
20
|
+
* server-side rendering need this. Default: parsed from `?token=...` in
|
|
21
|
+
* the URL. */
|
|
23
22
|
readonly token?: string;
|
|
24
|
-
/** href
|
|
23
|
+
/** href for the "Zum Login" link after success. Default "/login". */
|
|
25
24
|
readonly loginHref?: string;
|
|
26
25
|
};
|
|
27
26
|
|
|
@@ -75,10 +74,10 @@ export function ResetPasswordScreen({
|
|
|
75
74
|
|
|
76
75
|
const effectiveTitle = title ?? t("auth.resetPassword.title");
|
|
77
76
|
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
//
|
|
77
|
+
// No token in the URL: the user should click the link from their email again
|
|
78
|
+
// or request a new reset. Submitting without a token would only show the
|
|
79
|
+
// invalidResetToken error, which is confusing, so show a clear message
|
|
80
|
+
// immediately instead.
|
|
82
81
|
if (token === "") {
|
|
83
82
|
return (
|
|
84
83
|
<AuthCard title={effectiveTitle}>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// Session
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Session state for the browser renderer. Holds the currently signed-in
|
|
2
|
+
// user (profile + active tenant assignment + memberships), responds to
|
|
3
|
+
// login/logout/tenant switching, and refreshes the data automatically.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
5
|
+
// Context + useReducer is used instead of, for example, Zustand because
|
|
6
|
+
// the state is small (a handful of fields and a few transitions), avoiding
|
|
7
|
+
// another dependency in the browser bundle. Consumers live under
|
|
8
|
+
// `<SessionProvider>`; the `useSession()` hook provides the state
|
|
9
|
+
// and transitions.
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
type CurrentUser,
|
|
@@ -50,11 +50,12 @@ export type SessionState = {
|
|
|
50
50
|
readonly user: CurrentUserProfile | null;
|
|
51
51
|
readonly activeTenantId: string | null;
|
|
52
52
|
readonly tenants: readonly TenantSummary[];
|
|
53
|
-
/** Merged session
|
|
54
|
-
* SystemAdmin)
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* tenants[active].roles
|
|
53
|
+
/** Merged session roles for the active tenant: globalRoles (for example,
|
|
54
|
+
* SystemAdmin) plus the active tenant's membership roles. The server has
|
|
55
|
+
* already merged them into the JWT, but the JWT is HttpOnly and cannot be
|
|
56
|
+
* read by JavaScript; the client computes the same merge from
|
|
57
|
+
* user.globalRoles + tenants[active].roles so navigation filtering works.
|
|
58
|
+
* The result is deduplicated. */
|
|
58
59
|
readonly roles: readonly string[];
|
|
59
60
|
readonly bootstrapFailure: SessionBootstrapFailure | null;
|
|
60
61
|
/** Set when an authenticated session was ended server-side (revoked,
|
|
@@ -97,15 +98,15 @@ const INITIAL: SessionState = {
|
|
|
97
98
|
signedOutReason: null,
|
|
98
99
|
};
|
|
99
100
|
|
|
100
|
-
// kumiko_auth
|
|
101
|
+
// kumiko_auth is HttpOnly; kumiko_csrf is set together with it at login.
|
|
101
102
|
export function hasLikelyAuthSession(cookieSource?: string): boolean {
|
|
102
103
|
return readCsrfToken(cookieSource) !== undefined;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
// Exported
|
|
106
|
-
//
|
|
107
|
-
// login.write.ts
|
|
108
|
-
//
|
|
106
|
+
// Exported so tests can pin the merge path directly: this must be
|
|
107
|
+
// byte-identical to the server-side merge in auth-routes.ts +
|
|
108
|
+
// login.write.ts, otherwise the client sees different session roles
|
|
109
|
+
// from the server.
|
|
109
110
|
export function computeActiveRoles(
|
|
110
111
|
user: CurrentUserProfile | null,
|
|
111
112
|
activeTenantId: string | null,
|
|
@@ -120,14 +121,14 @@ export function computeActiveRoles(
|
|
|
120
121
|
return Array.from(new Set([...user.globalRoles, ...membershipRoles]));
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
/** Internal — exposed
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
124
|
+
/** Internal — exposed so tests can pass a mock SessionApi value
|
|
125
|
+
* without going through SessionProvider's refresh lifecycle. Application
|
|
126
|
+
* code uses SessionProvider + useSession; direct context access is
|
|
127
|
+
* intended for tests/stories. */
|
|
127
128
|
export const SessionContext = createContext<SessionApi | undefined>(undefined);
|
|
128
129
|
|
|
129
|
-
//
|
|
130
|
-
// /user:me.
|
|
130
|
+
// One refresh round: /auth/tenants → if 401, unauthenticated; otherwise
|
|
131
|
+
// /user:me. Together, both requests produce the complete SessionState.
|
|
131
132
|
async function refresh(): Promise<SessionState> {
|
|
132
133
|
if (!hasLikelyAuthSession()) {
|
|
133
134
|
return UNAUTHENTICATED;
|
|
@@ -183,7 +184,7 @@ export function SessionProvider({
|
|
|
183
184
|
}
|
|
184
185
|
}, []);
|
|
185
186
|
|
|
186
|
-
// kumiko-lint-ignore no-raw-hooks
|
|
187
|
+
// kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
|
|
187
188
|
useEffect(() => {
|
|
188
189
|
void doRefresh();
|
|
189
190
|
}, [doRefresh]);
|
|
@@ -191,7 +192,7 @@ export function SessionProvider({
|
|
|
191
192
|
const sessionEndedSignal = useSessionEndedSignal();
|
|
192
193
|
// Only an authenticated session can "end": an anonymous 401 on a public
|
|
193
194
|
// surface must not show the hint.
|
|
194
|
-
// kumiko-lint-ignore no-raw-hooks
|
|
195
|
+
// kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
|
|
195
196
|
useEffect(() => {
|
|
196
197
|
return sessionEndedSignal?.subscribe(() => {
|
|
197
198
|
setState((prev) =>
|
|
@@ -222,10 +223,10 @@ export function SessionProvider({
|
|
|
222
223
|
return;
|
|
223
224
|
}
|
|
224
225
|
setState(UNAUTHENTICATED);
|
|
225
|
-
// Hard
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
//
|
|
226
|
+
// Hard reload: the React tree, dispatcher live caches, and EventSource
|
|
227
|
+
// are all reset. After logout, this is the cheapest way to reach a clean
|
|
228
|
+
// state without having to invalidate every consumer through a context
|
|
229
|
+
// reset.
|
|
229
230
|
if (typeof window !== "undefined") {
|
|
230
231
|
window.location.reload();
|
|
231
232
|
}
|
|
@@ -233,10 +234,9 @@ export function SessionProvider({
|
|
|
233
234
|
|
|
234
235
|
const switchTenant = useCallback<SessionApi["switchTenant"]>(async (tenantId) => {
|
|
235
236
|
await switchTenantApi(tenantId);
|
|
236
|
-
// Tenant
|
|
237
|
-
// tenant-
|
|
238
|
-
//
|
|
239
|
-
// halbe State-Übergänge.
|
|
237
|
+
// Tenant switching rotates the JWT + cookies. The React tree contains
|
|
238
|
+
// tenant-bound caches (queries, live events), so a simple reload is
|
|
239
|
+
// consistent with the logout path and avoids partial state transitions.
|
|
240
240
|
if (typeof window !== "undefined") {
|
|
241
241
|
window.location.reload();
|
|
242
242
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// JWT + cookies (auto-login!) and returns the tenantKey.
|
|
6
6
|
//
|
|
7
7
|
// Token source is read-once via useUrlToken: reads `?token=...` on mount
|
|
8
|
-
// and scrubs the param from the URL afterwards
|
|
8
|
+
// and scrubs the param from the URL afterwards. Apps that inject a
|
|
9
9
|
// server-side token pass `token` as a prop instead.
|
|
10
10
|
//
|
|
11
11
|
// On success: shows a confirmation (account active, signed in) with a
|
|
@@ -117,8 +117,8 @@ export function SignupCompleteScreen({
|
|
|
117
117
|
? t("auth.signupComplete.activatedTitle")
|
|
118
118
|
: t("auth.signupComplete.title"));
|
|
119
119
|
|
|
120
|
-
//
|
|
121
|
-
// (
|
|
120
|
+
// No token in the URL → show a clear message instead of a form without a token
|
|
121
|
+
// (which would only show invalidSignupToken and confuse the user).
|
|
122
122
|
if (token === "") {
|
|
123
123
|
return (
|
|
124
124
|
<AuthCard title={effectiveTitle}>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
// SignupScreen — Magic-Link-
|
|
1
|
+
// SignupScreen — Magic-Link self-signup, Step 1.
|
|
2
2
|
//
|
|
3
|
-
// Form
|
|
4
|
-
// (silent
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// existing
|
|
3
|
+
// Form with an email input. Submission triggers /api/auth/signup-request
|
|
4
|
+
// (silent success, no account enumeration). The UI always shows a
|
|
5
|
+
// "email on its way" confirmation with a Resend button, even if the email
|
|
6
|
+
// is already registered (the server then sends the same email with the
|
|
7
|
+
// existing token from Redis, making the request idempotent).
|
|
8
8
|
//
|
|
9
|
-
//
|
|
10
|
-
// /signup)
|
|
11
|
-
// AuthGate).
|
|
12
|
-
// /signup
|
|
9
|
+
// The app is responsible for mounting the screen at a URL (e.g.
|
|
10
|
+
// /signup) and making it anonymously reachable (AuthPathGate before
|
|
11
|
+
// AuthGate). An apex marketing site can route its "Start for free" link to
|
|
12
|
+
// the /signup path.
|
|
13
13
|
|
|
14
14
|
import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
15
15
|
import { type FormEvent, type ReactNode, useState } from "react";
|
|
@@ -20,7 +20,7 @@ import { AuthCard } from "./auth-form-primitives.tsx";
|
|
|
20
20
|
export type SignupScreenProps = {
|
|
21
21
|
readonly title?: string;
|
|
22
22
|
readonly subtitle?: ReactNode;
|
|
23
|
-
/** href
|
|
23
|
+
/** href for the "Already have an account?" link. App-specific; defaults to
|
|
24
24
|
* "/login". */
|
|
25
25
|
readonly loginHref?: string;
|
|
26
26
|
};
|
|
@@ -67,9 +67,9 @@ export function SignupScreen({
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
const onResend = async (): Promise<void> => {
|
|
70
|
-
// Resend
|
|
71
|
-
//
|
|
72
|
-
//
|
|
70
|
+
// Resend uses the same endpoint: the server returns the existing
|
|
71
|
+
// token from Redis and sends a second email with the SAME
|
|
72
|
+
// activation link, so the old email remains valid.
|
|
73
73
|
setSubmitting(true);
|
|
74
74
|
setError(null);
|
|
75
75
|
try {
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
// TenantSwitcher —
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// TenantSwitcher — compact dropdown showing the active tenant and
|
|
2
|
+
// allowing switches to other memberships. Uses Radix-DropdownMenu for
|
|
3
|
+
// consistent click-outside, Escape, and keyboard-navigation behavior.
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// Switcher).
|
|
5
|
+
// Does NOT render when no user is logged in or when the user has only one
|
|
6
|
+
// tenant (single-tenant apps do not need a switcher).
|
|
8
7
|
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
8
|
+
// The display name comes from the optional `tenantName` prop or falls back
|
|
9
|
+
// to the ID hash. Design decision: TenantSwitcher does NOT fetch
|
|
10
|
+
// tenant:query:me itself, which would cost round trips per mount and
|
|
11
|
+
// require query-caching infrastructure. Instead, the host passes in the
|
|
12
|
+
// resolver (for example, from a useTenantNames() hook loaded once at app
|
|
13
|
+
// boot).
|
|
15
14
|
|
|
16
15
|
import { useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
17
16
|
import {
|
|
@@ -27,10 +26,10 @@ import { type ReactNode, useCallback, useState } from "react";
|
|
|
27
26
|
import { useSession } from "./session.tsx";
|
|
28
27
|
|
|
29
28
|
export type TenantSwitcherProps = {
|
|
30
|
-
/** Optional:
|
|
31
|
-
* Default:
|
|
32
|
-
*
|
|
33
|
-
*
|
|
29
|
+
/** Optional: provides a human-readable name for each tenant ID.
|
|
30
|
+
* Default: displays the ID directly (a short UUID is sufficient for
|
|
31
|
+
* development environments). In production, the host should cache
|
|
32
|
+
* tenant names at login and pass them here. */
|
|
34
33
|
readonly tenantName?: (tenantId: string) => string;
|
|
35
34
|
};
|
|
36
35
|
|
|
@@ -46,28 +45,28 @@ export function TenantSwitcher({ tenantName }: TenantSwitcherProps): ReactNode {
|
|
|
46
45
|
try {
|
|
47
46
|
await switchTenant(tenantId);
|
|
48
47
|
} finally {
|
|
49
|
-
// In
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
48
|
+
// In practice, switchTenant causes a full-page reload, so we never see
|
|
49
|
+
// the cleared state — `finally` only handles the edge case where
|
|
50
|
+
// switchTenant throws, preventing the UI from remaining stuck with
|
|
51
|
+
// the spinner.
|
|
53
52
|
setSwitching(null);
|
|
54
53
|
}
|
|
55
54
|
},
|
|
56
55
|
[activeTenantId, switchTenant],
|
|
57
56
|
);
|
|
58
57
|
|
|
59
|
-
// Label
|
|
60
|
-
// name/key
|
|
61
|
-
//
|
|
58
|
+
// Label priority: app-provided resolver (prop) > server-provided
|
|
59
|
+
// name/key from /auth/tenants > UUID prefix. The latter is only a
|
|
60
|
+
// last resort — it is indistinguishable for seeded tenants (00000000-…).
|
|
62
61
|
const nameOf = (tenantId: string): string => {
|
|
63
62
|
if (tenantName !== undefined) return tenantName(tenantId);
|
|
64
63
|
const membership = tenants.find((m) => m.tenantId === tenantId);
|
|
65
|
-
// ||
|
|
64
|
+
// || instead of ??: an empty name/key string must not be used as a label.
|
|
66
65
|
return membership?.name || membership?.key || tenantId.slice(0, 8);
|
|
67
66
|
};
|
|
68
67
|
|
|
69
|
-
// Rendering
|
|
70
|
-
// (
|
|
68
|
+
// Rendering gate: no user → nothing; only one tenant → nothing as well
|
|
69
|
+
// (single-tenant apps do not need a switcher).
|
|
71
70
|
if (user === null || tenants.length <= 1) return null;
|
|
72
71
|
|
|
73
72
|
const activeLabel =
|
|
@@ -76,7 +75,7 @@ export function TenantSwitcher({ tenantName }: TenantSwitcherProps): ReactNode {
|
|
|
76
75
|
return (
|
|
77
76
|
<DropdownMenu>
|
|
78
77
|
<DropdownMenuTrigger asChild>
|
|
79
|
-
{/* kumiko-lint-ignore primitives-discipline radix-asChild
|
|
78
|
+
{/* kumiko-lint-ignore primitives-discipline radix-asChild requires a DOM element as the trigger; Native has its own .native.tsx variant with ActionSheet */}
|
|
80
79
|
<button
|
|
81
80
|
type="button"
|
|
82
81
|
className={cn(
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// custom permission checks).
|
|
1
|
+
// Reads the logged-in user and roles for the active tenant from the session.
|
|
2
|
+
// This hook is the standard bridge between session state and layout components
|
|
3
|
+
// (WorkspaceShell.user, DefaultAppShell gates, custom permission checks).
|
|
5
4
|
//
|
|
6
|
-
// Returns undefined
|
|
7
|
-
// -
|
|
8
|
-
// -
|
|
9
|
-
// -
|
|
10
|
-
//
|
|
5
|
+
// Returns undefined while:
|
|
6
|
+
// - the session is loading (status="loading")
|
|
7
|
+
// - the user is unauthenticated
|
|
8
|
+
// - activeTenantId is missing from the tenants list (a defensive path that
|
|
9
|
+
// should not occur, but is harmless to check)
|
|
11
10
|
//
|
|
12
|
-
// WorkspaceShell
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
11
|
+
// WorkspaceShell and DefaultAppShell treat undefined as "no workspaces
|
|
12
|
+
// visible", which is the correct UX while loading or logged out. Apps that
|
|
13
|
+
// need more (such as a loading indicator) should check useSession().status
|
|
14
|
+
// directly.
|
|
16
15
|
|
|
17
16
|
import { useMemo } from "react";
|
|
18
17
|
import { useSession } from "./session.tsx";
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
// UserMenu —
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// UserMenu — avatar dropdown for the top bar (variant="pill", default) or the
|
|
2
|
+
// sidebar footer (variant="sidebar" = the sidebar-07-NavUser-Row). Shows
|
|
3
|
+
// name/email and logout. Uses Radix-DropdownMenu so click-outside, Escape,
|
|
4
|
+
// focus management, keyboard navigation (↑↓/Home/End), and ARIA roles work
|
|
5
|
+
// out of the box.
|
|
6
6
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// Fehler entsteht.
|
|
7
|
+
// Renders nothing when no user is logged in, so hosts can mount the component
|
|
8
|
+
// outside AuthGate without causing a hard error.
|
|
10
9
|
|
|
11
10
|
import { useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
12
11
|
import {
|
|
@@ -28,20 +27,20 @@ import { useSession } from "./session.tsx";
|
|
|
28
27
|
export type UserMenuVariant = "pill" | "sidebar";
|
|
29
28
|
|
|
30
29
|
export type UserMenuProps = {
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
30
|
+
/** Additional menu items above logout. The caller controls per-item
|
|
31
|
+
* classes and behavior; this component only provides the surrounding frame. */
|
|
33
32
|
readonly children?: ReactNode;
|
|
34
|
-
/** "pill" (
|
|
35
|
-
*
|
|
33
|
+
/** "pill" (default) = compact top-bar trigger; "sidebar" = full NavUser-
|
|
34
|
+
* row (avatar + name + email) for the App-Shell's `sidebarFooter` slot.
|
|
36
35
|
* Requires a `SidebarProvider` ancestor — the default App-Shell
|
|
37
36
|
* `sidebarFooter` slot already provides one. */
|
|
38
37
|
readonly variant?: UserMenuVariant;
|
|
39
38
|
};
|
|
40
39
|
|
|
41
40
|
function initials(value: string): string {
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
41
|
+
// Uses the first and last name when the display name contains a space;
|
|
42
|
+
// otherwise uses the first two characters of the email local part. This is
|
|
43
|
+
// deterministic, so the avatar content does not change between re-renders.
|
|
45
44
|
const trimmed = value.trim();
|
|
46
45
|
if (trimmed.length === 0) return "?";
|
|
47
46
|
const parts = trimmed.split(/\s+/);
|
|
@@ -84,8 +83,8 @@ export function UserMenu({ children, variant = "pill" }: UserMenuProps): ReactNo
|
|
|
84
83
|
</DropdownMenuContent>
|
|
85
84
|
);
|
|
86
85
|
|
|
87
|
-
// Sidebar
|
|
88
|
-
//
|
|
86
|
+
// Sidebar footer: full NavUser row (sidebar-07) as the dropdown trigger —
|
|
87
|
+
// matches SidebarUser visually while providing clickable logout/profile actions.
|
|
89
88
|
if (variant === "sidebar") {
|
|
90
89
|
return (
|
|
91
90
|
<SidebarMenu>
|
|
@@ -123,7 +122,7 @@ export function UserMenu({ children, variant = "pill" }: UserMenuProps): ReactNo
|
|
|
123
122
|
return (
|
|
124
123
|
<DropdownMenu>
|
|
125
124
|
<DropdownMenuTrigger asChild>
|
|
126
|
-
{/* kumiko-lint-ignore primitives-discipline radix-asChild
|
|
125
|
+
{/* kumiko-lint-ignore primitives-discipline radix-asChild requires a DOM element as the trigger; the native version in .native.tsx uses ActionSheet */}
|
|
127
126
|
<button
|
|
128
127
|
type="button"
|
|
129
128
|
className={cn(
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
// VerifyEmailScreen —
|
|
2
|
-
// /api/auth/verify-email
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// VerifyEmailScreen — reads `?token=...` from the URL and automatically sends it to
|
|
2
|
+
// /api/auth/verify-email on mount, then shows success/error. The server-side
|
|
3
|
+
// operation is idempotent (repeating it sets emailVerified=true again), so
|
|
4
|
+
// retries are safe.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// Banner sehen.
|
|
6
|
+
// The empty-deps effect and once guard prevent React Strict Mode from firing
|
|
7
|
+
// the verification call twice (Strict Mode dispatches useEffect twice in dev).
|
|
8
|
+
// The token roundtrip is single-use server-side, but this avoids showing an
|
|
9
|
+
// invalid-token banner after the first valid mount call.
|
|
11
10
|
|
|
12
11
|
import { usePrimitives, useTranslation } from "@cosmicdrift/kumiko-renderer";
|
|
13
12
|
import { type ReactNode, useEffect, useRef, useState } from "react";
|
|
@@ -16,9 +15,9 @@ import { AuthCard, useUrlToken } from "./auth-form-primitives.tsx";
|
|
|
16
15
|
|
|
17
16
|
export type VerifyEmailScreenProps = {
|
|
18
17
|
readonly title?: string;
|
|
19
|
-
/** Override
|
|
18
|
+
/** Override the token from the URL. Default: parsed from `?token=...`. */
|
|
20
19
|
readonly token?: string;
|
|
21
|
-
/** href
|
|
20
|
+
/** href for the "Zum Login" link. Default "/login". */
|
|
22
21
|
readonly loginHref?: string;
|
|
23
22
|
};
|
|
24
23
|
|
|
@@ -35,7 +34,7 @@ export function VerifyEmailScreen({
|
|
|
35
34
|
const [status, setStatus] = useState<Status>(token === "" ? "missing-token" : "verifying");
|
|
36
35
|
const startedRef = useRef(false);
|
|
37
36
|
|
|
38
|
-
// kumiko-lint-ignore no-raw-hooks
|
|
37
|
+
// kumiko-lint-ignore no-raw-hooks not yet converted to the framework hook set
|
|
39
38
|
useEffect(() => {
|
|
40
39
|
if (status !== "verifying") return;
|
|
41
40
|
if (startedRef.current) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Multiplicity boot-check for auth-foundation's `tokenVerifier` extension
|
|
2
|
-
// point
|
|
2
|
+
// point. Two static-shape conflicts a boot-check CAN catch (a
|
|
3
3
|
// runtime shape-match predicate's overlap can't be proven at boot): a
|
|
4
4
|
// malformed plugin registration, and two providers both claiming the same
|
|
5
5
|
// shape (resolveTokenVerifier can't tell them apart). Zero tokenVerifier
|
|
@@ -46,7 +46,7 @@ export function validateTokenVerifierMultiplicity(features: readonly FeatureDefi
|
|
|
46
46
|
|
|
47
47
|
if (namesByShape.size === 0) {
|
|
48
48
|
// Session-only apps (email-password + sessions) never hit tokenVerifier —
|
|
49
|
-
// cookie JWT auth uses sessionStore alone
|
|
49
|
+
// cookie JWT auth uses sessionStore alone.
|
|
50
50
|
for (const feature of features) {
|
|
51
51
|
for (const usage of feature.extensionUsages) {
|
|
52
52
|
// skip: sessionStore present — tokenVerifier optional for cookie-session apps.
|
|
@@ -114,7 +114,7 @@ function validateSingleProvider(
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
// Multiplicity boot-check for the `sessionStore` extension point
|
|
117
|
+
// Multiplicity boot-check for the `sessionStore` extension point.
|
|
118
118
|
// Single-provider, unlike tokenVerifier — no shape to route on, so ≥2 fails
|
|
119
119
|
// boot. Zero registrations is a valid configuration (see
|
|
120
120
|
// validateSingleProvider doc) — a pure machine API using auth-foundation for
|
|
@@ -129,7 +129,7 @@ export function validateSessionStoreMultiplicity(features: readonly FeatureDefin
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// Optional single-provider
|
|
132
|
+
// Optional single-provider. Zero registrations = OK (single-tenant /
|
|
133
133
|
// header-cookie path). ≥2 or malformed = boot fail.
|
|
134
134
|
export function validateTenantResolverMultiplicity(features: readonly FeatureDefinition[]): void {
|
|
135
135
|
validateSingleProvider(features, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Merge app-facing AnonymousAccessConfig with auth-foundation tenant providers.
|
|
3
|
-
* Providers win over any leftover callback fields
|
|
3
|
+
* Providers win over any leftover callback fields.
|
|
4
4
|
* Test stacks may still pass Resolved callbacks when no provider is mounted.
|
|
5
5
|
*/
|
|
6
6
|
import type {
|
|
@@ -30,7 +30,7 @@ export async function resolveAnonymousAccessFromRegistry(
|
|
|
30
30
|
// (EXT_TENANT_RESOLVER/EXT_TENANT_EXISTENCE) alone must never make
|
|
31
31
|
// anonymousAccess become defined for an app that never set it — that
|
|
32
32
|
// would upgrade every roles:["anonymous"] handler to reachable without
|
|
33
|
-
// a JWT the moment such a routing feature is mounted
|
|
33
|
+
// a JWT the moment such a routing feature is mounted.
|
|
34
34
|
if (!base) {
|
|
35
35
|
const needing = ANONYMOUS_ROUTE_FEATURES.filter((name) => deps.registry.getFeature(name));
|
|
36
36
|
if (needing.length > 0) {
|
|
@@ -42,7 +42,7 @@ export async function resolveAnonymousAccessFromRegistry(
|
|
|
42
42
|
return undefined;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
// Fail-closed (
|
|
45
|
+
// Fail-closed (security): inline tenantResolver without trust is the
|
|
46
46
|
// old ambiguous config — providers always carry trust; test stacks must too.
|
|
47
47
|
if (
|
|
48
48
|
!tenantResolver &&
|
|
@@ -57,7 +57,7 @@ export async function resolveAnonymousAccessFromRegistry(
|
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// Providers win
|
|
60
|
+
// Providers win. When none are mounted, keep any test-injected
|
|
61
61
|
// Resolved callbacks so framework middleware suites stay self-contained.
|
|
62
62
|
return {
|
|
63
63
|
...(base ?? {}),
|
|
@@ -80,7 +80,7 @@ export function tokenShapeKey(shape: TokenShape): string {
|
|
|
80
80
|
return shape.kind === "jwt" ? "jwt" : `prefix:${shape.prefix}`;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
// Session-store extension point
|
|
83
|
+
// Session-store extension point. Unlike EXT_TOKEN_VERIFIER, this is
|
|
84
84
|
// single-provider — sessions have no per-provider shape to route on, so
|
|
85
85
|
// exactly one implementation must be registered (boot-fails on 0 or ≥2).
|
|
86
86
|
|
|
@@ -108,7 +108,7 @@ export function isSessionStoreProvider(o: unknown): o is SessionStoreProvider {
|
|
|
108
108
|
return typeof o === "object" && o !== null && "build" in o && typeof o.build === "function";
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
// Tenant-resolution extension points
|
|
111
|
+
// Tenant-resolution extension points. Both are single-provider and
|
|
112
112
|
// optional — zero registered means today's single-tenant / header-cookie
|
|
113
113
|
// path (no subdomain resolver, no existence check). ≥2 fails boot.
|
|
114
114
|
|
|
@@ -45,9 +45,9 @@ export function createDisableHandler(opts: DisableOptions) {
|
|
|
45
45
|
if (!row) return mfaNotEnabled();
|
|
46
46
|
|
|
47
47
|
// Fail closed, matching verify.write.ts/enable-confirm-preauth.write.ts
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
48
|
+
// without ctx.redis, verifyMfaFactor's TOTP-replay burn is skipped, and
|
|
49
|
+
// a code observed once (phishing proxy/shoulder-surfing) could be
|
|
50
|
+
// replayed within the ±1-step window to disable MFA outright.
|
|
51
51
|
// "no ctx.redis means no one gets through MFA login" doesn't cover
|
|
52
52
|
// this route — it's session-authed, and JWTs issued before Redis was
|
|
53
53
|
// unwired stay valid until they expire.
|