@cosmicdrift/kumiko-framework 0.328.0 → 0.328.1
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/dist/api/anonymous-cookie.d.ts +8 -0
- package/dist/api/anonymous-cookie.js +40 -0
- package/dist/api/api-constants.d.ts +47 -0
- package/dist/api/api-constants.js +136 -0
- package/dist/api/auth-middleware.d.ts +42 -0
- package/dist/api/auth-middleware.js +450 -0
- package/dist/api/auth-routes.d.ts +83 -0
- package/dist/api/auth-routes.js +1003 -0
- package/dist/api/client-ip.d.ts +15 -0
- package/dist/api/client-ip.js +101 -0
- package/dist/api/csrf-middleware.d.ts +9 -0
- package/dist/api/csrf-middleware.js +67 -0
- package/dist/api/extra-route.d.ts +99 -0
- package/dist/api/extra-route.js +48 -0
- package/dist/api/http-cache.d.ts +31 -0
- package/dist/api/http-cache.js +102 -0
- package/dist/api/index.d.ts +32 -0
- package/dist/api/index.js +20 -0
- package/dist/api/jwt.d.ts +22 -0
- package/dist/api/jwt.js +199 -0
- package/dist/api/observability-middleware.d.ts +8 -0
- package/dist/api/observability-middleware.js +68 -0
- package/dist/api/origin-middleware.d.ts +12 -0
- package/dist/api/origin-middleware.js +120 -0
- package/dist/api/pat-route-guard.d.ts +2 -0
- package/dist/api/pat-route-guard.js +43 -0
- package/dist/api/pat-scope.d.ts +2 -0
- package/dist/api/pat-scope.js +13 -0
- package/dist/api/pii-leak-guard.d.ts +2 -0
- package/dist/api/pii-leak-guard.js +40 -0
- package/dist/api/post-auth-landing.d.ts +14 -0
- package/dist/api/post-auth-landing.js +92 -0
- package/dist/api/readiness.d.ts +23 -0
- package/dist/api/readiness.js +98 -0
- package/dist/api/redis-sse-broker.d.ts +13 -0
- package/dist/api/redis-sse-broker.js +138 -0
- package/dist/api/request-context.d.ts +34 -0
- package/dist/api/request-context.js +60 -0
- package/dist/api/request-id-middleware.d.ts +37 -0
- package/dist/api/request-id-middleware.js +112 -0
- package/dist/api/route-registrars.d.ts +24 -0
- package/dist/api/route-registrars.js +133 -0
- package/dist/api/routes.d.ts +20 -0
- package/dist/api/routes.js +373 -0
- package/dist/api/server.d.ts +81 -0
- package/dist/api/server.js +1068 -0
- package/dist/api/sse-broker.d.ts +36 -0
- package/dist/api/sse-broker.js +112 -0
- package/dist/api/sse-route.d.ts +24 -0
- package/dist/api/sse-route.js +61 -0
- package/dist/api/tokens.d.ts +1 -0
- package/dist/api/tokens.js +15 -0
- package/dist/api/websocket-route.d.ts +59 -0
- package/dist/api/websocket-route.js +239 -0
- package/dist/arg-parser.d.ts +8 -0
- package/dist/arg-parser.js +59 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/roles.d.ts +16 -0
- package/dist/auth/roles.js +35 -0
- package/dist/bun-db/connection.d.ts +16 -0
- package/dist/bun-db/connection.js +54 -0
- package/dist/bun-db/index.d.ts +4 -0
- package/dist/bun-db/index.js +4 -0
- package/dist/bun-db/query.d.ts +64 -0
- package/dist/bun-db/query.js +1145 -0
- package/dist/compliance/duration-spec.d.ts +7 -0
- package/dist/compliance/duration-spec.js +37 -0
- package/dist/compliance/index.d.ts +6 -0
- package/dist/compliance/index.js +7 -0
- package/dist/compliance/override-schema.d.ts +78 -0
- package/dist/compliance/override-schema.js +124 -0
- package/dist/compliance/profiles.d.ts +125 -0
- package/dist/compliance/profiles.js +284 -0
- package/dist/compliance/sub-processors.d.ts +69 -0
- package/dist/compliance/sub-processors.js +109 -0
- package/dist/consumer-cli.d.ts +5 -0
- package/dist/consumer-cli.js +116 -0
- package/dist/crypto/blind-index.d.ts +10 -0
- package/dist/crypto/blind-index.js +97 -0
- package/dist/crypto/ciphertext-pattern.d.ts +3 -0
- package/dist/crypto/ciphertext-pattern.js +16 -0
- package/dist/crypto/event-pii.d.ts +8 -0
- package/dist/crypto/event-pii.js +79 -0
- package/dist/crypto/in-memory-kms-adapter.d.ts +11 -0
- package/dist/crypto/in-memory-kms-adapter.js +33 -0
- package/dist/crypto/index.d.ts +11 -0
- package/dist/crypto/index.js +11 -0
- package/dist/crypto/is-self-pii-field.d.ts +5 -0
- package/dist/crypto/is-self-pii-field.js +4 -0
- package/dist/crypto/kek-source.d.ts +23 -0
- package/dist/crypto/kek-source.js +122 -0
- package/dist/crypto/kms-adapter.d.ts +26 -0
- package/dist/crypto/kms-adapter.js +46 -0
- package/dist/crypto/kms-wiring.d.ts +67 -0
- package/dist/crypto/kms-wiring.js +125 -0
- package/dist/crypto/pg-kms-adapter.d.ts +55 -0
- package/dist/crypto/pg-kms-adapter.js +232 -0
- package/dist/crypto/pii-field-encryption.d.ts +20 -0
- package/dist/crypto/pii-field-encryption.js +201 -0
- package/dist/crypto/request-kms-cache.d.ts +8 -0
- package/dist/crypto/request-kms-cache.js +21 -0
- package/dist/crypto/subject-resolver.d.ts +30 -0
- package/dist/crypto/subject-resolver.js +153 -0
- package/dist/crypto/system-event-pii.d.ts +4 -0
- package/dist/crypto/system-event-pii.js +37 -0
- package/dist/db/api.d.ts +18 -0
- package/dist/db/api.js +23 -0
- package/dist/db/apply-entity-event.d.ts +21 -0
- package/dist/db/apply-entity-event.js +175 -0
- package/dist/db/assert-exists-in.d.ts +23 -0
- package/dist/db/assert-exists-in.js +34 -0
- package/dist/db/blind-index-cleanup.d.ts +5 -0
- package/dist/db/blind-index-cleanup.js +112 -0
- package/dist/db/bun-provider.d.ts +2 -0
- package/dist/db/bun-provider.js +37 -0
- package/dist/db/collect-table-metas.d.ts +3 -0
- package/dist/db/collect-table-metas.js +76 -0
- package/dist/db/compound-types.d.ts +9 -0
- package/dist/db/compound-types.js +31 -0
- package/dist/db/config-seed.d.ts +19 -0
- package/dist/db/config-seed.js +75 -0
- package/dist/db/connection.d.ts +10 -0
- package/dist/db/connection.js +35 -0
- package/dist/db/cursor.d.ts +9 -0
- package/dist/db/cursor.js +39 -0
- package/dist/db/dialect.d.ts +100 -0
- package/dist/db/dialect.js +386 -0
- package/dist/db/eagerload.d.ts +18 -0
- package/dist/db/eagerload.js +191 -0
- package/dist/db/entity-field-encryption.d.ts +15 -0
- package/dist/db/entity-field-encryption.js +127 -0
- package/dist/db/entity-table-from-registry.d.ts +4 -0
- package/dist/db/entity-table-from-registry.js +25 -0
- package/dist/db/entity-table-meta-types.d.ts +1 -0
- package/dist/db/entity-table-meta-types.js +1 -0
- package/dist/db/entity-table-meta.d.ts +30 -0
- package/dist/db/entity-table-meta.js +423 -0
- package/dist/db/event-store-executor-context.d.ts +49 -0
- package/dist/db/event-store-executor-context.js +368 -0
- package/dist/db/event-store-executor-read.d.ts +10 -0
- package/dist/db/event-store-executor-read.js +683 -0
- package/dist/db/event-store-executor-write.d.ts +3 -0
- package/dist/db/event-store-executor-write.js +705 -0
- package/dist/db/event-store-executor.d.ts +20 -0
- package/dist/db/event-store-executor.js +11 -0
- package/dist/db/feature-table-sources.d.ts +6 -0
- package/dist/db/feature-table-sources.js +24 -0
- package/dist/db/index.d.ts +37 -0
- package/dist/db/index.js +29 -0
- package/dist/db/located-timestamp.d.ts +22 -0
- package/dist/db/located-timestamp.js +100 -0
- package/dist/db/migrate-generator.d.ts +81 -0
- package/dist/db/migrate-generator.js +428 -0
- package/dist/db/migrate-runner.d.ts +30 -0
- package/dist/db/migrate-runner.js +273 -0
- package/dist/db/money.d.ts +30 -0
- package/dist/db/money.js +153 -0
- package/dist/db/parent-ref-clause.d.ts +10 -0
- package/dist/db/parent-ref-clause.js +124 -0
- package/dist/db/pg-error.d.ts +10 -0
- package/dist/db/pg-error.js +63 -0
- package/dist/db/postgres-provider.d.ts +2 -0
- package/dist/db/postgres-provider.js +21 -0
- package/dist/db/queries/advisory-lock.d.ts +3 -0
- package/dist/db/queries/advisory-lock.js +5 -0
- package/dist/db/queries/backfill-pii.d.ts +38 -0
- package/dist/db/queries/backfill-pii.js +433 -0
- package/dist/db/queries/ddl.d.ts +4 -0
- package/dist/db/queries/ddl.js +22 -0
- package/dist/db/queries/entity-read.d.ts +2 -0
- package/dist/db/queries/entity-read.js +5 -0
- package/dist/db/queries/es-ops.d.ts +5 -0
- package/dist/db/queries/es-ops.js +10 -0
- package/dist/db/queries/event-consumer.d.ts +36 -0
- package/dist/db/queries/event-consumer.js +261 -0
- package/dist/db/queries/event-store-admin.d.ts +24 -0
- package/dist/db/queries/event-store-admin.js +71 -0
- package/dist/db/queries/event-store-transfer.d.ts +20 -0
- package/dist/db/queries/event-store-transfer.js +31 -0
- package/dist/db/queries/event-store.d.ts +54 -0
- package/dist/db/queries/event-store.js +231 -0
- package/dist/db/queries/pii-backfill-state.d.ts +7 -0
- package/dist/db/queries/pii-backfill-state.js +14 -0
- package/dist/db/queries/projection-rebuild.d.ts +6 -0
- package/dist/db/queries/projection-rebuild.js +65 -0
- package/dist/db/queries/raw-sql.d.ts +9 -0
- package/dist/db/queries/raw-sql.js +16 -0
- package/dist/db/queries/seed-context.d.ts +20 -0
- package/dist/db/queries/seed-context.js +25 -0
- package/dist/db/queries/shadow-swap.d.ts +18 -0
- package/dist/db/queries/shadow-swap.js +307 -0
- package/dist/db/queries/table-ops.d.ts +4 -0
- package/dist/db/queries/table-ops.js +8 -0
- package/dist/db/queries/test-stack.d.ts +6 -0
- package/dist/db/queries/test-stack.js +20 -0
- package/dist/db/query-api.d.ts +2 -0
- package/dist/db/query-api.js +6 -0
- package/dist/db/query.d.ts +1 -0
- package/dist/db/query.js +3 -0
- package/dist/db/rebuild-marker.d.ts +4 -0
- package/dist/db/rebuild-marker.js +96 -0
- package/dist/db/reference-data.d.ts +14 -0
- package/dist/db/reference-data.js +66 -0
- package/dist/db/render-ddl.d.ts +4 -0
- package/dist/db/render-ddl.js +55 -0
- package/dist/db/replay-migration-sql.d.ts +12 -0
- package/dist/db/replay-migration-sql.js +223 -0
- package/dist/db/schema-inspection.d.ts +3 -0
- package/dist/db/schema-inspection.js +60 -0
- package/dist/db/table-builder.d.ts +194 -0
- package/dist/db/table-builder.js +430 -0
- package/dist/db/tenant-db-runner.d.ts +4 -0
- package/dist/db/tenant-db-runner.js +17 -0
- package/dist/db/tenant-db.d.ts +32 -0
- package/dist/db/tenant-db.js +501 -0
- package/dist/derivatives/delete-stored-file.d.ts +6 -0
- package/dist/derivatives/delete-stored-file.js +70 -0
- package/dist/derivatives/derivatives-context.d.ts +21 -0
- package/dist/derivatives/derivatives-context.js +212 -0
- package/dist/derivatives/field-variants.d.ts +3 -0
- package/dist/derivatives/field-variants.js +16 -0
- package/dist/derivatives/index.d.ts +6 -0
- package/dist/derivatives/index.js +4 -0
- package/dist/derivatives/variant-key.d.ts +10 -0
- package/dist/derivatives/variant-key.js +100 -0
- package/dist/engine/access.d.ts +2 -0
- package/dist/engine/access.js +25 -0
- package/dist/engine/active-membership.d.ts +26 -0
- package/dist/engine/active-membership.js +25 -0
- package/dist/engine/boot-validator/access-declarations.d.ts +2 -0
- package/dist/engine/boot-validator/access-declarations.js +148 -0
- package/dist/engine/boot-validator/access-roles.d.ts +2 -0
- package/dist/engine/boot-validator/access-roles.js +76 -0
- package/dist/engine/boot-validator/action-wiring.d.ts +3 -0
- package/dist/engine/boot-validator/action-wiring.js +104 -0
- package/dist/engine/boot-validator/api-ext.d.ts +3 -0
- package/dist/engine/boot-validator/api-ext.js +54 -0
- package/dist/engine/boot-validator/boot-check.d.ts +2 -0
- package/dist/engine/boot-validator/boot-check.js +20 -0
- package/dist/engine/boot-validator/config-deps.d.ts +10 -0
- package/dist/engine/boot-validator/config-deps.js +180 -0
- package/dist/engine/boot-validator/custom-screen-write-qns.d.ts +8 -0
- package/dist/engine/boot-validator/custom-screen-write-qns.js +75 -0
- package/dist/engine/boot-validator/detail-screens.d.ts +6 -0
- package/dist/engine/boot-validator/detail-screens.js +31 -0
- package/dist/engine/boot-validator/entity-handler.d.ts +23 -0
- package/dist/engine/boot-validator/entity-handler.js +754 -0
- package/dist/engine/boot-validator/entity-list-screens.d.ts +4 -0
- package/dist/engine/boot-validator/entity-list-screens.js +75 -0
- package/dist/engine/boot-validator/gdpr-storage.d.ts +2 -0
- package/dist/engine/boot-validator/gdpr-storage.js +48 -0
- package/dist/engine/boot-validator/global-tenancy.d.ts +2 -0
- package/dist/engine/boot-validator/global-tenancy.js +24 -0
- package/dist/engine/boot-validator/i18n-keys.d.ts +2 -0
- package/dist/engine/boot-validator/i18n-keys.js +88 -0
- package/dist/engine/boot-validator/index.d.ts +34 -0
- package/dist/engine/boot-validator/index.js +196 -0
- package/dist/engine/boot-validator/nav.d.ts +20 -0
- package/dist/engine/boot-validator/nav.js +202 -0
- package/dist/engine/boot-validator/ownership.d.ts +36 -0
- package/dist/engine/boot-validator/ownership.js +268 -0
- package/dist/engine/boot-validator/parent-ref.d.ts +3 -0
- package/dist/engine/boot-validator/parent-ref.js +73 -0
- package/dist/engine/boot-validator/pii-retention.d.ts +2 -0
- package/dist/engine/boot-validator/pii-retention.js +204 -0
- package/dist/engine/boot-validator/projection-list-screens.d.ts +4 -0
- package/dist/engine/boot-validator/projection-list-screens.js +219 -0
- package/dist/engine/boot-validator/query-output-columns.d.ts +2 -0
- package/dist/engine/boot-validator/query-output-columns.js +160 -0
- package/dist/engine/boot-validator/query-refs.d.ts +2 -0
- package/dist/engine/boot-validator/query-refs.js +72 -0
- package/dist/engine/boot-validator/record-owned.d.ts +2 -0
- package/dist/engine/boot-validator/record-owned.js +16 -0
- package/dist/engine/boot-validator/screens.d.ts +34 -0
- package/dist/engine/boot-validator/screens.js +1665 -0
- package/dist/engine/boot-validator/security-baseline.d.ts +3 -0
- package/dist/engine/boot-validator/security-baseline.js +18 -0
- package/dist/engine/boot-validator/transfer-graph.d.ts +3 -0
- package/dist/engine/boot-validator/transfer-graph.js +120 -0
- package/dist/engine/boot-validator/url-prefill-fields.d.ts +2 -0
- package/dist/engine/boot-validator/url-prefill-fields.js +106 -0
- package/dist/engine/boot-validator/workspaces.d.ts +20 -0
- package/dist/engine/boot-validator/workspaces.js +81 -0
- package/dist/engine/boot-validator/zod-shape.d.ts +5 -0
- package/dist/engine/boot-validator/zod-shape.js +110 -0
- package/dist/engine/boot-validator.d.ts +1 -0
- package/dist/engine/boot-validator.js +1 -0
- package/dist/engine/build-app-schema.d.ts +14 -0
- package/dist/engine/build-app-schema.js +494 -0
- package/dist/engine/build-config-feature-schema.d.ts +15 -0
- package/dist/engine/build-config-feature-schema.js +582 -0
- package/dist/engine/build-target.d.ts +28 -0
- package/dist/engine/build-target.js +43 -0
- package/dist/engine/changeset-changes.d.ts +12 -0
- package/dist/engine/changeset-changes.js +104 -0
- package/dist/engine/codemod/index.d.ts +2 -0
- package/dist/engine/codemod/index.js +1 -0
- package/dist/engine/codemod/pipeline-codemod.d.ts +50 -0
- package/dist/engine/codemod/pipeline-codemod.js +529 -0
- package/dist/engine/config-helpers.d.ts +42 -0
- package/dist/engine/config-helpers.js +115 -0
- package/dist/engine/constants.d.ts +52 -0
- package/dist/engine/constants.js +79 -0
- package/dist/engine/create-app.d.ts +17 -0
- package/dist/engine/create-app.js +119 -0
- package/dist/engine/cross-tenant.d.ts +3 -0
- package/dist/engine/cross-tenant.js +18 -0
- package/dist/engine/dedupe-features.d.ts +2 -0
- package/dist/engine/dedupe-features.js +36 -0
- package/dist/engine/define-feature.d.ts +7 -0
- package/dist/engine/define-feature.js +143 -0
- package/dist/engine/define-handler.d.ts +21 -0
- package/dist/engine/define-handler.js +117 -0
- package/dist/engine/define-roles.d.ts +5 -0
- package/dist/engine/define-roles.js +14 -0
- package/dist/engine/define-step.d.ts +4 -0
- package/dist/engine/define-step.js +22 -0
- package/dist/engine/define-workflow.d.ts +89 -0
- package/dist/engine/define-workflow.js +70 -0
- package/dist/engine/effective-features.d.ts +6 -0
- package/dist/engine/effective-features.js +73 -0
- package/dist/engine/embedded-derived.d.ts +29 -0
- package/dist/engine/embedded-derived.js +82 -0
- package/dist/engine/entity-handlers.d.ts +67 -0
- package/dist/engine/entity-handlers.js +567 -0
- package/dist/engine/escape-hatch-declaration.d.ts +2 -0
- package/dist/engine/escape-hatch-declaration.js +5 -0
- package/dist/engine/event-helpers.d.ts +11 -0
- package/dist/engine/event-helpers.js +47 -0
- package/dist/engine/extension-names.d.ts +164 -0
- package/dist/engine/extension-names.js +172 -0
- package/dist/engine/extension-selector-plugins.d.ts +5 -0
- package/dist/engine/extension-selector-plugins.js +14 -0
- package/dist/engine/extensions/escape-hatch-usage.d.ts +2 -0
- package/dist/engine/extensions/escape-hatch-usage.js +12 -0
- package/dist/engine/extensions/storage-provider.d.ts +4 -0
- package/dist/engine/extensions/storage-provider.js +1 -0
- package/dist/engine/extensions/tenant-data.d.ts +15 -0
- package/dist/engine/extensions/tenant-data.js +7 -0
- package/dist/engine/extensions/tenant-resource.d.ts +14 -0
- package/dist/engine/extensions/tenant-resource.js +6 -0
- package/dist/engine/extensions/user-data.d.ts +152 -0
- package/dist/engine/extensions/user-data.js +12 -0
- package/dist/engine/factories.d.ts +195 -0
- package/dist/engine/factories.js +387 -0
- package/dist/engine/feature-ast/entity-field-types.d.ts +13 -0
- package/dist/engine/feature-ast/entity-field-types.js +35 -0
- package/dist/engine/feature-ast/extractors/ai-steps.d.ts +6 -0
- package/dist/engine/feature-ast/extractors/ai-steps.js +254 -0
- package/dist/engine/feature-ast/extractors/events.d.ts +5 -0
- package/dist/engine/feature-ast/extractors/events.js +262 -0
- package/dist/engine/feature-ast/extractors/handlers.d.ts +23 -0
- package/dist/engine/feature-ast/extractors/handlers.js +319 -0
- package/dist/engine/feature-ast/extractors/hooks.d.ts +23 -0
- package/dist/engine/feature-ast/extractors/hooks.js +228 -0
- package/dist/engine/feature-ast/extractors/index.d.ts +14 -0
- package/dist/engine/feature-ast/extractors/index.js +13 -0
- package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +7 -0
- package/dist/engine/feature-ast/extractors/jobs-routes.js +141 -0
- package/dist/engine/feature-ast/extractors/projections-screens.d.ts +10 -0
- package/dist/engine/feature-ast/extractors/projections-screens.js +195 -0
- package/dist/engine/feature-ast/extractors/resolve-import.d.ts +14 -0
- package/dist/engine/feature-ast/extractors/resolve-import.js +152 -0
- package/dist/engine/feature-ast/extractors/round1.d.ts +10 -0
- package/dist/engine/feature-ast/extractors/round1.js +81 -0
- package/dist/engine/feature-ast/extractors/round2.d.ts +7 -0
- package/dist/engine/feature-ast/extractors/round2.js +158 -0
- package/dist/engine/feature-ast/extractors/round3.d.ts +22 -0
- package/dist/engine/feature-ast/extractors/round3.js +280 -0
- package/dist/engine/feature-ast/extractors/round5.d.ts +8 -0
- package/dist/engine/feature-ast/extractors/round5.js +63 -0
- package/dist/engine/feature-ast/extractors/round6.d.ts +4 -0
- package/dist/engine/feature-ast/extractors/round6.js +17 -0
- package/dist/engine/feature-ast/extractors/shared.d.ts +85 -0
- package/dist/engine/feature-ast/extractors/shared.js +326 -0
- package/dist/engine/feature-ast/index.d.ts +16 -0
- package/dist/engine/feature-ast/index.js +10 -0
- package/dist/engine/feature-ast/parse.d.ts +30 -0
- package/dist/engine/feature-ast/parse.js +464 -0
- package/dist/engine/feature-ast/patch.d.ts +207 -0
- package/dist/engine/feature-ast/patch.js +771 -0
- package/dist/engine/feature-ast/patcher.d.ts +211 -0
- package/dist/engine/feature-ast/patcher.js +277 -0
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +670 -0
- package/dist/engine/feature-ast/pattern-change-schema.js +1196 -0
- package/dist/engine/feature-ast/patterns.d.ts +302 -0
- package/dist/engine/feature-ast/patterns.js +113 -0
- package/dist/engine/feature-ast/render.d.ts +47 -0
- package/dist/engine/feature-ast/render.js +681 -0
- package/dist/engine/feature-ast/source-location.d.ts +17 -0
- package/dist/engine/feature-ast/source-location.js +27 -0
- package/dist/engine/feature-builder-state.d.ts +69 -0
- package/dist/engine/feature-builder-state.js +64 -0
- package/dist/engine/feature-changelog.d.ts +21 -0
- package/dist/engine/feature-changelog.js +76 -0
- package/dist/engine/feature-config-events-jobs.d.ts +58 -0
- package/dist/engine/feature-config-events-jobs.js +318 -0
- package/dist/engine/feature-entity-handlers.d.ts +38 -0
- package/dist/engine/feature-entity-handlers.js +185 -0
- package/dist/engine/feature-manifest.d.ts +73 -0
- package/dist/engine/feature-manifest.js +87 -0
- package/dist/engine/feature-ui-extensions.d.ts +68 -0
- package/dist/engine/feature-ui-extensions.js +488 -0
- package/dist/engine/field-access.d.ts +4 -0
- package/dist/engine/field-access.js +119 -0
- package/dist/engine/field-helpers.d.ts +4 -0
- package/dist/engine/field-helpers.js +28 -0
- package/dist/engine/handler-helpers.d.ts +19 -0
- package/dist/engine/handler-helpers.js +24 -0
- package/dist/engine/hook-helpers.d.ts +4 -0
- package/dist/engine/hook-helpers.js +13 -0
- package/dist/engine/i18n-key.d.ts +2 -0
- package/dist/engine/i18n-key.js +10 -0
- package/dist/engine/index.d.ts +77 -0
- package/dist/engine/index.js +70 -0
- package/dist/engine/instruction-fields.d.ts +2 -0
- package/dist/engine/instruction-fields.js +9 -0
- package/dist/engine/membership-roles.d.ts +5 -0
- package/dist/engine/membership-roles.js +48 -0
- package/dist/engine/object-form.d.ts +4 -0
- package/dist/engine/object-form.js +21 -0
- package/dist/engine/ownership.d.ts +12 -0
- package/dist/engine/ownership.js +339 -0
- package/dist/engine/parse-ref-target.d.ts +6 -0
- package/dist/engine/parse-ref-target.js +21 -0
- package/dist/engine/pattern-library/index.d.ts +2 -0
- package/dist/engine/pattern-library/index.js +3 -0
- package/dist/engine/pattern-library/library.d.ts +14 -0
- package/dist/engine/pattern-library/library.js +92 -0
- package/dist/engine/pattern-library/mixed-schemas.d.ts +16 -0
- package/dist/engine/pattern-library/mixed-schemas.js +569 -0
- package/dist/engine/pattern-library/opaque-schemas.d.ts +7 -0
- package/dist/engine/pattern-library/opaque-schemas.js +115 -0
- package/dist/engine/pattern-library/shared-fields.d.ts +120 -0
- package/dist/engine/pattern-library/shared-fields.js +71 -0
- package/dist/engine/pattern-library/static-schemas.d.ts +19 -0
- package/dist/engine/pattern-library/static-schemas.js +435 -0
- package/dist/engine/pattern-library/types.d.ts +158 -0
- package/dist/engine/pattern-library/types.js +36 -0
- package/dist/engine/personal-data-fields.d.ts +5 -0
- package/dist/engine/personal-data-fields.js +56 -0
- package/dist/engine/pipeline.d.ts +4 -0
- package/dist/engine/pipeline.js +87 -0
- package/dist/engine/project-app-schema-for-roles.d.ts +2 -0
- package/dist/engine/project-app-schema-for-roles.js +679 -0
- package/dist/engine/projection-helpers.d.ts +7 -0
- package/dist/engine/projection-helpers.js +61 -0
- package/dist/engine/qualified-name.d.ts +27 -0
- package/dist/engine/qualified-name.js +137 -0
- package/dist/engine/read-claim.d.ts +2 -0
- package/dist/engine/read-claim.js +28 -0
- package/dist/engine/registry-facade.d.ts +3 -0
- package/dist/engine/registry-facade.js +231 -0
- package/dist/engine/registry-ingest.d.ts +14 -0
- package/dist/engine/registry-ingest.js +415 -0
- package/dist/engine/registry-state.d.ts +93 -0
- package/dist/engine/registry-state.js +233 -0
- package/dist/engine/registry-validate.d.ts +25 -0
- package/dist/engine/registry-validate.js +669 -0
- package/dist/engine/registry.d.ts +2 -0
- package/dist/engine/registry.js +52 -0
- package/dist/engine/resolve-config-or-param.d.ts +18 -0
- package/dist/engine/resolve-config-or-param.js +76 -0
- package/dist/engine/role-assignment.d.ts +1 -0
- package/dist/engine/role-assignment.js +58 -0
- package/dist/engine/run-in.d.ts +2 -0
- package/dist/engine/run-in.js +28 -0
- package/dist/engine/run-pipeline.d.ts +25 -0
- package/dist/engine/run-pipeline.js +111 -0
- package/dist/engine/schema-builder.d.ts +8 -0
- package/dist/engine/schema-builder.js +406 -0
- package/dist/engine/screen-filter-ops.d.ts +3 -0
- package/dist/engine/screen-filter-ops.js +55 -0
- package/dist/engine/screen-helpers.d.ts +27 -0
- package/dist/engine/screen-helpers.js +100 -0
- package/dist/engine/soft-delete-cleanup.d.ts +10 -0
- package/dist/engine/soft-delete-cleanup.js +114 -0
- package/dist/engine/state-machine.d.ts +34 -0
- package/dist/engine/state-machine.js +44 -0
- package/dist/engine/steps/_duration-utils.d.ts +1 -0
- package/dist/engine/steps/_duration-utils.js +28 -0
- package/dist/engine/steps/_event-match.d.ts +2 -0
- package/dist/engine/steps/_event-match.js +88 -0
- package/dist/engine/steps/_no-return-guard.d.ts +2 -0
- package/dist/engine/steps/_no-return-guard.js +16 -0
- package/dist/engine/steps/_read-source.d.ts +6 -0
- package/dist/engine/steps/_read-source.js +7 -0
- package/dist/engine/steps/_resolver-utils.d.ts +11 -0
- package/dist/engine/steps/_resolver-utils.js +36 -0
- package/dist/engine/steps/_step-dispatch-constants.d.ts +13 -0
- package/dist/engine/steps/_step-dispatch-constants.js +32 -0
- package/dist/engine/steps/aggregate-append-event.d.ts +10 -0
- package/dist/engine/steps/aggregate-append-event.js +43 -0
- package/dist/engine/steps/aggregate-create.d.ts +6 -0
- package/dist/engine/steps/aggregate-create.js +38 -0
- package/dist/engine/steps/aggregate-update.d.ts +10 -0
- package/dist/engine/steps/aggregate-update.js +38 -0
- package/dist/engine/steps/branch.d.ts +8 -0
- package/dist/engine/steps/branch.js +66 -0
- package/dist/engine/steps/call-feature.d.ts +7 -0
- package/dist/engine/steps/call-feature.js +30 -0
- package/dist/engine/steps/compute.d.ts +2 -0
- package/dist/engine/steps/compute.js +29 -0
- package/dist/engine/steps/describe-workflow-step-error.d.ts +1 -0
- package/dist/engine/steps/describe-workflow-step-error.js +6 -0
- package/dist/engine/steps/for-each.d.ts +9 -0
- package/dist/engine/steps/for-each.js +88 -0
- package/dist/engine/steps/mail-send.d.ts +10 -0
- package/dist/engine/steps/mail-send.js +33 -0
- package/dist/engine/steps/read-find-many.d.ts +10 -0
- package/dist/engine/steps/read-find-many.js +32 -0
- package/dist/engine/steps/read-find-one.d.ts +9 -0
- package/dist/engine/steps/read-find-one.js +41 -0
- package/dist/engine/steps/retry.d.ts +9 -0
- package/dist/engine/steps/retry.js +76 -0
- package/dist/engine/steps/return.d.ts +4 -0
- package/dist/engine/steps/return.js +25 -0
- package/dist/engine/steps/unsafe-projection-delete.d.ts +8 -0
- package/dist/engine/steps/unsafe-projection-delete.js +35 -0
- package/dist/engine/steps/unsafe-projection-upsert.d.ts +8 -0
- package/dist/engine/steps/unsafe-projection-upsert.js +73 -0
- package/dist/engine/steps/wait-for-event.d.ts +8 -0
- package/dist/engine/steps/wait-for-event.js +63 -0
- package/dist/engine/steps/wait.d.ts +6 -0
- package/dist/engine/steps/wait.js +50 -0
- package/dist/engine/steps/webhook-send.d.ts +24 -0
- package/dist/engine/steps/webhook-send.js +38 -0
- package/dist/engine/system-user.d.ts +8 -0
- package/dist/engine/system-user.js +29 -0
- package/dist/engine/tier-resolver-extension.d.ts +62 -0
- package/dist/engine/tier-resolver-extension.js +55 -0
- package/dist/engine/types/config.d.ts +1 -0
- package/dist/engine/types/config.js +1 -0
- package/dist/engine/types/define-handler.d.ts +1 -0
- package/dist/engine/types/define-handler.js +1 -0
- package/dist/engine/types/entity-handlers.d.ts +1 -0
- package/dist/engine/types/entity-handlers.js +1 -0
- package/dist/engine/types/event-type-map.js +1 -0
- package/dist/engine/types/extension-options-map.js +1 -0
- package/dist/engine/types/feature.d.ts +1 -0
- package/dist/engine/types/feature.js +1 -0
- package/dist/engine/types/fields.d.ts +1 -0
- package/dist/engine/types/fields.js +1 -0
- package/dist/engine/types/handlers.d.ts +2 -0
- package/dist/engine/types/handlers.js +1 -0
- package/dist/engine/types/hooks.d.ts +1 -0
- package/dist/engine/types/hooks.js +1 -0
- package/dist/engine/types/http-route.js +1 -0
- package/dist/engine/types/identifiers.js +1 -0
- package/dist/engine/types/index.d.ts +30 -0
- package/dist/engine/types/index.js +10 -0
- package/dist/engine/types/nav.d.ts +1 -0
- package/dist/engine/types/nav.js +1 -0
- package/dist/engine/types/ownership.d.ts +1 -0
- package/dist/engine/types/ownership.js +1 -0
- package/dist/engine/types/projection.d.ts +1 -0
- package/dist/engine/types/projection.js +1 -0
- package/dist/engine/types/relations.js +1 -0
- package/dist/engine/types/screen.d.ts +2 -0
- package/dist/engine/types/screen.js +1 -0
- package/dist/engine/types/step.d.ts +1 -0
- package/dist/engine/types/step.js +1 -0
- package/dist/engine/types/target-ref.js +1 -0
- package/dist/engine/types/tree-node.js +1 -0
- package/dist/engine/types/workspace.d.ts +1 -0
- package/dist/engine/types/workspace.js +1 -0
- package/dist/engine/validate-projection-allowlist.d.ts +10 -0
- package/dist/engine/validate-projection-allowlist.js +164 -0
- package/dist/engine/validation.d.ts +3 -0
- package/dist/engine/validation.js +23 -0
- package/dist/engine/where-rule-lint.d.ts +2 -0
- package/dist/engine/where-rule-lint.js +171 -0
- package/dist/engine/write-handler-qn-extract.d.ts +15 -0
- package/dist/engine/write-handler-qn-extract.js +36 -0
- package/dist/entrypoint/index.d.ts +83 -0
- package/dist/entrypoint/index.js +312 -0
- package/dist/env/_zod-introspect.d.ts +17 -0
- package/dist/env/_zod-introspect.js +35 -0
- package/dist/env/dry-run.d.ts +13 -0
- package/dist/env/dry-run.js +158 -0
- package/dist/env/index.d.ts +98 -0
- package/dist/env/index.js +313 -0
- package/dist/errors/classes.d.ts +109 -0
- package/dist/errors/classes.js +190 -0
- package/dist/errors/field-issue.d.ts +6 -0
- package/dist/errors/field-issue.js +1 -0
- package/dist/errors/index.d.ts +15 -0
- package/dist/errors/index.js +9 -0
- package/dist/errors/kumiko-error.d.ts +25 -0
- package/dist/errors/kumiko-error.js +43 -0
- package/dist/errors/member-resolution.d.ts +2 -0
- package/dist/errors/member-resolution.js +10 -0
- package/dist/errors/reasons.d.ts +23 -0
- package/dist/errors/reasons.js +81 -0
- package/dist/errors/serialize.d.ts +32 -0
- package/dist/errors/serialize.js +76 -0
- package/dist/errors/to-kumiko-error.d.ts +2 -0
- package/dist/errors/to-kumiko-error.js +9 -0
- package/dist/errors/transition-details.d.ts +7 -0
- package/dist/errors/transition-details.js +16 -0
- package/dist/errors/write-error-info.d.ts +20 -0
- package/dist/errors/write-error-info.js +99 -0
- package/dist/errors/zod-bridge.d.ts +3 -0
- package/dist/errors/zod-bridge.js +58 -0
- package/dist/es-ops/context.d.ts +19 -0
- package/dist/es-ops/context.js +70 -0
- package/dist/es-ops/index.d.ts +4 -0
- package/dist/es-ops/index.js +14 -0
- package/dist/es-ops/operations-schema.d.ts +5 -0
- package/dist/es-ops/operations-schema.js +40 -0
- package/dist/es-ops/runner.d.ts +29 -0
- package/dist/es-ops/runner.js +195 -0
- package/dist/es-ops/types.d.ts +92 -0
- package/dist/es-ops/types.js +14 -0
- package/dist/event-store/admin-api.d.ts +17 -0
- package/dist/event-store/admin-api.js +173 -0
- package/dist/event-store/archive.d.ts +14 -0
- package/dist/event-store/archive.js +55 -0
- package/dist/event-store/errors.d.ts +15 -0
- package/dist/event-store/errors.js +49 -0
- package/dist/event-store/event-store.d.ts +38 -0
- package/dist/event-store/event-store.js +310 -0
- package/dist/event-store/events-schema.d.ts +3 -0
- package/dist/event-store/events-schema.js +66 -0
- package/dist/event-store/index.d.ts +12 -0
- package/dist/event-store/index.js +12 -0
- package/dist/event-store/provenance-append.d.ts +13 -0
- package/dist/event-store/provenance-append.js +49 -0
- package/dist/event-store/rebuild-dead-letter.d.ts +25 -0
- package/dist/event-store/rebuild-dead-letter.js +71 -0
- package/dist/event-store/row-to-stored-event.d.ts +17 -0
- package/dist/event-store/row-to-stored-event.js +15 -0
- package/dist/event-store/snapshot.d.ts +26 -0
- package/dist/event-store/snapshot.js +155 -0
- package/dist/event-store/transfer.d.ts +13 -0
- package/dist/event-store/transfer.js +62 -0
- package/dist/event-store/types.d.ts +1 -0
- package/dist/event-store/types.js +1 -0
- package/dist/event-store/upcaster-dead-letter.d.ts +27 -0
- package/dist/event-store/upcaster-dead-letter.js +76 -0
- package/dist/event-store/upcaster.d.ts +14 -0
- package/dist/event-store/upcaster.js +86 -0
- package/dist/files/content-disposition.d.ts +3 -0
- package/dist/files/content-disposition.js +50 -0
- package/dist/files/feature.d.ts +9 -0
- package/dist/files/feature.js +26 -0
- package/dist/files/file-handle.d.ts +7 -0
- package/dist/files/file-handle.js +71 -0
- package/dist/files/file-ref-entity.d.ts +134 -0
- package/dist/files/file-ref-entity.js +32 -0
- package/dist/files/file-ref-table.d.ts +134 -0
- package/dist/files/file-ref-table.js +12 -0
- package/dist/files/file-routes.d.ts +34 -0
- package/dist/files/file-routes.js +433 -0
- package/dist/files/in-memory-provider.d.ts +7 -0
- package/dist/files/in-memory-provider.js +82 -0
- package/dist/files/index.d.ts +17 -0
- package/dist/files/index.js +13 -0
- package/dist/files/local-provider.d.ts +2 -0
- package/dist/files/local-provider.js +128 -0
- package/dist/files/provider-resolver.d.ts +58 -0
- package/dist/files/provider-resolver.js +87 -0
- package/dist/files/storage-tracking.d.ts +20 -0
- package/dist/files/storage-tracking.js +179 -0
- package/dist/files/types.d.ts +59 -0
- package/dist/files/types.js +276 -0
- package/dist/files/zip-stream.d.ts +31 -0
- package/dist/files/zip-stream.js +207 -0
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.js +1 -0
- package/dist/i18n/index.d.ts +12 -0
- package/dist/i18n/index.js +27 -0
- package/dist/i18n/mail-registry.d.ts +7 -0
- package/dist/i18n/mail-registry.js +34 -0
- package/dist/i18n/request-locale.d.ts +22 -0
- package/dist/i18n/request-locale.js +62 -0
- package/dist/i18n/required-surface-keys.d.ts +33 -0
- package/dist/i18n/required-surface-keys.js +416 -0
- package/dist/i18n/settings-hub-keys.d.ts +14 -0
- package/dist/i18n/settings-hub-keys.js +29 -0
- package/dist/jobs/index.d.ts +2 -0
- package/dist/jobs/index.js +1 -0
- package/dist/jobs/job-runner.d.ts +54 -0
- package/dist/jobs/job-runner.js +1110 -0
- package/dist/lifecycle/index.d.ts +2 -0
- package/dist/lifecycle/index.js +2 -0
- package/dist/lifecycle/lifecycle.d.ts +23 -0
- package/dist/lifecycle/lifecycle.js +111 -0
- package/dist/lifecycle/signal-handlers.d.ts +10 -0
- package/dist/lifecycle/signal-handlers.js +40 -0
- package/dist/logging/index.d.ts +4 -0
- package/dist/logging/index.js +2 -0
- package/dist/logging/pino-logger.d.ts +9 -0
- package/dist/logging/pino-logger.js +61 -0
- package/dist/logging/types.js +1 -0
- package/dist/logging/utils.d.ts +8 -0
- package/dist/logging/utils.js +41 -0
- package/dist/migrations/index.d.ts +4 -0
- package/dist/migrations/index.js +8 -0
- package/dist/migrations/kumiko-drift.d.ts +26 -0
- package/dist/migrations/kumiko-drift.js +151 -0
- package/dist/migrations/pending-rebuilds.d.ts +81 -0
- package/dist/migrations/pending-rebuilds.js +163 -0
- package/dist/migrations/pii-event-backfill.d.ts +40 -0
- package/dist/migrations/pii-event-backfill.js +275 -0
- package/dist/migrations/projection-table-index.d.ts +5 -0
- package/dist/migrations/projection-table-index.js +21 -0
- package/dist/observability/console-provider.d.ts +10 -0
- package/dist/observability/console-provider.js +101 -0
- package/dist/observability/context.d.ts +10 -0
- package/dist/observability/context.js +13 -0
- package/dist/observability/escape-hatch-report.d.ts +23 -0
- package/dist/observability/escape-hatch-report.js +92 -0
- package/dist/observability/fallback.d.ts +4 -0
- package/dist/observability/fallback.js +28 -0
- package/dist/observability/ids.d.ts +2 -0
- package/dist/observability/ids.js +22 -0
- package/dist/observability/index.d.ts +15 -0
- package/dist/observability/index.js +15 -0
- package/dist/observability/metric-validator.d.ts +4 -0
- package/dist/observability/metric-validator.js +73 -0
- package/dist/observability/metrics-handle.d.ts +5 -0
- package/dist/observability/metrics-handle.js +102 -0
- package/dist/observability/metrics-wiring.d.ts +18 -0
- package/dist/observability/metrics-wiring.js +21 -0
- package/dist/observability/noop-provider.d.ts +2 -0
- package/dist/observability/noop-provider.js +105 -0
- package/dist/observability/prometheus-meter.d.ts +26 -0
- package/dist/observability/prometheus-meter.js +257 -0
- package/dist/observability/recording-meter.d.ts +31 -0
- package/dist/observability/recording-meter.js +127 -0
- package/dist/observability/recording-tracer.d.ts +32 -0
- package/dist/observability/recording-tracer.js +135 -0
- package/dist/observability/redis-wrapper.d.ts +3 -0
- package/dist/observability/redis-wrapper.js +121 -0
- package/dist/observability/sensitive-filter.d.ts +9 -0
- package/dist/observability/sensitive-filter.js +92 -0
- package/dist/observability/standard-metrics.d.ts +41 -0
- package/dist/observability/standard-metrics.js +237 -0
- package/dist/observability/types/index.js +1 -0
- package/dist/observability/types/metric.js +1 -0
- package/dist/observability/types/provider.js +1 -0
- package/dist/observability/types/span.js +1 -0
- package/dist/pipeline/active-membership.d.ts +12 -0
- package/dist/pipeline/active-membership.js +124 -0
- package/dist/pipeline/append-event-core.d.ts +12 -0
- package/dist/pipeline/append-event-core.js +84 -0
- package/dist/pipeline/auth-claims-resolver.d.ts +9 -0
- package/dist/pipeline/auth-claims-resolver.js +76 -0
- package/dist/pipeline/cascade-handler.d.ts +6 -0
- package/dist/pipeline/cascade-handler.js +85 -0
- package/dist/pipeline/dispatch-batch.d.ts +5 -0
- package/dist/pipeline/dispatch-batch.js +217 -0
- package/dist/pipeline/dispatch-query.d.ts +4 -0
- package/dist/pipeline/dispatch-query.js +141 -0
- package/dist/pipeline/dispatch-shared.d.ts +58 -0
- package/dist/pipeline/dispatch-shared.js +924 -0
- package/dist/pipeline/dispatch-stream.d.ts +3 -0
- package/dist/pipeline/dispatch-stream.js +89 -0
- package/dist/pipeline/dispatch-write.d.ts +6 -0
- package/dist/pipeline/dispatch-write.js +428 -0
- package/dist/pipeline/dispatcher-utils.d.ts +36 -0
- package/dist/pipeline/dispatcher-utils.js +139 -0
- package/dist/pipeline/dispatcher.d.ts +30 -0
- package/dist/pipeline/dispatcher.js +131 -0
- package/dist/pipeline/distributed-lock.d.ts +13 -0
- package/dist/pipeline/distributed-lock.js +42 -0
- package/dist/pipeline/entity-cache.d.ts +7 -0
- package/dist/pipeline/entity-cache.js +68 -0
- package/dist/pipeline/event-consumer-state.d.ts +16 -0
- package/dist/pipeline/event-consumer-state.js +96 -0
- package/dist/pipeline/event-dedup.d.ts +11 -0
- package/dist/pipeline/event-dedup.js +12 -0
- package/dist/pipeline/event-dispatcher-admin.d.ts +46 -0
- package/dist/pipeline/event-dispatcher-admin.js +196 -0
- package/dist/pipeline/event-dispatcher-delivery.d.ts +68 -0
- package/dist/pipeline/event-dispatcher-delivery.js +310 -0
- package/dist/pipeline/event-dispatcher.d.ts +52 -0
- package/dist/pipeline/event-dispatcher.js +523 -0
- package/dist/pipeline/event-retention.d.ts +20 -0
- package/dist/pipeline/event-retention.js +78 -0
- package/dist/pipeline/idempotency.d.ts +19 -0
- package/dist/pipeline/idempotency.js +115 -0
- package/dist/pipeline/index.d.ts +34 -0
- package/dist/pipeline/index.js +19 -0
- package/dist/pipeline/irreversible-operation-gate.d.ts +4 -0
- package/dist/pipeline/irreversible-operation-gate.js +57 -0
- package/dist/pipeline/lifecycle-pipeline.d.ts +29 -0
- package/dist/pipeline/lifecycle-pipeline.js +266 -0
- package/dist/pipeline/member-read-only-transaction.d.ts +3 -0
- package/dist/pipeline/member-read-only-transaction.js +68 -0
- package/dist/pipeline/member-reader.d.ts +7 -0
- package/dist/pipeline/member-reader.js +87 -0
- package/dist/pipeline/msp-rebuild.d.ts +12 -0
- package/dist/pipeline/msp-rebuild.js +163 -0
- package/dist/pipeline/multi-stream-apply-context.d.ts +18 -0
- package/dist/pipeline/multi-stream-apply-context.js +40 -0
- package/dist/pipeline/pending-gap-ranges.d.ts +12 -0
- package/dist/pipeline/pending-gap-ranges.js +99 -0
- package/dist/pipeline/projection-rebuild.d.ts +55 -0
- package/dist/pipeline/projection-rebuild.js +285 -0
- package/dist/pipeline/projection-state.d.ts +9 -0
- package/dist/pipeline/projection-state.js +51 -0
- package/dist/pipeline/projections-runner.d.ts +5 -0
- package/dist/pipeline/projections-runner.js +57 -0
- package/dist/pipeline/redis-keys.d.ts +8 -0
- package/dist/pipeline/redis-keys.js +10 -0
- package/dist/pipeline/system-hooks.d.ts +25 -0
- package/dist/pipeline/system-hooks.js +590 -0
- package/dist/pipeline/system-identity-switch.d.ts +30 -0
- package/dist/pipeline/system-identity-switch.js +248 -0
- package/dist/pipeline/tenant-timezone-cache.d.ts +17 -0
- package/dist/pipeline/tenant-timezone-cache.js +55 -0
- package/dist/pipeline/write-origin.d.ts +10 -0
- package/dist/pipeline/write-origin.js +110 -0
- package/dist/random/generate.d.ts +56 -0
- package/dist/random/generate.js +92 -0
- package/dist/random/index.d.ts +2 -0
- package/dist/random/index.js +2 -0
- package/dist/random/words.d.ts +2 -0
- package/dist/random/words.js +391 -0
- package/dist/rate-limit/bucket.d.ts +14 -0
- package/dist/rate-limit/bucket.js +20 -0
- package/dist/rate-limit/index.d.ts +3 -0
- package/dist/rate-limit/index.js +3 -0
- package/dist/rate-limit/middleware.d.ts +24 -0
- package/dist/rate-limit/middleware.js +101 -0
- package/dist/rate-limit/resolver.d.ts +9 -0
- package/dist/rate-limit/resolver.js +177 -0
- package/dist/redis/client.d.ts +9 -0
- package/dist/redis/client.js +44 -0
- package/dist/redis/index.d.ts +4 -0
- package/dist/redis/index.js +2 -0
- package/dist/redis/pubsub-signal.d.ts +11 -0
- package/dist/redis/pubsub-signal.js +79 -0
- package/dist/schema-cli.d.ts +21 -0
- package/dist/schema-cli.js +438 -0
- package/dist/scripts/codemod/crypto-shredding-testing-move.d.ts +2 -0
- package/dist/scripts/codemod/crypto-shredding-testing-move.js +109 -0
- package/dist/scripts/codemod/migrate-cross-tenant.d.ts +19 -0
- package/dist/scripts/codemod/migrate-cross-tenant.js +266 -0
- package/dist/scripts/codemod/migrate-db-raw.d.ts +23 -0
- package/dist/scripts/codemod/migrate-db-raw.js +345 -0
- package/dist/scripts/codemod/migrate-open-to-all.d.ts +22 -0
- package/dist/scripts/codemod/migrate-open-to-all.js +194 -0
- package/dist/scripts/codemod/pii-personal-migration.d.ts +11 -0
- package/dist/scripts/codemod/pii-personal-migration.js +615 -0
- package/dist/scripts/codemod/unprocessable-error-details-reason.d.ts +2 -0
- package/dist/scripts/codemod/unprocessable-error-details-reason.js +235 -0
- package/dist/search/derive-search-adapter-config.d.ts +3 -0
- package/dist/search/derive-search-adapter-config.js +23 -0
- package/dist/search/in-memory-adapter.d.ts +2 -0
- package/dist/search/in-memory-adapter.js +96 -0
- package/dist/search/index.d.ts +6 -0
- package/dist/search/index.js +8 -0
- package/dist/search/meilisearch-adapter.d.ts +10 -0
- package/dist/search/meilisearch-adapter.js +175 -0
- package/dist/search/purge-subject.d.ts +7 -0
- package/dist/search/purge-subject.js +178 -0
- package/dist/search/reindex-entity.d.ts +18 -0
- package/dist/search/reindex-entity.js +139 -0
- package/dist/search/types.js +1 -0
- package/dist/secrets/dek-cache.d.ts +13 -0
- package/dist/secrets/dek-cache.js +97 -0
- package/dist/secrets/derive-purpose-secret.d.ts +1 -0
- package/dist/secrets/derive-purpose-secret.js +16 -0
- package/dist/secrets/env-master-key-provider.d.ts +6 -0
- package/dist/secrets/env-master-key-provider.js +134 -0
- package/dist/secrets/envelope-cipher.d.ts +8 -0
- package/dist/secrets/envelope-cipher.js +36 -0
- package/dist/secrets/envelope.d.ts +3 -0
- package/dist/secrets/envelope.js +44 -0
- package/dist/secrets/index.d.ts +9 -0
- package/dist/secrets/index.js +9 -0
- package/dist/secrets/leak-guard.d.ts +1 -0
- package/dist/secrets/leak-guard.js +79 -0
- package/dist/secrets/rotation.d.ts +2 -0
- package/dist/secrets/rotation.js +29 -0
- package/dist/secrets/stored-envelope.d.ts +11 -0
- package/dist/secrets/stored-envelope.js +32 -0
- package/dist/secrets/types.d.ts +1 -0
- package/dist/seeding/entity-seed.d.ts +19 -0
- package/dist/seeding/entity-seed.js +12 -0
- package/dist/seeding/index.d.ts +2 -0
- package/dist/seeding/index.js +2 -0
- package/dist/seeding/types.d.ts +7 -0
- package/dist/seeding/types.js +1 -0
- package/dist/stack/db.d.ts +19 -0
- package/dist/stack/db.js +61 -0
- package/dist/stack/drain-event-consumers.d.ts +4 -0
- package/dist/stack/drain-event-consumers.js +48 -0
- package/dist/stack/drain-jobs.d.ts +20 -0
- package/dist/stack/drain-jobs.js +99 -0
- package/dist/stack/event-collector.d.ts +9 -0
- package/dist/stack/event-collector.js +12 -0
- package/dist/stack/index.d.ts +9 -0
- package/dist/stack/index.js +19 -0
- package/dist/stack/push-entity-projection-tables.d.ts +24 -0
- package/dist/stack/push-entity-projection-tables.js +73 -0
- package/dist/stack/redis.d.ts +11 -0
- package/dist/stack/redis.js +38 -0
- package/dist/stack/request-helper.d.ts +35 -0
- package/dist/stack/request-helper.js +144 -0
- package/dist/stack/table-helpers.d.ts +32 -0
- package/dist/stack/table-helpers.js +138 -0
- package/dist/stack/test-stack.d.ts +161 -0
- package/dist/stack/test-stack.js +398 -0
- package/dist/stack/test-users.d.ts +33 -0
- package/dist/stack/test-users.js +29 -0
- package/dist/testing/access-assertions.d.ts +2 -0
- package/dist/testing/access-assertions.js +13 -0
- package/dist/testing/assertions.d.ts +10 -0
- package/dist/testing/assertions.js +22 -0
- package/dist/testing/boot-validator-fixture.d.ts +3 -0
- package/dist/testing/boot-validator-fixture.js +101 -0
- package/dist/testing/closed-connection-error.d.ts +7 -0
- package/dist/testing/closed-connection-error.js +47 -0
- package/dist/testing/db-cleanup.d.ts +9 -0
- package/dist/testing/db-cleanup.js +31 -0
- package/dist/testing/e2e-generator.d.ts +49 -0
- package/dist/testing/e2e-generator.js +377 -0
- package/dist/testing/expect-error.d.ts +2 -0
- package/dist/testing/expect-error.js +22 -0
- package/dist/testing/file-provider-contract.d.ts +2 -0
- package/dist/testing/file-provider-contract.js +102 -0
- package/dist/testing/handler-context.d.ts +4 -0
- package/dist/testing/handler-context.js +72 -0
- package/dist/testing/http-cookies.d.ts +7 -0
- package/dist/testing/http-cookies.js +47 -0
- package/dist/testing/index.d.ts +24 -0
- package/dist/testing/index.js +32 -0
- package/dist/testing/late-bound.d.ts +9 -0
- package/dist/testing/late-bound.js +31 -0
- package/dist/testing/multipart-helper.d.ts +22 -0
- package/dist/testing/multipart-helper.js +77 -0
- package/dist/testing/mutable-master-key-provider.d.ts +7 -0
- package/dist/testing/mutable-master-key-provider.js +35 -0
- package/dist/testing/observability-recorder.d.ts +9 -0
- package/dist/testing/observability-recorder.js +29 -0
- package/dist/testing/real-providers.d.ts +3 -0
- package/dist/testing/real-providers.js +21 -0
- package/dist/testing/seed.d.ts +9 -0
- package/dist/testing/seed.js +21 -0
- package/dist/testing/shared-entities.d.ts +256 -0
- package/dist/testing/shared-entities.js +56 -0
- package/dist/testing/utils.d.ts +1 -0
- package/dist/testing/utils.js +1 -0
- package/dist/testing/wait-for.d.ts +20 -0
- package/dist/testing/wait-for.js +46 -0
- package/dist/testing/without-ambient-temporal.d.ts +5 -0
- package/dist/testing/without-ambient-temporal.js +17 -0
- package/dist/time/boot-tz-warning.d.ts +5 -0
- package/dist/time/boot-tz-warning.js +24 -0
- package/dist/time/geo-tz.js +1 -0
- package/dist/time/iana.d.ts +1 -0
- package/dist/time/iana.js +18 -0
- package/dist/time/index.d.ts +6 -0
- package/dist/time/index.js +15 -0
- package/dist/time/legacy-date.d.ts +5 -0
- package/dist/time/legacy-date.js +15 -0
- package/dist/time/polyfill.d.ts +9 -0
- package/dist/time/polyfill.js +52 -0
- package/dist/time/tz-context.d.ts +13 -0
- package/dist/time/tz-context.js +80 -0
- package/dist/ui-types/app-schema.d.ts +26 -0
- package/dist/ui-types/app-schema.js +9 -0
- package/dist/ui-types/formality.d.ts +2 -0
- package/dist/ui-types/formality.js +5 -0
- package/dist/ui-types/index.d.ts +22 -0
- package/dist/ui-types/index.js +31 -0
- package/dist/ui-types/list-row-meta.d.ts +18 -0
- package/dist/ui-types/list-row-meta.js +65 -0
- package/dist/ui-types/plural.d.ts +12 -0
- package/dist/ui-types/plural.js +57 -0
- package/dist/upgrade-cli.d.ts +11 -0
- package/dist/upgrade-cli.js +532 -0
- package/dist/utils/assert.d.ts +1 -0
- package/dist/utils/assert.js +18 -0
- package/dist/utils/case.d.ts +1 -0
- package/dist/utils/case.js +6 -0
- package/dist/utils/compare.d.ts +1 -0
- package/dist/utils/compare.js +10 -0
- package/dist/utils/env-parse.d.ts +1 -0
- package/dist/utils/env-parse.js +13 -0
- package/dist/utils/ids.d.ts +2 -0
- package/dist/utils/ids.js +23 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/is-plain-object.d.ts +2 -0
- package/dist/utils/is-plain-object.js +4 -0
- package/dist/utils/parse-string-array-json.d.ts +2 -0
- package/dist/utils/parse-string-array-json.js +11 -0
- package/dist/utils/safe-json.d.ts +17 -0
- package/dist/utils/safe-json.js +47 -0
- package/dist/utils/serialization.d.ts +1 -0
- package/dist/utils/serialization.js +13 -0
- package/package.json +274 -93
- package/src/changes.json +6 -0
- package/src/scripts/codemod/pii-personal-migration.ts +5 -5
- package/src/__tests__/anonymous-access.integration.test.ts +0 -513
- package/src/__tests__/consumer-cli.integration.test.ts +0 -172
- package/src/__tests__/derived-fields.integration.test.ts +0 -126
- package/src/__tests__/entity-list-limits.integration.test.ts +0 -84
- package/src/__tests__/entity-permalink-open.integration.test.ts +0 -99
- package/src/__tests__/error-contract.integration.test.ts +0 -436
- package/src/__tests__/field-access.integration.test.ts +0 -273
- package/src/__tests__/fixtures/migrate-cross-tenant/manual-only.expected.ts +0 -44
- package/src/__tests__/fixtures/migrate-cross-tenant/manual-only.input.ts +0 -44
- package/src/__tests__/fixtures/migrate-cross-tenant/rewrite.expected.ts +0 -41
- package/src/__tests__/fixtures/migrate-cross-tenant/rewrite.input.ts +0 -41
- package/src/__tests__/fixtures/migrate-db-raw/global-fetch.expected.ts +0 -9
- package/src/__tests__/fixtures/migrate-db-raw/global-fetch.input.ts +0 -10
- package/src/__tests__/fixtures/migrate-db-raw/global-select.expected.ts +0 -6
- package/src/__tests__/fixtures/migrate-db-raw/global-select.input.ts +0 -12
- package/src/__tests__/fixtures/migrate-db-raw/import-pruning.expected.ts +0 -12
- package/src/__tests__/fixtures/migrate-db-raw/import-pruning.input.ts +0 -12
- package/src/__tests__/fixtures/migrate-db-raw/manual-only.expected.ts +0 -26
- package/src/__tests__/fixtures/migrate-db-raw/manual-only.input.ts +0 -26
- package/src/__tests__/fixtures/migrate-db-raw/own-tenant-const-shorthand.expected.ts +0 -10
- package/src/__tests__/fixtures/migrate-db-raw/own-tenant-const-shorthand.input.ts +0 -11
- package/src/__tests__/fixtures/migrate-db-raw/own-tenant-event.expected.ts +0 -9
- package/src/__tests__/fixtures/migrate-db-raw/own-tenant-event.input.ts +0 -15
- package/src/__tests__/fixtures/migrate-open-to-all/manual-only.expected.ts +0 -16
- package/src/__tests__/fixtures/migrate-open-to-all/manual-only.input.ts +0 -16
- package/src/__tests__/fixtures/migrate-open-to-all/test-nested-shorthand.expected.ts +0 -12
- package/src/__tests__/fixtures/migrate-open-to-all/test-nested-shorthand.input.ts +0 -12
- package/src/__tests__/fixtures/migrate-open-to-all/test-simple.expected.ts +0 -7
- package/src/__tests__/fixtures/migrate-open-to-all/test-simple.input.ts +0 -7
- package/src/__tests__/full-stack.integration.test.ts +0 -924
- package/src/__tests__/migrate-cross-tenant-codemod.test.ts +0 -106
- package/src/__tests__/migrate-db-raw-codemod.test.ts +0 -132
- package/src/__tests__/migrate-open-to-all-codemod.test.ts +0 -84
- package/src/__tests__/ownership-where-write-path.integration.test.ts +0 -147
- package/src/__tests__/ownership.integration.test.ts +0 -454
- package/src/__tests__/pii-personal-migration-report-codemod.test.ts +0 -160
- package/src/__tests__/reference-data.integration.test.ts +0 -243
- package/src/__tests__/related-list-parent-filter.integration.test.ts +0 -103
- package/src/__tests__/schema-cli-kms-slots.integration.test.ts +0 -172
- package/src/__tests__/schema-cli-rebuild.integration.test.ts +0 -189
- package/src/__tests__/schema-cli-status.integration.test.ts +0 -96
- package/src/__tests__/schema-cli-temporal-polyfill.test.ts +0 -48
- package/src/__tests__/schema-cli.integration.test.ts +0 -485
- package/src/__tests__/store-table.integration.test.ts +0 -94
- package/src/__tests__/transition-guard.integration.test.ts +0 -342
- package/src/__tests__/unprocessable-error-details-reason-codemod.test.ts +0 -205
- package/src/__tests__/upgrade-cli.test.ts +0 -723
- package/src/api/__tests__/api-constants-completeness.test.ts +0 -63
- package/src/api/__tests__/api.test.ts +0 -869
- package/src/api/__tests__/auth-middleware-anonymous-access-boot.test.ts +0 -40
- package/src/api/__tests__/auth-middleware-transport.test.ts +0 -102
- package/src/api/__tests__/auth-routes-cookie.test.ts +0 -330
- package/src/api/__tests__/auth-routes-invalid-body-invite.test.ts +0 -263
- package/src/api/__tests__/auth-routes-mfa-preauth-confirm.test.ts +0 -230
- package/src/api/__tests__/auth-routes-mfa-preauth-enable-start.test.ts +0 -263
- package/src/api/__tests__/auth-routes-mfa-verify.test.ts +0 -221
- package/src/api/__tests__/auth-routes-trusted-proxy.test.ts +0 -164
- package/src/api/__tests__/batch.integration.test.ts +0 -548
- package/src/api/__tests__/body-limit.test.ts +0 -184
- package/src/api/__tests__/client-ip.test.ts +0 -184
- package/src/api/__tests__/csrf-constants-sync.test.ts +0 -20
- package/src/api/__tests__/csrf-middleware.test.ts +0 -97
- package/src/api/__tests__/dispatcher-live.integration.test.ts +0 -292
- package/src/api/__tests__/extra-route-rejection.test.ts +0 -38
- package/src/api/__tests__/extra-routes.integration.test.ts +0 -663
- package/src/api/__tests__/http-cache.test.ts +0 -173
- package/src/api/__tests__/http-route-entry.integration.test.ts +0 -114
- package/src/api/__tests__/http-route-rate-limit.integration.test.ts +0 -148
- package/src/api/__tests__/jwt.test.ts +0 -316
- package/src/api/__tests__/login-rate-limiter-sweep.test.ts +0 -50
- package/src/api/__tests__/metrics-endpoint.test.ts +0 -132
- package/src/api/__tests__/nested-write-ownership.integration.test.ts +0 -268
- package/src/api/__tests__/nested-write.integration.test.ts +0 -210
- package/src/api/__tests__/origin-middleware.integration.test.ts +0 -273
- package/src/api/__tests__/origin-middleware.test.ts +0 -279
- package/src/api/__tests__/pat-route-guard.integration.test.ts +0 -126
- package/src/api/__tests__/pat-scope.test.ts +0 -36
- package/src/api/__tests__/pii-leak-guard.integration.test.ts +0 -112
- package/src/api/__tests__/post-auth-landing.test.ts +0 -100
- package/src/api/__tests__/readiness.test.ts +0 -76
- package/src/api/__tests__/redis-login-rate-limiter.integration.test.ts +0 -138
- package/src/api/__tests__/redis-sse-broker.integration.test.ts +0 -321
- package/src/api/__tests__/request-id-middleware.test.ts +0 -229
- package/src/api/__tests__/request-locale.integration.test.ts +0 -146
- package/src/api/__tests__/schema-route.integration.test.ts +0 -157
- package/src/api/__tests__/server-boot-guards.test.ts +0 -308
- package/src/api/__tests__/server-error-logging.test.ts +0 -342
- package/src/api/__tests__/server-jwt-ttl.test.ts +0 -58
- package/src/api/__tests__/sse-broker.test.ts +0 -267
- package/src/api/__tests__/sse-route.test.ts +0 -245
- package/src/api/__tests__/stream-escape-hatch.integration.test.ts +0 -203
- package/src/api/__tests__/websocket-route.test.ts +0 -552
- package/src/api/anonymous-cookie.ts +0 -61
- package/src/api/api-constants.ts +0 -153
- package/src/api/auth-middleware.ts +0 -694
- package/src/api/auth-routes.ts +0 -1590
- package/src/api/client-ip.ts +0 -131
- package/src/api/csrf-middleware.ts +0 -74
- package/src/api/extra-route.ts +0 -178
- package/src/api/http-cache.ts +0 -122
- package/src/api/index.ts +0 -117
- package/src/api/jwt.ts +0 -277
- package/src/api/observability-middleware.ts +0 -89
- package/src/api/origin-middleware.ts +0 -137
- package/src/api/pat-route-guard.ts +0 -51
- package/src/api/pat-scope.ts +0 -14
- package/src/api/pii-leak-guard.ts +0 -46
- package/src/api/post-auth-landing.ts +0 -105
- package/src/api/readiness.ts +0 -132
- package/src/api/redis-sse-broker.ts +0 -171
- package/src/api/request-context.ts +0 -137
- package/src/api/request-id-middleware.ts +0 -138
- package/src/api/route-registrars.ts +0 -193
- package/src/api/routes.ts +0 -432
- package/src/api/server.ts +0 -1550
- package/src/api/sse-broker.ts +0 -175
- package/src/api/sse-route.ts +0 -74
- package/src/api/tokens.ts +0 -16
- package/src/api/websocket-route.ts +0 -327
- package/src/arg-parser.ts +0 -66
- package/src/auth/__tests__/roles.test.ts +0 -24
- package/src/auth/index.ts +0 -7
- package/src/auth/roles.ts +0 -42
- package/src/bun-db/__tests__/PATTERN.md +0 -72
- package/src/bun-db/__tests__/_helpers.ts +0 -104
- package/src/bun-db/__tests__/batch-methods.integration.test.ts +0 -143
- package/src/bun-db/__tests__/batch-methods.test.ts +0 -21
- package/src/bun-db/__tests__/bun-test-db.ts +0 -19
- package/src/bun-db/__tests__/closed-connection-retry.integration.test.ts +0 -252
- package/src/bun-db/__tests__/coerce-row-plain-date.test.ts +0 -70
- package/src/bun-db/__tests__/coerce-row-temporal.test.ts +0 -41
- package/src/bun-db/__tests__/column-types.integration.test.ts +0 -132
- package/src/bun-db/__tests__/compound-types.integration.test.ts +0 -134
- package/src/bun-db/__tests__/decimal-field.integration.test.ts +0 -81
- package/src/bun-db/__tests__/extract-table-info.test.ts +0 -71
- package/src/bun-db/__tests__/jsonb-edge-cases.integration.test.ts +0 -235
- package/src/bun-db/__tests__/postgres-closed-socket-write.integration.test.ts +0 -87
- package/src/bun-db/__tests__/query-guards.test.ts +0 -111
- package/src/bun-db/__tests__/run-in-savepoint-if-supported.integration.test.ts +0 -47
- package/src/bun-db/__tests__/select-many-retry.integration.test.ts +0 -138
- package/src/bun-db/__tests__/smoke.integration.test.ts +0 -43
- package/src/bun-db/__tests__/sql-expr-brand.test.ts +0 -115
- package/src/bun-db/__tests__/sql-methods.integration.test.ts +0 -231
- package/src/bun-db/__tests__/where-patterns.integration.test.ts +0 -213
- package/src/bun-db/__tests__/write-brand.test.ts +0 -72
- package/src/bun-db/connection.ts +0 -87
- package/src/bun-db/index.ts +0 -36
- package/src/bun-db/query.ts +0 -1394
- package/src/compliance/__tests__/duration-spec.test.ts +0 -72
- package/src/compliance/__tests__/profiles.test.ts +0 -308
- package/src/compliance/__tests__/sub-processors.test.ts +0 -149
- package/src/compliance/duration-spec.ts +0 -44
- package/src/compliance/index.ts +0 -31
- package/src/compliance/override-schema.ts +0 -136
- package/src/compliance/profiles.ts +0 -424
- package/src/compliance/sub-processors.ts +0 -165
- package/src/consumer-cli.ts +0 -134
- package/src/crypto/__tests__/blind-index.test.ts +0 -132
- package/src/crypto/__tests__/event-pii.test.ts +0 -417
- package/src/crypto/__tests__/kek-rotation.integration.test.ts +0 -180
- package/src/crypto/__tests__/kek-source.test.ts +0 -441
- package/src/crypto/__tests__/kms-adapter-contract.ts +0 -134
- package/src/crypto/__tests__/kms-adapter.contract.test.ts +0 -4
- package/src/crypto/__tests__/kms-wiring.test.ts +0 -203
- package/src/crypto/__tests__/pg-kms-adapter.integration.test.ts +0 -154
- package/src/crypto/__tests__/pii-field-encryption.test.ts +0 -403
- package/src/crypto/__tests__/request-kms-cache.test.ts +0 -74
- package/src/crypto/__tests__/subject-id-schema.test.ts +0 -60
- package/src/crypto/__tests__/subject-key-record.test.ts +0 -109
- package/src/crypto/__tests__/subject-resolver.test.ts +0 -250
- package/src/crypto/__tests__/system-event-pii.test.ts +0 -77
- package/src/crypto/blind-index.ts +0 -118
- package/src/crypto/ciphertext-pattern.ts +0 -19
- package/src/crypto/event-pii.ts +0 -99
- package/src/crypto/in-memory-kms-adapter.ts +0 -50
- package/src/crypto/index.ts +0 -84
- package/src/crypto/is-self-pii-field.ts +0 -8
- package/src/crypto/kek-source.ts +0 -180
- package/src/crypto/kms-adapter.ts +0 -51
- package/src/crypto/kms-wiring.ts +0 -208
- package/src/crypto/pg-kms-adapter.ts +0 -303
- package/src/crypto/pii-field-encryption.ts +0 -266
- package/src/crypto/request-kms-cache.ts +0 -38
- package/src/crypto/subject-resolver.ts +0 -232
- package/src/crypto/system-event-pii.ts +0 -57
- package/src/db/__tests__/apply-entity-event-removed-column.integration.test.ts +0 -109
- package/src/db/__tests__/apply-entity-event-tenant.integration.test.ts +0 -159
- package/src/db/__tests__/assert-exists-in.integration.test.ts +0 -120
- package/src/db/__tests__/assert-no-unreachable-live-rows.integration.test.ts +0 -190
- package/src/db/__tests__/big-int-field.test.ts +0 -132
- package/src/db/__tests__/blind-index.integration.test.ts +0 -280
- package/src/db/__tests__/build-filter-where.test.ts +0 -50
- package/src/db/__tests__/collect-table-metas.test.ts +0 -188
- package/src/db/__tests__/column-ddl.integration.test.ts +0 -122
- package/src/db/__tests__/compound-types.test.ts +0 -126
- package/src/db/__tests__/config-seed.integration.test.ts +0 -292
- package/src/db/__tests__/connection-close-outage.integration.test.ts +0 -110
- package/src/db/__tests__/connection-options.test.ts +0 -68
- package/src/db/__tests__/cursor.test.ts +0 -42
- package/src/db/__tests__/decimal-field.test.ts +0 -109
- package/src/db/__tests__/dialect-instant.test.ts +0 -47
- package/src/db/__tests__/eagerload.integration.test.ts +0 -374
- package/src/db/__tests__/entity-field-encryption.test.ts +0 -74
- package/src/db/__tests__/entity-table-from-registry.test.ts +0 -79
- package/src/db/__tests__/entity-table-meta-source.test.ts +0 -92
- package/src/db/__tests__/entity-table-types.test.ts +0 -162
- package/src/db/__tests__/event-store-executor-context.pii-roundtrip.test.ts +0 -67
- package/src/db/__tests__/event-store-executor-global-tenancy.integration.test.ts +0 -73
- package/src/db/__tests__/event-store-executor-list.integration.test.ts +0 -791
- package/src/db/__tests__/event-store-executor-money-rehydrate.integration.test.ts +0 -153
- package/src/db/__tests__/event-store-executor-reference-search.integration.test.ts +0 -643
- package/src/db/__tests__/event-store-executor-reference-sort.integration.test.ts +0 -256
- package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +0 -788
- package/src/db/__tests__/event-store-executor.integration.test.ts +0 -844
- package/src/db/__tests__/event-store-system-stream.integration.test.ts +0 -96
- package/src/db/__tests__/feature-table-sources.test.ts +0 -34
- package/src/db/__tests__/implicit-projection-equivalence.integration.test.ts +0 -393
- package/src/db/__tests__/instant-to-driver-temporal.test.ts +0 -21
- package/src/db/__tests__/list-filter-field-access.integration.test.ts +0 -218
- package/src/db/__tests__/list-pagination.test.ts +0 -28
- package/src/db/__tests__/list-row-meta-drift.test.ts +0 -15
- package/src/db/__tests__/located-timestamp.test.ts +0 -203
- package/src/db/__tests__/managed-recreate.integration.test.ts +0 -78
- package/src/db/__tests__/migrate-generator.test.ts +0 -383
- package/src/db/__tests__/migrate-runner.test.ts +0 -118
- package/src/db/__tests__/money.test.ts +0 -291
- package/src/db/__tests__/multi-row-insert.integration.test.ts +0 -88
- package/src/db/__tests__/number-field-fractional.integration.test.ts +0 -58
- package/src/db/__tests__/parent-ref-clause.test.ts +0 -213
- package/src/db/__tests__/parse-auto-verb.test.ts +0 -70
- package/src/db/__tests__/pg-error.test.ts +0 -57
- package/src/db/__tests__/rebuild-marker.test.ts +0 -180
- package/src/db/__tests__/replay-migration-sql.test.ts +0 -401
- package/src/db/__tests__/required-not-null-migration-safety.integration.test.ts +0 -109
- package/src/db/__tests__/run-in-own-transaction.integration.test.ts +0 -166
- package/src/db/__tests__/schema-inspection.test.ts +0 -27
- package/src/db/__tests__/schema-migration.integration.test.ts +0 -354
- package/src/db/__tests__/source-shadow-create.integration.test.ts +0 -59
- package/src/db/__tests__/system-db-view-export.test.ts +0 -107
- package/src/db/__tests__/table-builder-indexes.test.ts +0 -189
- package/src/db/__tests__/table-builder-meta-lockstep.test.ts +0 -224
- package/src/db/__tests__/table-builder-required.test.ts +0 -214
- package/src/db/__tests__/tenant-db-convention-cross-tenant.test.ts +0 -72
- package/src/db/__tests__/tenant-db-count.integration.test.ts +0 -92
- package/src/db/__tests__/tenant-db-declared-unsafe-raw.test.ts +0 -163
- package/src/db/__tests__/tenant-db-global.integration.test.ts +0 -134
- package/src/db/__tests__/tenant-db-global.test.ts +0 -352
- package/src/db/__tests__/tenant-db-no-raw.test.ts +0 -85
- package/src/db/__tests__/tenant-db-where-merge.integration.test.ts +0 -123
- package/src/db/__tests__/tenant-db-where-merge.test.ts +0 -164
- package/src/db/__tests__/tenant-db.integration.test.ts +0 -575
- package/src/db/__tests__/unchecked-system-db.test.ts +0 -259
- package/src/db/__tests__/unique-violation-mapping.integration.test.ts +0 -200
- package/src/db/__tests__/with-systemdb-unsafe-raw-grant.test.ts +0 -71
- package/src/db/api.ts +0 -52
- package/src/db/apply-entity-event.ts +0 -211
- package/src/db/assert-exists-in.ts +0 -52
- package/src/db/blind-index-cleanup.ts +0 -145
- package/src/db/bun-provider.ts +0 -42
- package/src/db/collect-table-metas.ts +0 -98
- package/src/db/compound-types.ts +0 -47
- package/src/db/config-seed.ts +0 -104
- package/src/db/connection.ts +0 -57
- package/src/db/cursor.ts +0 -47
- package/src/db/dialect.ts +0 -544
- package/src/db/eagerload.ts +0 -260
- package/src/db/entity-field-encryption.ts +0 -158
- package/src/db/entity-table-from-registry.ts +0 -31
- package/src/db/entity-table-meta-types.ts +0 -2
- package/src/db/entity-table-meta.ts +0 -491
- package/src/db/event-store-executor-context.ts +0 -510
- package/src/db/event-store-executor-read.ts +0 -916
- package/src/db/event-store-executor-write.ts +0 -920
- package/src/db/event-store-executor.ts +0 -50
- package/src/db/feature-table-sources.ts +0 -35
- package/src/db/index.ts +0 -162
- package/src/db/located-timestamp.ts +0 -118
- package/src/db/migrate-generator.ts +0 -549
- package/src/db/migrate-runner.ts +0 -348
- package/src/db/money.ts +0 -211
- package/src/db/parent-ref-clause.ts +0 -182
- package/src/db/pg-error.ts +0 -74
- package/src/db/postgres-provider.ts +0 -28
- package/src/db/queries/__tests__/event-store-idempotency-index.integration.test.ts +0 -78
- package/src/db/queries/__tests__/shadow-swap.test.ts +0 -43
- package/src/db/queries/__tests__/unsafe-read-retrying.integration.test.ts +0 -115
- package/src/db/queries/advisory-lock.ts +0 -11
- package/src/db/queries/backfill-pii.ts +0 -578
- package/src/db/queries/ddl.ts +0 -45
- package/src/db/queries/entity-read.ts +0 -15
- package/src/db/queries/es-ops.ts +0 -17
- package/src/db/queries/event-consumer.ts +0 -418
- package/src/db/queries/event-store-admin.ts +0 -130
- package/src/db/queries/event-store-transfer.ts +0 -73
- package/src/db/queries/event-store.ts +0 -354
- package/src/db/queries/pii-backfill-state.ts +0 -33
- package/src/db/queries/projection-rebuild.ts +0 -104
- package/src/db/queries/raw-sql.ts +0 -28
- package/src/db/queries/seed-context.ts +0 -62
- package/src/db/queries/shadow-swap.ts +0 -378
- package/src/db/queries/table-ops.ts +0 -11
- package/src/db/queries/test-stack.ts +0 -32
- package/src/db/query-api.ts +0 -24
- package/src/db/query.ts +0 -35
- package/src/db/rebuild-marker.ts +0 -103
- package/src/db/reference-data.ts +0 -73
- package/src/db/render-ddl.ts +0 -57
- package/src/db/replay-migration-sql.ts +0 -257
- package/src/db/schema-inspection.ts +0 -81
- package/src/db/table-builder.ts +0 -692
- package/src/db/tenant-db-runner.ts +0 -23
- package/src/db/tenant-db.ts +0 -727
- package/src/derivatives/__tests__/derivatives-context.integration.test.ts +0 -231
- package/src/derivatives/__tests__/derivatives-context.test.ts +0 -369
- package/src/derivatives/__tests__/field-variants.test.ts +0 -62
- package/src/derivatives/__tests__/variant-key.test.ts +0 -183
- package/src/derivatives/__tests__/variant-route.integration.test.ts +0 -268
- package/src/derivatives/delete-stored-file.ts +0 -86
- package/src/derivatives/derivatives-context.ts +0 -314
- package/src/derivatives/field-variants.ts +0 -20
- package/src/derivatives/index.ts +0 -14
- package/src/derivatives/variant-key.ts +0 -108
- package/src/engine/__tests__/_pipeline-test-utils.ts +0 -23
- package/src/engine/__tests__/auth-claims-registrar.test.ts +0 -74
- package/src/engine/__tests__/boot-validator-action-wiring.test.ts +0 -362
- package/src/engine/__tests__/boot-validator-api-exposure.test.ts +0 -142
- package/src/engine/__tests__/boot-validator-boot-check.test.ts +0 -104
- package/src/engine/__tests__/boot-validator-dashboard.test.ts +0 -381
- package/src/engine/__tests__/boot-validator-detail-for.test.ts +0 -106
- package/src/engine/__tests__/boot-validator-entity-list.test.ts +0 -120
- package/src/engine/__tests__/boot-validator-gdpr-storage.test.ts +0 -85
- package/src/engine/__tests__/boot-validator-i18n-keys.test.ts +0 -153
- package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +0 -92
- package/src/engine/__tests__/boot-validator-nav-area.test.ts +0 -116
- package/src/engine/__tests__/boot-validator-pii-retention.test.ts +0 -994
- package/src/engine/__tests__/boot-validator-projection-list.test.ts +0 -629
- package/src/engine/__tests__/boot-validator-query-output-schema.test.ts +0 -578
- package/src/engine/__tests__/boot-validator-query-refs.test.ts +0 -151
- package/src/engine/__tests__/boot-validator-ref-entity.test.ts +0 -196
- package/src/engine/__tests__/boot-validator-s0-integration.test.ts +0 -172
- package/src/engine/__tests__/boot-validator.test.ts +0 -5984
- package/src/engine/__tests__/build-app-schema-settings-hub.test.ts +0 -246
- package/src/engine/__tests__/build-app-schema-url-prefill.test.ts +0 -222
- package/src/engine/__tests__/build-app-schema.test.ts +0 -1167
- package/src/engine/__tests__/build-config-feature-schema-extension-selector.test.ts +0 -395
- package/src/engine/__tests__/build-config-feature-schema-secrets.test.ts +0 -188
- package/src/engine/__tests__/build-config-feature-schema.test.ts +0 -511
- package/src/engine/__tests__/build-target.test.ts +0 -127
- package/src/engine/__tests__/changeset-changes.test.ts +0 -64
- package/src/engine/__tests__/claim-keys.test.ts +0 -274
- package/src/engine/__tests__/codemod-pipeline.test.ts +0 -682
- package/src/engine/__tests__/config-helpers.test.ts +0 -309
- package/src/engine/__tests__/content-collection.test.ts +0 -307
- package/src/engine/__tests__/decimal-field.test.ts +0 -59
- package/src/engine/__tests__/dedupe-features.test.ts +0 -85
- package/src/engine/__tests__/define-feature-entity-mapping.test.ts +0 -53
- package/src/engine/__tests__/define-roles.test.ts +0 -21
- package/src/engine/__tests__/define-workflow.test.ts +0 -79
- package/src/engine/__tests__/describe-workflow-step-error.test.ts +0 -17
- package/src/engine/__tests__/duration-utils.test.ts +0 -16
- package/src/engine/__tests__/effective-features.test.ts +0 -86
- package/src/engine/__tests__/embedded-derived.test.ts +0 -35
- package/src/engine/__tests__/engine.test.ts +0 -2406
- package/src/engine/__tests__/entity-create-caller-id.integration.test.ts +0 -87
- package/src/engine/__tests__/entity-exclude-fields.integration.test.ts +0 -134
- package/src/engine/__tests__/entity-handlers-escape-hatch.test.ts +0 -91
- package/src/engine/__tests__/entity-handlers.test.ts +0 -562
- package/src/engine/__tests__/entity-presave-wiring.integration.test.ts +0 -153
- package/src/engine/__tests__/entity-restore-tenant-isolation.integration.test.ts +0 -168
- package/src/engine/__tests__/entity-write-crosstenant.integration.test.ts +0 -317
- package/src/engine/__tests__/event-helpers.test.ts +0 -68
- package/src/engine/__tests__/event-migration-declarative.test.ts +0 -67
- package/src/engine/__tests__/event-type-map-augmentation.test.ts +0 -24
- package/src/engine/__tests__/extend-entity-projection.test.ts +0 -133
- package/src/engine/__tests__/extends-registrar.test.ts +0 -279
- package/src/engine/__tests__/factories-long-text.test.ts +0 -95
- package/src/engine/__tests__/factories-number-unit.test.ts +0 -23
- package/src/engine/__tests__/factories-personal.test.ts +0 -216
- package/src/engine/__tests__/factories-time.test.ts +0 -94
- package/src/engine/__tests__/feature-crud-shorthand.test.ts +0 -73
- package/src/engine/__tests__/feature-crud-verb-access.integration.test.ts +0 -83
- package/src/engine/__tests__/feature-manifest.test.ts +0 -137
- package/src/engine/__tests__/field-access.test.ts +0 -65
- package/src/engine/__tests__/field-predicates.test.ts +0 -48
- package/src/engine/__tests__/form-money-currency-types.test.ts +0 -90
- package/src/engine/__tests__/hook-identity-switch-grant.test.ts +0 -188
- package/src/engine/__tests__/hook-phases.test.ts +0 -172
- package/src/engine/__tests__/http-route-anonymous-required.test.ts +0 -43
- package/src/engine/__tests__/identifiers.test.ts +0 -35
- package/src/engine/__tests__/lifecycle-hooks.test.ts +0 -243
- package/src/engine/__tests__/membership-roles.test.ts +0 -67
- package/src/engine/__tests__/metric-navigate-tab.test.ts +0 -167
- package/src/engine/__tests__/multiselect-filter.integration.test.ts +0 -141
- package/src/engine/__tests__/nav.test.ts +0 -497
- package/src/engine/__tests__/no-return-guard.test.ts +0 -17
- package/src/engine/__tests__/ownership.test.ts +0 -475
- package/src/engine/__tests__/parse-ref-target.test.ts +0 -43
- package/src/engine/__tests__/pipeline-engine.test.ts +0 -215
- package/src/engine/__tests__/pipeline-handler.integration.test.ts +0 -880
- package/src/engine/__tests__/pipeline-observability.integration.test.ts +0 -142
- package/src/engine/__tests__/pipeline-performance.integration.test.ts +0 -152
- package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +0 -288
- package/src/engine/__tests__/post-query-hook.test.ts +0 -144
- package/src/engine/__tests__/project-app-schema-for-roles.test.ts +0 -500
- package/src/engine/__tests__/projection-detail-actions.test.ts +0 -145
- package/src/engine/__tests__/projection-detail-singleton.test.ts +0 -86
- package/src/engine/__tests__/projection-detail-tabs.test.ts +0 -314
- package/src/engine/__tests__/projection-helpers.test.ts +0 -75
- package/src/engine/__tests__/projection-list-filter.integration.test.ts +0 -115
- package/src/engine/__tests__/projection.test.ts +0 -191
- package/src/engine/__tests__/qualified-name.test.ts +0 -306
- package/src/engine/__tests__/read-steps-tenant-filter.integration.test.ts +0 -215
- package/src/engine/__tests__/registrar-object-form.test.ts +0 -141
- package/src/engine/__tests__/registry.test.ts +0 -326
- package/src/engine/__tests__/required-surface-keys.test.ts +0 -477
- package/src/engine/__tests__/resolve-config-or-param.test.ts +0 -315
- package/src/engine/__tests__/role-assignment.test.ts +0 -71
- package/src/engine/__tests__/row-action-navigate-tab.test.ts +0 -107
- package/src/engine/__tests__/run-in.test.ts +0 -38
- package/src/engine/__tests__/schema-builder-date-bounds.test.ts +0 -47
- package/src/engine/__tests__/schema-builder.test.ts +0 -1211
- package/src/engine/__tests__/screen-definition-exports.test.ts +0 -102
- package/src/engine/__tests__/screen-filter-ops.test.ts +0 -31
- package/src/engine/__tests__/screen-helpers.test.ts +0 -52
- package/src/engine/__tests__/screen.test.ts +0 -1684
- package/src/engine/__tests__/search-payload-extension.test.ts +0 -288
- package/src/engine/__tests__/soft-delete-cleanup-job-tenant-db.integration.test.ts +0 -82
- package/src/engine/__tests__/soft-delete-cleanup.test.ts +0 -167
- package/src/engine/__tests__/state-machine.test.ts +0 -148
- package/src/engine/__tests__/steps-aggregate-append-event.test.ts +0 -115
- package/src/engine/__tests__/steps-aggregate-create.test.ts +0 -92
- package/src/engine/__tests__/steps-aggregate-update.test.ts +0 -127
- package/src/engine/__tests__/steps-call-feature.test.ts +0 -123
- package/src/engine/__tests__/steps-mail-send.test.ts +0 -137
- package/src/engine/__tests__/steps-read.test.ts +0 -332
- package/src/engine/__tests__/steps-resolver-utils.test.ts +0 -50
- package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +0 -77
- package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +0 -131
- package/src/engine/__tests__/steps-webhook-send.test.ts +0 -143
- package/src/engine/__tests__/steps-workflow.test.ts +0 -353
- package/src/engine/__tests__/store-table.test.ts +0 -247
- package/src/engine/__tests__/system-user.test.ts +0 -57
- package/src/engine/__tests__/tier-resolver-extension.test.ts +0 -69
- package/src/engine/__tests__/toolbar-navigate-tab.test.ts +0 -233
- package/src/engine/__tests__/tree-actions-patterns.test.ts +0 -163
- package/src/engine/__tests__/validate-custom-screen-write-qns.test.ts +0 -43
- package/src/engine/__tests__/validate-projection-allowlist.test.ts +0 -498
- package/src/engine/__tests__/validation-hooks.test.ts +0 -77
- package/src/engine/__tests__/where-rule-lint.test.ts +0 -79
- package/src/engine/__tests__/write-handler-qn-extract.test.ts +0 -50
- package/src/engine/access.ts +0 -27
- package/src/engine/active-membership.ts +0 -70
- package/src/engine/boot-validator/__tests__/access-declarations.test.ts +0 -707
- package/src/engine/boot-validator/__tests__/access-roles.test.ts +0 -84
- package/src/engine/boot-validator/__tests__/action-icon.test.ts +0 -81
- package/src/engine/boot-validator/__tests__/anonymous-rate-limit-required.test.ts +0 -63
- package/src/engine/boot-validator/__tests__/config-deps.test.ts +0 -92
- package/src/engine/boot-validator/__tests__/global-tenancy.test.ts +0 -73
- package/src/engine/boot-validator/__tests__/i18n-keys.test.ts +0 -340
- package/src/engine/boot-validator/__tests__/nav.test.ts +0 -290
- package/src/engine/boot-validator/__tests__/no-all-role-in-handler-access.test.ts +0 -77
- package/src/engine/boot-validator/__tests__/ownership.test.ts +0 -87
- package/src/engine/boot-validator/__tests__/parent-ref.test.ts +0 -161
- package/src/engine/boot-validator/__tests__/rate-limit-disabled-reason.test.ts +0 -45
- package/src/engine/boot-validator/__tests__/record-owned.test.ts +0 -65
- package/src/engine/boot-validator/__tests__/security-baseline.test.ts +0 -107
- package/src/engine/boot-validator/__tests__/transfer-graph.test.ts +0 -138
- package/src/engine/boot-validator/access-declarations.ts +0 -211
- package/src/engine/boot-validator/access-roles.ts +0 -85
- package/src/engine/boot-validator/action-wiring.ts +0 -163
- package/src/engine/boot-validator/api-ext.ts +0 -81
- package/src/engine/boot-validator/boot-check.ts +0 -21
- package/src/engine/boot-validator/config-deps.ts +0 -246
- package/src/engine/boot-validator/custom-screen-write-qns.ts +0 -87
- package/src/engine/boot-validator/detail-screens.ts +0 -49
- package/src/engine/boot-validator/entity-handler.ts +0 -1011
- package/src/engine/boot-validator/entity-list-screens.ts +0 -100
- package/src/engine/boot-validator/gdpr-storage.ts +0 -59
- package/src/engine/boot-validator/global-tenancy.ts +0 -29
- package/src/engine/boot-validator/i18n-keys.ts +0 -101
- package/src/engine/boot-validator/index.ts +0 -301
- package/src/engine/boot-validator/nav.ts +0 -241
- package/src/engine/boot-validator/ownership.ts +0 -352
- package/src/engine/boot-validator/parent-ref.ts +0 -96
- package/src/engine/boot-validator/pii-retention.ts +0 -272
- package/src/engine/boot-validator/projection-list-screens.ts +0 -293
- package/src/engine/boot-validator/query-output-columns.ts +0 -273
- package/src/engine/boot-validator/query-refs.ts +0 -141
- package/src/engine/boot-validator/record-owned.ts +0 -21
- package/src/engine/boot-validator/screens.ts +0 -2604
- package/src/engine/boot-validator/security-baseline.ts +0 -26
- package/src/engine/boot-validator/transfer-graph.ts +0 -135
- package/src/engine/boot-validator/url-prefill-fields.ts +0 -178
- package/src/engine/boot-validator/workspaces.ts +0 -106
- package/src/engine/boot-validator/zod-shape.ts +0 -142
- package/src/engine/boot-validator.ts +0 -8
- package/src/engine/build-app-schema.ts +0 -542
- package/src/engine/build-config-feature-schema.ts +0 -815
- package/src/engine/build-target.ts +0 -99
- package/src/engine/changeset-changes.ts +0 -117
- package/src/engine/codemod/index.ts +0 -15
- package/src/engine/codemod/pipeline-codemod.ts +0 -641
- package/src/engine/config-helpers.ts +0 -217
- package/src/engine/constants.ts +0 -117
- package/src/engine/create-app.ts +0 -177
- package/src/engine/cross-tenant.test.ts +0 -32
- package/src/engine/cross-tenant.ts +0 -22
- package/src/engine/dedupe-features.ts +0 -46
- package/src/engine/define-feature.ts +0 -169
- package/src/engine/define-handler.ts +0 -194
- package/src/engine/define-roles.ts +0 -19
- package/src/engine/define-step.ts +0 -28
- package/src/engine/define-workflow.ts +0 -147
- package/src/engine/effective-features.ts +0 -97
- package/src/engine/embedded-derived.ts +0 -93
- package/src/engine/entity-handlers.ts +0 -782
- package/src/engine/escape-hatch-declaration.ts +0 -7
- package/src/engine/event-helpers.ts +0 -73
- package/src/engine/extension-names.ts +0 -242
- package/src/engine/extension-selector-plugins.ts +0 -24
- package/src/engine/extensions/__tests__/hook-ctx-db-tenant-scoped.test.ts +0 -76
- package/src/engine/extensions/escape-hatch-usage.ts +0 -16
- package/src/engine/extensions/storage-provider.ts +0 -16
- package/src/engine/extensions/tenant-data.ts +0 -34
- package/src/engine/extensions/tenant-resource.ts +0 -40
- package/src/engine/extensions/user-data.ts +0 -181
- package/src/engine/factories.ts +0 -559
- package/src/engine/feature-ast/__tests__/canonical-form.test.ts +0 -416
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-name-const/constants.ts +0 -1
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-name-const/feature.ts +0 -8
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-patch-const/constants.ts +0 -2
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-patch-const/feature.ts +0 -8
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/feature.ts +0 -9
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/screens.ts +0 -4
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/alias-reexport.ts +0 -1
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/cycle-a.ts +0 -1
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/cycle-b.ts +0 -1
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/entry.ts +0 -3
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/local-rebind.ts +0 -3
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/origin.ts +0 -1
- package/src/engine/feature-ast/__tests__/fixtures/resolve-import/star-barrel.ts +0 -1
- package/src/engine/feature-ast/__tests__/handler-header-roundtrip.test.ts +0 -669
- package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +0 -196
- package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +0 -138
- package/src/engine/feature-ast/__tests__/parse.test.ts +0 -2841
- package/src/engine/feature-ast/__tests__/patch-update.test.ts +0 -718
- package/src/engine/feature-ast/__tests__/patch.test.ts +0 -780
- package/src/engine/feature-ast/__tests__/patcher.test.ts +0 -468
- package/src/engine/feature-ast/__tests__/pattern-change-schema.test.ts +0 -819
- package/src/engine/feature-ast/__tests__/read-optional-access-rule.test.ts +0 -42
- package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +0 -947
- package/src/engine/feature-ast/__tests__/resolve-import.test.ts +0 -138
- package/src/engine/feature-ast/entity-field-types.ts +0 -41
- package/src/engine/feature-ast/extractors/ai-steps.ts +0 -352
- package/src/engine/feature-ast/extractors/events.ts +0 -349
- package/src/engine/feature-ast/extractors/handlers.ts +0 -459
- package/src/engine/feature-ast/extractors/hooks.ts +0 -331
- package/src/engine/feature-ast/extractors/index.ts +0 -92
- package/src/engine/feature-ast/extractors/jobs-routes.ts +0 -225
- package/src/engine/feature-ast/extractors/projections-screens.ts +0 -269
- package/src/engine/feature-ast/extractors/resolve-import.ts +0 -187
- package/src/engine/feature-ast/extractors/round1.ts +0 -150
- package/src/engine/feature-ast/extractors/round2.ts +0 -276
- package/src/engine/feature-ast/extractors/round3.ts +0 -474
- package/src/engine/feature-ast/extractors/round5.ts +0 -114
- package/src/engine/feature-ast/extractors/round6.ts +0 -32
- package/src/engine/feature-ast/extractors/shared.ts +0 -356
- package/src/engine/feature-ast/index.ts +0 -113
- package/src/engine/feature-ast/parse.ts +0 -615
- package/src/engine/feature-ast/patch.ts +0 -979
- package/src/engine/feature-ast/patcher.ts +0 -546
- package/src/engine/feature-ast/pattern-change-schema.ts +0 -1411
- package/src/engine/feature-ast/patterns.ts +0 -803
- package/src/engine/feature-ast/render.ts +0 -767
- package/src/engine/feature-ast/source-location.ts +0 -45
- package/src/engine/feature-builder-state.ts +0 -174
- package/src/engine/feature-changelog.ts +0 -95
- package/src/engine/feature-config-events-jobs.ts +0 -472
- package/src/engine/feature-entity-handlers.ts +0 -269
- package/src/engine/feature-manifest.ts +0 -173
- package/src/engine/feature-ui-extensions.ts +0 -648
- package/src/engine/field-access.ts +0 -140
- package/src/engine/field-helpers.ts +0 -35
- package/src/engine/handler-helpers.ts +0 -26
- package/src/engine/hook-helpers.ts +0 -16
- package/src/engine/i18n-key.ts +0 -12
- package/src/engine/index.ts +0 -585
- package/src/engine/instruction-fields.ts +0 -11
- package/src/engine/membership-roles.ts +0 -61
- package/src/engine/object-form.ts +0 -27
- package/src/engine/ownership.ts +0 -404
- package/src/engine/parse-ref-target.ts +0 -28
- package/src/engine/pattern-library/__tests__/library.test.ts +0 -399
- package/src/engine/pattern-library/index.ts +0 -24
- package/src/engine/pattern-library/library.ts +0 -140
- package/src/engine/pattern-library/mixed-schemas.ts +0 -588
- package/src/engine/pattern-library/opaque-schemas.ts +0 -124
- package/src/engine/pattern-library/shared-fields.ts +0 -79
- package/src/engine/pattern-library/static-schemas.ts +0 -456
- package/src/engine/pattern-library/types.ts +0 -255
- package/src/engine/personal-data-fields.ts +0 -66
- package/src/engine/pipeline.ts +0 -111
- package/src/engine/project-app-schema-for-roles.ts +0 -950
- package/src/engine/projection-helpers.ts +0 -79
- package/src/engine/qualified-name.ts +0 -165
- package/src/engine/read-claim.ts +0 -31
- package/src/engine/registry-facade.ts +0 -381
- package/src/engine/registry-ingest.ts +0 -479
- package/src/engine/registry-state.ts +0 -410
- package/src/engine/registry-validate.ts +0 -810
- package/src/engine/registry.ts +0 -94
- package/src/engine/resolve-config-or-param.ts +0 -157
- package/src/engine/role-assignment.ts +0 -63
- package/src/engine/run-in.ts +0 -29
- package/src/engine/run-pipeline.ts +0 -162
- package/src/engine/schema-builder.ts +0 -428
- package/src/engine/screen-filter-ops.ts +0 -60
- package/src/engine/screen-helpers.ts +0 -161
- package/src/engine/soft-delete-cleanup.ts +0 -126
- package/src/engine/state-machine.ts +0 -71
- package/src/engine/steps/__tests__/duration-utils.test.ts +0 -20
- package/src/engine/steps/_duration-utils.ts +0 -35
- package/src/engine/steps/_event-match.ts +0 -98
- package/src/engine/steps/_no-return-guard.ts +0 -21
- package/src/engine/steps/_read-source.ts +0 -12
- package/src/engine/steps/_resolver-utils.ts +0 -42
- package/src/engine/steps/_step-dispatch-constants.ts +0 -38
- package/src/engine/steps/aggregate-append-event.ts +0 -56
- package/src/engine/steps/aggregate-create.ts +0 -56
- package/src/engine/steps/aggregate-update.ts +0 -68
- package/src/engine/steps/branch.ts +0 -84
- package/src/engine/steps/call-feature.ts +0 -49
- package/src/engine/steps/compute.ts +0 -41
- package/src/engine/steps/describe-workflow-step-error.ts +0 -6
- package/src/engine/steps/for-each.ts +0 -111
- package/src/engine/steps/mail-send.ts +0 -48
- package/src/engine/steps/read-find-many.ts +0 -57
- package/src/engine/steps/read-find-one.ts +0 -59
- package/src/engine/steps/retry.ts +0 -99
- package/src/engine/steps/return.ts +0 -35
- package/src/engine/steps/unsafe-projection-delete.ts +0 -50
- package/src/engine/steps/unsafe-projection-upsert.ts +0 -88
- package/src/engine/steps/wait-for-event.ts +0 -90
- package/src/engine/steps/wait.ts +0 -69
- package/src/engine/steps/webhook-send.ts +0 -63
- package/src/engine/system-user.ts +0 -38
- package/src/engine/tier-resolver-extension.ts +0 -107
- package/src/engine/types/config.ts +0 -2
- package/src/engine/types/define-handler.ts +0 -2
- package/src/engine/types/entity-handlers.ts +0 -2
- package/src/engine/types/feature.ts +0 -2
- package/src/engine/types/fields.ts +0 -2
- package/src/engine/types/handlers.ts +0 -3
- package/src/engine/types/hooks.ts +0 -2
- package/src/engine/types/index.ts +0 -394
- package/src/engine/types/nav.ts +0 -2
- package/src/engine/types/ownership.ts +0 -2
- package/src/engine/types/projection.ts +0 -2
- package/src/engine/types/screen.ts +0 -3
- package/src/engine/types/step.ts +0 -2
- package/src/engine/types/workspace.ts +0 -2
- package/src/engine/validate-projection-allowlist.ts +0 -191
- package/src/engine/validation.ts +0 -33
- package/src/engine/where-rule-lint.ts +0 -196
- package/src/engine/write-handler-qn-extract.ts +0 -47
- package/src/entrypoint/__tests__/entrypoint-attach-dispatcher.integration.test.ts +0 -140
- package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +0 -292
- package/src/entrypoint/__tests__/split-deploy.integration.test.ts +0 -467
- package/src/entrypoint/index.ts +0 -541
- package/src/env/__tests__/compose-env-schema.test.ts +0 -410
- package/src/env/__tests__/dry-run.test.ts +0 -161
- package/src/env/__tests__/parse-env-dry-run.test.ts +0 -40
- package/src/env/_zod-introspect.ts +0 -51
- package/src/env/dry-run.ts +0 -204
- package/src/env/index.ts +0 -435
- package/src/errors/__tests__/classes.test.ts +0 -442
- package/src/errors/__tests__/error-helpers.test.ts +0 -58
- package/src/errors/__tests__/reason-i18n.test.ts +0 -46
- package/src/errors/__tests__/write-failures.test.ts +0 -167
- package/src/errors/classes.ts +0 -311
- package/src/errors/field-issue.ts +0 -8
- package/src/errors/i18n/de.yaml +0 -244
- package/src/errors/i18n/en.yaml +0 -234
- package/src/errors/index.ts +0 -47
- package/src/errors/kumiko-error.ts +0 -67
- package/src/errors/member-resolution.ts +0 -12
- package/src/errors/reasons.ts +0 -102
- package/src/errors/serialize.ts +0 -136
- package/src/errors/to-kumiko-error.ts +0 -8
- package/src/errors/transition-details.ts +0 -30
- package/src/errors/write-error-info.ts +0 -124
- package/src/errors/zod-bridge.ts +0 -62
- package/src/es-ops/README.md +0 -179
- package/src/es-ops/__tests__/context.integration.test.ts +0 -378
- package/src/es-ops/__tests__/runner.integration.test.ts +0 -483
- package/src/es-ops/__tests__/runner.test.ts +0 -202
- package/src/es-ops/context.ts +0 -98
- package/src/es-ops/index.ts +0 -34
- package/src/es-ops/operations-schema.ts +0 -57
- package/src/es-ops/runner.ts +0 -253
- package/src/es-ops/types.ts +0 -124
- package/src/event-store/__tests__/admin-api.integration.test.ts +0 -412
- package/src/event-store/__tests__/backfill-pii.integration.test.ts +0 -880
- package/src/event-store/__tests__/event-attribution.integration.test.ts +0 -236
- package/src/event-store/__tests__/event-store.integration.test.ts +0 -932
- package/src/event-store/__tests__/get-stream-version-perf.integration.test.ts +0 -87
- package/src/event-store/__tests__/perf.integration.test.ts +0 -283
- package/src/event-store/__tests__/provenance-append.integration.test.ts +0 -140
- package/src/event-store/__tests__/row-to-stored-event.test.ts +0 -68
- package/src/event-store/__tests__/snapshot.integration.test.ts +0 -328
- package/src/event-store/__tests__/transfer.integration.test.ts +0 -236
- package/src/event-store/__tests__/unscoped-stream-primitives.guard.test.ts +0 -62
- package/src/event-store/__tests__/upcaster-dead-letter.integration.test.ts +0 -202
- package/src/event-store/__tests__/upcaster.integration.test.ts +0 -491
- package/src/event-store/admin-api.ts +0 -241
- package/src/event-store/archive.ts +0 -83
- package/src/event-store/errors.ts +0 -58
- package/src/event-store/event-store.ts +0 -449
- package/src/event-store/events-schema.ts +0 -89
- package/src/event-store/index.ts +0 -80
- package/src/event-store/provenance-append.ts +0 -67
- package/src/event-store/rebuild-dead-letter.ts +0 -111
- package/src/event-store/row-to-stored-event.ts +0 -34
- package/src/event-store/snapshot.ts +0 -235
- package/src/event-store/transfer.ts +0 -84
- package/src/event-store/types.ts +0 -2
- package/src/event-store/upcaster-dead-letter.ts +0 -120
- package/src/event-store/upcaster.ts +0 -147
- package/src/files/__tests__/build-storage-key.test.ts +0 -28
- package/src/files/__tests__/content-disposition.test.ts +0 -123
- package/src/files/__tests__/file-field-pipeline.integration.test.ts +0 -229
- package/src/files/__tests__/file-handle.test.ts +0 -175
- package/src/files/__tests__/file-ref-entity.test.ts +0 -42
- package/src/files/__tests__/files.integration.test.ts +0 -1749
- package/src/files/__tests__/in-memory-provider.contract.test.ts +0 -4
- package/src/files/__tests__/in-memory-provider.test.ts +0 -94
- package/src/files/__tests__/local-provider.contract.test.ts +0 -14
- package/src/files/__tests__/local-provider.test.ts +0 -31
- package/src/files/__tests__/provider-resolver.test.ts +0 -70
- package/src/files/__tests__/read-stream.test.ts +0 -105
- package/src/files/__tests__/storage-tracking.integration.test.ts +0 -238
- package/src/files/__tests__/storage-tracking.test.ts +0 -46
- package/src/files/__tests__/write-stream.test.ts +0 -250
- package/src/files/__tests__/zip-stream.test.ts +0 -357
- package/src/files/content-disposition.ts +0 -55
- package/src/files/feature.ts +0 -44
- package/src/files/file-handle.ts +0 -83
- package/src/files/file-ref-entity.ts +0 -33
- package/src/files/file-ref-table.ts +0 -13
- package/src/files/file-routes.ts +0 -579
- package/src/files/in-memory-provider.ts +0 -113
- package/src/files/index.ts +0 -57
- package/src/files/local-provider.ts +0 -132
- package/src/files/provider-resolver.ts +0 -176
- package/src/files/storage-tracking.ts +0 -245
- package/src/files/types.ts +0 -336
- package/src/files/zip-stream.ts +0 -251
- package/src/http/index.ts +0 -10
- package/src/i18n/__tests__/i18n.test.ts +0 -113
- package/src/i18n/__tests__/mail-registry.test.ts +0 -54
- package/src/i18n/__tests__/request-locale.test.ts +0 -19
- package/src/i18n/__tests__/required-surface-keys.test.ts +0 -17
- package/src/i18n/index.ts +0 -51
- package/src/i18n/mail-registry.ts +0 -42
- package/src/i18n/request-locale.ts +0 -72
- package/src/i18n/required-surface-keys.ts +0 -459
- package/src/i18n/settings-hub-keys.ts +0 -31
- package/src/jobs/__tests__/job-attempt-context.integration.test.ts +0 -76
- package/src/jobs/__tests__/job-backoff.integration.test.ts +0 -147
- package/src/jobs/__tests__/job-event-trigger.integration.test.ts +0 -175
- package/src/jobs/__tests__/job-last-success.integration.test.ts +0 -135
- package/src/jobs/__tests__/job-multi-trigger.integration.test.ts +0 -147
- package/src/jobs/__tests__/job-public-intake-origin.integration.test.ts +0 -536
- package/src/jobs/__tests__/job-queue-depth.integration.test.ts +0 -82
- package/src/jobs/__tests__/job-retention.integration.test.ts +0 -316
- package/src/jobs/__tests__/job-retry-enqueue-paths.integration.test.ts +0 -309
- package/src/jobs/__tests__/job-runner-boot-timeout.test.ts +0 -55
- package/src/jobs/__tests__/job-systemdb.integration.test.ts +0 -153
- package/src/jobs/__tests__/job-tenant-db.integration.test.ts +0 -162
- package/src/jobs/__tests__/job-write-as.integration.test.ts +0 -251
- package/src/jobs/__tests__/jobs.integration.test.ts +0 -1563
- package/src/jobs/__tests__/scheduler-id.test.ts +0 -30
- package/src/jobs/index.ts +0 -8
- package/src/jobs/job-runner.ts +0 -1390
- package/src/lifecycle/__tests__/create-test-lifecycle.ts +0 -19
- package/src/lifecycle/__tests__/lifecycle-server.integration.test.ts +0 -108
- package/src/lifecycle/__tests__/lifecycle.test.ts +0 -212
- package/src/lifecycle/__tests__/signal-handlers.test.ts +0 -98
- package/src/lifecycle/index.ts +0 -13
- package/src/lifecycle/lifecycle.ts +0 -157
- package/src/lifecycle/signal-handlers.ts +0 -64
- package/src/logging/__tests__/fallback-logger.test.ts +0 -90
- package/src/logging/__tests__/pino-trace-bridge.test.ts +0 -50
- package/src/logging/index.ts +0 -4
- package/src/logging/pino-logger.ts +0 -68
- package/src/logging/utils.ts +0 -50
- package/src/migrations/__tests__/kumiko-drift.integration.test.ts +0 -238
- package/src/migrations/__tests__/kumiko-drift.report.test.ts +0 -105
- package/src/migrations/__tests__/pending-rebuilds.integration.test.ts +0 -412
- package/src/migrations/__tests__/pii-event-backfill.integration.test.ts +0 -457
- package/src/migrations/index.ts +0 -36
- package/src/migrations/kumiko-drift.ts +0 -187
- package/src/migrations/pending-rebuilds.ts +0 -251
- package/src/migrations/pii-event-backfill.ts +0 -422
- package/src/migrations/projection-table-index.ts +0 -23
- package/src/observability/__tests__/console-provider.test.ts +0 -67
- package/src/observability/__tests__/escape-hatch-report.test.ts +0 -149
- package/src/observability/__tests__/metric-validator.test.ts +0 -95
- package/src/observability/__tests__/metrics-handle.test.ts +0 -30
- package/src/observability/__tests__/metrics-wiring.test.ts +0 -61
- package/src/observability/__tests__/noop-provider.test.ts +0 -82
- package/src/observability/__tests__/observability.integration.test.ts +0 -639
- package/src/observability/__tests__/prometheus-meter.test.ts +0 -144
- package/src/observability/__tests__/recording-meter.test.ts +0 -101
- package/src/observability/__tests__/recording-tracer.test.ts +0 -112
- package/src/observability/__tests__/sensitive-filter.test.ts +0 -98
- package/src/observability/console-provider.ts +0 -130
- package/src/observability/context.ts +0 -26
- package/src/observability/escape-hatch-report.ts +0 -129
- package/src/observability/fallback.ts +0 -34
- package/src/observability/ids.ts +0 -25
- package/src/observability/index.ts +0 -88
- package/src/observability/metric-validator.ts +0 -98
- package/src/observability/metrics-handle.ts +0 -105
- package/src/observability/metrics-wiring.ts +0 -32
- package/src/observability/noop-provider.ts +0 -137
- package/src/observability/prometheus-meter.ts +0 -286
- package/src/observability/recording-meter.ts +0 -156
- package/src/observability/recording-tracer.ts +0 -186
- package/src/observability/redis-wrapper.ts +0 -132
- package/src/observability/sensitive-filter.ts +0 -108
- package/src/observability/standard-metrics.ts +0 -295
- package/src/pipeline/__tests__/archive-stream.integration.test.ts +0 -299
- package/src/pipeline/__tests__/auth-claims-resolver.test.ts +0 -279
- package/src/pipeline/__tests__/blind-index-rebuild-guard.integration.test.ts +0 -94
- package/src/pipeline/__tests__/cascade-handler.integration.test.ts +0 -435
- package/src/pipeline/__tests__/cascade-handler.test.ts +0 -67
- package/src/pipeline/__tests__/causation-chain.integration.test.ts +0 -207
- package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +0 -507
- package/src/pipeline/__tests__/ctx-systemdb.integration.test.ts +0 -120
- package/src/pipeline/__tests__/dispatcher-utils.test.ts +0 -132
- package/src/pipeline/__tests__/dispatcher.test.ts +0 -1091
- package/src/pipeline/__tests__/distributed-lock.integration.test.ts +0 -110
- package/src/pipeline/__tests__/domain-events-projections.integration.test.ts +0 -323
- package/src/pipeline/__tests__/escape-hatch-audit.integration.test.ts +0 -254
- package/src/pipeline/__tests__/escape-hatch.integration.test.ts +0 -90
- package/src/pipeline/__tests__/event-consumer-state.integration.test.ts +0 -81
- package/src/pipeline/__tests__/event-dedup.integration.test.ts +0 -153
- package/src/pipeline/__tests__/event-define-event-strict.integration.test.ts +0 -196
- package/src/pipeline/__tests__/event-dispatcher-batch-delivery.test.ts +0 -178
- package/src/pipeline/__tests__/event-dispatcher-batch-handler.integration.test.ts +0 -143
- package/src/pipeline/__tests__/event-dispatcher-commit-order.integration.test.ts +0 -278
- package/src/pipeline/__tests__/event-dispatcher-db-outage.integration.test.ts +0 -224
- package/src/pipeline/__tests__/event-dispatcher-delivery-max-attempts.test.ts +0 -127
- package/src/pipeline/__tests__/event-dispatcher-idle.integration.test.ts +0 -94
- package/src/pipeline/__tests__/event-dispatcher-lifecycle.integration.test.ts +0 -209
- package/src/pipeline/__tests__/event-dispatcher-multi-instance.integration.test.ts +0 -424
- package/src/pipeline/__tests__/event-dispatcher-pass-failure.integration.test.ts +0 -266
- package/src/pipeline/__tests__/event-dispatcher-per-consumer-turns.integration.test.ts +0 -126
- package/src/pipeline/__tests__/event-dispatcher-pg-listen.integration.test.ts +0 -106
- package/src/pipeline/__tests__/event-dispatcher-rearm.integration.test.ts +0 -263
- package/src/pipeline/__tests__/event-dispatcher-recovery.integration.test.ts +0 -202
- package/src/pipeline/__tests__/event-dispatcher-second-audit.integration.test.ts +0 -282
- package/src/pipeline/__tests__/event-dispatcher-start-from.integration.test.ts +0 -276
- package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +0 -67
- package/src/pipeline/__tests__/event-dispatcher.integration.test.ts +0 -290
- package/src/pipeline/__tests__/event-retention.integration.test.ts +0 -242
- package/src/pipeline/__tests__/fetch-for-writing.integration.test.ts +0 -364
- package/src/pipeline/__tests__/hook-systemdb-escape-hatch.integration.test.ts +0 -246
- package/src/pipeline/__tests__/idempotency-transient-failure.integration.test.ts +0 -198
- package/src/pipeline/__tests__/instruction-field-gate.integration.test.ts +0 -213
- package/src/pipeline/__tests__/irreversible-operation-gate.integration.test.ts +0 -249
- package/src/pipeline/__tests__/job-trigger-consumer.integration.test.ts +0 -235
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +0 -800
- package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +0 -281
- package/src/pipeline/__tests__/member-resolution-read-only.test.ts +0 -79
- package/src/pipeline/__tests__/msp-error-mode.integration.test.ts +0 -149
- package/src/pipeline/__tests__/msp-multi-hop.integration.test.ts +0 -231
- package/src/pipeline/__tests__/msp-rebuild.integration.test.ts +0 -510
- package/src/pipeline/__tests__/multi-stream-projection.integration.test.ts +0 -313
- package/src/pipeline/__tests__/pending-gap-ranges.test.ts +0 -94
- package/src/pipeline/__tests__/perf-rebuild.integration.test.ts +0 -147
- package/src/pipeline/__tests__/post-query-hook.integration.test.ts +0 -165
- package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +0 -1033
- package/src/pipeline/__tests__/projections-runner-systemscope.integration.test.ts +0 -101
- package/src/pipeline/__tests__/public-intake-runtime-gate.integration.test.ts +0 -684
- package/src/pipeline/__tests__/query-projection.integration.test.ts +0 -357
- package/src/pipeline/__tests__/rate-limit-default.integration.test.ts +0 -118
- package/src/pipeline/__tests__/rate-limit-default.test.ts +0 -117
- package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +0 -275
- package/src/pipeline/__tests__/redis-keys.test.ts +0 -12
- package/src/pipeline/__tests__/redis-pipeline.integration.test.ts +0 -490
- package/src/pipeline/__tests__/search-consumer-named-events.integration.test.ts +0 -274
- package/src/pipeline/__tests__/system-identity-switch.integration.test.ts +0 -583
- package/src/pipeline/__tests__/system-identity-switch.test.ts +0 -645
- package/src/pipeline/__tests__/tenant-timezone-cache.test.ts +0 -89
- package/src/pipeline/__tests__/try-append-event.integration.test.ts +0 -168
- package/src/pipeline/__tests__/unsafe-raw-escape-hatch.integration.test.ts +0 -103
- package/src/pipeline/active-membership.ts +0 -190
- package/src/pipeline/append-event-core.ts +0 -117
- package/src/pipeline/auth-claims-resolver.ts +0 -103
- package/src/pipeline/cascade-handler.ts +0 -109
- package/src/pipeline/dispatch-batch.ts +0 -269
- package/src/pipeline/dispatch-query.ts +0 -195
- package/src/pipeline/dispatch-shared.ts +0 -1242
- package/src/pipeline/dispatch-stream.ts +0 -129
- package/src/pipeline/dispatch-write.ts +0 -599
- package/src/pipeline/dispatcher-utils.ts +0 -199
- package/src/pipeline/dispatcher.ts +0 -278
- package/src/pipeline/distributed-lock.ts +0 -66
- package/src/pipeline/entity-cache.ts +0 -82
- package/src/pipeline/event-consumer-state.ts +0 -190
- package/src/pipeline/event-dedup.ts +0 -23
- package/src/pipeline/event-dispatcher-admin.ts +0 -320
- package/src/pipeline/event-dispatcher-delivery.ts +0 -499
- package/src/pipeline/event-dispatcher.ts +0 -817
- package/src/pipeline/event-retention.ts +0 -144
- package/src/pipeline/idempotency.ts +0 -158
- package/src/pipeline/index.ts +0 -83
- package/src/pipeline/irreversible-operation-gate.ts +0 -76
- package/src/pipeline/lifecycle-pipeline.ts +0 -421
- package/src/pipeline/member-read-only-transaction.ts +0 -71
- package/src/pipeline/member-reader.ts +0 -110
- package/src/pipeline/msp-rebuild.ts +0 -312
- package/src/pipeline/multi-stream-apply-context.ts +0 -85
- package/src/pipeline/pending-gap-ranges.ts +0 -120
- package/src/pipeline/projection-rebuild.ts +0 -539
- package/src/pipeline/projection-state.ts +0 -60
- package/src/pipeline/projections-runner.ts +0 -66
- package/src/pipeline/redis-keys.ts +0 -11
- package/src/pipeline/system-hooks.ts +0 -695
- package/src/pipeline/system-identity-switch.ts +0 -401
- package/src/pipeline/tenant-timezone-cache.ts +0 -92
- package/src/pipeline/write-origin.ts +0 -128
- package/src/random/__tests__/generate.test.ts +0 -149
- package/src/random/__tests__/words.test.ts +0 -44
- package/src/random/generate.ts +0 -141
- package/src/random/index.ts +0 -8
- package/src/random/words.ts +0 -393
- package/src/rate-limit/__tests__/dispatcher-l3.integration.test.ts +0 -111
- package/src/rate-limit/__tests__/middleware.integration.test.ts +0 -246
- package/src/rate-limit/__tests__/resolver.integration.test.ts +0 -211
- package/src/rate-limit/bucket.ts +0 -36
- package/src/rate-limit/index.ts +0 -14
- package/src/rate-limit/middleware.ts +0 -179
- package/src/rate-limit/resolver.ts +0 -251
- package/src/redis/__tests__/redis-options.test.ts +0 -54
- package/src/redis/client.ts +0 -77
- package/src/redis/index.ts +0 -4
- package/src/redis/pubsub-signal.ts +0 -107
- package/src/schema-cli.ts +0 -510
- package/src/search/__tests__/derive-search-adapter-config.test.ts +0 -65
- package/src/search/__tests__/meilisearch-adapter.integration.test.ts +0 -413
- package/src/search/__tests__/meilisearch-ids.test.ts +0 -30
- package/src/search/__tests__/reindex-entity.integration.test.ts +0 -243
- package/src/search/__tests__/search-adapter.test.ts +0 -271
- package/src/search/__tests__/search-consumer-batch.integration.test.ts +0 -306
- package/src/search/__tests__/search-pii-derived-index.integration.test.ts +0 -208
- package/src/search/derive-search-adapter-config.ts +0 -27
- package/src/search/in-memory-adapter.ts +0 -129
- package/src/search/index.ts +0 -20
- package/src/search/meilisearch-adapter.ts +0 -213
- package/src/search/purge-subject.ts +0 -253
- package/src/search/reindex-entity.ts +0 -190
- package/src/secrets/__tests__/contains-secret.test.ts +0 -108
- package/src/secrets/__tests__/dek-cache.test.ts +0 -211
- package/src/secrets/__tests__/derive-purpose-secret.test.ts +0 -52
- package/src/secrets/__tests__/env-master-key-provider.test.ts +0 -119
- package/src/secrets/__tests__/envelope-cipher.test.ts +0 -59
- package/src/secrets/__tests__/envelope.test.ts +0 -74
- package/src/secrets/__tests__/leak-guard.test.ts +0 -104
- package/src/secrets/__tests__/rotation.test.ts +0 -149
- package/src/secrets/dek-cache.ts +0 -137
- package/src/secrets/derive-purpose-secret.ts +0 -17
- package/src/secrets/env-master-key-provider.ts +0 -162
- package/src/secrets/envelope-cipher.ts +0 -53
- package/src/secrets/envelope.ts +0 -57
- package/src/secrets/index.ts +0 -33
- package/src/secrets/leak-guard.ts +0 -87
- package/src/secrets/rotation.ts +0 -34
- package/src/secrets/stored-envelope.ts +0 -46
- package/src/seeding/__tests__/entity-seed.test.ts +0 -70
- package/src/seeding/entity-seed.ts +0 -31
- package/src/seeding/index.ts +0 -6
- package/src/seeding/types.ts +0 -8
- package/src/stack/__tests__/drain-event-consumers.integration.test.ts +0 -166
- package/src/stack/__tests__/drain-jobs.integration.test.ts +0 -159
- package/src/stack/__tests__/event-collector.test.ts +0 -42
- package/src/stack/__tests__/ownership-boot-guard.integration.test.ts +0 -108
- package/src/stack/__tests__/push-entity-projection-tables-column-sync.integration.test.ts +0 -107
- package/src/stack/__tests__/request-helper.integration.test.ts +0 -140
- package/src/stack/__tests__/request-helper.test.ts +0 -159
- package/src/stack/__tests__/setup-test-stack-entity-tables.integration.test.ts +0 -65
- package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +0 -185
- package/src/stack/__tests__/setup-test-stack-metrics.integration.test.ts +0 -79
- package/src/stack/db.ts +0 -82
- package/src/stack/drain-event-consumers.ts +0 -74
- package/src/stack/drain-jobs.ts +0 -129
- package/src/stack/event-collector.ts +0 -23
- package/src/stack/index.ts +0 -34
- package/src/stack/push-entity-projection-tables.ts +0 -95
- package/src/stack/redis.ts +0 -55
- package/src/stack/request-helper.ts +0 -298
- package/src/stack/table-helpers.ts +0 -175
- package/src/stack/test-stack.ts +0 -620
- package/src/stack/test-users.ts +0 -37
- package/src/testing/__tests__/db-cleanup.test.ts +0 -40
- package/src/testing/__tests__/e2e-generator.test.ts +0 -349
- package/src/testing/__tests__/ensure-entity-table.integration.test.ts +0 -52
- package/src/testing/__tests__/late-bound.test.ts +0 -32
- package/src/testing/__tests__/multipart-helper.test.ts +0 -49
- package/src/testing/__tests__/real-providers.test.ts +0 -62
- package/src/testing/__tests__/wait-for.test.ts +0 -104
- package/src/testing/access-assertions.ts +0 -15
- package/src/testing/assertions.ts +0 -35
- package/src/testing/boot-validator-fixture.ts +0 -124
- package/src/testing/closed-connection-error.ts +0 -62
- package/src/testing/db-cleanup.ts +0 -45
- package/src/testing/e2e-generator.ts +0 -494
- package/src/testing/expect-error.ts +0 -25
- package/src/testing/file-provider-contract.ts +0 -123
- package/src/testing/handler-context.ts +0 -143
- package/src/testing/http-cookies.ts +0 -52
- package/src/testing/index.ts +0 -60
- package/src/testing/late-bound.ts +0 -41
- package/src/testing/multipart-helper.ts +0 -94
- package/src/testing/mutable-master-key-provider.ts +0 -57
- package/src/testing/observability-recorder.ts +0 -54
- package/src/testing/real-providers.ts +0 -30
- package/src/testing/seed.ts +0 -50
- package/src/testing/shared-entities.ts +0 -65
- package/src/testing/utils.ts +0 -1
- package/src/testing/wait-for.ts +0 -49
- package/src/testing/without-ambient-temporal.ts +0 -14
- package/src/time/__tests__/boot-tz-warning.test.ts +0 -46
- package/src/time/__tests__/geo-tz.test.ts +0 -71
- package/src/time/__tests__/iana.test.ts +0 -35
- package/src/time/__tests__/polyfill-reinstall.test.ts +0 -17
- package/src/time/__tests__/polyfill.test.ts +0 -73
- package/src/time/__tests__/tz-context.test.ts +0 -121
- package/src/time/__tests__/tz-dateline.test.ts +0 -34
- package/src/time/boot-tz-warning.ts +0 -30
- package/src/time/iana.ts +0 -19
- package/src/time/index.ts +0 -23
- package/src/time/legacy-date.ts +0 -18
- package/src/time/polyfill.ts +0 -59
- package/src/time/tz-context.ts +0 -100
- package/src/ui-types/__tests__/plural.test.ts +0 -108
- package/src/ui-types/app-schema.ts +0 -91
- package/src/ui-types/formality.ts +0 -7
- package/src/ui-types/index.ts +0 -159
- package/src/ui-types/list-row-meta.ts +0 -87
- package/src/ui-types/plural.ts +0 -69
- package/src/upgrade-cli.ts +0 -651
- package/src/utils/__tests__/assert.test.ts +0 -17
- package/src/utils/__tests__/case.test.ts +0 -16
- package/src/utils/__tests__/compare.test.ts +0 -20
- package/src/utils/__tests__/env-parse.test.ts +0 -54
- package/src/utils/__tests__/ids.test.ts +0 -52
- package/src/utils/__tests__/is-plain-object.test.ts +0 -16
- package/src/utils/__tests__/parse-string-array-json.test.ts +0 -16
- package/src/utils/__tests__/safe-json-temporal.test.ts +0 -28
- package/src/utils/__tests__/safe-json.test.ts +0 -22
- package/src/utils/__tests__/serialization.test.ts +0 -30
- package/src/utils/assert.ts +0 -18
- package/src/utils/case.ts +0 -6
- package/src/utils/compare.ts +0 -10
- package/src/utils/env-parse.ts +0 -16
- package/src/utils/ids.ts +0 -26
- package/src/utils/index.ts +0 -9
- package/src/utils/is-plain-object.ts +0 -4
- package/src/utils/parse-string-array-json.ts +0 -14
- package/src/utils/safe-json.ts +0 -50
- package/src/utils/serialization.ts +0 -14
- /package/{src/engine/types/event-type-map.ts → dist/engine/types/event-type-map.d.ts} +0 -0
- /package/{src/engine/types/extension-options-map.ts → dist/engine/types/extension-options-map.d.ts} +0 -0
- /package/{src/engine/types/http-route.ts → dist/engine/types/http-route.d.ts} +0 -0
- /package/{src/engine/types/identifiers.ts → dist/engine/types/identifiers.d.ts} +0 -0
- /package/{src/engine/types/relations.ts → dist/engine/types/relations.d.ts} +0 -0
- /package/{src/engine/types/target-ref.ts → dist/engine/types/target-ref.d.ts} +0 -0
- /package/{src/engine/types/tree-node.ts → dist/engine/types/tree-node.d.ts} +0 -0
- /package/{src/logging/types.ts → dist/logging/types.d.ts} +0 -0
- /package/{src/observability/types/index.ts → dist/observability/types/index.d.ts} +0 -0
- /package/{src/observability/types/metric.ts → dist/observability/types/metric.d.ts} +0 -0
- /package/{src/observability/types/provider.ts → dist/observability/types/provider.d.ts} +0 -0
- /package/{src/observability/types/span.ts → dist/observability/types/span.d.ts} +0 -0
- /package/{src/search/types.ts → dist/search/types.d.ts} +0 -0
- /package/{src/secrets/types.ts → dist/secrets/types.js} +0 -0
- /package/{src/time/geo-tz.ts → dist/time/geo-tz.d.ts} +0 -0
package/src/api/auth-routes.ts
DELETED
|
@@ -1,1590 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import type { Context } from "hono";
|
|
3
|
-
import { Hono } from "hono";
|
|
4
|
-
import { deleteCookie, setCookie } from "hono/cookie";
|
|
5
|
-
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
6
|
-
import type Redis from "ioredis";
|
|
7
|
-
import * as z from "zod";
|
|
8
|
-
import { buildSessionRoles } from "../engine/membership-roles";
|
|
9
|
-
import { createAnonymousUser, createSystemUser } from "../engine/system-user";
|
|
10
|
-
import {
|
|
11
|
-
type ActiveMembershipRejection,
|
|
12
|
-
type ActiveMembershipResult,
|
|
13
|
-
type SessionUser,
|
|
14
|
-
SYSTEM_TENANT_ID,
|
|
15
|
-
type TenantId,
|
|
16
|
-
} from "../engine/types";
|
|
17
|
-
import { NotFoundError, toKumikoError, toWriteErrorInfo } from "../errors";
|
|
18
|
-
import type { Dispatcher } from "../pipeline/dispatcher";
|
|
19
|
-
import { assertUnreachable } from "../utils";
|
|
20
|
-
import { parseRoles } from "../utils/serialization";
|
|
21
|
-
import { Routes } from "./api-constants";
|
|
22
|
-
import {
|
|
23
|
-
AUTH_COOKIE_NAME,
|
|
24
|
-
type AuthSessionChecker,
|
|
25
|
-
type AuthSessionStatus,
|
|
26
|
-
CSRF_COOKIE_NAME,
|
|
27
|
-
getUser,
|
|
28
|
-
type TokenVerifier,
|
|
29
|
-
} from "./auth-middleware";
|
|
30
|
-
import {
|
|
31
|
-
type ClientIpResolver,
|
|
32
|
-
clientIpSourceFromHonoContext,
|
|
33
|
-
createClientIpResolver,
|
|
34
|
-
} from "./client-ip";
|
|
35
|
-
import type { JwtHelper } from "./jwt";
|
|
36
|
-
import type { PostAuthLandingArgs, PostAuthLandingResolver } from "./post-auth-landing";
|
|
37
|
-
import { resolvePostAuthLandingPath } from "./post-auth-landing";
|
|
38
|
-
import { generateToken } from "./tokens";
|
|
39
|
-
|
|
40
|
-
// Resolves the Secure cookie flag. Locked off in dev/test so Playwright
|
|
41
|
-
// against http://localhost:… can actually receive the cookie. Production
|
|
42
|
-
// flips it on — browsers drop Secure cookies on http, so a misconfigured
|
|
43
|
-
// prod deploy would silently break login rather than fail loud.
|
|
44
|
-
function cookieSecure(): boolean {
|
|
45
|
-
return process.env["NODE_ENV"] === "production";
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Double-entry cookie write used at login and switch-tenant. kumiko_auth is
|
|
49
|
-
// the HttpOnly carrier of the JWT; kumiko_csrf is the JS-readable token the
|
|
50
|
-
// web client echoes in X-CSRF-Token on every state-changing request. Both
|
|
51
|
-
// cookies share lifetime and SameSite so a stale auth-cookie can't outlive
|
|
52
|
-
// its csrf partner (or vice versa) and leave the client in a half-logged-in
|
|
53
|
-
// state that would trip the csrf-middleware on every retry.
|
|
54
|
-
function setAuthCookies(
|
|
55
|
-
c: Context,
|
|
56
|
-
opts: {
|
|
57
|
-
token: string;
|
|
58
|
-
csrfToken: string;
|
|
59
|
-
sameSite: "lax" | "strict";
|
|
60
|
-
domain?: string | undefined;
|
|
61
|
-
// Cookie lifetime must track the JWT's exp claim — both are issued
|
|
62
|
-
// together, both reference the same session. Callers pass jwt.ttlSeconds
|
|
63
|
-
// so the two never drift apart.
|
|
64
|
-
ttlSeconds: number;
|
|
65
|
-
},
|
|
66
|
-
): void {
|
|
67
|
-
const sameSite = opts.sameSite === "strict" ? "Strict" : "Lax";
|
|
68
|
-
const common = {
|
|
69
|
-
secure: cookieSecure(),
|
|
70
|
-
sameSite,
|
|
71
|
-
path: "/",
|
|
72
|
-
maxAge: opts.ttlSeconds,
|
|
73
|
-
...(opts.domain !== undefined && { domain: opts.domain }),
|
|
74
|
-
} as const;
|
|
75
|
-
|
|
76
|
-
// Bei gesetzter Domain zuerst die host-only-Variante invalidieren (analog
|
|
77
|
-
// clearAuthCookies): sonst koexistiert nach einem Deploy mit neuem
|
|
78
|
-
// cookieDomain das alte host-only-Cookie mit dem neuen Domain-Cookie
|
|
79
|
-
// (RFC 6265: name+domain ist distinct) und der Server bindet
|
|
80
|
-
// umgebungsabhängig potenziell ans veraltete host-only-Token.
|
|
81
|
-
if (opts.domain !== undefined) {
|
|
82
|
-
deleteCookie(c, AUTH_COOKIE_NAME, { path: "/" });
|
|
83
|
-
deleteCookie(c, CSRF_COOKIE_NAME, { path: "/" });
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
setCookie(c, AUTH_COOKIE_NAME, opts.token, { ...common, httpOnly: true });
|
|
87
|
-
// Intentionally NOT HttpOnly — the web client has to read this from
|
|
88
|
-
// document.cookie to include it in the X-CSRF-Token request header.
|
|
89
|
-
setCookie(c, CSRF_COOKIE_NAME, opts.csrfToken, { ...common, httpOnly: false });
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function clearAuthCookies(c: Context, domain?: string): void {
|
|
93
|
-
// Beide Varianten löschen: mit Domain (aktuelle Cookies) UND host-only
|
|
94
|
-
// (Bestand aus der Zeit vor cookieDomain) — sonst bleibt nach einem
|
|
95
|
-
// Deploy mit neu gesetztem cookieDomain der alte Cookie liegen und der
|
|
96
|
-
// Logout wirkt nur scheinbar.
|
|
97
|
-
deleteCookie(c, AUTH_COOKIE_NAME, { path: "/" });
|
|
98
|
-
deleteCookie(c, CSRF_COOKIE_NAME, { path: "/" });
|
|
99
|
-
if (domain !== undefined) {
|
|
100
|
-
deleteCookie(c, AUTH_COOKIE_NAME, { path: "/", domain });
|
|
101
|
-
deleteCookie(c, CSRF_COOKIE_NAME, { path: "/", domain });
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Body schema for POST /auth/login. Enforced BEFORE rate-limit so that a
|
|
106
|
-
// malformed body (`email: 42`, missing password, …) returns 400 instead of
|
|
107
|
-
// crashing on `.toLowerCase()` and leaking a 500 that never increments the
|
|
108
|
-
// login counter — previous wiring let attackers spam the endpoint without
|
|
109
|
-
// tripping the bucket.
|
|
110
|
-
const LoginBody = z.object({
|
|
111
|
-
email: z.string().min(1),
|
|
112
|
-
password: z.string(),
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// Body schema for POST /auth/mfa/verify. challengeToken is opaque to the
|
|
116
|
-
// framework — it's minted and verified entirely by the mfaVerifyHandler
|
|
117
|
-
// (auth-mfa owns the token format, TOTP/recovery-code check, and the
|
|
118
|
-
// brute-force cap). code covers both 6-digit TOTP and XXXX-XXXX recovery
|
|
119
|
-
// codes (9 chars incl. the dash).
|
|
120
|
-
const MfaVerifyBody = z.object({
|
|
121
|
-
challengeToken: z.string().min(1),
|
|
122
|
-
code: z.string().min(6).max(9),
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// Body schema for POST /auth/mfa/preauth-enable-start. preauthSetupToken is
|
|
126
|
-
// opaque to the framework — minted by login.write.ts's mfaStatusChecker
|
|
127
|
-
// (auth-mfa) when enforcement policy blocks an unenrolled user, verified
|
|
128
|
-
// entirely by the mfaPreauthEnableStartHandler. accountLabel is
|
|
129
|
-
// client-supplied (the email the user just typed at login) for the
|
|
130
|
-
// otpauth:// URI, mirroring auth-mfa's own enable-start.write.ts.
|
|
131
|
-
const MfaPreauthEnableStartBody = z.object({
|
|
132
|
-
preauthSetupToken: z.string().min(1),
|
|
133
|
-
accountLabel: z.string().min(1).max(200),
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// Body schema for POST /auth/mfa/preauth-confirm. setupToken is opaque to
|
|
137
|
-
// the framework — minted by the mfaPreauthEnableStartHandler, verified
|
|
138
|
-
// entirely by the mfaPreauthConfirmHandler. code is TOTP-only (no recovery
|
|
139
|
-
// codes at enrollment time), mirroring auth-mfa's own enable-confirm.write.ts.
|
|
140
|
-
const MfaPreauthConfirmBody = z.object({
|
|
141
|
-
setupToken: z.string().min(1),
|
|
142
|
-
code: z.string().length(6),
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const ResetPasswordBody = z.object({
|
|
146
|
-
token: z.string().min(1),
|
|
147
|
-
newPassword: z.string().min(8).max(200),
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
const VerifyEmailBody = z.object({
|
|
151
|
-
token: z.string().min(1),
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
const SignupConfirmBody = z.object({
|
|
155
|
-
token: z.string().min(1),
|
|
156
|
-
password: z.string().min(8).max(200),
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
// Cross-device try-first handover (kumiko-framework#3035 follow-up,
|
|
160
|
-
// offlot-app#454): an optional tenant-handover grant the signup-request
|
|
161
|
-
// route forwards to the handler for server-side verification and binding —
|
|
162
|
-
// the grant itself never appears anywhere else (URL, mail, log, response).
|
|
163
|
-
const SignupRequestBody = z.object({
|
|
164
|
-
email: z.email(),
|
|
165
|
-
handover: z
|
|
166
|
-
.object({
|
|
167
|
-
entityType: z.string().min(1).max(200),
|
|
168
|
-
token: z.string().min(1).max(4096),
|
|
169
|
-
})
|
|
170
|
-
.optional(),
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
const InviteAcceptBody = z.object({
|
|
174
|
-
token: z.string().min(1),
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const InviteAcceptWithLoginBody = z.object({
|
|
178
|
-
token: z.string().min(1),
|
|
179
|
-
email: z.string().email(),
|
|
180
|
-
password: z.string().min(8).max(200),
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
const InviteSignupCompleteBody = z.object({
|
|
184
|
-
token: z.string().min(1),
|
|
185
|
-
password: z.string().min(8).max(200),
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
const InviteInfoBody = z.object({
|
|
189
|
-
token: z.string().min(1),
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
// Shape guard for "handler not registered" — the only legitimate reason to
|
|
193
|
-
// fall back to a single-tenant reply on /auth/tenants or /auth/switch-tenant.
|
|
194
|
-
// Every other error (DB down, revoker throws, access denied, …) has to
|
|
195
|
-
// propagate — otherwise we'd silently paper over outages.
|
|
196
|
-
function isUnknownHandlerError(e: unknown): boolean {
|
|
197
|
-
if (!(e instanceof NotFoundError)) return false;
|
|
198
|
-
// @cast-boundary error-details — KumikoError.details shape is per-error
|
|
199
|
-
const details = e.details as { entity?: string } | undefined;
|
|
200
|
-
return details?.entity === "handler";
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function switchTenantRejectionResponse(c: Context, reason: ActiveMembershipRejection): Response {
|
|
204
|
-
switch (reason) {
|
|
205
|
-
case "not_a_member":
|
|
206
|
-
return c.json({ error: "not_a_member" }, 403);
|
|
207
|
-
case "principal_blocked":
|
|
208
|
-
return c.json({ error: "principal_blocked" }, 403);
|
|
209
|
-
case "tenant_teardown":
|
|
210
|
-
return c.json({ error: "tenant_unavailable" }, 410);
|
|
211
|
-
default:
|
|
212
|
-
return assertUnreachable(reason, "ActiveMembershipRejection");
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
type MembershipRow = {
|
|
217
|
-
userId: string;
|
|
218
|
-
tenantId: TenantId;
|
|
219
|
-
roles: string[];
|
|
220
|
-
/** Display-Name des Tenants — liefert die membershipQuery seit dem
|
|
221
|
-
* tenant-switcher-Fix mit; optional für ältere App-eigene Queries. */
|
|
222
|
-
tenantName?: string;
|
|
223
|
-
tenantKey?: string;
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
// Pluggable rate-limiter for POST /auth/login. Returning `false` blocks the
|
|
227
|
-
// request with 429 before the login handler runs — use this to slow down
|
|
228
|
-
// brute-force attempts. The framework ships a default in-memory impl; apps
|
|
229
|
-
// can swap it for a Redis-backed one for multi-node deployments.
|
|
230
|
-
export type LoginRateLimiter = {
|
|
231
|
-
check(key: string): Promise<boolean>;
|
|
232
|
-
// Called on successful login so a legitimate user's counter gets reset.
|
|
233
|
-
reset(key: string): Promise<void>;
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
// Per-session metadata forwarded to the sessionCreator. Captured at login
|
|
237
|
-
// time so the sessions feature can store IP/UA alongside each record for
|
|
238
|
-
// session-list UIs ("your devices") and security-audit flows.
|
|
239
|
-
export type SessionMetadata = {
|
|
240
|
-
readonly ip: string;
|
|
241
|
-
readonly userAgent: string;
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
// Invoked on a successful login (and on switch-tenant) so an app can persist
|
|
245
|
-
// a session record and return its ID. The returned string is embedded in the
|
|
246
|
-
// JWT's `jti` claim and echoed back as `SessionUser.sid` on every request.
|
|
247
|
-
// When the callback is not wired, JWTs are stateless — they remain valid
|
|
248
|
-
// until expiration, with no server-side revocation. The framework stays
|
|
249
|
-
// agnostic about WHERE sessions live (DB, Redis, memory); that's the
|
|
250
|
-
// sessions feature's job.
|
|
251
|
-
export type SessionCreator = (user: SessionUser, meta: SessionMetadata) => Promise<string>;
|
|
252
|
-
|
|
253
|
-
// Invoked on logout and on switch-tenant. No-op if the app hasn't wired a
|
|
254
|
-
// sessionCreator; in that case the framework never populates a `sid` and
|
|
255
|
-
// there's nothing to revoke.
|
|
256
|
-
export type SessionRevoker = (sid: string) => Promise<void>;
|
|
257
|
-
|
|
258
|
-
// Mass-revoke every live session for a user. Used by password-change and
|
|
259
|
-
// "sign out everywhere" (sessions feature) and by auth-foundation's
|
|
260
|
-
// SessionStore extension point — canonical home so both can re-export
|
|
261
|
-
// the same type instead of restating it.
|
|
262
|
-
export type SessionMassRevoker = (userId: string) => Promise<number>;
|
|
263
|
-
|
|
264
|
-
// Status reported by the session-store to the auth-middleware. The concrete
|
|
265
|
-
// type lives on auth-middleware to keep the tight coupling visible there;
|
|
266
|
-
// auth-routes just re-uses the alias for the AuthRoutesConfig surface.
|
|
267
|
-
// "live" → let the request through; anything else → 401 with the status as
|
|
268
|
-
// the response reason, so logs/metrics can distinguish "revoked" from
|
|
269
|
-
// "expired" from "someone forged a sid that never existed".
|
|
270
|
-
export type SessionChecker = AuthSessionChecker;
|
|
271
|
-
export type { AuthSessionStatus };
|
|
272
|
-
|
|
273
|
-
export type AuthRoutesConfig = {
|
|
274
|
-
membershipQuery: string; // qualified query handler name, e.g. config.membershipQuery
|
|
275
|
-
// Optional: qualified query handler that returns the user-row inkl.
|
|
276
|
-
// globaler Rollen (`roles` als JSON-encoded string[]). Wenn gesetzt,
|
|
277
|
-
// ruft switch-tenant diese Query und mergt die globalen Rollen mit den
|
|
278
|
-
// tenant-membership-Rollen — so überlebt SystemAdmin (oder ähnliche
|
|
279
|
-
// tenant-unabhängige Rollen) den Tenant-Switch. Erwartete Shape:
|
|
280
|
-
// `{id, roles?: string|null}`. Default nicht gesetzt = kein merge
|
|
281
|
-
// (backwards-compat für Apps ohne globale Rollen).
|
|
282
|
-
userQuery?: string;
|
|
283
|
-
// Optional: qualified write handler for login. When set, POST /auth/login
|
|
284
|
-
// dispatches to this handler with a guest identity and issues a JWT on
|
|
285
|
-
// success. Handler must return { kind: "auth-session", session: SessionUser }.
|
|
286
|
-
loginHandler?: string;
|
|
287
|
-
// Maps feature-specific login error codes to HTTP status codes. Unknown
|
|
288
|
-
// errors default to 400. Keeps the framework unaware of concrete auth codes.
|
|
289
|
-
loginErrorStatusMap?: Readonly<Record<string, number>>;
|
|
290
|
-
// Rate-limit for POST /auth/login. Defaults to in-memory 10/5min per
|
|
291
|
-
// (ip + email) bucket. Pass `null` to disable (tests, trusted networks).
|
|
292
|
-
loginRateLimit?: LoginRateLimiter | null;
|
|
293
|
-
// Optional: qualified write handler completing a two-step (password +
|
|
294
|
-
// TOTP/recovery-code) login. When set, POST /auth/mfa/verify dispatches
|
|
295
|
-
// { challengeToken, code } to this handler with a guest identity. On
|
|
296
|
-
// success the handler must return { kind: "mfa-verify-success", session:
|
|
297
|
-
// SessionUser } and the route mints a JWT exactly like /auth/login.
|
|
298
|
-
// Everything MFA-specific (challenge-token format, TOTP/recovery check,
|
|
299
|
-
// the per-account brute-force cap) is owned by the handler — the
|
|
300
|
-
// framework stays as agnostic about it as it is about password hashing.
|
|
301
|
-
mfaVerifyHandler?: string;
|
|
302
|
-
// Maps mfaVerifyHandler error codes to HTTP status codes, same pattern as
|
|
303
|
-
// loginErrorStatusMap. Unknown errors default to the error's own httpStatus.
|
|
304
|
-
mfaVerifyErrorStatusMap?: Readonly<Record<string, number>>;
|
|
305
|
-
// Rate-limit for POST /auth/mfa/verify, keyed by client IP. Defaults to
|
|
306
|
-
// in-memory 10/5min. Pass `null` to disable. This is DELIBERATELY separate
|
|
307
|
-
// from loginRateLimit: unlike /auth/login (a dispatcher write-handler
|
|
308
|
-
// route that could inherit a handler-level rateLimit), this is a
|
|
309
|
-
// framework route with no handler.rateLimit to fall back on — and it's
|
|
310
|
-
// also separate from any per-account brute-force cap the mfaVerifyHandler
|
|
311
|
-
// enforces itself (see its own doc comment) — IP-scoped abuse protection
|
|
312
|
-
// and per-account guessing protection are different threats, neither
|
|
313
|
-
// substitutes for the other.
|
|
314
|
-
mfaVerifyRateLimit?: LoginRateLimiter | null;
|
|
315
|
-
// Optional: qualified write handler generating a TOTP secret + QR for a
|
|
316
|
-
// user blocked at login by MFA enforcement but not yet enrolled (see
|
|
317
|
-
// mfaStatusChecker's setupRequired branch, auth-mfa). When set, POST
|
|
318
|
-
// /auth/mfa/preauth-enable-start dispatches { preauthSetupToken,
|
|
319
|
-
// accountLabel } to this handler with a guest identity — no session is
|
|
320
|
-
// minted, the response is just { setupToken, otpauthUri, recoveryCodes }
|
|
321
|
-
// (same shape as auth-mfa's own enable-start.write.ts).
|
|
322
|
-
mfaPreauthEnableStartHandler?: string;
|
|
323
|
-
// Maps mfaPreauthEnableStartHandler error codes to HTTP status codes,
|
|
324
|
-
// same pattern as mfaVerifyErrorStatusMap.
|
|
325
|
-
mfaPreauthEnableStartErrorStatusMap?: Readonly<Record<string, number>>;
|
|
326
|
-
// Rate-limit for POST /auth/mfa/preauth-enable-start, keyed by client IP.
|
|
327
|
-
// Defaults to in-memory 10/5min. Pass `null` to disable. This route does
|
|
328
|
-
// NOT inherit the generic L2 authEndpointRateLimit on /api/auth/* by
|
|
329
|
-
// default (that's opt-in per-app via runProdApp's rateLimit.auth), and a
|
|
330
|
-
// preauthSetupToken is valid for the full setup-token TTL and not
|
|
331
|
-
// single-use until preauth-confirm burns it — an unrate-limited replay
|
|
332
|
-
// means every hit re-derives a fresh TOTP secret + 8 argon2id recovery-
|
|
333
|
-
// code hashes (recovery-codes.ts, Promise.all), a memory-hard CPU
|
|
334
|
-
// amplifier reachable from a single stolen/leaked token.
|
|
335
|
-
mfaPreauthEnableStartRateLimit?: LoginRateLimiter | null;
|
|
336
|
-
// Optional: qualified write handler completing the enrollment started by
|
|
337
|
-
// mfaPreauthEnableStartHandler — takes the secret-carrying setupToken
|
|
338
|
-
// from that step plus a TOTP code. When set, POST /auth/mfa/preauth-
|
|
339
|
-
// confirm dispatches { setupToken, code } to this handler with a guest
|
|
340
|
-
// identity. On success the handler must return { kind: "mfa-preauth-
|
|
341
|
-
// confirm-success", session: SessionUser } and the route mints a JWT
|
|
342
|
-
// exactly like /auth/mfa/verify — this call both finishes enrollment AND
|
|
343
|
-
// completes the login that was blocked by mfa-setup-required. Unlike
|
|
344
|
-
// mfaPreauthEnableStartHandler, THIS is the per-account TOTP-guessing
|
|
345
|
-
// surface the enable-start doc comment refers to — the handler owns its
|
|
346
|
-
// own brute-force cap (mirroring mfaVerifyHandler's), and this route adds
|
|
347
|
-
// its own IP-scoped rate limiter for the same reason mfaVerifyRateLimit
|
|
348
|
-
// exists separately from loginRateLimit.
|
|
349
|
-
mfaPreauthConfirmHandler?: string;
|
|
350
|
-
// Maps mfaPreauthConfirmHandler error codes to HTTP status codes, same
|
|
351
|
-
// pattern as mfaVerifyErrorStatusMap.
|
|
352
|
-
mfaPreauthConfirmErrorStatusMap?: Readonly<Record<string, number>>;
|
|
353
|
-
// Rate-limit for POST /auth/mfa/preauth-confirm, keyed by client IP. Same
|
|
354
|
-
// reasoning as mfaVerifyRateLimit — defaults to in-memory 10/5min, pass
|
|
355
|
-
// `null` to disable.
|
|
356
|
-
mfaPreauthConfirmRateLimit?: LoginRateLimiter | null;
|
|
357
|
-
// Session-lifecycle callbacks. When both are wired the JWT carries a `jti`
|
|
358
|
-
// (sid) and the server can revoke individual sessions (logout, compromise,
|
|
359
|
-
// password-change). When unwired the framework issues plain stateless JWTs.
|
|
360
|
-
// Mirrors the loginRateLimit pattern: feature-owned storage, framework-
|
|
361
|
-
// owned routing.
|
|
362
|
-
sessionCreator?: SessionCreator;
|
|
363
|
-
sessionRevoker?: SessionRevoker;
|
|
364
|
-
// Consulted by the auth-middleware on every authenticated request when the
|
|
365
|
-
// incoming JWT carries a `jti`. Paired with sessionCreator: create a sid
|
|
366
|
-
// at login, check it here on every request. Leaving this empty disables
|
|
367
|
-
// the revocation path — old JWTs stay valid until they expire naturally.
|
|
368
|
-
sessionChecker?: SessionChecker;
|
|
369
|
-
// Resolves bearer tokens (any registered auth-foundation `tokenVerifier`
|
|
370
|
-
// provider — PAT today, future JWT-provider), consulted BEFORE jwt.verify.
|
|
371
|
-
// Wired by run-prod-app/run-dev-app when at least one provider feature is
|
|
372
|
-
// mounted; unwired = no non-JWT bearer auth.
|
|
373
|
-
tokenVerifier?: TokenVerifier;
|
|
374
|
-
// Per-token request-rate limiter for PAT-authenticated requests, keyed by
|
|
375
|
-
// the token id (SessionUser.pat.tokenId). Cookie/JWT requests are unaffected.
|
|
376
|
-
// Reuses the LoginRateLimiter shape (a generic keyed check/reset limiter).
|
|
377
|
-
// Wired by run-prod-app when the PAT feature is mounted; unwired = no PAT
|
|
378
|
-
// rate limiting.
|
|
379
|
-
patRateLimiter?: LoginRateLimiter;
|
|
380
|
-
// Tenant-lifecycle 410 gate — wired by tenant-lifecycle / run-prod-app.
|
|
381
|
-
resolveTenantLifecycleStatus?: import("./auth-middleware").TenantLifecycleStatusResolver;
|
|
382
|
-
// Password-reset flow. When wired, POST /auth/request-password-reset and
|
|
383
|
-
// POST /auth/reset-password are mounted as public routes. The framework
|
|
384
|
-
// dispatches to the feature-level handlers (authoring QNs typically come
|
|
385
|
-
// from `AuthHandlers.requestPasswordReset` / `.resetPassword`) and
|
|
386
|
-
// invokes sendResetEmail with the freshly-signed token when a user was
|
|
387
|
-
// actually found. Silent-success: every response to request-reset is
|
|
388
|
-
// { isSuccess: true } regardless of whether the email existed.
|
|
389
|
-
passwordReset?: PasswordResetConfig;
|
|
390
|
-
// Email-verification flow. Symmetric to passwordReset.
|
|
391
|
-
emailVerification?: EmailVerificationConfig;
|
|
392
|
-
// Account-unlock flow (#1266). When wired, POST
|
|
393
|
-
// /auth/request-account-unlock + /auth/confirm-account-unlock are
|
|
394
|
-
// mounted as public routes. Confirm needs no extra body field
|
|
395
|
-
// (token-only, like email-verification) — the handler only clears the
|
|
396
|
-
// Redis lockout state, no entity write.
|
|
397
|
-
accountUnlock?: AccountUnlockConfig;
|
|
398
|
-
// Self-Signup (Magic-Link). Wenn wired, mountet POST
|
|
399
|
-
// /auth/signup-request + /auth/signup-confirm. Confirm returnt JWT-
|
|
400
|
-
// Cookie + Session-Body wie login.
|
|
401
|
-
signup?: SignupConfig;
|
|
402
|
-
// Tenant-Invite (Magic-Link). Mountet 3 accept-Routes für die 3
|
|
403
|
-
// Branches (logged-in / anon-existing-email / anon-new-email).
|
|
404
|
-
invite?: InviteConfig;
|
|
405
|
-
// SameSite flag for the HttpOnly auth cookie + JS-readable csrf cookie
|
|
406
|
-
// issued by /auth/login and /auth/switch-tenant.
|
|
407
|
-
// "lax" (default) — blocks cross-site POSTs entirely (which is what
|
|
408
|
-
// CSRF relies on) while allowing top-level GET navigation
|
|
409
|
-
// from external sites. Email deep-links (invite, magic-link,
|
|
410
|
-
// notification click) keep working.
|
|
411
|
-
// "strict" — blocks the cookie on ANY cross-site navigation including
|
|
412
|
-
// top-level GETs. Strongest CSRF control but silently breaks
|
|
413
|
-
// email deep-links — opt-in for banking / high-security apps
|
|
414
|
-
// that don't ship deep-linkable emails.
|
|
415
|
-
// The framework always pairs the cookie with a Double-Submit CSRF token
|
|
416
|
-
// (see csrf-middleware), so "lax" is defense-in-depth, not defense-alone.
|
|
417
|
-
cookieSameSite?: "lax" | "strict";
|
|
418
|
-
// Domain attribute for both auth cookies. Unset (default) = host-only
|
|
419
|
-
// cookie, scoped to the exact host that served the response. Set it to
|
|
420
|
-
// the registrable parent domain (e.g. "example.eu") when login and app
|
|
421
|
-
// live on DIFFERENT subdomains (login on apex, app on admin.) — the
|
|
422
|
-
// browser then sends the session to every subdomain. Careful: that
|
|
423
|
-
// includes ALL subdomains (tenant pages, previews); widen the scope
|
|
424
|
-
// only when the cross-subdomain session is actually required — and pair
|
|
425
|
-
// it with `allowedOrigins` so the server-side Origin guard stays on (a
|
|
426
|
-
// wide cookie makes the JS-readable csrf cookie reachable from every
|
|
427
|
-
// subdomain, weakening the double-submit defence).
|
|
428
|
-
cookieDomain?: string;
|
|
429
|
-
// Origin-allowlist for the server-side CSRF-hardening guard (origin-
|
|
430
|
-
// middleware). When non-empty, every cookie-authenticated, state-changing
|
|
431
|
-
// /api request must carry an `Origin` header that exact-matches one of
|
|
432
|
-
// these entries (scheme+host+optional port, e.g. "https://example.eu", no
|
|
433
|
-
// trailing slash, no wildcards). Requests without an Origin fall back to
|
|
434
|
-
// Sec-Fetch-Site and then to the CSRF token — the guard is defense-in-
|
|
435
|
-
// depth, not a replacement.
|
|
436
|
-
//
|
|
437
|
-
// List ONLY the trusted entry hosts: the apex and the admin host. Do NOT
|
|
438
|
-
// list tenant/public subdomains — with a wide `cookieDomain` they share
|
|
439
|
-
// the session cookie, so an XSS there is exactly the threat this blocks.
|
|
440
|
-
// Empty/unset (default) disables the guard; required only when
|
|
441
|
-
// `cookieDomain` widens the cookie across subdomains.
|
|
442
|
-
allowedOrigins?: readonly string[];
|
|
443
|
-
// Explicit opt-out of the fail-closed Origin guard. When `cookieDomain` is
|
|
444
|
-
// set the framework REFUSES TO BOOT unless `allowedOrigins` is configured — a
|
|
445
|
-
// wide cookie without an Origin check is the unguarded-subdomain-XSS footgun.
|
|
446
|
-
// Set this true ONLY for a single-host deployment that shares no untrusted
|
|
447
|
-
// subdomains and genuinely needs the wide cookie anyway; you accept that any
|
|
448
|
-
// subdomain can then forge authenticated state-changing requests. Prefer
|
|
449
|
-
// setting `allowedOrigins`.
|
|
450
|
-
unsafeSkipOriginCheck?: boolean;
|
|
451
|
-
// Number of trusted reverse-proxy hops between the client and this
|
|
452
|
-
// process that APPEND (not overwrite) their peer address to
|
|
453
|
-
// `x-forwarded-for` (e.g. nginx `$proxy_add_x_forwarded_for`). Used to
|
|
454
|
-
// derive the client IP for every auth rate-limiter (login, mfa-verify,
|
|
455
|
-
// preauth-enable-start, preauth-confirm) and for requestMeta's session
|
|
456
|
-
// IP via the shared resolveClientIp (see client-ip.ts for the extraction
|
|
457
|
-
// algorithm). Deprecated in favor of the
|
|
458
|
-
// top-level `trustedProxyHops` on ServerOptions/RunProdAppOptions/
|
|
459
|
-
// RunDevAppOptions, which wins when both are set — kept as a fallback so
|
|
460
|
-
// existing consumers that only set this don't regress. Default 0 = trust
|
|
461
|
-
// no proxy header, only the socket address (or "unknown") counts. Set
|
|
462
|
-
// this to your real proxy hop count (1 for a single ingress/reverse-
|
|
463
|
-
// proxy, 2 for edge-LB + ingress, etc.) when deployed behind a proxy.
|
|
464
|
-
trustedProxyHops?: number;
|
|
465
|
-
// Server-computed post-auth redirect, consulted at login, mfa-verify,
|
|
466
|
-
// mfa-preauth-confirm, signup-confirm, and all three invite-accept branches.
|
|
467
|
-
// Result lands in the response as `landingPath`; an invalid path or a
|
|
468
|
-
// throwing resolver just omits the field (see post-auth-landing.ts).
|
|
469
|
-
postAuthLanding?: PostAuthLandingResolver;
|
|
470
|
-
// Shared resolver instance from buildServer — takes precedence over
|
|
471
|
-
// `trustedProxyHops` so the whole server shares exactly one resolver
|
|
472
|
-
// instance (and warn-once flag) instead of building a private one here.
|
|
473
|
-
// Only standalone callers of createAuthRoutes
|
|
474
|
-
// (no buildServer) should rely on `trustedProxyHops` instead.
|
|
475
|
-
resolver?: ClientIpResolver;
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
export type PasswordResetConfig = {
|
|
479
|
-
// Qualified name of the request handler (the one that emits either
|
|
480
|
-
// { kind: "reset-requested", ... } or { kind: "no-op" }). The handler
|
|
481
|
-
// builds the magic-link and sends the mail via delivery (ctx.notify) — the
|
|
482
|
-
// route only dispatches and returns the silent-success envelope.
|
|
483
|
-
requestHandler: string;
|
|
484
|
-
// Qualified name of the confirm handler (token + newPassword → set).
|
|
485
|
-
confirmHandler: string;
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
export type EmailVerificationConfig = {
|
|
489
|
-
requestHandler: string;
|
|
490
|
-
confirmHandler: string;
|
|
491
|
-
};
|
|
492
|
-
|
|
493
|
-
export type AccountUnlockConfig = {
|
|
494
|
-
requestHandler: string;
|
|
495
|
-
// Token-only body (mirrors EmailVerificationConfig) — no entity write, so
|
|
496
|
-
// there's no newPassword-equivalent field.
|
|
497
|
-
confirmHandler: string;
|
|
498
|
-
};
|
|
499
|
-
|
|
500
|
-
// Tenant-Invite Magic-Link. Drei Accept-Branches für klare Separation:
|
|
501
|
-
// - acceptHandler: logged-in User akzeptiert via JWT (Branch 1)
|
|
502
|
-
// - acceptWithLoginHandler: anon User mit existing email (Branch 2)
|
|
503
|
-
// - signupCompleteHandler: anon User mit neuer email (Branch 3)
|
|
504
|
-
// Branch 2+3 minten JWT analog signup-confirm.
|
|
505
|
-
export type InviteConfig = {
|
|
506
|
-
// Qualified handler names. invite-create dispatches the invite mail itself
|
|
507
|
-
// via delivery (ctx.notify); the route layer only wires the accept branches.
|
|
508
|
-
readonly acceptHandler: string;
|
|
509
|
-
readonly acceptWithLoginHandler: string;
|
|
510
|
-
readonly signupCompleteHandler: string;
|
|
511
|
-
// Optional: qualified query handler name for the anonymous invite-info
|
|
512
|
-
// lookup (email + hasAccount for a pending invite, token not consumed).
|
|
513
|
-
// When unset, POST /auth/invite-info is not mounted.
|
|
514
|
-
readonly infoHandler?: string;
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
// Magic-Link Self-Signup. Anders als reset/verify NICHT HMAC-signed —
|
|
518
|
-
// der Token ist opaque random, Redis ist Source of Truth. The request
|
|
519
|
-
// handler dispatches the activation mail via delivery (ctx.notify); the
|
|
520
|
-
// route only forwards the dispatch. Confirm returnt
|
|
521
|
-
// `{ kind: "auth-session", session, tenantKey }` analog zu loginHandler,
|
|
522
|
-
// sodass die Route JWT minten + Cookies setzen kann (Auto-Login direkt
|
|
523
|
-
// nach Activation, kein zweiter login-Roundtrip).
|
|
524
|
-
export type SignupConfig = {
|
|
525
|
-
// Qualified name of the request handler (typisch
|
|
526
|
-
// AuthHandlers.signupRequest).
|
|
527
|
-
requestHandler: string;
|
|
528
|
-
// Qualified name of the confirm handler (typisch
|
|
529
|
-
// AuthHandlers.signupConfirm). Returnt SessionUser-Shape — die
|
|
530
|
-
// Route wickelt das wie einen erfolgreichen login.
|
|
531
|
-
confirmHandler: string;
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
// Second rate-limit axis for preauth-enable-start: unlike the IP, a
|
|
535
|
-
// preauthSetupToken isn't freely choosable by the attacker (it's minted by
|
|
536
|
-
// login.write.ts), so hashing it into a bucket key still caps the replay
|
|
537
|
-
// even when the IP-based bucket is bypassed via header rotation.
|
|
538
|
-
function preauthTokenKeyOf(token: string): string {
|
|
539
|
-
return `preauth-token:${createHash("sha256").update(token).digest("hex")}`;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// Extract `ip` and `user-agent` for the sessionCreator. Client-IP resolution
|
|
543
|
-
// (trustedProxyHops-aware) is the shared resolveClientIp (see client-ip.ts)
|
|
544
|
-
// — createAuthRoutes builds one resolver instance below and
|
|
545
|
-
// closes over it here and in getClientIp.
|
|
546
|
-
function requestMeta(c: Context, resolver: ClientIpResolver): SessionMetadata {
|
|
547
|
-
const ip = resolver.resolve(clientIpSourceFromHonoContext(c));
|
|
548
|
-
const userAgent = c.req.header("user-agent") ?? "unknown";
|
|
549
|
-
return { ip, userAgent };
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// Default: in-memory fixed window. Fine for a single Node process; for
|
|
553
|
-
// multi-process deployments, inject a Redis-backed LoginRateLimiter instead
|
|
554
|
-
// so attempts can't be spread across replicas.
|
|
555
|
-
//
|
|
556
|
-
// Memory management: entries expire after `windowMs` but the map entries
|
|
557
|
-
// themselves linger until something touches them. To stop the map from
|
|
558
|
-
// growing unbounded (a single attacker can create entries with different
|
|
559
|
-
// `ip|email` buckets at ~req rate), we opportunistically sweep expired
|
|
560
|
-
// entries when the map crosses `sweepThreshold` keys and hard-cap total
|
|
561
|
-
// entries at `maxEntries` — oldest ones get dropped first.
|
|
562
|
-
export function createInMemoryLoginRateLimiter(
|
|
563
|
-
maxAttempts = 10,
|
|
564
|
-
windowMs = 5 * 60_000,
|
|
565
|
-
{
|
|
566
|
-
maxEntries = 10_000,
|
|
567
|
-
sweepThreshold = 1_000,
|
|
568
|
-
}: { maxEntries?: number; sweepThreshold?: number } = {},
|
|
569
|
-
): LoginRateLimiter {
|
|
570
|
-
const hits = new Map<string, { count: number; resetAt: number }>();
|
|
571
|
-
|
|
572
|
-
function sweepExpired(now: number): void {
|
|
573
|
-
for (const [k, entry] of hits) {
|
|
574
|
-
if (entry.resetAt <= now) hits.delete(k);
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
function enforceCap(): void {
|
|
579
|
-
// Map iteration is insertion-order, so the oldest entries are first.
|
|
580
|
-
// Drop from the front until we're back under the cap.
|
|
581
|
-
// skip: under the cap, nothing to do
|
|
582
|
-
if (hits.size <= maxEntries) return;
|
|
583
|
-
const toDrop = hits.size - maxEntries;
|
|
584
|
-
let dropped = 0;
|
|
585
|
-
for (const k of hits.keys()) {
|
|
586
|
-
if (dropped >= toDrop) break;
|
|
587
|
-
hits.delete(k);
|
|
588
|
-
dropped++;
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
return {
|
|
593
|
-
async check(key) {
|
|
594
|
-
const now = Date.now();
|
|
595
|
-
if (hits.size >= sweepThreshold) sweepExpired(now);
|
|
596
|
-
|
|
597
|
-
const entry = hits.get(key);
|
|
598
|
-
if (!entry || entry.resetAt <= now) {
|
|
599
|
-
hits.set(key, { count: 1, resetAt: now + windowMs });
|
|
600
|
-
enforceCap();
|
|
601
|
-
return true;
|
|
602
|
-
}
|
|
603
|
-
if (entry.count >= maxAttempts) return false;
|
|
604
|
-
entry.count++;
|
|
605
|
-
return true;
|
|
606
|
-
},
|
|
607
|
-
async reset(key) {
|
|
608
|
-
hits.delete(key);
|
|
609
|
-
},
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// Redis-backed sibling of createInMemoryLoginRateLimiter — same fixed-window
|
|
614
|
-
// semantics (count <= maxAttempts allows, window anchored on first hit), but
|
|
615
|
-
// shared across replicas via INCR/PEXPIRE instead of an in-process Map.
|
|
616
|
-
// runProdApp defaults to this: an in-memory limiter only rate-limits within
|
|
617
|
-
// a single instance, so a multi-replica prod deployment would silently give
|
|
618
|
-
// each replica its own bucket. namespace separates the login-key keyspace
|
|
619
|
-
// from the mfa-verify one (they share the same LoginRateLimiter shape but
|
|
620
|
-
// key on different values).
|
|
621
|
-
// Fail-closed on Redis outage, unlike the in-memory limiter (which never
|
|
622
|
-
// throws): `check`/`reset` propagate any Redis error, so callers 500
|
|
623
|
-
// instead of falling back to unlimited attempts. Deliberate — Redis is
|
|
624
|
-
// already required infra for a multi-replica deployment, and for a
|
|
625
|
-
// security-relevant limiter "briefly unavailable" should read as "briefly
|
|
626
|
-
// down", not "briefly unlimited".
|
|
627
|
-
export function createRedisLoginRateLimiter(
|
|
628
|
-
redis: Redis,
|
|
629
|
-
maxAttempts = 10,
|
|
630
|
-
windowMs = 5 * 60_000,
|
|
631
|
-
namespace = "login",
|
|
632
|
-
): LoginRateLimiter {
|
|
633
|
-
const prefix = `kumiko:auth:ratelimit:${namespace}:`;
|
|
634
|
-
|
|
635
|
-
return {
|
|
636
|
-
async check(key) {
|
|
637
|
-
const redisKey = `${prefix}${key}`;
|
|
638
|
-
// INCR then PEXPIRE was two round-trips: a crash/network blip between
|
|
639
|
-
// them (only possible right after count===1, when the key is fresh)
|
|
640
|
-
// left the key permanently without a TTL — the window never resets,
|
|
641
|
-
// the counter only grows, and the bucket is locked out until an
|
|
642
|
-
// operator manually resets/deletes the key. One atomic eval closes
|
|
643
|
-
// the gap: the TTL is set in the same script invocation that creates
|
|
644
|
-
// the key, so no observer (including a crash) can see count===1
|
|
645
|
-
// without the expiry already applied. The `PTTL < 0` branch also
|
|
646
|
-
// heals keys that already exist without a TTL from before this fix
|
|
647
|
-
// shipped (PTTL returns -1 for "no expiry set, key exists") — without
|
|
648
|
-
// it, those pre-existing keys would grow forever with no way back to
|
|
649
|
-
// a normal window.
|
|
650
|
-
const count = (await redis.eval(
|
|
651
|
-
`local c = redis.call('INCR', KEYS[1])
|
|
652
|
-
if c == 1 or redis.call('PTTL', KEYS[1]) < 0 then redis.call('PEXPIRE', KEYS[1], ARGV[1]) end
|
|
653
|
-
return c`,
|
|
654
|
-
1,
|
|
655
|
-
redisKey,
|
|
656
|
-
windowMs,
|
|
657
|
-
)) as number;
|
|
658
|
-
return count <= maxAttempts;
|
|
659
|
-
},
|
|
660
|
-
async reset(key) {
|
|
661
|
-
await redis.del(`${prefix}${key}`);
|
|
662
|
-
},
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
export function createAuthRoutes(
|
|
667
|
-
dispatcher: Dispatcher,
|
|
668
|
-
jwt: JwtHelper,
|
|
669
|
-
config: AuthRoutesConfig,
|
|
670
|
-
): Hono {
|
|
671
|
-
const api = new Hono();
|
|
672
|
-
// Default to "lax": CSRF control comes from the double-submit token, and
|
|
673
|
-
// "lax" keeps email deep-links (invite, magic-link, notification click)
|
|
674
|
-
// working. High-security apps can opt into "strict" — see AuthRoutesConfig.
|
|
675
|
-
const cookieSameSite = config.cookieSameSite ?? "lax";
|
|
676
|
-
const cookieDomain = config.cookieDomain;
|
|
677
|
-
// Single hop-count-aware IP getter for every rate-limit call site below —
|
|
678
|
-
// see AuthRoutesConfig.trustedProxyHops and client-ip.ts's resolveClientIp
|
|
679
|
-
// doc comment. createClientIpResolver fails loud on a non-finite/negative
|
|
680
|
-
// value rather than letting it silently collapse every request into the
|
|
681
|
-
// shared "unknown" bucket.
|
|
682
|
-
const clientIpResolver =
|
|
683
|
-
config.resolver ?? createClientIpResolver(config.trustedProxyHops ?? 0, "createAuthRoutes");
|
|
684
|
-
const getClientIp = (c: Context): string =>
|
|
685
|
-
clientIpResolver.resolve(clientIpSourceFromHonoContext(c));
|
|
686
|
-
|
|
687
|
-
// Shared tail of every route that ends a request logged-in: create the
|
|
688
|
-
// session record (if wired), sign the JWT, set the auth+csrf cookies. Was
|
|
689
|
-
// duplicated 5x (login/signup-confirm/invite-accept-with-login/invite-
|
|
690
|
-
// signup-complete/switch-tenant) — extracted so a 6th caller (mfa-verify)
|
|
691
|
-
// doesn't grow it to 6.
|
|
692
|
-
async function mintSessionAndRespond(c: Context, session: SessionUser): Promise<string> {
|
|
693
|
-
let sessionForJwt = session;
|
|
694
|
-
if (config.sessionCreator) {
|
|
695
|
-
const sid = await config.sessionCreator(session, requestMeta(c, clientIpResolver));
|
|
696
|
-
sessionForJwt = { ...session, sid };
|
|
697
|
-
}
|
|
698
|
-
const token = await jwt.sign(sessionForJwt);
|
|
699
|
-
const csrfToken = generateToken();
|
|
700
|
-
setAuthCookies(c, {
|
|
701
|
-
token,
|
|
702
|
-
csrfToken,
|
|
703
|
-
sameSite: cookieSameSite,
|
|
704
|
-
domain: cookieDomain,
|
|
705
|
-
ttlSeconds: jwt.ttlSeconds,
|
|
706
|
-
});
|
|
707
|
-
return token;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// Spreadable landingPath fragment for the 7 auth-response call sites below
|
|
711
|
-
// — absent (not `landingPath: undefined`) when unwired/invalid/throwing.
|
|
712
|
-
function landingPathFragment(args: PostAuthLandingArgs): { readonly landingPath?: string } {
|
|
713
|
-
const landingPath = resolvePostAuthLandingPath(config.postAuthLanding, args);
|
|
714
|
-
return landingPath === undefined ? {} : { landingPath };
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
// POST /auth/login — public endpoint (bypasses auth middleware via PUBLIC_API_PATHS).
|
|
718
|
-
// The configured login handler authenticates and returns a SessionUser;
|
|
719
|
-
// the route signs the JWT and hands it back to the client.
|
|
720
|
-
if (config.loginHandler) {
|
|
721
|
-
const loginQn = config.loginHandler;
|
|
722
|
-
const statusMap = config.loginErrorStatusMap ?? {};
|
|
723
|
-
// Default to in-memory limiter unless the caller opted out via null.
|
|
724
|
-
const rateLimiter =
|
|
725
|
-
config.loginRateLimit === null
|
|
726
|
-
? null
|
|
727
|
-
: (config.loginRateLimit ?? createInMemoryLoginRateLimiter());
|
|
728
|
-
|
|
729
|
-
api.post(Routes.authLogin, async (c) => {
|
|
730
|
-
const raw = await c.req.json().catch(() => null);
|
|
731
|
-
const parsed = LoginBody.safeParse(raw);
|
|
732
|
-
if (!parsed.success) {
|
|
733
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
734
|
-
}
|
|
735
|
-
const body = parsed.data;
|
|
736
|
-
|
|
737
|
-
const clientIp = getClientIp(c);
|
|
738
|
-
const rateLimitKey = `${clientIp}|${body.email.toLowerCase()}`;
|
|
739
|
-
|
|
740
|
-
if (rateLimiter) {
|
|
741
|
-
// Bucket by both IP and email so a single guessed password can't
|
|
742
|
-
// block a real user from logging in, but also so one abuser can't
|
|
743
|
-
// just cycle emails.
|
|
744
|
-
const allowed = await rateLimiter.check(rateLimitKey);
|
|
745
|
-
if (!allowed) {
|
|
746
|
-
return c.json({ isSuccess: false, error: "rate_limited" }, 429);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
const result = await dispatcher.write(loginQn, body, createAnonymousUser(SYSTEM_TENANT_ID));
|
|
751
|
-
|
|
752
|
-
if (!result.isSuccess) {
|
|
753
|
-
// Feature-specific auth reason codes arrive via UnprocessableError.details.reason
|
|
754
|
-
// (e.g. "invalid_credentials", "user_locked"). Fall back to the KumikoError code
|
|
755
|
-
// so unmapped cases still get a sensible status.
|
|
756
|
-
// @cast-boundary error-details — KumikoError.details shape is per-error
|
|
757
|
-
const reason =
|
|
758
|
-
(result.error.details as { reason?: string } | undefined)?.reason ?? result.error.code;
|
|
759
|
-
// @cast-boundary engine-payload — statusMap value union narrows to the http-status union
|
|
760
|
-
const status = (statusMap[reason] ?? result.error.httpStatus) as 400 | 401 | 403 | 500;
|
|
761
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
// @cast-boundary engine-payload — generic dispatcher.write result for
|
|
765
|
-
// login. Three possible shapes: a straight session, an MFA challenge
|
|
766
|
-
// when the loginHandler is wired with a second-factor gate, or a hard
|
|
767
|
-
// block when enforcement policy demands MFA but the user never
|
|
768
|
-
// enrolled (see auth-mfa's config.ts for why this has no in-band
|
|
769
|
-
// recovery yet).
|
|
770
|
-
const data = result.data as
|
|
771
|
-
| { kind: "auth-session"; session: SessionUser }
|
|
772
|
-
| { kind: "mfa-challenge"; challengeToken: string }
|
|
773
|
-
| { kind: "mfa-setup-required"; preauthSetupToken: string };
|
|
774
|
-
|
|
775
|
-
if (data.kind === "mfa-setup-required") {
|
|
776
|
-
// No session, no challenge — the client must show an
|
|
777
|
-
// enrollment-required message. No rate-limit reset (same reasoning
|
|
778
|
-
// as the mfa-challenge branch below).
|
|
779
|
-
return c.json({
|
|
780
|
-
isSuccess: true,
|
|
781
|
-
mfaSetupRequired: true,
|
|
782
|
-
preauthSetupToken: data.preauthSetupToken,
|
|
783
|
-
});
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
if (data.kind === "mfa-challenge") {
|
|
787
|
-
// No session minted yet — no cookies, no token. The client must
|
|
788
|
-
// complete /auth/mfa/verify with this token before it gets either.
|
|
789
|
-
// Rate-limit counter is NOT reset here: a "correct password, wrong/
|
|
790
|
-
// no TOTP yet" outcome hasn't proven the caller owns the account any
|
|
791
|
-
// more than a wrong password did.
|
|
792
|
-
return c.json({ isSuccess: true, mfaRequired: true, challengeToken: data.challengeToken });
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// Session creation (optional) + JWT sign + cookies — see
|
|
796
|
-
// mintSessionAndRespond. Creating the session BEFORE signing the JWT
|
|
797
|
-
// is load-bearing: the sid must exist on the server before the token
|
|
798
|
-
// that references it can be handed out, otherwise a fast client could
|
|
799
|
-
// arrive at an auth-middleware check before the insert commits.
|
|
800
|
-
const token = await mintSessionAndRespond(c, data.session);
|
|
801
|
-
const landingPath = landingPathFragment({
|
|
802
|
-
flow: "login",
|
|
803
|
-
roles: data.session.roles,
|
|
804
|
-
tenantId: data.session.tenantId,
|
|
805
|
-
});
|
|
806
|
-
|
|
807
|
-
if (rateLimiter) {
|
|
808
|
-
await rateLimiter.reset(rateLimitKey);
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
return c.json({
|
|
812
|
-
isSuccess: true,
|
|
813
|
-
token,
|
|
814
|
-
user: { id: data.session.id, tenantId: data.session.tenantId, roles: data.session.roles },
|
|
815
|
-
...landingPath,
|
|
816
|
-
});
|
|
817
|
-
});
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
// POST /auth/mfa/verify — completes a two-step login. Mirrors /auth/login
|
|
821
|
-
// structurally (public, anonymous identity dispatch, mintSessionAndRespond on
|
|
822
|
-
// success) but with its OWN rate limiter (mfaVerifyRateLimit) — this route
|
|
823
|
-
// never goes through a dispatcher write-handler's own rateLimit config,
|
|
824
|
-
// so without this it would have NO rate limiting at all. Per-account
|
|
825
|
-
// brute-force protection (capping wrong-code guesses against one
|
|
826
|
-
// still-valid challenge token) is a separate mechanism the handler itself
|
|
827
|
-
// owns — see AuthRoutesConfig.mfaVerifyHandler's doc comment.
|
|
828
|
-
if (config.mfaVerifyHandler) {
|
|
829
|
-
const mfaVerifyQn = config.mfaVerifyHandler;
|
|
830
|
-
const statusMap = config.mfaVerifyErrorStatusMap ?? {};
|
|
831
|
-
const rateLimiter =
|
|
832
|
-
config.mfaVerifyRateLimit === null
|
|
833
|
-
? null
|
|
834
|
-
: (config.mfaVerifyRateLimit ?? createInMemoryLoginRateLimiter());
|
|
835
|
-
|
|
836
|
-
api.post(Routes.authMfaVerify, async (c) => {
|
|
837
|
-
const raw = await c.req.json().catch(() => null);
|
|
838
|
-
const parsed = MfaVerifyBody.safeParse(raw);
|
|
839
|
-
if (!parsed.success) {
|
|
840
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
841
|
-
}
|
|
842
|
-
const body = parsed.data;
|
|
843
|
-
|
|
844
|
-
const clientIp = getClientIp(c);
|
|
845
|
-
|
|
846
|
-
if (rateLimiter) {
|
|
847
|
-
const allowed = await rateLimiter.check(clientIp);
|
|
848
|
-
if (!allowed) {
|
|
849
|
-
return c.json({ isSuccess: false, error: "rate_limited" }, 429);
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
const result = await dispatcher.write(
|
|
854
|
-
mfaVerifyQn,
|
|
855
|
-
body,
|
|
856
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
857
|
-
);
|
|
858
|
-
|
|
859
|
-
if (!result.isSuccess) {
|
|
860
|
-
// @cast-boundary error-details — KumikoError.details shape is per-error
|
|
861
|
-
const reason =
|
|
862
|
-
(result.error.details as { reason?: string } | undefined)?.reason ?? result.error.code;
|
|
863
|
-
// @cast-boundary engine-payload — statusMap value union narrows to the http-status union
|
|
864
|
-
const status = (statusMap[reason] ?? result.error.httpStatus) as
|
|
865
|
-
| 400
|
|
866
|
-
| 401
|
|
867
|
-
| 403
|
|
868
|
-
| 422
|
|
869
|
-
| 429
|
|
870
|
-
| 500;
|
|
871
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
// @cast-boundary engine-payload — generic dispatcher.write result for mfa-verify handler
|
|
875
|
-
const data = result.data as { kind: "mfa-verify-success"; session: SessionUser };
|
|
876
|
-
|
|
877
|
-
const token = await mintSessionAndRespond(c, data.session);
|
|
878
|
-
const landingPath = landingPathFragment({
|
|
879
|
-
flow: "login",
|
|
880
|
-
roles: data.session.roles,
|
|
881
|
-
tenantId: data.session.tenantId,
|
|
882
|
-
});
|
|
883
|
-
|
|
884
|
-
if (rateLimiter) {
|
|
885
|
-
await rateLimiter.reset(clientIp);
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
return c.json({
|
|
889
|
-
isSuccess: true,
|
|
890
|
-
token,
|
|
891
|
-
user: { id: data.session.id, tenantId: data.session.tenantId, roles: data.session.roles },
|
|
892
|
-
...landingPath,
|
|
893
|
-
});
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
// POST /auth/mfa/preauth-enable-start — lets a user blocked at login by
|
|
898
|
-
// MFA enforcement (mfa-setup-required) generate a TOTP secret + QR
|
|
899
|
-
// without a session, using the preauthSetupToken login.write.ts issued.
|
|
900
|
-
// No JWT is minted here (unlike /auth/login and /auth/mfa/verify) — the
|
|
901
|
-
// handler's response carries a secret-bearing setupToken that a later
|
|
902
|
-
// pre-auth confirm step (the same shape auth-mfa's own enable-confirm
|
|
903
|
-
// consumes) verifies. Rate-limited like mfaVerifyRateLimit/
|
|
904
|
-
// mfaPreauthConfirmRateLimit — a preauthSetupToken is valid and
|
|
905
|
-
// not-single-use for its whole TTL, so without this cap a replay is a
|
|
906
|
-
// memory-hard CPU amplifier (see AuthRoutesConfig doc comment).
|
|
907
|
-
if (config.mfaPreauthEnableStartHandler) {
|
|
908
|
-
const mfaPreauthEnableStartQn = config.mfaPreauthEnableStartHandler;
|
|
909
|
-
const statusMap = config.mfaPreauthEnableStartErrorStatusMap ?? {};
|
|
910
|
-
const rateLimiter =
|
|
911
|
-
config.mfaPreauthEnableStartRateLimit === null
|
|
912
|
-
? null
|
|
913
|
-
: (config.mfaPreauthEnableStartRateLimit ?? createInMemoryLoginRateLimiter());
|
|
914
|
-
|
|
915
|
-
api.post(Routes.authMfaPreauthEnableStart, async (c) => {
|
|
916
|
-
const raw = await c.req.json().catch(() => null);
|
|
917
|
-
const parsed = MfaPreauthEnableStartBody.safeParse(raw);
|
|
918
|
-
if (!parsed.success) {
|
|
919
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
920
|
-
}
|
|
921
|
-
const body = parsed.data;
|
|
922
|
-
|
|
923
|
-
const clientIp = getClientIp(c);
|
|
924
|
-
|
|
925
|
-
if (rateLimiter) {
|
|
926
|
-
const allowed = await rateLimiter.check(clientIp);
|
|
927
|
-
if (!allowed) {
|
|
928
|
-
return c.json({ isSuccess: false, error: "rate_limited" }, 429);
|
|
929
|
-
}
|
|
930
|
-
// Second axis, independent of the IP-derived bucket above: the
|
|
931
|
-
// preauthSetupToken is minted by login.write.ts and not freely
|
|
932
|
-
// choosable, so this cap survives an attacker rotating
|
|
933
|
-
// x-forwarded-for to bypass the IP bucket (kumiko-framework#1522).
|
|
934
|
-
const tokenAllowed = await rateLimiter.check(preauthTokenKeyOf(body.preauthSetupToken));
|
|
935
|
-
if (!tokenAllowed) {
|
|
936
|
-
return c.json({ isSuccess: false, error: "rate_limited" }, 429);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
const result = await dispatcher.write(
|
|
941
|
-
mfaPreauthEnableStartQn,
|
|
942
|
-
body,
|
|
943
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
944
|
-
);
|
|
945
|
-
|
|
946
|
-
if (!result.isSuccess) {
|
|
947
|
-
// @cast-boundary error-details — KumikoError.details shape is per-error
|
|
948
|
-
const reason =
|
|
949
|
-
(result.error.details as { reason?: string } | undefined)?.reason ?? result.error.code;
|
|
950
|
-
// @cast-boundary engine-payload — statusMap value union narrows to the http-status union
|
|
951
|
-
const status = (statusMap[reason] ?? result.error.httpStatus) as
|
|
952
|
-
| 400
|
|
953
|
-
| 401
|
|
954
|
-
| 403
|
|
955
|
-
| 422
|
|
956
|
-
| 429
|
|
957
|
-
| 500;
|
|
958
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
// @cast-boundary engine-payload — generic dispatcher.write result for
|
|
962
|
-
// the preauth-enable-start handler
|
|
963
|
-
const data = result.data as {
|
|
964
|
-
setupToken: string;
|
|
965
|
-
otpauthUri: string;
|
|
966
|
-
recoveryCodes: readonly string[];
|
|
967
|
-
};
|
|
968
|
-
|
|
969
|
-
return c.json({ isSuccess: true, ...data });
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
// POST /auth/mfa/preauth-confirm — completes both the enrollment started
|
|
974
|
-
// by preauth-enable-start AND the login mfa-setup-required blocked.
|
|
975
|
-
// Mirrors /auth/mfa/verify structurally (public, anonymous identity dispatch,
|
|
976
|
-
// mintSessionAndRespond on success) with its OWN rate limiter
|
|
977
|
-
// (mfaPreauthConfirmRateLimit) — same reasoning as mfaVerifyRateLimit.
|
|
978
|
-
// Per-account brute-force protection (capping wrong-code guesses against
|
|
979
|
-
// one still-valid setupToken) is owned by the handler itself — see
|
|
980
|
-
// AuthRoutesConfig.mfaPreauthConfirmHandler's doc comment.
|
|
981
|
-
if (config.mfaPreauthConfirmHandler) {
|
|
982
|
-
const mfaPreauthConfirmQn = config.mfaPreauthConfirmHandler;
|
|
983
|
-
const statusMap = config.mfaPreauthConfirmErrorStatusMap ?? {};
|
|
984
|
-
const rateLimiter =
|
|
985
|
-
config.mfaPreauthConfirmRateLimit === null
|
|
986
|
-
? null
|
|
987
|
-
: (config.mfaPreauthConfirmRateLimit ?? createInMemoryLoginRateLimiter());
|
|
988
|
-
|
|
989
|
-
api.post(Routes.authMfaPreauthConfirm, async (c) => {
|
|
990
|
-
const raw = await c.req.json().catch(() => null);
|
|
991
|
-
const parsed = MfaPreauthConfirmBody.safeParse(raw);
|
|
992
|
-
if (!parsed.success) {
|
|
993
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
994
|
-
}
|
|
995
|
-
const body = parsed.data;
|
|
996
|
-
|
|
997
|
-
const clientIp = getClientIp(c);
|
|
998
|
-
|
|
999
|
-
if (rateLimiter) {
|
|
1000
|
-
const allowed = await rateLimiter.check(clientIp);
|
|
1001
|
-
if (!allowed) {
|
|
1002
|
-
return c.json({ isSuccess: false, error: "rate_limited" }, 429);
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
const result = await dispatcher.write(
|
|
1007
|
-
mfaPreauthConfirmQn,
|
|
1008
|
-
body,
|
|
1009
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1010
|
-
);
|
|
1011
|
-
|
|
1012
|
-
if (!result.isSuccess) {
|
|
1013
|
-
// @cast-boundary error-details — KumikoError.details shape is per-error
|
|
1014
|
-
const reason =
|
|
1015
|
-
(result.error.details as { reason?: string } | undefined)?.reason ?? result.error.code;
|
|
1016
|
-
// @cast-boundary engine-payload — statusMap value union narrows to the http-status union
|
|
1017
|
-
const status = (statusMap[reason] ?? result.error.httpStatus) as
|
|
1018
|
-
| 400
|
|
1019
|
-
| 401
|
|
1020
|
-
| 403
|
|
1021
|
-
| 422
|
|
1022
|
-
| 429
|
|
1023
|
-
| 500;
|
|
1024
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
// @cast-boundary engine-payload — generic dispatcher.write result for mfa-preauth-confirm handler
|
|
1028
|
-
const data = result.data as { kind: "mfa-preauth-confirm-success"; session: SessionUser };
|
|
1029
|
-
|
|
1030
|
-
const token = await mintSessionAndRespond(c, data.session);
|
|
1031
|
-
const landingPath = landingPathFragment({
|
|
1032
|
-
flow: "login",
|
|
1033
|
-
roles: data.session.roles,
|
|
1034
|
-
tenantId: data.session.tenantId,
|
|
1035
|
-
});
|
|
1036
|
-
|
|
1037
|
-
if (rateLimiter) {
|
|
1038
|
-
await rateLimiter.reset(clientIp);
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
return c.json({
|
|
1042
|
-
isSuccess: true,
|
|
1043
|
-
token,
|
|
1044
|
-
user: { id: data.session.id, tenantId: data.session.tenantId, roles: data.session.roles },
|
|
1045
|
-
...landingPath,
|
|
1046
|
-
});
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
// POST /auth/request-password-reset + /auth/reset-password — public.
|
|
1051
|
-
// Silent-success on request (no enumeration), typed failure on confirm.
|
|
1052
|
-
// Rate-limit covered via config.rateLimit.auth (Sprint G.5 L2, /auth/*).
|
|
1053
|
-
if (config.passwordReset) {
|
|
1054
|
-
const pr = config.passwordReset;
|
|
1055
|
-
registerTokenRequestRoute({
|
|
1056
|
-
api,
|
|
1057
|
-
dispatcher,
|
|
1058
|
-
path: Routes.authRequestPasswordReset,
|
|
1059
|
-
requestHandler: pr.requestHandler,
|
|
1060
|
-
});
|
|
1061
|
-
registerTokenConfirmRoute({
|
|
1062
|
-
api,
|
|
1063
|
-
dispatcher,
|
|
1064
|
-
path: Routes.authResetPassword,
|
|
1065
|
-
confirmHandler: pr.confirmHandler,
|
|
1066
|
-
schema: ResetPasswordBody,
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
|
-
// Email-verification mirrors password-reset.
|
|
1071
|
-
if (config.emailVerification) {
|
|
1072
|
-
const ev = config.emailVerification;
|
|
1073
|
-
registerTokenRequestRoute({
|
|
1074
|
-
api,
|
|
1075
|
-
dispatcher,
|
|
1076
|
-
path: Routes.authRequestEmailVerification,
|
|
1077
|
-
requestHandler: ev.requestHandler,
|
|
1078
|
-
});
|
|
1079
|
-
registerTokenConfirmRoute({
|
|
1080
|
-
api,
|
|
1081
|
-
dispatcher,
|
|
1082
|
-
path: Routes.authVerifyEmail,
|
|
1083
|
-
confirmHandler: ev.confirmHandler,
|
|
1084
|
-
schema: VerifyEmailBody,
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
// Account-unlock mirrors email-verification (token-only confirm body) —
|
|
1089
|
-
// clears the Redis lockout state instead of an entity field, see
|
|
1090
|
-
// confirm-account-unlock.write.ts.
|
|
1091
|
-
if (config.accountUnlock) {
|
|
1092
|
-
const au = config.accountUnlock;
|
|
1093
|
-
registerTokenRequestRoute({
|
|
1094
|
-
api,
|
|
1095
|
-
dispatcher,
|
|
1096
|
-
path: Routes.authRequestAccountUnlock,
|
|
1097
|
-
requestHandler: au.requestHandler,
|
|
1098
|
-
});
|
|
1099
|
-
registerTokenConfirmRoute({
|
|
1100
|
-
api,
|
|
1101
|
-
dispatcher,
|
|
1102
|
-
path: Routes.authConfirmAccountUnlock,
|
|
1103
|
-
confirmHandler: au.confirmHandler,
|
|
1104
|
-
schema: VerifyEmailBody,
|
|
1105
|
-
});
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
// Self-Signup (Magic-Link). Request mountet wie reset/verify den
|
|
1109
|
-
// silent-success-Pfad mit Token-Mail. Confirm ist anders: returnt
|
|
1110
|
-
// SessionUser → die Route mintet JWT + setzt Cookies (Auto-Login
|
|
1111
|
-
// direkt nach Activation, kein zweiter Login-Roundtrip nötig).
|
|
1112
|
-
if (config.signup) {
|
|
1113
|
-
const sg = config.signup;
|
|
1114
|
-
registerTokenRequestRoute({
|
|
1115
|
-
api,
|
|
1116
|
-
dispatcher,
|
|
1117
|
-
path: Routes.authSignupRequest,
|
|
1118
|
-
requestHandler: sg.requestHandler,
|
|
1119
|
-
schema: SignupRequestBody,
|
|
1120
|
-
});
|
|
1121
|
-
|
|
1122
|
-
api.post(Routes.authSignupConfirm, async (c) => {
|
|
1123
|
-
const raw = await c.req.json().catch(() => null);
|
|
1124
|
-
const parsed = SignupConfirmBody.safeParse(raw);
|
|
1125
|
-
if (!parsed.success) {
|
|
1126
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
|
-
const result = await dispatcher.write(
|
|
1130
|
-
sg.confirmHandler,
|
|
1131
|
-
parsed.data,
|
|
1132
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1133
|
-
);
|
|
1134
|
-
|
|
1135
|
-
if (!result.isSuccess) {
|
|
1136
|
-
// 422 für invalid_signup_token (handler-level UnprocessableError).
|
|
1137
|
-
// @cast-boundary engine-payload — KumikoError.httpStatus narrows to the http-status union
|
|
1138
|
-
const status = result.error.httpStatus as 400 | 401 | 403 | 422 | 500;
|
|
1139
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
// @cast-boundary engine-payload — generic dispatcher.write result for signup-confirm
|
|
1143
|
-
const data = result.data as {
|
|
1144
|
-
kind: "auth-session";
|
|
1145
|
-
session: SessionUser;
|
|
1146
|
-
tenantKey: string;
|
|
1147
|
-
handover?: { entityType: string; id: string };
|
|
1148
|
-
};
|
|
1149
|
-
|
|
1150
|
-
// Session creation + JWT sign + cookies — see mintSessionAndRespond.
|
|
1151
|
-
const token = await mintSessionAndRespond(c, data.session);
|
|
1152
|
-
const landingPath = landingPathFragment({
|
|
1153
|
-
flow: "signup",
|
|
1154
|
-
roles: data.session.roles,
|
|
1155
|
-
tenantId: data.session.tenantId,
|
|
1156
|
-
tenantKey: data.tenantKey,
|
|
1157
|
-
...(data.handover !== undefined && { handover: data.handover }),
|
|
1158
|
-
});
|
|
1159
|
-
|
|
1160
|
-
return c.json({
|
|
1161
|
-
isSuccess: true,
|
|
1162
|
-
token,
|
|
1163
|
-
user: {
|
|
1164
|
-
id: data.session.id,
|
|
1165
|
-
tenantId: data.session.tenantId,
|
|
1166
|
-
roles: data.session.roles,
|
|
1167
|
-
},
|
|
1168
|
-
// tenantKey für Post-Signup-Redirect zu /<tenantKey>/.
|
|
1169
|
-
// Anders als der login-response der nur `tenants[]` braucht
|
|
1170
|
-
// (User wählt im Switcher), kennt der signup nur EINE
|
|
1171
|
-
// membership — die Frontend-UI nimmt das direkt als Redirect-
|
|
1172
|
-
// Target.
|
|
1173
|
-
tenantKey: data.tenantKey,
|
|
1174
|
-
// Cross-device try-first handover (kumiko-framework#3035 follow-up):
|
|
1175
|
-
// present only when signup-confirm actually claimed a bound grant —
|
|
1176
|
-
// absent, not null, so a client that doesn't know the field sees
|
|
1177
|
-
// nothing unusual.
|
|
1178
|
-
...(data.handover !== undefined && { handover: data.handover }),
|
|
1179
|
-
...landingPath,
|
|
1180
|
-
});
|
|
1181
|
-
});
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
// Tenant-Invite Magic-Link. 3 separate Routes für 3 Accept-Branches:
|
|
1185
|
-
if (config.invite) {
|
|
1186
|
-
const inv = config.invite;
|
|
1187
|
-
|
|
1188
|
-
// Branch 1: logged-in User klickt Invite-Link → Membership-Add im
|
|
1189
|
-
// invited Tenant (NICHT Tenant-Switch — User bleibt in seiner
|
|
1190
|
-
// aktuellen Session, kann später via Tenant-Switcher wechseln).
|
|
1191
|
-
// Requires JWT (siehe PUBLIC_API_PATHS — invite-accept ist NICHT
|
|
1192
|
-
// public, im Gegensatz zu acceptWithLogin/signupComplete).
|
|
1193
|
-
api.post(Routes.authInviteAccept, async (c) => {
|
|
1194
|
-
const user = getUser(c);
|
|
1195
|
-
const raw = await c.req.json().catch(() => null);
|
|
1196
|
-
const parsed = InviteAcceptBody.safeParse(raw);
|
|
1197
|
-
if (!parsed.success) {
|
|
1198
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
1199
|
-
}
|
|
1200
|
-
const result = await dispatcher.write(inv.acceptHandler, parsed.data, user);
|
|
1201
|
-
if (!result.isSuccess) {
|
|
1202
|
-
// @cast-boundary engine-payload — KumikoError.httpStatus
|
|
1203
|
-
const status = result.error.httpStatus as 400 | 401 | 403 | 422 | 500;
|
|
1204
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
1205
|
-
}
|
|
1206
|
-
// @cast-boundary engine-payload — generic dispatcher.write result
|
|
1207
|
-
const data = result.data as {
|
|
1208
|
-
kind: "invite-accepted";
|
|
1209
|
-
tenantId: TenantId;
|
|
1210
|
-
role: string;
|
|
1211
|
-
alreadyMember: boolean;
|
|
1212
|
-
};
|
|
1213
|
-
const landingPath = landingPathFragment({
|
|
1214
|
-
flow: "invite",
|
|
1215
|
-
roles: [data.role],
|
|
1216
|
-
tenantId: data.tenantId,
|
|
1217
|
-
});
|
|
1218
|
-
return c.json({
|
|
1219
|
-
isSuccess: true,
|
|
1220
|
-
tenantId: data.tenantId,
|
|
1221
|
-
role: data.role,
|
|
1222
|
-
alreadyMember: data.alreadyMember,
|
|
1223
|
-
...landingPath,
|
|
1224
|
-
});
|
|
1225
|
-
});
|
|
1226
|
-
|
|
1227
|
-
// Branch 2: anon User mit existing email — Login + Accept in einem
|
|
1228
|
-
// Roundtrip. JWT-mint analog signup-confirm.
|
|
1229
|
-
api.post(Routes.authInviteAcceptWithLogin, async (c) => {
|
|
1230
|
-
const raw = await c.req.json().catch(() => null);
|
|
1231
|
-
const parsed = InviteAcceptWithLoginBody.safeParse(raw);
|
|
1232
|
-
if (!parsed.success) {
|
|
1233
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
1234
|
-
}
|
|
1235
|
-
const result = await dispatcher.write(
|
|
1236
|
-
inv.acceptWithLoginHandler,
|
|
1237
|
-
parsed.data,
|
|
1238
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1239
|
-
);
|
|
1240
|
-
if (!result.isSuccess) {
|
|
1241
|
-
const status = result.error.httpStatus as 400 | 401 | 403 | 422 | 500; // @cast-boundary engine-payload
|
|
1242
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
1243
|
-
}
|
|
1244
|
-
// @cast-boundary engine-payload — same three-shape union as /auth/login
|
|
1245
|
-
// (see gateEnforceMfa): a straight session, an MFA challenge, or a
|
|
1246
|
-
// hard mfa-setup-required block. Only the auth-session branch also
|
|
1247
|
-
// carries tenantId/role (invite-specific).
|
|
1248
|
-
const data = result.data as
|
|
1249
|
-
| { kind: "auth-session"; session: SessionUser; tenantId: TenantId; role: string }
|
|
1250
|
-
| { kind: "mfa-challenge"; challengeToken: string }
|
|
1251
|
-
| { kind: "mfa-setup-required"; preauthSetupToken: string };
|
|
1252
|
-
|
|
1253
|
-
if (data.kind === "mfa-setup-required") {
|
|
1254
|
-
return c.json({
|
|
1255
|
-
isSuccess: true,
|
|
1256
|
-
mfaSetupRequired: true,
|
|
1257
|
-
preauthSetupToken: data.preauthSetupToken,
|
|
1258
|
-
});
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
if (data.kind === "mfa-challenge") {
|
|
1262
|
-
return c.json({ isSuccess: true, mfaRequired: true, challengeToken: data.challengeToken });
|
|
1263
|
-
}
|
|
1264
|
-
|
|
1265
|
-
const token = await mintSessionAndRespond(c, data.session);
|
|
1266
|
-
const landingPath = landingPathFragment({
|
|
1267
|
-
flow: "invite",
|
|
1268
|
-
roles: data.session.roles,
|
|
1269
|
-
tenantId: data.tenantId,
|
|
1270
|
-
});
|
|
1271
|
-
return c.json({
|
|
1272
|
-
isSuccess: true,
|
|
1273
|
-
token,
|
|
1274
|
-
user: {
|
|
1275
|
-
id: data.session.id,
|
|
1276
|
-
tenantId: data.session.tenantId,
|
|
1277
|
-
roles: data.session.roles,
|
|
1278
|
-
},
|
|
1279
|
-
tenantId: data.tenantId,
|
|
1280
|
-
role: data.role,
|
|
1281
|
-
...landingPath,
|
|
1282
|
-
});
|
|
1283
|
-
});
|
|
1284
|
-
|
|
1285
|
-
// Branch 3: anon User mit neuer email — User+Membership entstehen,
|
|
1286
|
-
// KEIN neuer Tenant. JWT-mint.
|
|
1287
|
-
api.post(Routes.authInviteSignupComplete, async (c) => {
|
|
1288
|
-
const raw = await c.req.json().catch(() => null);
|
|
1289
|
-
const parsed = InviteSignupCompleteBody.safeParse(raw);
|
|
1290
|
-
if (!parsed.success) {
|
|
1291
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
1292
|
-
}
|
|
1293
|
-
const result = await dispatcher.write(
|
|
1294
|
-
inv.signupCompleteHandler,
|
|
1295
|
-
parsed.data,
|
|
1296
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1297
|
-
);
|
|
1298
|
-
if (!result.isSuccess) {
|
|
1299
|
-
const status = result.error.httpStatus as 400 | 401 | 403 | 422 | 500; // @cast-boundary engine-payload
|
|
1300
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
1301
|
-
}
|
|
1302
|
-
const data = result.data as {
|
|
1303
|
-
kind: "auth-session";
|
|
1304
|
-
session: SessionUser;
|
|
1305
|
-
tenantId: TenantId;
|
|
1306
|
-
role: string;
|
|
1307
|
-
}; // @cast-boundary engine-payload
|
|
1308
|
-
const token = await mintSessionAndRespond(c, data.session);
|
|
1309
|
-
const landingPath = landingPathFragment({
|
|
1310
|
-
flow: "invite",
|
|
1311
|
-
roles: data.session.roles,
|
|
1312
|
-
tenantId: data.tenantId,
|
|
1313
|
-
});
|
|
1314
|
-
return c.json({
|
|
1315
|
-
isSuccess: true,
|
|
1316
|
-
token,
|
|
1317
|
-
user: {
|
|
1318
|
-
id: data.session.id,
|
|
1319
|
-
tenantId: data.session.tenantId,
|
|
1320
|
-
roles: data.session.roles,
|
|
1321
|
-
},
|
|
1322
|
-
tenantId: data.tenantId,
|
|
1323
|
-
role: data.role,
|
|
1324
|
-
...landingPath,
|
|
1325
|
-
});
|
|
1326
|
-
});
|
|
1327
|
-
|
|
1328
|
-
// Anonymous, read-only invite lookup for the acceptance page: pre-fill
|
|
1329
|
-
// the invited email and pick Branch 2 (existing account) vs Branch 3
|
|
1330
|
-
// (new account) before the user submits. Token is never consumed here.
|
|
1331
|
-
if (inv.infoHandler) {
|
|
1332
|
-
const infoHandler = inv.infoHandler;
|
|
1333
|
-
api.post(Routes.authInviteInfo, async (c) => {
|
|
1334
|
-
const raw = await c.req.json().catch(() => null);
|
|
1335
|
-
const parsed = InviteInfoBody.safeParse(raw);
|
|
1336
|
-
if (!parsed.success) {
|
|
1337
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
1338
|
-
}
|
|
1339
|
-
try {
|
|
1340
|
-
// @cast-boundary engine-payload — generic dispatcher.query result
|
|
1341
|
-
const data = (await dispatcher.query(
|
|
1342
|
-
infoHandler,
|
|
1343
|
-
parsed.data,
|
|
1344
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1345
|
-
)) as { email: string; hasAccount: boolean };
|
|
1346
|
-
return c.json({ isSuccess: true, ...data });
|
|
1347
|
-
} catch (e) {
|
|
1348
|
-
const err = toKumikoError(e);
|
|
1349
|
-
// Same body shape as the write routes' `{ isSuccess: false, error:
|
|
1350
|
-
// result.error }` (WriteErrorInfo) — this is a query, not a write,
|
|
1351
|
-
// so there's no WriteResult to read `.error` off; toWriteErrorInfo
|
|
1352
|
-
// builds the equivalent shape directly from the caught error.
|
|
1353
|
-
return c.json(
|
|
1354
|
-
{ isSuccess: false, error: toWriteErrorInfo(err) },
|
|
1355
|
-
err.httpStatus as ContentfulStatusCode, // @cast-boundary engine-payload
|
|
1356
|
-
);
|
|
1357
|
-
}
|
|
1358
|
-
});
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
// POST /auth/logout — revokes the current session. Requires a valid JWT so
|
|
1363
|
-
// the middleware has already populated `user.sid` from the `jti` claim. If
|
|
1364
|
-
// the app hasn't wired a sessionRevoker, logout is effectively a no-op on
|
|
1365
|
-
// the server — the client can just drop the token.
|
|
1366
|
-
api.post(Routes.authLogout, async (c) => {
|
|
1367
|
-
const user = getUser(c);
|
|
1368
|
-
if (config.sessionRevoker && user.sid) {
|
|
1369
|
-
await config.sessionRevoker(user.sid);
|
|
1370
|
-
}
|
|
1371
|
-
// Clear cookies on the cookie-transport path. Idempotent — clearing a
|
|
1372
|
-
// missing cookie is a no-op, so bearer-only clients aren't affected.
|
|
1373
|
-
clearAuthCookies(c, cookieDomain);
|
|
1374
|
-
return c.json({ isSuccess: true });
|
|
1375
|
-
});
|
|
1376
|
-
|
|
1377
|
-
// GET /auth/tenants — list tenants the current user belongs to
|
|
1378
|
-
api.get(Routes.authTenants, async (c) => {
|
|
1379
|
-
const user = getUser(c);
|
|
1380
|
-
|
|
1381
|
-
try {
|
|
1382
|
-
// System-scoped: membershipQuery is access-locked to system-role.
|
|
1383
|
-
// @cast-boundary engine-payload — generic dispatcher.query result
|
|
1384
|
-
const memberships = (await dispatcher.query(
|
|
1385
|
-
config.membershipQuery,
|
|
1386
|
-
{ userId: user.id },
|
|
1387
|
-
createSystemUser(user.tenantId),
|
|
1388
|
-
)) as MembershipRow[];
|
|
1389
|
-
|
|
1390
|
-
return c.json({
|
|
1391
|
-
tenants: memberships.map((m) => ({
|
|
1392
|
-
tenantId: m.tenantId,
|
|
1393
|
-
roles: m.roles,
|
|
1394
|
-
...(m.tenantName !== undefined && { name: m.tenantName }),
|
|
1395
|
-
...(m.tenantKey !== undefined && { key: m.tenantKey }),
|
|
1396
|
-
})),
|
|
1397
|
-
activeTenantId: user.tenantId,
|
|
1398
|
-
});
|
|
1399
|
-
} catch (e) {
|
|
1400
|
-
// Only legitimate fallback: the app hasn't wired membershipQuery at
|
|
1401
|
-
// all. A DB fault or a permission failure has to bubble up so ops
|
|
1402
|
-
// sees it — collapsing them into "just your current tenant" hides
|
|
1403
|
-
// outages behind a UI that looks fine.
|
|
1404
|
-
if (!isUnknownHandlerError(e)) throw e;
|
|
1405
|
-
return c.json({
|
|
1406
|
-
tenants: [{ tenantId: user.tenantId, roles: [...user.roles] }],
|
|
1407
|
-
activeTenantId: user.tenantId,
|
|
1408
|
-
});
|
|
1409
|
-
}
|
|
1410
|
-
});
|
|
1411
|
-
|
|
1412
|
-
// POST /auth/switch-tenant — switch to a different tenant
|
|
1413
|
-
api.post(Routes.authSwitchTenant, async (c) => {
|
|
1414
|
-
const user = getUser(c);
|
|
1415
|
-
const body = await c.req.json<{ tenantId: TenantId }>();
|
|
1416
|
-
const targetTenantId = body.tenantId;
|
|
1417
|
-
|
|
1418
|
-
if (targetTenantId === user.tenantId) {
|
|
1419
|
-
return c.json({ error: "already_in_tenant" }, 400);
|
|
1420
|
-
}
|
|
1421
|
-
|
|
1422
|
-
// Membership + principal-blocked + tenant-teardown in one building
|
|
1423
|
-
// block — trusted server code asking on the user's behalf, same trust boundary as before.
|
|
1424
|
-
let activeMembership: ActiveMembershipResult;
|
|
1425
|
-
try {
|
|
1426
|
-
activeMembership = await dispatcher.resolveActiveMembership(user.id, targetTenantId);
|
|
1427
|
-
} catch (e) {
|
|
1428
|
-
// No membershipQuery wired → switching tenants is just not offered in
|
|
1429
|
-
// this deployment. Any other error propagates so a broken query handler
|
|
1430
|
-
// surfaces as a real 5xx instead of a misleading 400.
|
|
1431
|
-
if (!isUnknownHandlerError(e)) throw e;
|
|
1432
|
-
return c.json({ error: "tenant_switch_not_available" }, 400);
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
if (activeMembership.kind === "rejected") {
|
|
1436
|
-
return switchTenantRejectionResponse(c, activeMembership.reason);
|
|
1437
|
-
}
|
|
1438
|
-
const membership = activeMembership.membership;
|
|
1439
|
-
|
|
1440
|
-
// Globale Rollen aus user-feature lesen wenn userQuery wired —
|
|
1441
|
-
// tenant-unabhängige Rollen (SystemAdmin etc.) überleben so den
|
|
1442
|
-
// tenant-switch. `parseRoles` liegt utils-side, hier inline-deserialize
|
|
1443
|
-
// damit das Framework keine bundled-features-Imports kriegt.
|
|
1444
|
-
let globalRoles: readonly string[] = [];
|
|
1445
|
-
if (config.userQuery) {
|
|
1446
|
-
try {
|
|
1447
|
-
// @cast-boundary engine-payload — dispatcher.query returnt unknown,
|
|
1448
|
-
// userQuery liefert per AuthUserRow-Contract eine row mit roles-spalte.
|
|
1449
|
-
const userRow = (await dispatcher.query(
|
|
1450
|
-
config.userQuery,
|
|
1451
|
-
{ id: user.id },
|
|
1452
|
-
createSystemUser(user.tenantId),
|
|
1453
|
-
)) as { roles?: unknown } | null;
|
|
1454
|
-
// roles is jsonb string[] (multiSelect); parseRoles also accepts legacy
|
|
1455
|
-
// JSON-encoded text from pre-0.217.0 rows.
|
|
1456
|
-
globalRoles = parseRoles(userRow?.roles ?? null);
|
|
1457
|
-
} catch (e) {
|
|
1458
|
-
// Non-fatal: globale Rollen kann nicht aufgelöst werden → switch
|
|
1459
|
-
// läuft weiter mit nur tenant-rollen. Server-error mit nur dem
|
|
1460
|
-
// Cause ohne Stack hochwerfen wäre für die UX schlimmer als ein
|
|
1461
|
-
// Tenant-Switch ohne SystemAdmin (User merkt's und meldet's). Log
|
|
1462
|
-
// it via the dispatcher so Ops sieht's.
|
|
1463
|
-
if (!isUnknownHandlerError(e)) throw e;
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
// Issue new JWT with the target tenant and its roles. Claims MUST be
|
|
1468
|
-
// recomputed for the new tenant — stale claims from the previous
|
|
1469
|
-
// tenant would leak identity facts across tenancies (e.g. teamId from
|
|
1470
|
-
// tenant A accidentally surviving into tenant B's session). The
|
|
1471
|
-
// resolver runs each feature's r.authClaims() hook under the new
|
|
1472
|
-
// TenantDb scope.
|
|
1473
|
-
// buildSessionRoles calls stripForbiddenMembershipRoles internally and
|
|
1474
|
-
// strips reserved roles from the membership side only — globalRoles
|
|
1475
|
-
// (where SystemAdmin legitimately lives) is never filtered. Backstop for a
|
|
1476
|
-
// membership role that a projection rebuild resurrected past command-time
|
|
1477
|
-
// validation (see engine/membership-roles).
|
|
1478
|
-
const mergedRoles = buildSessionRoles(globalRoles, membership.roles);
|
|
1479
|
-
const targetSession: SessionUser = {
|
|
1480
|
-
id: user.id,
|
|
1481
|
-
tenantId: targetTenantId,
|
|
1482
|
-
roles: mergedRoles,
|
|
1483
|
-
// Tenant-independent prefs must survive the switch (fw#2343).
|
|
1484
|
-
...(user.timezone ? { timezone: user.timezone } : {}),
|
|
1485
|
-
...(user.locale ? { locale: user.locale } : {}),
|
|
1486
|
-
};
|
|
1487
|
-
const claims = await dispatcher.resolveAuthClaims(targetSession);
|
|
1488
|
-
const sessionForJwt: SessionUser =
|
|
1489
|
-
Object.keys(claims).length > 0 ? { ...targetSession, claims } : targetSession;
|
|
1490
|
-
|
|
1491
|
-
// Session rotation: revoke old sid BEFORE creating the new one so a
|
|
1492
|
-
// creator failure leaves the user logged-out cleanly rather than with
|
|
1493
|
-
// two live sessions. Client must log in again on creator-throw. A
|
|
1494
|
-
// revoker/creator that actually throws (Redis down, DB deadlock) surfaces
|
|
1495
|
-
// as a 5xx — swallowing it into tenant_switch_not_available was hiding
|
|
1496
|
-
// real outages.
|
|
1497
|
-
if (config.sessionRevoker && user.sid) {
|
|
1498
|
-
await config.sessionRevoker(user.sid);
|
|
1499
|
-
}
|
|
1500
|
-
// Session creation + JWT sign + cookies — see mintSessionAndRespond. A
|
|
1501
|
-
// fresh csrfToken is minted (inside the helper) so a compromised csrf-
|
|
1502
|
-
// value can't cross a tenant boundary.
|
|
1503
|
-
const newToken = await mintSessionAndRespond(c, sessionForJwt);
|
|
1504
|
-
|
|
1505
|
-
return c.json({ token: newToken, tenantId: targetTenantId, roles: mergedRoles });
|
|
1506
|
-
});
|
|
1507
|
-
|
|
1508
|
-
return api;
|
|
1509
|
-
}
|
|
1510
|
-
|
|
1511
|
-
// --- shared route builders for token flows ---------------------------------
|
|
1512
|
-
// Password-reset, email-verification and signup share the exact same request
|
|
1513
|
-
// HTTP-shape: parse body → dispatch the request handler → always-200 (no
|
|
1514
|
-
// enumeration). The handler mints the token AND dispatches the magic-link mail
|
|
1515
|
-
// via delivery (ctx.notify); the route never sees the token. confirm-route
|
|
1516
|
-
// validates the token + does the state change → typed failure or 200. Keeping
|
|
1517
|
-
// the silent-success invariant in one place means changing how the framework
|
|
1518
|
-
// handles "invalid_body" on a public token endpoint is one edit, not three.
|
|
1519
|
-
|
|
1520
|
-
function registerTokenRequestRoute(opts: {
|
|
1521
|
-
api: Hono;
|
|
1522
|
-
dispatcher: Dispatcher;
|
|
1523
|
-
path: string;
|
|
1524
|
-
requestHandler: string;
|
|
1525
|
-
// reset/verify/unlock keep the plain RequestTokenBody; signup passes its
|
|
1526
|
-
// own schema (adds an optional `handover`, see SignupRequestBody above)
|
|
1527
|
-
// so the extra field reaches the handler instead of being parsed away.
|
|
1528
|
-
schema?: typeof RequestTokenBody | typeof SignupRequestBody;
|
|
1529
|
-
}): void {
|
|
1530
|
-
const body = opts.schema ?? RequestTokenBody;
|
|
1531
|
-
opts.api.post(opts.path, async (c) => {
|
|
1532
|
-
const raw = await c.req.json().catch(() => null);
|
|
1533
|
-
const parsed = body.safeParse(raw);
|
|
1534
|
-
// Malformed body → silent success. A probing client mustn't learn
|
|
1535
|
-
// anything from the shape of their input.
|
|
1536
|
-
if (!parsed.success) return c.json({ isSuccess: true });
|
|
1537
|
-
|
|
1538
|
-
// The handler dispatches the magic-link mail via delivery before returning.
|
|
1539
|
-
// Handler-level failures (misconfiguration, e.g. no RateLimitResolver) stay
|
|
1540
|
-
// out of the response so it is uniform for unknown vs. known emails, but
|
|
1541
|
-
// they are logged — otherwise the mail silently never goes out. No email in
|
|
1542
|
-
// the log line (PII).
|
|
1543
|
-
const result = await opts.dispatcher.write(
|
|
1544
|
-
opts.requestHandler,
|
|
1545
|
-
parsed.data,
|
|
1546
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1547
|
-
);
|
|
1548
|
-
if (!result.isSuccess) {
|
|
1549
|
-
console.error(
|
|
1550
|
-
`[kumiko] token request handler "${opts.requestHandler}" failed: ${result.error.code}`,
|
|
1551
|
-
);
|
|
1552
|
-
}
|
|
1553
|
-
|
|
1554
|
-
return c.json({ isSuccess: true });
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
function registerTokenConfirmRoute(opts: {
|
|
1559
|
-
api: Hono;
|
|
1560
|
-
dispatcher: Dispatcher;
|
|
1561
|
-
path: string;
|
|
1562
|
-
confirmHandler: string;
|
|
1563
|
-
// Endpoint-specific body shape (reset has `newPassword`, verify doesn't).
|
|
1564
|
-
schema: typeof ResetPasswordBody | typeof VerifyEmailBody;
|
|
1565
|
-
}): void {
|
|
1566
|
-
opts.api.post(opts.path, async (c) => {
|
|
1567
|
-
const raw = await c.req.json().catch(() => null);
|
|
1568
|
-
const parsed = opts.schema.safeParse(raw);
|
|
1569
|
-
if (!parsed.success) {
|
|
1570
|
-
return c.json({ isSuccess: false, error: "invalid_body" }, 400);
|
|
1571
|
-
}
|
|
1572
|
-
const result = await opts.dispatcher.write(
|
|
1573
|
-
opts.confirmHandler,
|
|
1574
|
-
parsed.data,
|
|
1575
|
-
createAnonymousUser(SYSTEM_TENANT_ID),
|
|
1576
|
-
);
|
|
1577
|
-
if (!result.isSuccess) {
|
|
1578
|
-
const status = result.error.httpStatus as 400 | 401 | 403 | 422 | 500; // @cast-boundary engine-payload
|
|
1579
|
-
return c.json({ isSuccess: false, error: result.error }, status);
|
|
1580
|
-
}
|
|
1581
|
-
return c.json({ isSuccess: true });
|
|
1582
|
-
});
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
// Shared request-body shape for request-password-reset + request-email-
|
|
1586
|
-
// verification. Extracted so the two flows stay in sync when the schema
|
|
1587
|
-
// gains optional fields (locale, deviceId, …).
|
|
1588
|
-
const RequestTokenBody = z.object({
|
|
1589
|
-
email: z.email(),
|
|
1590
|
-
});
|