@wildo-ai/saas-backend-lib 1.1.1 → 1.1.3
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/esm/applications/services/worker-remote-client-factory.backend.service.d.ts.map +1 -1
- package/dist/esm/applications/services/worker-remote-client-factory.backend.service.js +19 -1
- package/dist/esm/applications/services/worker-remote-client-factory.backend.service.js.map +1 -1
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +4 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
- package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.d.ts +35 -0
- package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.js +111 -0
- package/dist/esm/base-classes/services/batches/child-lifecycle-teardown.batch.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.d.ts +50 -0
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js +199 -0
- package/dist/esm/base-classes/services/batches/credential-expiry-sweep.batch.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.d.ts +111 -0
- package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.d.ts.map +1 -1
- package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.js +140 -0
- package/dist/esm/base-classes/services/batches/engine-custom-batch-manifests.js.map +1 -1
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts +14 -3
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +138 -24
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +3 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +8 -3
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts +11 -0
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js +11 -2
- package/dist/esm/base-classes/services/repositories/field-clearing-partition.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.d.ts +124 -13
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js +207 -21
- package/dist/esm/base-classes/services/repositories/http-api/http-api-provider-access.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.d.ts +60 -8
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js +174 -26
- package/dist/esm/base-classes/services/repositories/http-api/http-api-read-client.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts +48 -4
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js +102 -30
- package/dist/esm/base-classes/services/repositories/http-api/http-api-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.d.ts +55 -0
- package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.d.ts.map +1 -0
- package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.js +114 -0
- package/dist/esm/base-classes/services/repositories/http-api/http-api-rest-operation-reference.backend.js.map +1 -0
- package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.d.ts +89 -14
- package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.js +84 -11
- package/dist/esm/base-classes/services/repositories/http-api/http-api-transport.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js +16 -0
- package/dist/esm/base-classes/services/repositories/http-api/odata-query-compiler.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts +20 -6
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +96 -32
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts +3 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js +32 -7
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts +8 -5
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/introspection/introspection-resource-source.backend.port.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +80 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +298 -23
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +71 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +85 -5
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +21 -0
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +146 -4
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts +22 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts +3 -26
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js +3 -68
- package/dist/esm/base-classes/services/services/resource-operation-implementation-coverage.backend.utils.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js +4 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.d.ts +11 -0
- package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.js +39 -5
- package/dist/esm/base-classes/services/services/resource-status-transition.definitions.backend.js.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +181 -2
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +533 -43
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
- package/dist/esm/base-classes/services/services/system-access.backend.service.d.ts +36 -3
- package/dist/esm/base-classes/services/services/system-access.backend.service.d.ts.map +1 -1
- package/dist/esm/base-classes/services/services/system-access.backend.service.js +70 -8
- package/dist/esm/base-classes/services/services/system-access.backend.service.js.map +1 -1
- package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.d.ts +28 -0
- package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.js +90 -0
- package/dist/esm/billing/batches/billing-reconciliation.batch.backend.service.js.map +1 -0
- package/dist/esm/billing/batches/usage-flush.batch.backend.service.d.ts +44 -0
- package/dist/esm/billing/batches/usage-flush.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/batches/usage-flush.batch.backend.service.js +99 -0
- package/dist/esm/billing/batches/usage-flush.batch.backend.service.js.map +1 -0
- package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.d.ts +91 -0
- package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.d.ts.map +1 -0
- package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.js +152 -0
- package/dist/esm/billing/models/billing-provider-event-settlement.backend.schemas.js.map +1 -0
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts +186 -0
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js +474 -0
- package/dist/esm/billing/services/back-office/billing-reconciliation.backend.service.js.map +1 -0
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts +100 -0
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js +209 -6
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js.map +1 -1
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts +200 -4
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.js +593 -64
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.js.map +1 -1
- package/dist/esm/billing/services/billing-adapter-registry.backend.d.ts +36 -0
- package/dist/esm/billing/services/billing-adapter-registry.backend.d.ts.map +1 -0
- package/dist/esm/billing/services/billing-adapter-registry.backend.js +83 -0
- package/dist/esm/billing/services/billing-adapter-registry.backend.js.map +1 -0
- package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.d.ts +9 -0
- package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.d.ts.map +1 -1
- package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.js +11 -1
- package/dist/esm/billing/services/billing-checkout-metadata.backend.utils.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +54 -13
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts +38 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js +67 -2
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts +30 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js +43 -1
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts +11 -3
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js +30 -16
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js +104 -25
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts +18 -1
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js +106 -2
- package/dist/esm/billing/services/stripe-standard-billing-provider.backend.service.js.map +1 -1
- package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.d.ts +52 -0
- package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.d.ts.map +1 -0
- package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.js +74 -0
- package/dist/esm/billing/services/webhooks/__tests__/settlement-ledger.test-double.js.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts +104 -11
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts.map +1 -1
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js +260 -26
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js.map +1 -1
- package/dist/esm/billing/testing/mock-billing-provider.d.ts +30 -1
- package/dist/esm/billing/testing/mock-billing-provider.d.ts.map +1 -1
- package/dist/esm/billing/testing/mock-billing-provider.js +25 -0
- package/dist/esm/billing/testing/mock-billing-provider.js.map +1 -1
- package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.js +11 -4
- package/dist/esm/compliance/audit-trails/batches/audit-logs-archive.batch.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +263 -13
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +376 -58
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +264 -7
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +414 -5
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.js +7 -1
- package/dist/esm/compliance/audit-trails/services/composite-audit-log-sink.backend.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts +16 -0
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +140 -0
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts +42 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +65 -6
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.d.ts +110 -0
- package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.js +192 -0
- package/dist/esm/compliance/audit-trails/services/utils/leased-value-cache.backend.utils.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js +45 -0
- package/dist/esm/compliance/audit-trails/services/utils/ocsf-activity-mapping.backend.utils.js.map +1 -1
- package/dist/esm/config/bootstrap/application-runtime-profile.backend.d.ts +5 -0
- package/dist/esm/config/bootstrap/application-runtime-profile.backend.d.ts.map +1 -1
- package/dist/esm/config/bootstrap/application-runtime-profile.backend.js +6 -0
- package/dist/esm/config/bootstrap/application-runtime-profile.backend.js.map +1 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.js +7 -1
- package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -1
- package/dist/esm/config/models/app-config.backend.schemas.d.ts +146 -46
- package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/app-config.backend.schemas.js +121 -12
- package/dist/esm/config/models/app-config.backend.schemas.js.map +1 -1
- package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.d.ts +38 -15
- package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.d.ts.map +1 -1
- package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.js +17 -2
- package/dist/esm/config/models/provider-runtime-artifact.backend.schemas.js.map +1 -1
- package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts +0 -1
- package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration-loader.backend.service.js +68 -76
- package/dist/esm/config/services/app-configuration-loader.backend.service.js.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.service.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.service.js +23 -1
- package/dist/esm/config/services/app-configuration.backend.service.js.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts +43 -1
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.js +52 -3
- package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -1
- package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts +25 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts.map +1 -1
- package/dist/esm/config/services/application-startup-config-validator.backend.service.js +41 -1
- package/dist/esm/config/services/application-startup-config-validator.backend.service.js.map +1 -1
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.d.ts +2 -2
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js +2 -2
- package/dist/esm/data-seeding/services/shared/data-seed-scope-iteration.shared.utils.js.map +1 -1
- package/dist/esm/databases/models/filter.backend.schemas.js +2 -2
- package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +20 -1
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.d.ts.map +1 -1
- package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.js +48 -0
- package/dist/esm/databases/services/postgresql-schema-plan-diff.backend.js.map +1 -1
- package/dist/esm/databases/services/redis.service.d.ts +27 -0
- package/dist/esm/databases/services/redis.service.d.ts.map +1 -1
- package/dist/esm/databases/services/redis.service.js +29 -0
- package/dist/esm/databases/services/redis.service.js.map +1 -1
- package/dist/esm/errors/services/error-builder.backend.service.d.ts +13 -1
- package/dist/esm/errors/services/error-builder.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/error-builder.backend.service.js +13 -1
- package/dist/esm/errors/services/error-builder.backend.service.js.map +1 -1
- package/dist/esm/errors/services/error-handler.backend.service.d.ts +70 -7
- package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/error-handler.backend.service.js +134 -8
- package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -1
- package/dist/esm/errors/services/rate-limit.backend.service.d.ts +66 -0
- package/dist/esm/errors/services/rate-limit.backend.service.d.ts.map +1 -1
- package/dist/esm/errors/services/rate-limit.backend.service.js +102 -25
- package/dist/esm/errors/services/rate-limit.backend.service.js.map +1 -1
- package/dist/esm/errors/utils/error-log-level-classification.backend.utils.d.ts +5 -0
- package/dist/esm/errors/utils/error-log-level-classification.backend.utils.d.ts.map +1 -1
- package/dist/esm/errors/utils/error-log-level-classification.backend.utils.js +25 -0
- package/dist/esm/errors/utils/error-log-level-classification.backend.utils.js.map +1 -1
- package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.d.ts +33 -0
- package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.d.ts.map +1 -1
- package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.js +40 -0
- package/dist/esm/errors/utils/rate-limit-environment-relaxation.backend.utils.js.map +1 -1
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts +41 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.d.ts.map +1 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js +40 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.contracts.js.map +1 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts +64 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.d.ts.map +1 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js +193 -0
- package/dist/esm/external-data/controllers/external-data-admin.backend.controller.js.map +1 -0
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts +72 -4
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.js +60 -19
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.js.map +1 -1
- package/dist/esm/external-data/external-data-transform.backend.d.ts.map +1 -1
- package/dist/esm/external-data/external-data-transform.backend.js +7 -1
- package/dist/esm/external-data/external-data-transform.backend.js.map +1 -1
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts +2 -0
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.d.ts.map +1 -1
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js +13 -0
- package/dist/esm/external-data/models/external-data-pipeline-state.backend.schemas.js.map +1 -1
- package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.d.ts +4 -2
- package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.d.ts.map +1 -1
- package/dist/esm/external-providers/models/provider-selection-resolution-evidence.backend.definitions.js.map +1 -1
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts +256 -0
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.d.ts.map +1 -0
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js +333 -0
- package/dist/esm/external-providers/operations/provider-operation-executor.backend.service.js.map +1 -0
- package/dist/esm/external-providers/operations/provider-operation-request.backend.d.ts +56 -0
- package/dist/esm/external-providers/operations/provider-operation-request.backend.d.ts.map +1 -0
- package/dist/esm/external-providers/operations/provider-operation-request.backend.js +211 -0
- package/dist/esm/external-providers/operations/provider-operation-request.backend.js.map +1 -0
- package/dist/esm/external-providers/operations/provider-request-signing.backend.d.ts +45 -0
- package/dist/esm/external-providers/operations/provider-request-signing.backend.d.ts.map +1 -0
- package/dist/esm/external-providers/operations/provider-request-signing.backend.js +216 -0
- package/dist/esm/external-providers/operations/provider-request-signing.backend.js.map +1 -0
- package/dist/esm/external-providers/operations/provider-rest-call-client.backend.d.ts +56 -0
- package/dist/esm/external-providers/operations/provider-rest-call-client.backend.d.ts.map +1 -0
- package/dist/esm/external-providers/operations/provider-rest-call-client.backend.js +78 -0
- package/dist/esm/external-providers/operations/provider-rest-call-client.backend.js.map +1 -0
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts +1 -1
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js +2 -2
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js.map +1 -1
- package/dist/esm/external-providers/services/backend-provider-loader.backend.service.d.ts +89 -0
- package/dist/esm/external-providers/services/backend-provider-loader.backend.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/backend-provider-loader.backend.service.js +164 -0
- package/dist/esm/external-providers/services/backend-provider-loader.backend.service.js.map +1 -0
- package/dist/esm/external-providers/services/backend-provider-registry.backend.service.d.ts +26 -27
- package/dist/esm/external-providers/services/backend-provider-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/backend-provider-registry.backend.service.js +50 -64
- package/dist/esm/external-providers/services/backend-provider-registry.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/document-extraction.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/document-extraction.backend.service.js +3 -3
- package/dist/esm/external-providers/services/document-extraction.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/embeddings.backend.service.js +4 -4
- package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +306 -7
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +539 -45
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.d.ts.map +1 -1
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js +25 -2
- package/dist/esm/external-providers/services/frontend-bootstrap.backend.service.js.map +1 -1
- package/dist/esm/files/controllers/file.controller.d.ts +24 -1
- package/dist/esm/files/controllers/file.controller.d.ts.map +1 -1
- package/dist/esm/files/controllers/file.controller.js +83 -11
- package/dist/esm/files/controllers/file.controller.js.map +1 -1
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts +17 -0
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.d.ts.map +1 -0
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js +1 -0
- package/dist/esm/files/handlers/file-upload-route-locals.backend.types.js.map +1 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +5 -1
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +76 -13
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +18 -0
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-operation-handler.backend.service.js +36 -28
- package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-scanning.backend.service.d.ts +94 -9
- package/dist/esm/files/services/file-scanning.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-scanning.backend.service.js +197 -17
- package/dist/esm/files/services/file-scanning.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-text-extraction.backend.service.d.ts +60 -1
- package/dist/esm/files/services/file-text-extraction.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-text-extraction.backend.service.js +167 -8
- package/dist/esm/files/services/file-text-extraction.backend.service.js.map +1 -1
- package/dist/esm/files/services/file-upload-grant.backend.service.d.ts +214 -0
- package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-upload-grant.backend.service.js +566 -0
- package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -0
- package/dist/esm/files/services/files.backend.service.d.ts +87 -0
- package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/files.backend.service.js +252 -19
- package/dist/esm/files/services/files.backend.service.js.map +1 -1
- package/dist/esm/files/storage/application-storage-key.backend.utils.d.ts +109 -0
- package/dist/esm/files/storage/application-storage-key.backend.utils.d.ts.map +1 -0
- package/dist/esm/files/storage/application-storage-key.backend.utils.js +123 -0
- package/dist/esm/files/storage/application-storage-key.backend.utils.js.map +1 -0
- package/dist/esm/files/storage/file-storage-provider.types.d.ts +16 -10
- package/dist/esm/files/storage/file-storage-provider.types.d.ts.map +1 -1
- package/dist/esm/files/storage/file-storage-provider.types.js.map +1 -1
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts +67 -8
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js +101 -28
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js.map +1 -1
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.d.ts.map +1 -1
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js +8 -55
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js.map +1 -1
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.js +20 -0
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.js.map +1 -1
- package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -1
- package/dist/esm/files/utils/file-uploader.utils.js +12 -0
- package/dist/esm/files/utils/file-uploader.utils.js.map +1 -1
- package/dist/esm/files/utils/office-document-text-extraction.backend.utils.d.ts +86 -0
- package/dist/esm/files/utils/office-document-text-extraction.backend.utils.d.ts.map +1 -0
- package/dist/esm/files/utils/office-document-text-extraction.backend.utils.js +288 -0
- package/dist/esm/files/utils/office-document-text-extraction.backend.utils.js.map +1 -0
- package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.d.ts +15 -0
- package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.js +76 -5
- package/dist/esm/flows-actors/a2a/batches/a2a-abandoned-task-sweep.batch.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/controllers/a2a.controller.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/controllers/a2a.controller.js +6 -1
- package/dist/esm/flows-actors/a2a/controllers/a2a.controller.js.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.d.ts +60 -0
- package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.js +63 -0
- package/dist/esm/flows-actors/a2a/models/a2a.backend.schemas.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.d.ts +74 -0
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js +200 -44
- package/dist/esm/flows-actors/a2a/services/a2a-task-cancellation.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.d.ts +7 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.js +53 -1
- package/dist/esm/flows-actors/a2a/services/a2a-task.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.d.ts +18 -0
- package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.js +18 -0
- package/dist/esm/flows-actors/a2a/services/a2a-token-budget.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a.backend.service.d.ts +12 -7
- package/dist/esm/flows-actors/a2a/services/a2a.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/a2a/services/a2a.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts +0 -13
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js +14 -22
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts +8 -3
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.js +25 -15
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts +13 -1
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.js.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +88 -8
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +333 -31
- package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.d.ts.map +1 -1
- package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.js +4 -2
- package/dist/esm/flows-actors/models/market-generation.actors-system.backend.definitions.js.map +1 -1
- package/dist/esm/flows-actors/models/mcp-client.backend.definitions.d.ts +113 -0
- package/dist/esm/flows-actors/models/mcp-client.backend.definitions.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/mcp-client.backend.definitions.js +62 -0
- package/dist/esm/flows-actors/models/mcp-client.backend.definitions.js.map +1 -0
- package/dist/esm/flows-actors/services/actors-system.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/actors-system.backend.service.js +0 -2
- package/dist/esm/flows-actors/services/actors-system.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts +107 -1
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/agents.backend.service.js +519 -56
- package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +5 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +79 -16
- package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +34 -5
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js +154 -20
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
- package/dist/esm/flows-actors/services/flows.backend.services.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/flows.backend.services.js +27 -23
- package/dist/esm/flows-actors/services/flows.backend.services.js.map +1 -1
- package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.js +7 -1
- package/dist/esm/flows-actors/services/llm-observability-agent-call-trace-sink.backend.js.map +1 -1
- package/dist/esm/flows-actors/services/mcp-client.backend.service.d.ts +90 -0
- package/dist/esm/flows-actors/services/mcp-client.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/mcp-client.backend.service.js +368 -0
- package/dist/esm/flows-actors/services/mcp-client.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts +9 -5
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts.map +1 -1
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js +12 -17
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +151 -41
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +308 -143
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.d.ts +0 -207
- package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.js +8 -243
- package/dist/esm/flows-actors/utils/meta-workflow-canonical-json.backend.utils.js.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.d.ts.map +1 -1
- package/dist/esm/flows-actors/utils/meta-workflow-structured-generation-plan.backend.utils.js.map +1 -1
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts +9 -14
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts.map +1 -1
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.js +18 -89
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.js.map +1 -1
- package/dist/esm/guidance/services/progression-state-store.backend.service.d.ts +86 -0
- package/dist/esm/guidance/services/progression-state-store.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/services/progression-state-store.backend.service.js +155 -0
- package/dist/esm/guidance/services/progression-state-store.backend.service.js.map +1 -0
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts +10 -0
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.js +55 -5
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.js.map +1 -1
- package/dist/esm/index.d.ts +15 -5
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +45 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/inject/models/container.d.ts.map +1 -1
- package/dist/esm/inject/models/container.js +82 -10
- package/dist/esm/inject/models/container.js.map +1 -1
- package/dist/esm/inject/models/service-types.d.ts +20 -3
- package/dist/esm/inject/models/service-types.d.ts.map +1 -1
- package/dist/esm/inject/models/service-types.js +21 -3
- package/dist/esm/inject/models/service-types.js.map +1 -1
- package/dist/esm/mcp/controllers/mcp.controller.d.ts.map +1 -1
- package/dist/esm/mcp/controllers/mcp.controller.js +32 -4
- package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts +34 -0
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.d.ts.map +1 -1
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.js +42 -0
- package/dist/esm/mcp/models/mcp-tool.backend.schemas.js.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +84 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.js +235 -11
- package/dist/esm/mcp/services/mcp-server.backend.service.js.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts +64 -2
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +152 -6
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js.map +1 -1
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js +49 -4
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.d.ts +66 -0
- package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.js +199 -0
- package/dist/esm/monitoring/analytics/services/value-moment-definition-registry.backend.service.js.map +1 -0
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts +149 -13
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js +411 -19
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts +11 -2
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.js.map +1 -1
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts +28 -9
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.js +30 -10
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.js.map +1 -1
- package/dist/esm/monitoring/logger/services/logger.service.d.ts +12 -0
- package/dist/esm/monitoring/logger/services/logger.service.d.ts.map +1 -1
- package/dist/esm/monitoring/logger/services/logger.service.js +52 -11
- package/dist/esm/monitoring/logger/services/logger.service.js.map +1 -1
- package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.d.ts +62 -0
- package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.d.ts.map +1 -0
- package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.js +78 -0
- package/dist/esm/monitoring/logger/utils/log-severity-floor.backend.utils.js.map +1 -0
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts +309 -0
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.js +385 -0
- package/dist/esm/monitoring/observability/audit-observation-emission.backend.js.map +1 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +1 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts +21 -0
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
- package/dist/esm/monitoring/observability/services/metrics.service.js +38 -0
- package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
- package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts +0 -80
- package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts.map +0 -1
- package/dist/esm/notifications/email/models/email-context-provider.interface.js +0 -25
- package/dist/esm/notifications/email/models/email-context-provider.interface.js.map +0 -1
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts +0 -49
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts.map +0 -1
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js +0 -141
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js.map +0 -1
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts +0 -37
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts.map +0 -1
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js +0 -121
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js.map +0 -1
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts +66 -1
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.js +105 -10
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.js.map +1 -1
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts +0 -58
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts.map +0 -1
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js +0 -223
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js.map +0 -1
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.js +10 -1
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.js.map +1 -1
- package/dist/esm/notifications/email/services/email.backend.service.d.ts +60 -4
- package/dist/esm/notifications/email/services/email.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/email/services/email.backend.service.js +145 -43
- package/dist/esm/notifications/email/services/email.backend.service.js.map +1 -1
- package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts +0 -1
- package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts.map +1 -1
- package/dist/esm/notifications/email/utils/color-conversion.utils.js.map +1 -1
- package/dist/esm/notifications/services/notification-badge.backend.service.d.ts +142 -21
- package/dist/esm/notifications/services/notification-badge.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/services/notification-badge.backend.service.js +283 -58
- package/dist/esm/notifications/services/notification-badge.backend.service.js.map +1 -1
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +108 -13
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +432 -101
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -1
- package/dist/esm/notifications/sms/services/sms.backend.service.d.ts +2 -2
- package/dist/esm/notifications/sms/services/sms.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/sms/services/sms.backend.service.js +5 -5
- package/dist/esm/notifications/sms/services/sms.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +117 -5
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +164 -6
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts +0 -6
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js +54 -7
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts +5 -5
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js +14 -13
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.utils.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts +2 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js +18 -8
- package/dist/esm/notifications/webhooks/outbound/m2m-webhook-signed-request.backend.utils.js.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js +20 -18
- package/dist/esm/notifications/webhooks/outbound/services/webhook-config-test-endpoint.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts +16 -0
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts.map +1 -1
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js +18 -0
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js.map +1 -1
- package/dist/esm/organizations/batches/organization-purge.batch.backend.service.d.ts +2 -2
- package/dist/esm/organizations/batches/organization-purge.batch.backend.service.js +2 -2
- package/dist/esm/organizations/batches/organization-purge.batch.backend.service.js.map +1 -1
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js +63 -2
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js.map +1 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js +4 -1
- package/dist/esm/organizations/services/organization-unit-custom-implementation.backend.service.js.map +1 -1
- package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.d.ts +66 -0
- package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.js +257 -0
- package/dist/esm/queue/adapters/in-memory-queue-adapter.backend.service.js.map +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.binding.d.ts +12 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.binding.d.ts.map +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.binding.js +47 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.binding.js.map +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.interface.d.ts +87 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.interface.d.ts.map +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.interface.js +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.interface.js.map +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.options.d.ts +31 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.options.d.ts.map +1 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.options.js +13 -0
- package/dist/esm/queue/adapters/queue-adapter.backend.options.js.map +1 -0
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts +19 -25
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js +33 -0
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js.map +1 -1
- package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts +2 -2
- package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/domain-queue-consumer.backend.service.js +1 -4
- package/dist/esm/queue/domain-queue-consumer.backend.service.js.map +1 -1
- package/dist/esm/queue/job-consumer.backend.service.d.ts +2 -2
- package/dist/esm/queue/job-consumer.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/job-consumer.backend.service.js +1 -4
- package/dist/esm/queue/job-consumer.backend.service.js.map +1 -1
- package/dist/esm/queue/job-executor.backend.service.d.ts +2 -2
- package/dist/esm/queue/job-executor.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/job-executor.backend.service.js +1 -4
- package/dist/esm/queue/job-executor.backend.service.js.map +1 -1
- package/dist/esm/queue/queue-monitoring.backend.service.d.ts +8 -4
- package/dist/esm/queue/queue-monitoring.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue-monitoring.backend.service.js +25 -17
- package/dist/esm/queue/queue-monitoring.backend.service.js.map +1 -1
- package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts +16 -1
- package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue-worker-initializer.backend.service.js +16 -1
- package/dist/esm/queue/queue-worker-initializer.backend.service.js.map +1 -1
- package/dist/esm/queue/queue.backend.service.d.ts +3 -3
- package/dist/esm/queue/queue.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/queue.backend.service.js +26 -4
- package/dist/esm/queue/queue.backend.service.js.map +1 -1
- package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts +2 -2
- package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts.map +1 -1
- package/dist/esm/queue/worker-shutdown-manager.backend.service.js +18 -3
- package/dist/esm/queue/worker-shutdown-manager.backend.service.js.map +1 -1
- package/dist/esm/rag/utils/rag-chunking.backend.utils.d.ts +50 -25
- package/dist/esm/rag/utils/rag-chunking.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-chunking.backend.utils.js +147 -39
- package/dist/esm/rag/utils/rag-chunking.backend.utils.js.map +1 -1
- package/dist/esm/rag/utils/rag-context-assembly.backend.utils.d.ts +12 -3
- package/dist/esm/rag/utils/rag-context-assembly.backend.utils.d.ts.map +1 -1
- package/dist/esm/rag/utils/rag-context-assembly.backend.utils.js +12 -3
- package/dist/esm/rag/utils/rag-context-assembly.backend.utils.js.map +1 -1
- package/dist/esm/requests/service/websocket.service.d.ts +9 -0
- package/dist/esm/requests/service/websocket.service.d.ts.map +1 -1
- package/dist/esm/requests/service/websocket.service.js +88 -15
- package/dist/esm/requests/service/websocket.service.js.map +1 -1
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -1
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +16 -2
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -1
- package/dist/esm/resources/models/resources-operations.backend.definitions.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-operations.backend.definitions.js +2 -0
- package/dist/esm/resources/models/resources-operations.backend.definitions.js.map +1 -1
- package/dist/esm/resources/models/resources-relationships.backend.definitions.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-relationships.backend.definitions.js +14 -0
- package/dist/esm/resources/models/resources-relationships.backend.definitions.js.map +1 -1
- package/dist/esm/resources/models/resources-types.backend.schemas.d.ts +2 -1
- package/dist/esm/resources/models/resources-types.backend.schemas.d.ts.map +1 -1
- package/dist/esm/resources/models/resources-types.backend.schemas.js +8 -0
- package/dist/esm/resources/models/resources-types.backend.schemas.js.map +1 -1
- package/dist/esm/resources/services/resource-id.backend.service.js +3 -3
- package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -1
- package/dist/esm/resources/services/resources-registry.backend.service.d.ts +60 -5
- package/dist/esm/resources/services/resources-registry.backend.service.d.ts.map +1 -1
- package/dist/esm/resources/services/resources-registry.backend.service.js +91 -7
- package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -1
- package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts +36 -3
- package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/controllers/health-controller.backend.service.js +32 -10
- package/dist/esm/runtime/controllers/health-controller.backend.service.js.map +1 -1
- package/dist/esm/runtime/domain-module.backend.definitions.d.ts +24 -0
- package/dist/esm/runtime/domain-module.backend.definitions.d.ts.map +1 -1
- package/dist/esm/runtime/domain-module.backend.definitions.js +24 -0
- package/dist/esm/runtime/domain-module.backend.definitions.js.map +1 -1
- package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js +13 -7
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts +51 -0
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts.map +1 -1
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.js.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.d.ts +26 -0
- package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/http-server.backend.service.js +181 -1
- package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
- package/dist/esm/runtime/services/start-application.backend.service.d.ts +47 -1
- package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -1
- package/dist/esm/runtime/services/start-application.backend.service.js +343 -77
- package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -1
- package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.d.ts +15 -0
- package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.js +28 -0
- package/dist/esm/security/api-keys/api-keys.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts +5 -1
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js +24 -4
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js +29 -4
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.d.ts +114 -0
- package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.js +354 -3
- package/dist/esm/security/authentications/controllers/oauth-provider-controller.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/models/cimd.backend.schemas.d.ts +1 -0
- package/dist/esm/security/authentications/models/cimd.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/cimd.backend.schemas.js +22 -0
- package/dist/esm/security/authentications/models/cimd.backend.schemas.js.map +1 -1
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +3 -23
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/jwt.backend.schemas.js +20 -45
- package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -1
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts +15 -0
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts +0 -2
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js +23 -14
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts +0 -1
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js +15 -12
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts +113 -3
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js +207 -30
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts +95 -2
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js +153 -9
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts +190 -0
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.js +377 -53
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +9 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +77 -2
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +5 -3
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts +41 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js +202 -23
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js +42 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js +34 -4
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts +29 -5
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js +77 -5
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +41 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +87 -4
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts +43 -1
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js +277 -97
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.d.ts +28 -5
- package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.js +72 -12
- package/dist/esm/security/authentications/services/cimd-client-metadata.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js +3 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts +28 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +283 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts +4 -3
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js +4 -3
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.d.ts +35 -0
- package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.js +111 -21
- package/dist/esm/security/authentications/services/oauth-provider-token.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.d.ts +14 -1
- package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.js +49 -8
- package/dist/esm/security/authentications/services/oidc-authorization-code.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.js +4 -0
- package/dist/esm/security/authentications/services/utils/auth-policy-resolution.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js +6 -0
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js.map +1 -1
- package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.d.ts +37 -1
- package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.js +51 -0
- package/dist/esm/security/authentications/services/utils/external-turn-rate-limit.backend.utils.js.map +1 -1
- package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.d.ts +41 -0
- package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.js +45 -0
- package/dist/esm/security/authentications/utils/enterprise-sso-enforcement.backend.utils.js.map +1 -1
- package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.d.ts +116 -0
- package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.d.ts.map +1 -0
- package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.js +162 -0
- package/dist/esm/security/authorizations/cross-tenant-read-observation.backend.js.map +1 -0
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js +24 -1
- package/dist/esm/security/authorizations/initiator-organization-confinement.backend.js.map +1 -1
- package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.d.ts +20 -20
- package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.js +27 -28
- package/dist/esm/security/authorizations/organization-owner-floor.backend.utils.js.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js +77 -3
- package/dist/esm/security/authorizations/platform-access-grant-custom-implementation.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts +117 -0
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js +104 -0
- package/dist/esm/security/authorizations/privileged-access-review.backend.utils.js.map +1 -0
- package/dist/esm/security/authorizations/role-ceiling.backend.utils.d.ts +4 -0
- package/dist/esm/security/authorizations/role-ceiling.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/role-ceiling.backend.utils.js +4 -0
- package/dist/esm/security/authorizations/role-ceiling.backend.utils.js.map +1 -1
- package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts +93 -0
- package/dist/esm/security/authorizations/role-conferral.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/authorizations/role-conferral.backend.utils.js +95 -0
- package/dist/esm/security/authorizations/role-conferral.backend.utils.js.map +1 -0
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts +124 -1
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.d.ts.map +1 -1
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js +142 -5
- package/dist/esm/security/authorizations/scope-root-collection-confinement.backend.js.map +1 -1
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +175 -14
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js +385 -49
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts +6 -14
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js +13 -22
- package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
- package/dist/esm/security/connected-accounts/connection-target-authorization.backend.d.ts +60 -0
- package/dist/esm/security/connected-accounts/connection-target-authorization.backend.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/connection-target-authorization.backend.js +79 -0
- package/dist/esm/security/connected-accounts/connection-target-authorization.backend.js.map +1 -0
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts +161 -0
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js +512 -0
- package/dist/esm/security/connected-accounts/controllers/provider-connection.controller.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts +59 -0
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.js +22 -0
- package/dist/esm/security/connected-accounts/organization-provider-credential-resolver.port.js.map +1 -0
- package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.d.ts +44 -0
- package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.js +20 -0
- package/dist/esm/security/connected-accounts/provider-oauth2-refresher.port.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts +191 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js +385 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credential-store.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.d.ts +41 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.js +358 -0
- package/dist/esm/security/connected-accounts/services/organization-provider-credentials.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.d.ts +160 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js +266 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-exchange.backend.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts +111 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js +107 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-pending-authorization.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.d.ts +54 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js +153 -0
- package/dist/esm/security/connected-accounts/services/provider-oauth2-refresher.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts +195 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js +387 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credential-store.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.d.ts +45 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.js +291 -0
- package/dist/esm/security/connected-accounts/services/user-provider-credentials.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts +62 -0
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.js +29 -0
- package/dist/esm/security/connected-accounts/user-provider-credential-resolver.port.js.map +1 -0
- package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.d.ts +127 -0
- package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.js +277 -0
- package/dist/esm/security/connected-accounts/utils/provider-credential-envelope.backend.utils.js.map +1 -0
- package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.d.ts +66 -0
- package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.js +75 -0
- package/dist/esm/security/connected-accounts/utils/stored-credential-value.backend.utils.js.map +1 -0
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +18 -1
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +110 -74
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -1
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts +22 -0
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js +22 -0
- package/dist/esm/security/consumable-tokens/consumable-token-models.exports.js.map +1 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +17 -3
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +12 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -1
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +41 -3
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -1
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +83 -20
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -1
- package/dist/esm/security/credential-rotation-grace.backend.utils.d.ts +9 -4
- package/dist/esm/security/credential-rotation-grace.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/credential-rotation-grace.backend.utils.js +9 -4
- package/dist/esm/security/credential-rotation-grace.backend.utils.js.map +1 -1
- package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -1
- package/dist/esm/security/jwt/services/jwt.backend.service.js +1 -18
- package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.d.ts +26 -0
- package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.js +43 -0
- package/dist/esm/security/oauth-clients/oauth-client-generation.backend.utils.js.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts +8 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js +49 -0
- package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
- package/dist/esm/security/scim/controllers/scim.backend.controller.d.ts.map +1 -1
- package/dist/esm/security/scim/controllers/scim.backend.controller.js +17 -5
- package/dist/esm/security/scim/controllers/scim.backend.controller.js.map +1 -1
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts +67 -29
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts.map +1 -1
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js +47 -25
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js.map +1 -1
- package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.d.ts +10 -2
- package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.d.ts.map +1 -1
- package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.js +10 -2
- package/dist/esm/security/ssrf/outbound-target-guard.backend.utils.js.map +1 -1
- package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.d.ts +143 -0
- package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.d.ts.map +1 -0
- package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.js +258 -0
- package/dist/esm/security/ssrf/pinned-outbound-fetch.backend.utils.js.map +1 -0
- package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.d.ts +39 -0
- package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.js +159 -0
- package/dist/esm/users/services/user-read-retained.custom-impl.backend.service.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +17 -9
- package/dist/esm/.builder.pid +0 -9
|
@@ -24,7 +24,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
24
24
|
};
|
|
25
25
|
import { injectable, inject, optional } from 'inversify';
|
|
26
26
|
import crypto from 'crypto';
|
|
27
|
-
import { ConsumableToken_ConsumptionMode, ErrorType, ErrorCustomMessageReference, PersistenceAdapter, } from '@wildo-ai/saas-models';
|
|
27
|
+
import { ConsumableToken_ConsumptionMode, ErrorType, ErrorCustomMessageReference, isWildoBackendError, FILE_UPLOAD_GRANT_ABSOLUTE_MAX_MINUTES, CoreConsumableTokenTypes, PersistenceAdapter, } from '@wildo-ai/saas-models';
|
|
28
28
|
import { durationToSeconds } from '@wildo-ai/zod-decorators';
|
|
29
29
|
import { SAAS_SERVICE_TYPES } from '../../../inject/models/service-types.js';
|
|
30
30
|
import { ErrorBuilderBackendService } from '../../../errors/services/error-builder.backend.service.js';
|
|
@@ -103,6 +103,27 @@ let ConsumableTokenBackendService = class ConsumableTokenBackendService {
|
|
|
103
103
|
});
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
+
// assurance-control: WILDO.IDENTITY.CREDENTIAL_LIFECYCLE — a file upload grant is a bearer credential
|
|
107
|
+
// DESIGNED to leave the trust boundary (an LLM transcript, a shell history), so its lifetime is bounded
|
|
108
|
+
// HERE, at the one mint chokepoint, per type and fail-closed: an over-ceiling request is REJECTED, never
|
|
109
|
+
// clamped (issue #312, D8). Nothing else bounds a consumable token's life — measured 2026-09-05, the
|
|
110
|
+
// one-off ceiling above was the only one — which is why this cannot be left to the caller's `expiresIn`.
|
|
111
|
+
// SINGLE_USE only: a reusable upload credential is the presigned-URL defect rebuilt inside the API.
|
|
112
|
+
if (params.tokenType === CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {
|
|
113
|
+
const requestedMinutes = durationToSeconds(params.expiresIn) / 60;
|
|
114
|
+
if (requestedMinutes > FILE_UPLOAD_GRANT_ABSOLUTE_MAX_MINUTES) {
|
|
115
|
+
throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {
|
|
116
|
+
customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_DURATION_EXCEEDS_MAX,
|
|
117
|
+
context: { requestedMinutes: Math.round(requestedMinutes), absoluteMaxMinutes: FILE_UPLOAD_GRANT_ABSOLUTE_MAX_MINUTES }, // diagnostic (log-only)
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (params.consumptionMode !== ConsumableToken_ConsumptionMode.SINGLE_USE) {
|
|
121
|
+
throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {
|
|
122
|
+
customMessageReference: ErrorCustomMessageReference.VALIDATION,
|
|
123
|
+
context: { message: 'A file upload grant must be SINGLE_USE', consumptionMode: params.consumptionMode }, // diagnostic (log-only)
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
106
127
|
/**
|
|
107
128
|
* Identity through the framework AUTHORITY, not `crypto.randomUUID()`.
|
|
108
129
|
*
|
|
@@ -428,12 +449,24 @@ let ConsumableTokenBackendService = class ConsumableTokenBackendService {
|
|
|
428
449
|
* `tokenId` is guarded by the same non-string check as every other primitive here (`{ _id }` reaches
|
|
429
450
|
* Mongo directly, so a `{$ne}`-shaped value would otherwise match an ARBITRARY token).
|
|
430
451
|
*/
|
|
452
|
+
/**
|
|
453
|
+
* Read a token row by its VALUE regardless of state — expired, consumed and revoked rows included.
|
|
454
|
+
*
|
|
455
|
+
* For status surfaces that must say WHY a token is unusable (`validateToken` refuses those rows, which
|
|
456
|
+
* is right for authentication and wrong for a status read). Callers hold the value already, so this
|
|
457
|
+
* discloses nothing they could not learn by presenting it. Never logs the value (R2).
|
|
458
|
+
*/
|
|
459
|
+
async findTokenByValue(tokenValue) {
|
|
460
|
+
this.assertTokenValueIsString(tokenValue);
|
|
461
|
+
const doc = await this.repositoriesRegistry.readUnscopedByKey(BackendResourceType.CONSUMABLE_TOKENS, { token: tokenValue });
|
|
462
|
+
return doc ?? null;
|
|
463
|
+
}
|
|
431
464
|
async findTokenById(tokenId) {
|
|
432
465
|
this.assertTokenValueIsString(tokenId);
|
|
433
|
-
// Adapter-neutral, like every other read on this service: `getTokenCollection`
|
|
434
|
-
// driver directly, so a raw `findOne` here would make this the one
|
|
435
|
-
// PostgreSQL-backed application cannot open. `readUnscopedByKey` is the same
|
|
436
|
-
// token-VALUE lookups above already use; only the key differs.
|
|
466
|
+
// Adapter-neutral, like every other read on this service: the retired `getTokenCollection`
|
|
467
|
+
// accessor reached the Mongo driver directly, so a raw `findOne` here would make this the one
|
|
468
|
+
// token-lookup door a PostgreSQL-backed application cannot open. `readUnscopedByKey` is the same
|
|
469
|
+
// primitive the token-VALUE lookups above already use; only the key differs.
|
|
437
470
|
const tokenDoc = await this.repositoriesRegistry.readUnscopedByKey(BackendResourceType.CONSUMABLE_TOKENS, { _id: tokenId });
|
|
438
471
|
return tokenDoc ?? null;
|
|
439
472
|
}
|
|
@@ -448,6 +481,26 @@ let ConsumableTokenBackendService = class ConsumableTokenBackendService {
|
|
|
448
481
|
* and never write a duplicate row under a race. Returns whether THIS call performed the revocation
|
|
449
482
|
* (`false` = the token was already revoked, or does not exist).
|
|
450
483
|
*/
|
|
484
|
+
/**
|
|
485
|
+
* Record, on a redeemed FILE_UPLOAD_GRANT, the file its one upload produced (issue #312, D6/D10).
|
|
486
|
+
*
|
|
487
|
+
* Written AFTER the grant is consumed and the FILES row exists, so there is exactly one writer and
|
|
488
|
+
* a plain replace of `metadata` is safe. Best-effort by contract: the upload has already succeeded
|
|
489
|
+
* when this runs, so a failure here must not fail it — the caller logs and the status read falls
|
|
490
|
+
* back to "REDEEMED, file unknown; re-read the resource". Returns whether a row was written.
|
|
491
|
+
*
|
|
492
|
+
* Replaces the whole `metadata` object rather than a dotted path so the write is adapter-neutral:
|
|
493
|
+
* the PostgreSQL arm stores `metadata` as one JSON column.
|
|
494
|
+
*/
|
|
495
|
+
async recordFileUploadGrantProducedFile(tokenId, fileId) {
|
|
496
|
+
const existing = await this.findTokenById(tokenId);
|
|
497
|
+
if (!existing || existing.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
const now = new Date();
|
|
501
|
+
const written = await this.repositoriesRegistry.atomicGuardedMutation(BackendResourceType.CONSUMABLE_TOKENS, { _id: tokenId, isConsumed: true }, { set: { metadata: { ...(existing.metadata ?? {}), producedFileId: fileId }, updatedAt: now } });
|
|
502
|
+
return written !== null;
|
|
503
|
+
}
|
|
451
504
|
async revokeToken(tokenId) {
|
|
452
505
|
const now = new Date();
|
|
453
506
|
// Adapter-neutral by construction: `atomicGuardedMutation` compiles the SAME conditional
|
|
@@ -725,25 +778,35 @@ let ConsumableTokenBackendService = class ConsumableTokenBackendService {
|
|
|
725
778
|
return transaction.nativeSession;
|
|
726
779
|
}
|
|
727
780
|
/**
|
|
728
|
-
* Match only the sparse active-generation index. `createToken` also writes
|
|
729
|
-
*
|
|
730
|
-
*
|
|
781
|
+
* Match only the sparse active-generation index. `createToken` also writes other unique fields
|
|
782
|
+
* (notably the raw token), and collapsing their failures into a RESEND race would hide an
|
|
783
|
+
* unrelated persistence defect.
|
|
784
|
+
*
|
|
785
|
+
* ## Branches on the CLASSIFIED conflict, never on driver internals
|
|
786
|
+
*
|
|
787
|
+
* This used to require a raw MongoDB error with `code: 11000` and a `keyPattern`, and could
|
|
788
|
+
* therefore never fire. `insertRawDocument` translates the duplicate before it escapes —
|
|
789
|
+
* `throw this.handleMongoDBError(error)` on the Mongo arm, `handlePostgresError` on the
|
|
790
|
+
* PostgreSQL one — so what reaches this catch is the classified CONFLICT, carrying no `code` and
|
|
791
|
+
* no `keyPattern`. The RESEND race surfaced as a generic CONFLICT and the specific
|
|
792
|
+
* `consumable_token_active_generation_conflict` reference was unreachable through the real stack.
|
|
793
|
+
*
|
|
794
|
+
* The infrastructure tier's own comment says why detecting on driver internals was the wrong
|
|
795
|
+
* shape in the first place: without the translation "every caller would need adapter-specific
|
|
796
|
+
* detection, which is precisely what this tier exists to remove". On PostgreSQL there is no
|
|
797
|
+
* `code: 11000` to match at ALL — a unique violation is SQLSTATE `23505` — so the old predicate
|
|
798
|
+
* was not merely unreachable, it was unwritable for the adapter both example applications now run.
|
|
799
|
+
*
|
|
800
|
+
* `violatedFields` is the adapter-neutral answer both arms populate: Mongo from `keyPattern`
|
|
801
|
+
* (falling back to the message), PostgreSQL from the constraint's columns.
|
|
731
802
|
*/
|
|
732
803
|
isActiveGenerationKeyDuplicate(error) {
|
|
733
|
-
if (error
|
|
804
|
+
if (!isWildoBackendError(error))
|
|
734
805
|
return false;
|
|
735
|
-
|
|
736
|
-
if (mongoError.code !== 11000)
|
|
806
|
+
if (error.type !== ErrorType.CONFLICT)
|
|
737
807
|
return false;
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
&& Object.prototype.hasOwnProperty.call(value, 'activeGenerationKey');
|
|
741
|
-
if (hasActiveGenerationField(mongoError.keyPattern)
|
|
742
|
-
|| hasActiveGenerationField(mongoError.keyValue)) {
|
|
743
|
-
return true;
|
|
744
|
-
}
|
|
745
|
-
return (typeof mongoError.message === 'string'
|
|
746
|
-
&& /\bindex:\s+activeGenerationKey_1\b/.test(mongoError.message));
|
|
808
|
+
const violatedFields = error.context?.violatedFields;
|
|
809
|
+
return Array.isArray(violatedFields) && violatedFields.includes('activeGenerationKey');
|
|
747
810
|
}
|
|
748
811
|
/**
|
|
749
812
|
* Calculate the expiration date from a relative duration.
|
package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumable-token.backend.service.js","sourceRoot":"","sources":["../../../../../../src/security/consumable-tokens/services/consumable-token.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EACL,+BAA+B,EAE/B,SAAS,EACT,2BAA2B,EAC3B,kBAAkB,GAMnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAsB,MAAM,0BAA0B,CAAC;AAEjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEpF,OAAO,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAE9G,OAAO,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAC;AAGvF,OAAO,EAAE,2BAA2B,EAAE,MAAM,8EAA8E,CAAC;AAC3H,OAAO,EAAE,mBAAmB,EAAE,MAAM,qEAAqE,CAAC;AAK1G,OAAO,EACL,mCAAmC,GAEpC,MAAM,gEAAgE,CAAC;AA8CxE,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,oCAAoC,GAAG,EAAE,GAAG,EAAE,CAAC;AAGrD,IAAM,6BAA6B,GAAnC,MAAM,6BAA6B;IACvB,MAAM,CAAgB;IACtB,YAAY,CAA6B;IACzC,cAAc,CAAiB;IAC/B,iBAAiB,CAA4B;IAC7C,4BAA4B,CAA6C;IAE1F,YACqC,MAAqB,EACR,YAAwC,EAC7C,cAA8B,EAGR,iBAA4C,EAQlC,oBAAgE;QAE3I,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAC3C,IAAI,CAAC,4BAA4B,GAAG,oBAAoB,CAAC;IAC3D,CAAC;IAGD,6EAA6E;IAC7E,wBAAwB;IACxB,6EAA6E;IAE7E;;;;;;OAMG;IACI,KAAK,CAAC,WAAW,CACtB,MAAyB,EACzB,WAAgC;QAEhC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAEjE,wFAAwF;QACxF,sGAAsG;QACtG,sGAAsG;QACtG,kGAAkG;QAClG,6GAA6G;QAC7G,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAChC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;YAClE,IAAI,gBAAgB,GAAG,oCAAoC,EAAE,CAAC;gBAC5D,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE;oBAClE,sBAAsB,EAAE,2BAA2B,CAAC,oCAAoC;oBACxF,OAAO,EAAE,EAAE,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,oCAAoC,EAAE,EAAE,wBAAwB;iBAChJ,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD;;;;;;;;;;;;;;;;;;;WAmBG;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB;YAChC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,iBAA0B,CAAC,CAAC;YACpG,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;QAExB,MAAM,SAAS,GAAoB;YACjC,GAAG;YACH,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,GAAG,CAAC,MAAM,CAAC,mBAAmB,IAAI;gBAChC,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;aAChD,CAAC;YACF,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;YAC/B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;YACzB,SAAS;YACT,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE,CAAC;YACZ,GAAG,CAAC,MAAM,CAAC,oBAAoB,KAAK,SAAS,IAAI,EAAE,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACvG,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;YACxD,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;YACxD,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG;SACf,CAAC;QAEF,wCAAwC;QACxC,IAAI,MAAM,CAAC,eAAe,KAAK,+BAA+B,CAAC,aAAa,EAAE,CAAC;YAC7E,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,EAAE;oBAClE,sBAAsB,EAAE,2BAA2B,CAAC,UAAU;oBAC9D,OAAO,EAAE,EAAE,MAAM,EAAE,+DAA+D,EAAE;iBACrF,CAAC,CAAC;YACL,CAAC;YACD,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACrC,CAAC;QAED,6FAA6F;QAC7F,mDAAmD;QACnD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,oBAAoB,CAAC,+BAA+B,CAC7D,mBAAmB,CAAC,iBAA0B,EAC9C,SAA+C,EAC/C,SAAS,EACT,EAAE,WAAW,EAAE,CAChB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,CAAC,mBAAmB,IAAI,IAAI,CAAC,8BAA8B,CAAC,KAAK,CAAC,EAC1E,CAAC;gBACD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE;oBAChE,sBAAsB,EACpB,2BAA2B,CAAC,2BAA2B;oBACzD,OAAO,EAAE;wBACP,MAAM,EAAE,6CAA6C;wBACrD,SAAS,EAAE,MAAM,CAAC,SAAS;wBAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;qBAC5B;iBACF,CAAC,CAAC;YACL,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QAED,uEAAuE;QACvE,uDAAuD;QACvD,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;YAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;gBAC3C,OAAO,EAAE,GAAG;gBACZ,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,cAAc,EAAE,MAAM,CAAC,cAAc;gBACrC,SAAS,EAAE,SAAS,CAAC,WAAW,EAAE;aACnC,CAAC,CAAC;QACL,CAAC,CAAC;QACF,IAAI,WAAW,EAAE,CAAC;YAChB,mCAAmC,CAAC,WAAW,EAAE;gBAC/C,GAAG,EAAE,4BAA4B,GAAG,EAAE;gBACtC,OAAO,EAAE,WAAW;aACrB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,EAAE,CAAC;QACtB,CAAC;QAED,OAAO,SAAgD,CAAC;IAC1D,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,aAAa,CACxB,UAAkB,EAClB,aAAsC;QAEtC,IAAI,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAChE,mBAAmB,CAAC,iBAA0B,EAC9C,EAAE,KAAK,EAAE,UAAU,EAAE,CACtB,CAAC;QAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,0BAA0B;aAC/E,CAAC,CAAC;QACL,CAAC;QAED,MAAM,KAAK,GAAG,QAAsC,CAAC;QAErD,mBAAmB;QACnB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/D,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,wBAAwB;gBAC5E,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE;aAChC,CAAC,CAAC;QACL,CAAC;QAED,eAAe;QACf,IAAI,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/D,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,wBAAwB;gBAC5E,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE;aAChC,CAAC,CAAC;QACL,CAAC;QAED,yCAAyC;QACzC,IAAI,KAAK,CAAC,eAAe,KAAK,+BAA+B,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAC7F,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,iCAAiC;gBACrF,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE;aAChC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,eAAe,KAAK,+BAA+B,CAAC,aAAa,EAAE,CAAC;YAC5E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAC9B,IAAI,OAAO,IAAI,KAAK,CAAC,SAAS,IAAI,OAAO,EAAE,CAAC;gBAC1C,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;oBACtE,sBAAsB,EAAE,2BAA2B,CAAC,iCAAiC;oBACrF,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE;iBACrE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,eAAe,KAAK,+BAA+B,CAAC,eAAe,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YAClG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,iCAAiC;gBACrF,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE;aAChC,CAAC,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAiC,CAAC,EAAE,CAAC;gBACrE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;oBACtC,OAAO,EAAE,KAAK,CAAC,GAAG;oBAClB,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,aAAa;iBACd,CAAC,CAAC;gBACH,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;oBACtE,sBAAsB,EAAE,2BAA2B,CAAC,8BAA8B;oBAClF,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,aAAa,EAAE;iBAC3E,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;;OAWG;IACI,KAAK,CAAC,YAAY,CACvB,UAAkB,EAClB,WAAgC;QAEhC,IAAI,CAAC,wBAAwB,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,2DAA2D;QAC3D,4DAA4D;QAC5D,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CACxE,mBAAmB,CAAC,iBAA0B,EAC9C;YACE,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;YAC7B,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;SACxB,EACD,EAAE,WAAW,EAAE,CAChB,CAAC;QACF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,0BAA0B;aAC/E,CAAC,CAAC;QACL,CAAC;QACD,MAAM,aAAa,GAAG,gBAA8C,CAAC;QAErE,IAAI,MAA2B,CAAC;QAChC,IAAI,QAAmC,CAAC;QACxC;;;;WAIG;QACH,IAAI,cAAkC,CAAC;QAEvC,+FAA+F;QAC/F,sGAAsG;QACtG,MAAM,WAAW,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC;QAE/E,QAAQ,aAAa,CAAC,eAAe,EAAE,CAAC;YACtC,KAAK,+BAA+B,CAAC,UAAU,CAAC,CAAC,CAAC;gBAChD,MAAM,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,WAAW,EAAE,CAAC;gBAClE,gFAAgF;gBAChF,QAAQ,GAAG;oBACT,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;oBACvD,KAAK,EAAE,CAAC,qBAAqB,CAAC;iBAC/B,CAAC;gBACF,MAAM;YACR,CAAC;YAED,KAAK,+BAA+B,CAAC,aAAa,CAAC,CAAC,CAAC;gBACnD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,CAAC;gBAC3C,MAAM,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,GAAG,WAAW,EAAE,CAAC;gBAC5E,oEAAoE;gBACpE,wDAAwD;gBACxD,+DAA+D;gBAC/D,yEAAyE;gBACzE;;;;;;;;;;;;;;;;;;;mBAmBG;gBACH,cAAc,GAAG,OAAO,CAAC;gBACzB,QAAQ,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC;gBACpE,MAAM;YACR,CAAC;YAED,KAAK,+BAA+B,CAAC,eAAe,CAAC,CAAC,CAAC;gBACrD,MAAM,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,WAAW,EAAE,CAAC;gBAClE,gFAAgF;gBAChF,QAAQ,GAAG;oBACT,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE;oBACvD,KAAK,EAAE,CAAC,qBAAqB,CAAC;iBAC/B,CAAC;gBACF,MAAM;YACR,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE;oBAChE,OAAO,EAAE;wBACP,MAAM,EAAE,2CAA2C;wBACnD,OAAO,EAAE,aAAa,CAAC,GAAG;wBAC1B,eAAe,EAAE,aAAa,CAAC,eAAe;qBAC/C;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,CAClE,mBAAmB,CAAC,iBAA0B,EAC9C,MAAM,EACN,QAAQ,EACR,SAAS,EACT,EAAE,WAAW,EAAE,CAChB,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC;YACrF,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE;gBAChE,sBAAsB,EAAE,2BAA2B,CAAC,+BAA+B;gBACnF,OAAO,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,GAAG,EAAE;aACxC,CAAC,CAAC;QACL,CAAC;QAED;;;;;;;WAOG;QACH,IAAI,cAAc,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC;YAC9E,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,CACnD,mBAAmB,CAAC,iBAA0B,EAC9C,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,EACnB,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,EAAE,EAC7D,SAAS,EACT,EAAE,WAAW,EAAE,CAChB,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4EAA4E,EAAE;oBAC7F,OAAO,EAAE,MAAM,CAAC,GAAG;oBACnB,GAAG,2BAA2B,CAAC,KAAK,CAAC;iBACtC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,cAAc,GAAG,KAAK,IAAmB,EAAE;YAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE;gBAC5C,OAAO,EAAE,aAAa,CAAC,GAAG;gBAC1B,eAAe,EAAE,aAAa,CAAC,eAAe;aAC/C,CAAC,CAAC;QACL,CAAC,CAAC;QACF,IAAI,WAAW,EAAE,CAAC;YAChB,mCAAmC,CAAC,WAAW,EAAE;gBAC/C,GAAG,EAAE,6BAA6B,aAAa,CAAC,GAAG,EAAE;gBACrD,OAAO,EAAE,cAAc;aACxB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,cAAc,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,MAAoC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;;OAWG;IACI,KAAK,CAAC,aAAa,CAAC,OAAe;QACxC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAEvC,iGAAiG;QACjG,uFAAuF;QACvF,2FAA2F;QAC3F,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAChE,mBAAmB,CAAC,iBAA0B,EAC9C,EAAE,GAAG,EAAE,OAAO,EAAE,CACjB,CAAC;QACF,OAAO,QAAQ,IAAI,IAAI,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;OAUG;IACI,KAAK,CAAC,WAAW,CAAC,OAAe;QACtC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,yFAAyF;QACzF,uFAAuF;QACvF,6FAA6F;QAC7F,yFAAyF;QACzF,2FAA2F;QAC3F,yFAAyF;QACzF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,CACnE,mBAAmB,CAAC,iBAA0B,EAC9C,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAC/C,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,EAAE,CAC5E,CAAC;QAEF,0FAA0F;QAC1F,wEAAwE;QACxE,MAAM,SAAS,GAAG,OAAO,KAAK,IAAI,CAAC;QACnC,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,uBAAuB,CAClC,SAAiB,EACjB,SAAgC,EAChC,WAAgC;QAEhC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,MAAM,MAAM,GAAwB;YAClC,SAAS;YACT,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;SAC9B,CAAC;QACF,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;QAC/B,CAAC;QAED,2FAA2F;QAC3F,8CAA8C;QAC9C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,2BAA2B,CAC9E,mBAAmB,CAAC,iBAA0B,EAC9C,MAAM,EACN,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,EAAE,EAC3E,SAAS,EAAE,0FAA0F;QACrG,iGAAiG;QACjG,gGAAgG;QAChG,0EAA0E;QAC1E,EAAE,WAAW,EAAE,CAChB,CAAC;QACF,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE;gBAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,EAAE;oBACzD,SAAS;oBACT,SAAS;oBACT,YAAY;iBACb,CAAC,CAAC;YACL,CAAC,CAAC;YACF,IAAI,WAAW,EAAE,CAAC;gBAChB,mCAAmC,CAAC,WAAW,EAAE;oBAC/C,GAAG,EAAE,6BAA6B,SAAS,IAAI,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,EAAE;oBAC3E,OAAO,EAAE,aAAa;iBACvB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,EAAE,CAAC;YACxB,CAAC;QACH,CAAC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,qBAAqB,CAChC,SAAiB,EACjB,SAA+B;QAE/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,yBAAyB,CACpE,mBAAmB,CAAC,iBAA0B,EAC9C;YACE,SAAS;YACT,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;YAC7B,UAAU,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;YACzB,SAAS,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;SACxB,CACF,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAC7E,gFAAgF;IAChF,6EAA6E;IAE7E;;;;;OAKG;IACI,KAAK,CAAC,sBAAsB,CACjC,MAA6B,EAC7B,YAAiC,EACjC,gBAIC,EACD,WAA+B;QAE/B,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,CAAC;QAC/D,IAAI,MAAM,CAAC,4BAA4B,IAAI,CAAC,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,EAClG,CAAC;YACD,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE;gBACrE,OAAO,EAAE;oBACP,MAAM,EAAE,2CAA2C;oBACnD,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK;iBAC/C;aACF,CAAC,CAAC;QACL,CAAC;QAED,MAAM,mBAAmB,GACvB,MAAM,CAAC,4BAA4B,IAAI,SAAS;YAC9C,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC;YAC5D,CAAC,CAAC,SAAS,CAAC;QAEhB,uCAAuC;QACvC,IAAI,MAAM,CAAC,4BAA4B,EAAE,CAAC;YACxC,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,MAAM,iBAAiB,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACtF,MAAM,oBAAoB,GAAG,MAAM,CAAC,YAAY;YAC9C,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC;YAChE,CAAC,CAAC,SAAS,CAAC;QAEd,sBAAsB;QACtB,MAAM,YAAY,GAAsB;YACtC,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,SAAS,EAAE,iBAAiB;YAC5B,cAAc,EAAE,YAAY,CAAC,cAAc,IAAI,gBAAgB,CAAC,cAAc;YAC9E,kBAAkB,EAAE,gBAAgB,CAAC,YAAY;YACjD,SAAS;YACT,GAAG,CAAC,mBAAmB,IAAI;gBACzB,mBAAmB;aACpB,CAAC;YACF,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC;QAEF,+BAA+B;QAC/B,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACzD,CAAC;QAED,oDAAoD;QACpD,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAChC,YAAY,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACzC,YAAY,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAC5C,CAAC;QAED,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3B,MAAM,YAAY,GAA2B,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,YAAY,CAAC,cAAc,IAAI,gBAAgB,CAAC,cAAc,CAAC;YAC7E,IAAI,KAAK;gBAAE,YAAY,CAAC,cAAc,GAAG,KAAK,CAAC;YAC/C,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC1E,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;gBACtC,IAAI,KAAK;oBAAE,YAAY,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzC,YAAY,CAAC,SAAS,GAAG,EAAE,YAAY,EAAE,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAEhE,OAAO,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,sBAAsB,CACjC,MAA6B,EAC7B,YAAiC,EACjC,iBAA8C,EAC9C,WAAgC;QAEhC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,CAAC;QAE/D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,EAAE;gBAC/D,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK;aAC/C,CAAC,CAAC;YACH,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QAC7B,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAC9C,SAAS,EACT,SAAS,EACT,WAAW,CACZ,CAAC;YACF,YAAY,IAAI,KAAK,CAAC;QACxB,CAAC;QAED,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE;YAC9C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,4BAA4B,EAAE;gBAC7C,SAAS;gBACT,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,YAAY;aACb,CAAC,CAAC;QACL,CAAC,CAAC;QACF,IAAI,WAAW,EAAE,CAAC;YAChB,mCAAmC,CAAC,WAAW,EAAE;gBAC/C,GAAG,EACD,yCAAyC,SAAS,GAAG;sBACnD,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;gBAClD,OAAO,EAAE,aAAa;aACvB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,aAAa,EAAE,CAAC;QACxB,CAAC;QAED,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;IACxC,CAAC;IAED,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAErE,wBAAwB,CAC9B,SAA+B,EAC/B,SAAiB;QAEjB,OAAO,MAAM;aACV,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;aAC5C,MAAM,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAEO,uBAAuB,CAAC,KAAsB;QACpD,OAAO;YACL,UAAU,EAAE,KAAK,CAAC,KAAK;YACvB,OAAO,EAAE,KAAK,CAAC,GAAG;SACnB,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACK,wBAAwB,CAAC,UAAmB;QAClD,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,EAAE;gBACtE,sBAAsB,EAAE,2BAA2B,CAAC,0BAA0B;aAC/E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,IAAY,oBAAoB;QAC9B,IAAI,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC;YACvC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE;gBAChE,OAAO,EAAE,EAAE,MAAM,EAAE,2DAA2D,EAAE;aACjF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,4BAA4B,CAAC;IAC3C,CAAC;IAED;;;;;;;OAOG;IACK,eAAe,CAAC,WAAgC;QACtD,IAAI,CAAC,WAAW;YAAE,OAAO,SAAS,CAAC;QACnC,IAAI,WAAW,CAAC,YAAY,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAC5D,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,EAAE;gBACrE,OAAO,EAAE;oBACP,MAAM,EAAE,+CAA+C;oBACvD,uBAAuB,EAAE,WAAW,CAAC,YAAY;iBAClD;aACF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,WAAW,CAAC,aAA8B,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACK,8BAA8B,CAAC,KAAc;QACnD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9D,MAAM,UAAU,GAAG,KAKlB,CAAC;QACF,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QAE5C,MAAM,wBAAwB,GAAG,CAAC,KAAc,EAAW,EAAE,CAC3D,KAAK,KAAK,IAAI;eACX,OAAO,KAAK,KAAK,QAAQ;eACzB,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QACxE,IACE,wBAAwB,CAAC,UAAU,CAAC,UAAU,CAAC;eAC5C,wBAAwB,CAAC,UAAU,CAAC,QAAQ,CAAC,EAChD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,CACL,OAAO,UAAU,CAAC,OAAO,KAAK,QAAQ;eACnC,oCAAoC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CACjE,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,SAAwB,EAAE,OAAa,IAAI,IAAI,EAAE;QAC1E,MAAM,EAAE,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QAC/C,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACK,sBAAsB,CAAI,KAAyB,EAAE,aAAkC;QAC7F,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,OAAQ,KAAyC,CAAC,aAAa,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AAp2BY,6BAA6B;IADzC,UAAU,EAAE;IASR,WAAA,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACjC,WAAA,MAAM,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,CAAA;IAC9C,WAAA,MAAM,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAGzC,WAAA,MAAM,CAAC,kBAAkB,CAAC,wBAAwB,CAAC,CAAA;IAAE,WAAA,QAAQ,EAAE,CAAA;IAQ/D,WAAA,MAAM,CAAC,kBAAkB,CAAC,kCAAkC,CAAC,CAAA;IAAE,WAAA,QAAQ,EAAE,CAAA;+CAZZ,0BAA0B;QAC7B,cAAc;GAVhE,6BAA6B,CAo2BzC","sourcesContent":["/**\n * Consumable Token Backend Service\n *\n * Central service for the full lifecycle of consumable tokens:\n * - Token creation with crypto-secure random values\n * - Token validation (expiry, consumption, revocation, type matching)\n * - Atomic token consumption (race-condition safe via findOneAndUpdate)\n * - Token revocation (soft invalidation via revokedAt)\n * - Pipeline helpers for declarative tokenGeneration/tokenRevocation configs\n *\n * Security (R2): Raw token values are NEVER logged. Only token._id is logged.\n */\n\nimport { injectable, inject, optional } from 'inversify';\nimport crypto from 'crypto';\n\nimport {\n ConsumableToken_ConsumptionMode,\n resolveSharedPersistenceCollectionName,\n ErrorType,\n ErrorCustomMessageReference,\n PersistenceAdapter,\n type ConsumableTokenTypes,\n type TokenGenerationConfig,\n type TokenRevocationConfig,\n type StaticOrDerived,\n type ExecutionContext_RoleInfo,\n} from '@wildo-ai/saas-models';\nimport { durationToSeconds, type DurationValue } from '@wildo-ai/zod-decorators';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\n\nimport { MongoDBService } from '~wildo-backend-lib/databases/services/mongodb.service';\nimport type { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport type { RepositoryGuardedMutation } from '~wildo-backend-lib/base-classes/services/repositories/repository-guarded-mutation.backend.types';\nimport { projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { BackendResourceType } from '~wildo-backend-lib/resources/models/resources-types.backend.schemas';\nimport type { ResourceIdBackendService } from '~wildo-backend-lib/resources/services/resource-id.backend.service';\nimport type {\n ConsumableToken,\n} from '~wildo-backend-lib/security/consumable-tokens/models/consumable-tokens.shared.schemas';\nimport {\n registerTransactionPostCommitEffect,\n type TransactionContext,\n} from '~wildo-backend-lib/databases/models/transaction.shared.schemas';\nimport type { ClientSession } from 'mongodb';\n\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface CreateTokenParams {\n /** Token type identifier (e.g., CoreConsumableTokenTypes.FILE_PUBLIC_ACCESS). NOT the Wildo resource type. */\n tokenType: ConsumableTokenTypes;\n consumptionMode: ConsumableToken_ConsumptionMode;\n expiresIn: DurationValue;\n organizationId?: string;\n userId?: string;\n /** The Wildo resource identifier this token targets (e.g., 'users', 'files'). */\n resourceIdentifier?: string;\n relatedId?: string;\n metadata?: Record<string, any>;\n roles?: ExecutionContext_RoleInfo[];\n maxUses?: number;\n /** W7.3b: Whether this token can be exchanged for a one-off session JWT. */\n createsOneOffSession?: boolean;\n /** W7.3b: When the token is consumed — at exchange time or at target operation time. */\n consumeAt?: 'EXCHANGE' | 'TARGET_OPERATION';\n /** W7.3b: Scoped caller identity for audit and authorization narrowing. */\n targeting?: {\n initiatorIds?: Record<string, string>;\n };\n /**\n * Sparse database-unique ownership key for replace-existing generation.\n * Removed when the token is revoked or reaches its terminal consumption.\n */\n activeGenerationKey?: string;\n}\n\nexport interface TokenGenerationResult {\n tokenValue: string;\n tokenId: string;\n}\n\nexport interface TokenRevocationResult {\n revokedCount: number;\n}\n\n\n// ============================================================================\n// SERVICE\n// ============================================================================\n\n/**\n * revocation-B1: the hard ceiling (in minutes) on the lifetime of ANY one-off SESSION, enforced at TWO points:\n * (1) at MINT — `createToken`, the single chokepoint BOTH one-off mint paths funnel through (the super-admin\n * route's `createOneOffToken` and the declarative resource-config `processTokenGeneration`) — bounding the\n * token's authored duration / LINK validity window fail-closed; and (2) at EXCHANGE —\n * `computeOneOffSessionExpiresAt` — which anchors the minted SESSION's lifetime at CONSUMPTION (the exchange),\n * NOT at production, and clamps it to this ceiling. The exchange anchor is the authoritative session bound;\n * the mint ceiling additionally keeps the link from being exchangeable for longer than the ceiling.\n *\n * A one-off token with `createsOneOffSession` is a session-establishing credential: exchanging it mints a\n * JWT session for another user. The security industry treats the maximum lifetime of such a delegated /\n * impersonated credential as a hard ceiling enforced AT ISSUANCE, on EVERY path, fail-closed — and puts that\n * ceiling at ~12 hours, measured from when the session begins. A per-user-type `oneOffSessionMaxDurationMinutes`\n * may only TIGHTEN below this; nothing exceeds it. Non-session consumable tokens (password-reset, invitation,\n * magic-link) are unaffected.\n *\n * spec-cite: AWS STS `AssumeRole` — `DurationSeconds` is validated against the role's `MaxSessionDuration`\n * (1h default, 12h hard max); an over-max request is REJECTED, not clamped —\n * https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html\n * spec-cite: GCP IAM short-lived credentials — impersonated-credential lifetime defaults to 1h and is capped\n * at 12h (43200s), extendable only via the `iam.allowServiceAccountCredentialLifetimeExtension` org policy —\n * https://cloud.google.com/iam/docs/create-short-lived-credentials-direct\n * spec-cite: OWASP Session Management Cheat Sheet, \"Absolute Timeout\" — every session must have an absolute\n * maximum lifetime enforced regardless of activity, to bound how long a hijacked session stays usable —\n * https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html\n */\nexport const ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES = 12 * 60;\n\n@injectable()\nexport class ConsumableTokenBackendService {\n private readonly logger: LoggerService;\n private readonly errorBuilder: ErrorBuilderBackendService;\n private readonly mongoDBService: MongoDBService;\n private readonly resourceIdService?: ResourceIdBackendService;\n private readonly injectedRepositoriesRegistry?: RepositoriesRegistryHandlerBackendService;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.MongoDBService) mongoDBService: MongoDBService,\n // LAST and OPTIONAL: appended so existing positional constructions keep working, optional so the\n // harnesses that build this service directly are not forced to wire a dependency they do not use.\n @inject(SAAS_SERVICE_TYPES.ResourceIdBackendService) @optional() resourceIdService?: ResourceIdBackendService,\n /**\n * The adapter-neutral persistence plane this service now writes through.\n *\n * LAST and OPTIONAL for the same reason `resourceIdService` is: several harnesses construct this\n * service positionally, and making it required would break them at construction rather than at\n * the call they actually exercise.\n */\n @inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService) @optional() repositoriesRegistry?: RepositoriesRegistryHandlerBackendService,\n ) {\n this.logger = logger;\n this.errorBuilder = errorBuilder;\n this.mongoDBService = mongoDBService;\n this.resourceIdService = resourceIdService;\n this.injectedRepositoriesRegistry = repositoriesRegistry;\n }\n\n\n // ==========================================================================\n // CORE TOKEN OPERATIONS\n // ==========================================================================\n\n /**\n * Create a new consumable token.\n * Generates a 32-byte hex crypto-random token value and persists it.\n *\n * @returns The full entity WITH the raw token value (for passing to emails/responses).\n * NEVER log the returned token value (R2).\n */\n public async createToken(\n params: CreateTokenParams,\n transaction?: TransactionContext,\n ): Promise<ConsumableToken & { token: string }> {\n const tokenValue = crypto.randomBytes(32).toString('hex');\n const now = new Date();\n const expiresAt = this.calculateExpiresAt(params.expiresIn, now);\n\n // assurance-control: WILDO.IDENTITY.CREDENTIAL_LIFECYCLE — a one-off session token is a\n // session-establishing credential minted for another user, so its lifetime is bounded by the industry\n // hard ceiling (ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES) HERE — the single point every one-off mint path\n // funnels through (super-admin route + resource-config `processTokenGeneration`). Fail-closed: an\n // over-ceiling mint is REJECTED, never silently clamped (matching AWS STS rejecting an over-max AssumeRole).\n if (params.createsOneOffSession) {\n const requestedMinutes = durationToSeconds(params.expiresIn) / 60;\n if (requestedMinutes > ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.ONE_OFF_SESSION_DURATION_EXCEEDS_MAX,\n context: { requestedMinutes: Math.round(requestedMinutes), absoluteMaxMinutes: ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES }, // diagnostic (log-only)\n });\n }\n }\n /**\n * Identity through the framework AUTHORITY, not `crypto.randomUUID()`.\n *\n * The id format is a per-resource framework decision (`ResourceIdBackendService`), and the\n * PostgreSQL repository already mints through it in `withGeneratedRowIdentity`. Minting a UUID\n * here instead produced a row whose `_id` is not the shape the resource declares, and the\n * consequence was measured rather than reasoned: the repository read the row correctly but with\n * **no `_id` at all**, because Mongoose cannot hydrate a UUID into its declared identity type.\n *\n * That was invisible while every token path addressed rows by their `token` value and never by\n * `_id` — the same \"agreed by never meeting\" shape as the collection-name split this service also\n * carried. It stops being invisible the moment creation moves to the repository (R-W5-3), which\n * mints through this same authority, so the two would disagree about what an existing row's id\n * even looks like.\n *\n * `@optional()` on the injection: the service is constructed directly in several harnesses, and a\n * required dependency there would be a churn cost with no safety gain. The fallback is the\n * previous behaviour, so a harness that does not supply it degrades to what it had before rather\n * than to something new.\n */\n const _id = this.resourceIdService\n ? String(this.resourceIdService.generateForResource(BackendResourceType.CONSUMABLE_TOKENS as never))\n : crypto.randomUUID();\n\n const tokenData: ConsumableToken = {\n _id,\n token: tokenValue,\n tokenType: params.tokenType,\n resourceIdentifier: params.resourceIdentifier,\n consumptionMode: params.consumptionMode,\n organizationId: params.organizationId,\n userId: params.userId,\n relatedId: params.relatedId,\n ...(params.activeGenerationKey && {\n activeGenerationKey: params.activeGenerationKey,\n }),\n metadata: params.metadata || {},\n roles: params.roles || [],\n expiresAt,\n isConsumed: false,\n usesCount: 0,\n ...(params.createsOneOffSession !== undefined && { createsOneOffSession: params.createsOneOffSession }),\n ...(params.consumeAt && { consumeAt: params.consumeAt }),\n ...(params.targeting && { targeting: params.targeting }),\n createdAt: now,\n updatedAt: now,\n };\n\n // maxUses is required for BOUNDED_REUSE\n if (params.consumptionMode === ConsumableToken_ConsumptionMode.BOUNDED_REUSE) {\n if (!params.maxUses || params.maxUses < 1) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.VALIDATION,\n context: { reason: 'maxUses is required and must be >= 1 for BOUNDED_REUSE tokens' }\n });\n }\n tokenData.maxUses = params.maxUses;\n }\n\n // The adapter narrows `transaction` itself and raises the mismatch error, so this service no\n // longer needs its own MongoDB-specific narrowing.\n try {\n await this.repositoriesRegistry.insertDocumentForInfrastructure(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n tokenData as unknown as Record<string, unknown>,\n undefined,\n { transaction },\n );\n } catch (error) {\n if (params.activeGenerationKey && this.isActiveGenerationKeyDuplicate(error)\n ) {\n throw this.errorBuilder.buildError(ErrorType.CONFLICT, undefined, {\n customMessageReference:\n ErrorCustomMessageReference.UNIQUE_CONSTRAINT_VIOLATION,\n context: {\n reason: 'consumable_token_active_generation_conflict',\n tokenType: params.tokenType,\n relatedId: params.relatedId,\n },\n });\n }\n throw error;\n }\n\n // Log creation without the raw token value (R2), and only after commit\n // when this token participates in a wider transaction.\n const logCreation = async (): Promise<void> => {\n this.logger.info('Consumable token created', {\n tokenId: _id,\n tokenType: params.tokenType,\n consumptionMode: params.consumptionMode,\n relatedId: params.relatedId,\n organizationId: params.organizationId,\n expiresAt: expiresAt.toISOString(),\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key: `consumable-token-created:${_id}`,\n execute: logCreation,\n });\n } else {\n await logCreation();\n }\n\n return tokenData as ConsumableToken & { token: string };\n }\n\n /**\n * Validate a token without consuming it.\n * Checks: existence, revocation, expiry, consumption status, type matching.\n *\n * @param tokenValue - The raw token string from the request\n * @param expectedTypes - Optional array of accepted token types for this operation\n * @returns The validated token entity\n * @throws Appropriate error for each failure mode\n */\n public async validateToken(\n tokenValue: string,\n expectedTypes?: ConsumableTokenTypes[],\n ): Promise<ConsumableToken> {\n this.assertTokenValueIsString(tokenValue);\n const tokenDoc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { token: tokenValue },\n );\n\n if (!tokenDoc) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_NOT_FOUND,\n });\n }\n\n const token = tokenDoc as unknown as ConsumableToken;\n\n // Check revocation\n if (token.revokedAt) {\n this.logger.warn('Revoked token used', { tokenId: token._id });\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_REVOKED,\n context: { tokenId: token._id },\n });\n }\n\n // Check expiry\n if (token.expiresAt < new Date()) {\n this.logger.warn('Expired token used', { tokenId: token._id });\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_EXPIRED,\n context: { tokenId: token._id },\n });\n }\n\n // Check consumption status based on mode\n if (token.consumptionMode === ConsumableToken_ConsumptionMode.SINGLE_USE && token.isConsumed) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_ALREADY_CONSUMED,\n context: { tokenId: token._id },\n });\n }\n\n if (token.consumptionMode === ConsumableToken_ConsumptionMode.BOUNDED_REUSE) {\n const maxUses = token.maxUses;\n if (maxUses && token.usesCount >= maxUses) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_ALREADY_CONSUMED,\n context: { tokenId: token._id, usesCount: token.usesCount, maxUses },\n });\n }\n }\n\n if (token.consumptionMode === ConsumableToken_ConsumptionMode.EPHEMERAL_STATE && token.isConsumed) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_ALREADY_CONSUMED,\n context: { tokenId: token._id },\n });\n }\n\n // Check type matching\n if (expectedTypes && expectedTypes.length > 0) {\n if (!expectedTypes.includes(token.tokenType as ConsumableTokenTypes)) {\n this.logger.warn('Token type mismatch', {\n tokenId: token._id,\n tokenType: token.tokenType,\n expectedTypes\n });\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_TYPE_MISMATCH,\n context: { tokenId: token._id, tokenType: token.tokenType, expectedTypes },\n });\n }\n }\n\n return token;\n }\n\n /**\n * Atomically consume a token.\n * Uses MongoDB `findOneAndUpdate` with conditions to prevent race conditions.\n *\n * - SINGLE_USE: condition `{ isConsumed: false }`, sets `{ isConsumed: true, usesCount: 1 }`\n * - BOUNDED_REUSE: condition `{ usesCount: { $lt: maxUses } }`, inc `usesCount`, set `isConsumed` if exhausted\n * - EPHEMERAL_STATE: condition `{ isConsumed: false }`, sets `{ isConsumed: true }`\n *\n * @param tokenValue - The raw token string\n * @returns The updated token entity\n * @throws CONSUMABLE_TOKEN_RACE_CONDITION if atomic update fails (concurrent consumption)\n */\n public async consumeToken(\n tokenValue: string,\n transaction?: TransactionContext,\n ): Promise<ConsumableToken> {\n this.assertTokenValueIsString(tokenValue);\n const now = new Date();\n\n // First, read the token to determine its consumption mode.\n // Also check that the token hasn't expired or been revoked.\n const existingTokenDoc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n {\n token: tokenValue,\n revokedAt: { $exists: false },\n expiresAt: { $gt: now },\n },\n { transaction },\n );\n if (!existingTokenDoc) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_NOT_FOUND,\n });\n }\n const existingToken = existingTokenDoc as unknown as ConsumableToken;\n\n let filter: Record<string, any>;\n let mutation: RepositoryGuardedMutation;\n /**\n * BOUNDED_REUSE only. `isConsumed` is DERIVED state for that mode — a cache read solely by the\n * cleanup batch's hard-delete, never by an authorization path — so it is computed from the\n * post-increment row rather than inside the statement. See the note at the write below.\n */\n let boundedMaxUses: number | undefined;\n\n // All filters include expiresAt + revokedAt guards to prevent consuming expired/revoked tokens\n // in the atomic update (defense-in-depth against TOCTOU between the read above and the update below).\n const expiryGuard = { expiresAt: { $gt: now }, revokedAt: { $exists: false } };\n\n switch (existingToken.consumptionMode) {\n case ConsumableToken_ConsumptionMode.SINGLE_USE: {\n filter = { token: tokenValue, isConsumed: false, ...expiryGuard };\n // Fully expressible: every assignment is a constant, and `$$REMOVE` is `clear`.\n mutation = {\n set: { isConsumed: true, usesCount: 1, updatedAt: now },\n clear: ['activeGenerationKey'],\n };\n break;\n }\n\n case ConsumableToken_ConsumptionMode.BOUNDED_REUSE: {\n const maxUses = existingToken.maxUses || 1;\n filter = { token: tokenValue, usesCount: { $lt: maxUses }, ...expiryGuard };\n // Use aggregation pipeline update to atomically increment usesCount\n // AND compute isConsumed from the post-increment value.\n // This avoids the race condition where two concurrent requests\n // both read the same pre-increment usesCount and fail to set isConsumed.\n /**\n * The INCREMENT is the guarantee; the flag is not.\n *\n * Atomicity here comes from the FILTER (`usesCount < maxUses`), which is what refuses the\n * consume once the allowance is spent — and it is `usesCount`, never `isConsumed`, that\n * every authorization path reads: this filter, and `validateToken`'s BOUNDED_REUSE branch.\n * `isConsumed` is a denormalized flag whose only consumer is the cleanup batch's\n * hard-delete, which ALREADY carries a second sweep for exactly this window (\"defense in\n * depth for the race condition edge case where isConsumed may not have been atomically\n * set\").\n *\n * MongoDB expressed the derivation inside an aggregation-pipeline update; that is precisely\n * the raw-operator form the adapter-neutral vocabulary excludes, and a computed set is not\n * expressible for both adapters through it. Deriving it from the returned post-increment row\n * keeps the authoritative counter atomic and costs only freshness on a flag nothing gates on.\n *\n * Rejected: narrowing the filter to a compare-and-swap on `usesCount` so the post-value were\n * known here — that would turn two legitimate concurrent consumers of a bounded-reuse token\n * into one CONFLICT, a behaviour regression rather than a translation.\n */\n boundedMaxUses = maxUses;\n mutation = { increment: { usesCount: 1 }, set: { updatedAt: now } };\n break;\n }\n\n case ConsumableToken_ConsumptionMode.EPHEMERAL_STATE: {\n filter = { token: tokenValue, isConsumed: false, ...expiryGuard };\n // Fully expressible: every assignment is a constant, and `$$REMOVE` is `clear`.\n mutation = {\n set: { isConsumed: true, usesCount: 1, updatedAt: now },\n clear: ['activeGenerationKey'],\n };\n break;\n }\n\n default: {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n context: {\n reason: 'consumable_token_consumption_mode_invalid',\n tokenId: existingToken._id,\n consumptionMode: existingToken.consumptionMode,\n },\n });\n }\n }\n\n const result = await this.repositoriesRegistry.atomicGuardedMutation<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n filter,\n mutation,\n undefined,\n { transaction },\n );\n\n if (!result) {\n this.logger.warn('Token consumption race condition', { tokenId: existingToken._id });\n throw this.errorBuilder.buildError(ErrorType.CONFLICT, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_RACE_CONDITION,\n context: { tokenId: existingToken._id },\n });\n }\n\n /**\n * Settle the DERIVED flag for BOUNDED_REUSE, now that the authoritative counter is known.\n *\n * Guarded on the same allowance, so a concurrent consumer that has not yet exhausted the token\n * cannot flip it early. Nothing gates on this flag (see the mutation note above), so a failure to\n * write it is a freshness loss the cleanup batch's second sweep already covers — it must not turn\n * a SUCCESSFUL consume into an error for the caller.\n */\n if (boundedMaxUses !== undefined && (result.usesCount ?? 0) >= boundedMaxUses) {\n result.isConsumed = true;\n try {\n await this.repositoriesRegistry.atomicGuardedMutation(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: result._id },\n { set: { isConsumed: true }, clear: ['activeGenerationKey'] },\n undefined,\n { transaction },\n );\n } catch (error) {\n this.logger.warn('Consumable token exhausted but its derived isConsumed flag was not written', {\n tokenId: result._id,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n\n const logConsumption = async (): Promise<void> => {\n this.logger.info('Consumable token consumed', {\n tokenId: existingToken._id,\n consumptionMode: existingToken.consumptionMode,\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key: `consumable-token-consumed:${existingToken._id}`,\n execute: logConsumption,\n });\n } else {\n await logConsumption();\n }\n\n return result as unknown as ConsumableToken;\n }\n\n /**\n * Fetch a token by its `_id`, WITHOUT any state assertions — a revoked, expired, or consumed row all\n * pass through. This is deliberately different from `validateToken`, which keys on the token VALUE and\n * THROWS on any non-live state: an operator flow that acts ON a token needs to read it first and decide\n * for itself. The one-off-session revoke route uses it to (a) return NOT_FOUND for a missing id, (b)\n * confirm the row IS a one-off session token before revoking (this door must never touch a\n * password-reset / invitation / magic-link token by id), and (c) build the revocation audit from the\n * token's own `userId` / `tokenType`. Returns `null` when no row matches.\n *\n * `tokenId` is guarded by the same non-string check as every other primitive here (`{ _id }` reaches\n * Mongo directly, so a `{$ne}`-shaped value would otherwise match an ARBITRARY token).\n */\n public async findTokenById(tokenId: string): Promise<ConsumableToken | null> {\n this.assertTokenValueIsString(tokenId);\n\n // Adapter-neutral, like every other read on this service: `getTokenCollection` reaches the Mongo\n // driver directly, so a raw `findOne` here would make this the one token-lookup door a\n // PostgreSQL-backed application cannot open. `readUnscopedByKey` is the same primitive the\n // token-VALUE lookups above already use; only the key differs.\n const tokenDoc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: tokenId },\n );\n return tokenDoc ?? null;\n }\n\n /**\n * Soft-revoke a token by setting revokedAt.\n * This is a soft invalidation — the record stays in DB for audit.\n * Hard deletion is handled by the cleanup cron job.\n *\n * CONDITIONAL on the row not already being revoked (`revokedAt: { $exists: false }`), mirroring\n * `revokeTokensByRelatedId`. This makes the transition atomic: two concurrent revocations of the SAME token\n * transition it exactly once, so a caller can emit its audit only on the real transition (returned `true`)\n * and never write a duplicate row under a race. Returns whether THIS call performed the revocation\n * (`false` = the token was already revoked, or does not exist).\n */\n public async revokeToken(tokenId: string): Promise<boolean> {\n const now = new Date();\n\n // Adapter-neutral by construction: `atomicGuardedMutation` compiles the SAME conditional\n // transition on either adapter — the PostgreSQL arm translates `{ $exists: false }` to\n // `IS NULL` — and `clear` is the neutral spelling of the pipeline's `$$REMOVE`. Dropping the\n // active-generation key is what frees a later token of the same generation to be minted.\n // Deliberately the same idiom as `revokeTokensByRelatedId`, which the conditional mirrors:\n // a raw driver call here would make this the one revocation door PostgreSQL cannot open.\n const revoked = await this.repositoriesRegistry.atomicGuardedMutation(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: tokenId, revokedAt: { $exists: false } },\n { set: { revokedAt: now, updatedAt: now }, clear: ['activeGenerationKey'] },\n );\n\n // `null` is the neutral spelling of \"no row matched the guard\" — the same fact the driver\n // reported as `modifiedCount === 0`: already revoked, or no such token.\n const didRevoke = revoked !== null;\n if (didRevoke) {\n this.logger.info('Consumable token revoked', { tokenId });\n }\n return didRevoke;\n }\n\n /**\n * Revoke all tokens matching a relatedId and optionally a token type.\n * Uses repository directly (R6 — intentional, not routed through operation pipeline).\n *\n * @returns Count of revoked tokens\n */\n public async revokeTokensByRelatedId(\n relatedId: string,\n tokenType?: ConsumableTokenTypes,\n transaction?: TransactionContext,\n ): Promise<number> {\n const now = new Date();\n\n const filter: Record<string, any> = {\n relatedId,\n revokedAt: { $exists: false },\n };\n if (tokenType) {\n filter.tokenType = tokenType;\n }\n\n // The COUNT is the contract: callers report how many tokens were revoked, so the multi-row\n // primitive returns it rather than a boolean.\n const revokedCount = await this.repositoriesRegistry.bulkUpdateForInfrastructure(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n filter,\n { set: { revokedAt: now, updatedAt: now }, clear: ['activeGenerationKey'] },\n undefined, // no execution context: this is a framework-internal revocation, below the operation tier\n // JOIN THE CALLER'S TRANSACTION. Without this the revocation committed immediately even when the\n // caller was mid-transaction, so a driver retry could not roll it back — the retry then revoked\n // nothing and reported 0 for work that had already happened exactly once.\n { transaction },\n );\n if (revokedCount > 0) {\n const logRevocation = async (): Promise<void> => {\n this.logger.info('Consumable tokens revoked by relatedId', {\n relatedId,\n tokenType,\n revokedCount,\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key: `consumable-tokens-revoked:${relatedId}:${String(tokenType ?? 'all')}`,\n execute: logRevocation,\n });\n } else {\n await logRevocation();\n }\n }\n\n return revokedCount;\n }\n\n /**\n * Find all unconsumed, non-revoked, non-expired tokens for a given relatedId and token type.\n * Used by Email OTP verification (Step 10) to find matching OTP tokens.\n *\n * @returns Array of matching token documents (may be empty)\n */\n public async findTokensByRelatedId(\n relatedId: string,\n tokenType: ConsumableTokenTypes,\n ): Promise<ConsumableToken[]> {\n const now = new Date();\n\n const docs = await this.repositoriesRegistry.findManyForInfrastructure<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n {\n relatedId,\n tokenType: tokenType,\n revokedAt: { $exists: false },\n isConsumed: { $ne: true },\n expiresAt: { $gt: now },\n },\n );\n\n return docs;\n }\n\n // ==========================================================================\n // PIPELINE HELPERS — Called by services-registry-handler for declarative config\n // ==========================================================================\n\n /**\n * Process a declarative tokenGeneration config from an operation variant.\n * Called AFTER the core operation succeeds, BEFORE notification dispatch.\n *\n * Returns `{ tokenValue, tokenId }` for injection into notification context.\n */\n public async processTokenGeneration(\n config: TokenGenerationConfig,\n currentState: Record<string, any>,\n executionContext: {\n organizationId?: string;\n userId?: string;\n resourceType?: string;\n },\n transaction: TransactionContext,\n ): Promise<TokenGenerationResult> {\n const relatedId = currentState[config.relatedIdField || '_id'];\n if (config.revokeExistingForSameRelated && (typeof relatedId !== 'string' || relatedId.length === 0)\n ) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n context: {\n reason: 'replace_existing_token_related_id_missing',\n tokenType: config.tokenType,\n relatedIdField: config.relatedIdField || '_id',\n },\n });\n }\n\n const activeGenerationKey =\n config.revokeExistingForSameRelated && relatedId\n ? this.buildActiveGenerationKey(config.tokenType, relatedId)\n : undefined;\n\n // Revoke existing tokens if configured\n if (config.revokeExistingForSameRelated) {\n if (relatedId) {\n await this.revokeTokensByRelatedId(relatedId, config.tokenType, transaction);\n }\n }\n\n // Resolve static or derived values\n const resolvedExpiresIn = this.resolveStaticOrDerived(config.expiresIn, currentState);\n const resolvedGrantedRoles = config.grantedRoles\n ? this.resolveStaticOrDerived(config.grantedRoles, currentState)\n : undefined;\n\n // Build create params\n const createParams: CreateTokenParams = {\n tokenType: config.tokenType,\n consumptionMode: config.consumptionMode,\n expiresIn: resolvedExpiresIn,\n organizationId: currentState.organizationId || executionContext.organizationId,\n resourceIdentifier: executionContext.resourceType,\n relatedId,\n ...(activeGenerationKey && {\n activeGenerationKey,\n }),\n roles: resolvedGrantedRoles,\n maxUses: config.maxUses,\n };\n\n // Resolve userId if configured\n if (config.userIdField) {\n createParams.userId = currentState[config.userIdField];\n }\n\n // W7.3b: Bridge to one-off sessions when configured\n if (config.createsOneOffSession) {\n createParams.createsOneOffSession = true;\n createParams.consumeAt = config.consumeAt;\n }\n\n if (config.targetingFields) {\n const initiatorIds: Record<string, string> = {};\n const orgId = currentState.organizationId || executionContext.organizationId;\n if (orgId) initiatorIds.organizationId = orgId;\n for (const [fieldId, fieldPath] of Object.entries(config.targetingFields)) {\n const value = currentState[fieldPath];\n if (value) initiatorIds[fieldId] = String(value);\n }\n if (Object.keys(initiatorIds).length > 0) {\n createParams.targeting = { initiatorIds };\n }\n }\n\n const token = await this.createToken(createParams, transaction);\n\n return this.toTokenGenerationResult(token);\n }\n\n /**\n * Process a declarative tokenRevocation config from an operation variant.\n * Called BEFORE the core operation (pre-operation step).\n *\n * Revokes all tokens matching the related resource ID and configured token types.\n */\n public async processTokenRevocation(\n config: TokenRevocationConfig,\n currentState: Record<string, any>,\n _executionContext: { organizationId?: string },\n transaction?: TransactionContext,\n ): Promise<TokenRevocationResult> {\n const relatedId = currentState[config.relatedIdField || '_id'];\n\n if (!relatedId) {\n this.logger.warn('Token revocation skipped: no relatedId found', {\n relatedIdField: config.relatedIdField || '_id',\n });\n return { revokedCount: 0 };\n }\n\n let totalRevoked = 0;\n for (const tokenType of config.tokenTypes) {\n const count = await this.revokeTokensByRelatedId(\n relatedId,\n tokenType,\n transaction,\n );\n totalRevoked += count;\n }\n\n const logCompletion = async (): Promise<void> => {\n this.logger.info('Token revocation completed', {\n relatedId,\n tokenTypes: config.tokenTypes,\n totalRevoked,\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key:\n `consumable-token-revocation-completed:${relatedId}:`\n + config.tokenTypes.map(String).sort().join(','),\n execute: logCompletion,\n });\n } else {\n await logCompletion();\n }\n\n return { revokedCount: totalRevoked };\n }\n\n // ==========================================================================\n // PRIVATE HELPERS\n // ==========================================================================\n\n private buildActiveGenerationKey(\n tokenType: ConsumableTokenTypes,\n relatedId: string,\n ): string {\n return crypto\n .createHash('sha256')\n .update(`${String(tokenType)}\\0${relatedId}`)\n .digest('hex');\n }\n\n private toTokenGenerationResult(token: ConsumableToken): TokenGenerationResult {\n return {\n tokenValue: token.token,\n tokenId: token._id,\n };\n }\n\n /**\n * Defense-in-depth against NoSQL operator injection. Every raw-collection lookup here keys on the\n * caller-supplied `token` value (`findOne({ token: tokenValue })`, `findOneAndUpdate({ token: … })`),\n * so a NON-STRING value (e.g. a `{$regex}` / `{$ne}` object that slipped a caller's boundary\n * validation) would be interpreted by Mongo as a query OPERATOR and match/consume an ARBITRARY token —\n * a remote token-destruction primitive (password-reset / invitation / magic-link). A real token value\n * is always a high-entropy string, so a non-string is by definition \"not found\"; we throw the same\n * `CONSUMABLE_TOKEN_NOT_FOUND` (kept non-oracle — the injection case is indistinguishable from a miss).\n * The OAuth provider already rejects such input at its HTTP boundary (400 `invalid_request`); this\n * guards EVERY other caller of the primitive too.\n */\n private assertTokenValueIsString(tokenValue: unknown): asserts tokenValue is string {\n if (typeof tokenValue !== 'string') {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_NOT_FOUND,\n });\n }\n }\n\n /**\n * The persistence plane this service writes through.\n *\n * **Replaced a raw MongoDB collection handle.** This service used to reach\n * `connection.collection(resolveSharedPersistenceCollectionName(CONSUMABLE_TOKENS))` and issue\n * driver calls directly, which is why consumable-token persistence was \"a MongoDB-native\n * capability\" — and why every token-coupled operation carried a hard\n * `requiredAdapter: MONGODB`, making `organizationMembers | create · revoke · resend`\n * unresolvable on a PostgreSQL platform.\n *\n * The registry's framework-internal tier is the right home rather than the resource's declared\n * operations: those are the ADMINISTRATIVE surface (role-gated on `ORG_ADMIN`), whereas the token\n * lifecycle runs where there is NO principal — a verification email is a system action, and a\n * magic-link click is pre-authentication by definition. Routing it through the declared operations\n * would mean fabricating an administrator to authorize the very credential being established.\n *\n * The collection-identity concern the old accessor documented is now structural rather than\n * conventional: the registry resolves the resource's own storage, so there is no second physical\n * name for anything to diverge from.\n *\n * **Named `repositoriesRegistry` deliberately.** `guarded-write-registry-dispatch.guard.test.ts`\n * requires every guarded-write call to have a receiver whose last segment is exactly that, because\n * those primitives do NOT apply the retention hide themselves — it is applied once, at the registry\n * dispatch. An accessor named anything else would route correctly and still read, to that guard and\n * to a human, like a call on a bare repository handle.\n */\n private get repositoriesRegistry(): RepositoriesRegistryHandlerBackendService {\n if (!this.injectedRepositoriesRegistry) {\n throw this.errorBuilder.buildError(ErrorType.DATABASE, undefined, {\n context: { reason: 'Repositories registry not available for consumable tokens' },\n });\n }\n return this.injectedRepositoriesRegistry;\n }\n\n /**\n * Narrow the database-agnostic transaction before any MongoDB access.\n *\n * Consumable-token persistence is MongoDB-native. Casting another adapter's\n * opaque native transaction to `ClientSession` would turn a configuration\n * mismatch into driver-dependent behavior, so every transactional entry\n * path fails at this boundary first.\n */\n private getMongoSession(transaction?: TransactionContext): ClientSession | undefined {\n if (!transaction) return undefined;\n if (transaction.databaseType !== PersistenceAdapter.MONGODB) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n context: {\n reason: 'consumable_token_requires_mongodb_transaction',\n transactionDatabaseType: transaction.databaseType,\n },\n });\n }\n return transaction.nativeSession as ClientSession;\n }\n\n /**\n * Match only the sparse active-generation index. `createToken` also writes\n * other unique fields (notably the raw token), and collapsing their failures\n * into a RESEND race would hide an unrelated persistence defect.\n */\n private isActiveGenerationKeyDuplicate(error: unknown): boolean {\n if (error === null || typeof error !== 'object') return false;\n const mongoError = error as {\n code?: unknown;\n keyPattern?: unknown;\n keyValue?: unknown;\n message?: unknown;\n };\n if (mongoError.code !== 11000) return false;\n\n const hasActiveGenerationField = (value: unknown): boolean =>\n value !== null\n && typeof value === 'object'\n && Object.prototype.hasOwnProperty.call(value, 'activeGenerationKey');\n if (\n hasActiveGenerationField(mongoError.keyPattern)\n || hasActiveGenerationField(mongoError.keyValue)\n ) {\n return true;\n }\n\n return (\n typeof mongoError.message === 'string'\n && /\\bindex:\\s+activeGenerationKey_1\\b/.test(mongoError.message)\n );\n }\n\n /**\n * Calculate the expiration date from a relative duration.\n */\n private calculateExpiresAt(expiresIn: DurationValue, from: Date = new Date()): Date {\n const ms = durationToSeconds(expiresIn) * 1000;\n return new Date(from.getTime() + ms);\n }\n\n /**\n * Resolve a StaticOrDerived value.\n * If the value is a function, call it with the currentObject.\n * If static, return as-is.\n */\n private resolveStaticOrDerived<T>(value: StaticOrDerived<T>, currentObject: Record<string, any>): T {\n if (typeof value === 'function') {\n return (value as (obj: Record<string, any>) => T)(currentObject);\n }\n return value;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"consumable-token.backend.service.js","sourceRoot":"","sources":["../../../../../../src/security/consumable-tokens/services/consumable-token.backend.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Consumable Token Backend Service\n *\n * Central service for the full lifecycle of consumable tokens:\n * - Token creation with crypto-secure random values\n * - Token validation (expiry, consumption, revocation, type matching)\n * - Atomic token consumption (race-condition safe via findOneAndUpdate)\n * - Token revocation (soft invalidation via revokedAt)\n * - Pipeline helpers for declarative tokenGeneration/tokenRevocation configs\n *\n * Security (R2): Raw token values are NEVER logged. Only token._id is logged.\n */\n\nimport { injectable, inject, optional } from 'inversify';\nimport crypto from 'crypto';\n\nimport {\n ConsumableToken_ConsumptionMode,\n resolveSharedPersistenceCollectionName,\n ErrorType,\n ErrorCustomMessageReference,\n isWildoBackendError,\n FILE_UPLOAD_GRANT_ABSOLUTE_MAX_MINUTES,\n CoreConsumableTokenTypes,\n PersistenceAdapter,\n type ConsumableTokenTypes,\n type TokenGenerationConfig,\n type TokenRevocationConfig,\n type StaticOrDerived,\n type ExecutionContext_RoleInfo,\n} from '@wildo-ai/saas-models';\nimport { durationToSeconds, type DurationValue } from '@wildo-ai/zod-decorators';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport type { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';\nimport { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\n\nimport { MongoDBService } from '~wildo-backend-lib/databases/services/mongodb.service';\nimport type { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport type { RepositoryGuardedMutation } from '~wildo-backend-lib/base-classes/services/repositories/repository-guarded-mutation.backend.types';\nimport { projectCaughtErrorLogFields } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport { BackendResourceType } from '~wildo-backend-lib/resources/models/resources-types.backend.schemas';\nimport type { ResourceIdBackendService } from '~wildo-backend-lib/resources/services/resource-id.backend.service';\nimport type {\n ConsumableToken,\n} from '~wildo-backend-lib/security/consumable-tokens/models/consumable-tokens.shared.schemas';\nimport {\n registerTransactionPostCommitEffect,\n type TransactionContext,\n} from '~wildo-backend-lib/databases/models/transaction.shared.schemas';\nimport type { ClientSession } from 'mongodb';\n\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport interface CreateTokenParams {\n /** Token type identifier (e.g., CoreConsumableTokenTypes.FILE_PUBLIC_ACCESS). NOT the Wildo resource type. */\n tokenType: ConsumableTokenTypes;\n consumptionMode: ConsumableToken_ConsumptionMode;\n expiresIn: DurationValue;\n organizationId?: string;\n userId?: string;\n /** The Wildo resource identifier this token targets (e.g., 'users', 'files'). */\n resourceIdentifier?: string;\n relatedId?: string;\n metadata?: Record<string, any>;\n roles?: ExecutionContext_RoleInfo[];\n maxUses?: number;\n /** W7.3b: Whether this token can be exchanged for a one-off session JWT. */\n createsOneOffSession?: boolean;\n /** W7.3b: When the token is consumed — at exchange time or at target operation time. */\n consumeAt?: 'EXCHANGE' | 'TARGET_OPERATION';\n /** W7.3b: Scoped caller identity for audit and authorization narrowing. */\n targeting?: {\n initiatorIds?: Record<string, string>;\n };\n /**\n * Sparse database-unique ownership key for replace-existing generation.\n * Removed when the token is revoked or reaches its terminal consumption.\n */\n activeGenerationKey?: string;\n}\n\nexport interface TokenGenerationResult {\n tokenValue: string;\n tokenId: string;\n}\n\nexport interface TokenRevocationResult {\n revokedCount: number;\n}\n\n\n// ============================================================================\n// SERVICE\n// ============================================================================\n\n/**\n * revocation-B1: the hard ceiling (in minutes) on the lifetime of ANY one-off SESSION, enforced at TWO points:\n * (1) at MINT — `createToken`, the single chokepoint BOTH one-off mint paths funnel through (the super-admin\n * route's `createOneOffToken` and the declarative resource-config `processTokenGeneration`) — bounding the\n * token's authored duration / LINK validity window fail-closed; and (2) at EXCHANGE —\n * `computeOneOffSessionExpiresAt` — which anchors the minted SESSION's lifetime at CONSUMPTION (the exchange),\n * NOT at production, and clamps it to this ceiling. The exchange anchor is the authoritative session bound;\n * the mint ceiling additionally keeps the link from being exchangeable for longer than the ceiling.\n *\n * A one-off token with `createsOneOffSession` is a session-establishing credential: exchanging it mints a\n * JWT session for another user. The security industry treats the maximum lifetime of such a delegated /\n * impersonated credential as a hard ceiling enforced AT ISSUANCE, on EVERY path, fail-closed — and puts that\n * ceiling at ~12 hours, measured from when the session begins. A per-user-type `oneOffSessionMaxDurationMinutes`\n * may only TIGHTEN below this; nothing exceeds it. Non-session consumable tokens (password-reset, invitation,\n * magic-link) are unaffected.\n *\n * spec-cite: AWS STS `AssumeRole` — `DurationSeconds` is validated against the role's `MaxSessionDuration`\n * (1h default, 12h hard max); an over-max request is REJECTED, not clamped —\n * https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html\n * spec-cite: GCP IAM short-lived credentials — impersonated-credential lifetime defaults to 1h and is capped\n * at 12h (43200s), extendable only via the `iam.allowServiceAccountCredentialLifetimeExtension` org policy —\n * https://cloud.google.com/iam/docs/create-short-lived-credentials-direct\n * spec-cite: OWASP Session Management Cheat Sheet, \"Absolute Timeout\" — every session must have an absolute\n * maximum lifetime enforced regardless of activity, to bound how long a hijacked session stays usable —\n * https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html\n */\nexport const ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES = 12 * 60;\n\n@injectable()\nexport class ConsumableTokenBackendService {\n private readonly logger: LoggerService;\n private readonly errorBuilder: ErrorBuilderBackendService;\n private readonly mongoDBService: MongoDBService;\n private readonly resourceIdService?: ResourceIdBackendService;\n private readonly injectedRepositoriesRegistry?: RepositoriesRegistryHandlerBackendService;\n\n constructor(\n @inject(SAAS_SERVICE_TYPES.Logger) logger: LoggerService,\n @inject(SAAS_SERVICE_TYPES.ErrorBuilderService) errorBuilder: ErrorBuilderBackendService,\n @inject(SAAS_SERVICE_TYPES.MongoDBService) mongoDBService: MongoDBService,\n // LAST and OPTIONAL: appended so existing positional constructions keep working, optional so the\n // harnesses that build this service directly are not forced to wire a dependency they do not use.\n @inject(SAAS_SERVICE_TYPES.ResourceIdBackendService) @optional() resourceIdService?: ResourceIdBackendService,\n /**\n * The adapter-neutral persistence plane this service now writes through.\n *\n * LAST and OPTIONAL for the same reason `resourceIdService` is: several harnesses construct this\n * service positionally, and making it required would break them at construction rather than at\n * the call they actually exercise.\n */\n @inject(SAAS_SERVICE_TYPES.RepositoriesRegistryHandlerService) @optional() repositoriesRegistry?: RepositoriesRegistryHandlerBackendService,\n ) {\n this.logger = logger;\n this.errorBuilder = errorBuilder;\n this.mongoDBService = mongoDBService;\n this.resourceIdService = resourceIdService;\n this.injectedRepositoriesRegistry = repositoriesRegistry;\n }\n\n\n // ==========================================================================\n // CORE TOKEN OPERATIONS\n // ==========================================================================\n\n /**\n * Create a new consumable token.\n * Generates a 32-byte hex crypto-random token value and persists it.\n *\n * @returns The full entity WITH the raw token value (for passing to emails/responses).\n * NEVER log the returned token value (R2).\n */\n public async createToken(\n params: CreateTokenParams,\n transaction?: TransactionContext,\n ): Promise<ConsumableToken & { token: string }> {\n const tokenValue = crypto.randomBytes(32).toString('hex');\n const now = new Date();\n const expiresAt = this.calculateExpiresAt(params.expiresIn, now);\n\n // assurance-control: WILDO.IDENTITY.CREDENTIAL_LIFECYCLE — a one-off session token is a\n // session-establishing credential minted for another user, so its lifetime is bounded by the industry\n // hard ceiling (ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES) HERE — the single point every one-off mint path\n // funnels through (super-admin route + resource-config `processTokenGeneration`). Fail-closed: an\n // over-ceiling mint is REJECTED, never silently clamped (matching AWS STS rejecting an over-max AssumeRole).\n if (params.createsOneOffSession) {\n const requestedMinutes = durationToSeconds(params.expiresIn) / 60;\n if (requestedMinutes > ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.ONE_OFF_SESSION_DURATION_EXCEEDS_MAX,\n context: { requestedMinutes: Math.round(requestedMinutes), absoluteMaxMinutes: ONE_OFF_SESSION_ABSOLUTE_MAX_MINUTES }, // diagnostic (log-only)\n });\n }\n }\n // assurance-control: WILDO.IDENTITY.CREDENTIAL_LIFECYCLE — a file upload grant is a bearer credential\n // DESIGNED to leave the trust boundary (an LLM transcript, a shell history), so its lifetime is bounded\n // HERE, at the one mint chokepoint, per type and fail-closed: an over-ceiling request is REJECTED, never\n // clamped (issue #312, D8). Nothing else bounds a consumable token's life — measured 2026-09-05, the\n // one-off ceiling above was the only one — which is why this cannot be left to the caller's `expiresIn`.\n // SINGLE_USE only: a reusable upload credential is the presigned-URL defect rebuilt inside the API.\n if (params.tokenType === CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {\n const requestedMinutes = durationToSeconds(params.expiresIn) / 60;\n if (requestedMinutes > FILE_UPLOAD_GRANT_ABSOLUTE_MAX_MINUTES) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.FILE_UPLOAD_GRANT_DURATION_EXCEEDS_MAX,\n context: { requestedMinutes: Math.round(requestedMinutes), absoluteMaxMinutes: FILE_UPLOAD_GRANT_ABSOLUTE_MAX_MINUTES }, // diagnostic (log-only)\n });\n }\n if (params.consumptionMode !== ConsumableToken_ConsumptionMode.SINGLE_USE) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.VALIDATION,\n context: { message: 'A file upload grant must be SINGLE_USE', consumptionMode: params.consumptionMode }, // diagnostic (log-only)\n });\n }\n }\n /**\n * Identity through the framework AUTHORITY, not `crypto.randomUUID()`.\n *\n * The id format is a per-resource framework decision (`ResourceIdBackendService`), and the\n * PostgreSQL repository already mints through it in `withGeneratedRowIdentity`. Minting a UUID\n * here instead produced a row whose `_id` is not the shape the resource declares, and the\n * consequence was measured rather than reasoned: the repository read the row correctly but with\n * **no `_id` at all**, because Mongoose cannot hydrate a UUID into its declared identity type.\n *\n * That was invisible while every token path addressed rows by their `token` value and never by\n * `_id` — the same \"agreed by never meeting\" shape as the collection-name split this service also\n * carried. It stops being invisible the moment creation moves to the repository (R-W5-3), which\n * mints through this same authority, so the two would disagree about what an existing row's id\n * even looks like.\n *\n * `@optional()` on the injection: the service is constructed directly in several harnesses, and a\n * required dependency there would be a churn cost with no safety gain. The fallback is the\n * previous behaviour, so a harness that does not supply it degrades to what it had before rather\n * than to something new.\n */\n const _id = this.resourceIdService\n ? String(this.resourceIdService.generateForResource(BackendResourceType.CONSUMABLE_TOKENS as never))\n : crypto.randomUUID();\n\n const tokenData: ConsumableToken = {\n _id,\n token: tokenValue,\n tokenType: params.tokenType,\n resourceIdentifier: params.resourceIdentifier,\n consumptionMode: params.consumptionMode,\n organizationId: params.organizationId,\n userId: params.userId,\n relatedId: params.relatedId,\n ...(params.activeGenerationKey && {\n activeGenerationKey: params.activeGenerationKey,\n }),\n metadata: params.metadata || {},\n roles: params.roles || [],\n expiresAt,\n isConsumed: false,\n usesCount: 0,\n ...(params.createsOneOffSession !== undefined && { createsOneOffSession: params.createsOneOffSession }),\n ...(params.consumeAt && { consumeAt: params.consumeAt }),\n ...(params.targeting && { targeting: params.targeting }),\n createdAt: now,\n updatedAt: now,\n };\n\n // maxUses is required for BOUNDED_REUSE\n if (params.consumptionMode === ConsumableToken_ConsumptionMode.BOUNDED_REUSE) {\n if (!params.maxUses || params.maxUses < 1) {\n throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.VALIDATION,\n context: { reason: 'maxUses is required and must be >= 1 for BOUNDED_REUSE tokens' }\n });\n }\n tokenData.maxUses = params.maxUses;\n }\n\n // The adapter narrows `transaction` itself and raises the mismatch error, so this service no\n // longer needs its own MongoDB-specific narrowing.\n try {\n await this.repositoriesRegistry.insertDocumentForInfrastructure(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n tokenData as unknown as Record<string, unknown>,\n undefined,\n { transaction },\n );\n } catch (error) {\n if (params.activeGenerationKey && this.isActiveGenerationKeyDuplicate(error)\n ) {\n throw this.errorBuilder.buildError(ErrorType.CONFLICT, undefined, {\n customMessageReference:\n ErrorCustomMessageReference.UNIQUE_CONSTRAINT_VIOLATION,\n context: {\n reason: 'consumable_token_active_generation_conflict',\n tokenType: params.tokenType,\n relatedId: params.relatedId,\n },\n });\n }\n throw error;\n }\n\n // Log creation without the raw token value (R2), and only after commit\n // when this token participates in a wider transaction.\n const logCreation = async (): Promise<void> => {\n this.logger.info('Consumable token created', {\n tokenId: _id,\n tokenType: params.tokenType,\n consumptionMode: params.consumptionMode,\n relatedId: params.relatedId,\n organizationId: params.organizationId,\n expiresAt: expiresAt.toISOString(),\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key: `consumable-token-created:${_id}`,\n execute: logCreation,\n });\n } else {\n await logCreation();\n }\n\n return tokenData as ConsumableToken & { token: string };\n }\n\n /**\n * Validate a token without consuming it.\n * Checks: existence, revocation, expiry, consumption status, type matching.\n *\n * @param tokenValue - The raw token string from the request\n * @param expectedTypes - Optional array of accepted token types for this operation\n * @returns The validated token entity\n * @throws Appropriate error for each failure mode\n */\n public async validateToken(\n tokenValue: string,\n expectedTypes?: ConsumableTokenTypes[],\n ): Promise<ConsumableToken> {\n this.assertTokenValueIsString(tokenValue);\n const tokenDoc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { token: tokenValue },\n );\n\n if (!tokenDoc) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_NOT_FOUND,\n });\n }\n\n const token = tokenDoc as unknown as ConsumableToken;\n\n // Check revocation\n if (token.revokedAt) {\n this.logger.warn('Revoked token used', { tokenId: token._id });\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_REVOKED,\n context: { tokenId: token._id },\n });\n }\n\n // Check expiry\n if (token.expiresAt < new Date()) {\n this.logger.warn('Expired token used', { tokenId: token._id });\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_EXPIRED,\n context: { tokenId: token._id },\n });\n }\n\n // Check consumption status based on mode\n if (token.consumptionMode === ConsumableToken_ConsumptionMode.SINGLE_USE && token.isConsumed) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_ALREADY_CONSUMED,\n context: { tokenId: token._id },\n });\n }\n\n if (token.consumptionMode === ConsumableToken_ConsumptionMode.BOUNDED_REUSE) {\n const maxUses = token.maxUses;\n if (maxUses && token.usesCount >= maxUses) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_ALREADY_CONSUMED,\n context: { tokenId: token._id, usesCount: token.usesCount, maxUses },\n });\n }\n }\n\n if (token.consumptionMode === ConsumableToken_ConsumptionMode.EPHEMERAL_STATE && token.isConsumed) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_ALREADY_CONSUMED,\n context: { tokenId: token._id },\n });\n }\n\n // Check type matching\n if (expectedTypes && expectedTypes.length > 0) {\n if (!expectedTypes.includes(token.tokenType as ConsumableTokenTypes)) {\n this.logger.warn('Token type mismatch', {\n tokenId: token._id,\n tokenType: token.tokenType,\n expectedTypes\n });\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_TYPE_MISMATCH,\n context: { tokenId: token._id, tokenType: token.tokenType, expectedTypes },\n });\n }\n }\n\n return token;\n }\n\n /**\n * Atomically consume a token.\n * Uses MongoDB `findOneAndUpdate` with conditions to prevent race conditions.\n *\n * - SINGLE_USE: condition `{ isConsumed: false }`, sets `{ isConsumed: true, usesCount: 1 }`\n * - BOUNDED_REUSE: condition `{ usesCount: { $lt: maxUses } }`, inc `usesCount`, set `isConsumed` if exhausted\n * - EPHEMERAL_STATE: condition `{ isConsumed: false }`, sets `{ isConsumed: true }`\n *\n * @param tokenValue - The raw token string\n * @returns The updated token entity\n * @throws CONSUMABLE_TOKEN_RACE_CONDITION if atomic update fails (concurrent consumption)\n */\n public async consumeToken(\n tokenValue: string,\n transaction?: TransactionContext,\n ): Promise<ConsumableToken> {\n this.assertTokenValueIsString(tokenValue);\n const now = new Date();\n\n // First, read the token to determine its consumption mode.\n // Also check that the token hasn't expired or been revoked.\n const existingTokenDoc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n {\n token: tokenValue,\n revokedAt: { $exists: false },\n expiresAt: { $gt: now },\n },\n { transaction },\n );\n if (!existingTokenDoc) {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_NOT_FOUND,\n });\n }\n const existingToken = existingTokenDoc as unknown as ConsumableToken;\n\n let filter: Record<string, any>;\n let mutation: RepositoryGuardedMutation;\n /**\n * BOUNDED_REUSE only. `isConsumed` is DERIVED state for that mode — a cache read solely by the\n * cleanup batch's hard-delete, never by an authorization path — so it is computed from the\n * post-increment row rather than inside the statement. See the note at the write below.\n */\n let boundedMaxUses: number | undefined;\n\n // All filters include expiresAt + revokedAt guards to prevent consuming expired/revoked tokens\n // in the atomic update (defense-in-depth against TOCTOU between the read above and the update below).\n const expiryGuard = { expiresAt: { $gt: now }, revokedAt: { $exists: false } };\n\n switch (existingToken.consumptionMode) {\n case ConsumableToken_ConsumptionMode.SINGLE_USE: {\n filter = { token: tokenValue, isConsumed: false, ...expiryGuard };\n // Fully expressible: every assignment is a constant, and `$$REMOVE` is `clear`.\n mutation = {\n set: { isConsumed: true, usesCount: 1, updatedAt: now },\n clear: ['activeGenerationKey'],\n };\n break;\n }\n\n case ConsumableToken_ConsumptionMode.BOUNDED_REUSE: {\n const maxUses = existingToken.maxUses || 1;\n filter = { token: tokenValue, usesCount: { $lt: maxUses }, ...expiryGuard };\n // Use aggregation pipeline update to atomically increment usesCount\n // AND compute isConsumed from the post-increment value.\n // This avoids the race condition where two concurrent requests\n // both read the same pre-increment usesCount and fail to set isConsumed.\n /**\n * The INCREMENT is the guarantee; the flag is not.\n *\n * Atomicity here comes from the FILTER (`usesCount < maxUses`), which is what refuses the\n * consume once the allowance is spent — and it is `usesCount`, never `isConsumed`, that\n * every authorization path reads: this filter, and `validateToken`'s BOUNDED_REUSE branch.\n * `isConsumed` is a denormalized flag whose only consumer is the cleanup batch's\n * hard-delete, which ALREADY carries a second sweep for exactly this window (\"defense in\n * depth for the race condition edge case where isConsumed may not have been atomically\n * set\").\n *\n * MongoDB expressed the derivation inside an aggregation-pipeline update; that is precisely\n * the raw-operator form the adapter-neutral vocabulary excludes, and a computed set is not\n * expressible for both adapters through it. Deriving it from the returned post-increment row\n * keeps the authoritative counter atomic and costs only freshness on a flag nothing gates on.\n *\n * Rejected: narrowing the filter to a compare-and-swap on `usesCount` so the post-value were\n * known here — that would turn two legitimate concurrent consumers of a bounded-reuse token\n * into one CONFLICT, a behaviour regression rather than a translation.\n */\n boundedMaxUses = maxUses;\n mutation = { increment: { usesCount: 1 }, set: { updatedAt: now } };\n break;\n }\n\n case ConsumableToken_ConsumptionMode.EPHEMERAL_STATE: {\n filter = { token: tokenValue, isConsumed: false, ...expiryGuard };\n // Fully expressible: every assignment is a constant, and `$$REMOVE` is `clear`.\n mutation = {\n set: { isConsumed: true, usesCount: 1, updatedAt: now },\n clear: ['activeGenerationKey'],\n };\n break;\n }\n\n default: {\n throw this.errorBuilder.buildError(ErrorType.INTERNAL, undefined, {\n context: {\n reason: 'consumable_token_consumption_mode_invalid',\n tokenId: existingToken._id,\n consumptionMode: existingToken.consumptionMode,\n },\n });\n }\n }\n\n const result = await this.repositoriesRegistry.atomicGuardedMutation<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n filter,\n mutation,\n undefined,\n { transaction },\n );\n\n if (!result) {\n this.logger.warn('Token consumption race condition', { tokenId: existingToken._id });\n throw this.errorBuilder.buildError(ErrorType.CONFLICT, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_RACE_CONDITION,\n context: { tokenId: existingToken._id },\n });\n }\n\n /**\n * Settle the DERIVED flag for BOUNDED_REUSE, now that the authoritative counter is known.\n *\n * Guarded on the same allowance, so a concurrent consumer that has not yet exhausted the token\n * cannot flip it early. Nothing gates on this flag (see the mutation note above), so a failure to\n * write it is a freshness loss the cleanup batch's second sweep already covers — it must not turn\n * a SUCCESSFUL consume into an error for the caller.\n */\n if (boundedMaxUses !== undefined && (result.usesCount ?? 0) >= boundedMaxUses) {\n result.isConsumed = true;\n try {\n await this.repositoriesRegistry.atomicGuardedMutation(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: result._id },\n { set: { isConsumed: true }, clear: ['activeGenerationKey'] },\n undefined,\n { transaction },\n );\n } catch (error) {\n this.logger.warn('Consumable token exhausted but its derived isConsumed flag was not written', {\n tokenId: result._id,\n ...projectCaughtErrorLogFields(error),\n });\n }\n }\n\n const logConsumption = async (): Promise<void> => {\n this.logger.info('Consumable token consumed', {\n tokenId: existingToken._id,\n consumptionMode: existingToken.consumptionMode,\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key: `consumable-token-consumed:${existingToken._id}`,\n execute: logConsumption,\n });\n } else {\n await logConsumption();\n }\n\n return result as unknown as ConsumableToken;\n }\n\n /**\n * Fetch a token by its `_id`, WITHOUT any state assertions — a revoked, expired, or consumed row all\n * pass through. This is deliberately different from `validateToken`, which keys on the token VALUE and\n * THROWS on any non-live state: an operator flow that acts ON a token needs to read it first and decide\n * for itself. The one-off-session revoke route uses it to (a) return NOT_FOUND for a missing id, (b)\n * confirm the row IS a one-off session token before revoking (this door must never touch a\n * password-reset / invitation / magic-link token by id), and (c) build the revocation audit from the\n * token's own `userId` / `tokenType`. Returns `null` when no row matches.\n *\n * `tokenId` is guarded by the same non-string check as every other primitive here (`{ _id }` reaches\n * Mongo directly, so a `{$ne}`-shaped value would otherwise match an ARBITRARY token).\n */\n /**\n * Read a token row by its VALUE regardless of state — expired, consumed and revoked rows included.\n *\n * For status surfaces that must say WHY a token is unusable (`validateToken` refuses those rows, which\n * is right for authentication and wrong for a status read). Callers hold the value already, so this\n * discloses nothing they could not learn by presenting it. Never logs the value (R2).\n */\n public async findTokenByValue(tokenValue: string): Promise<ConsumableToken | null> {\n this.assertTokenValueIsString(tokenValue);\n const doc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { token: tokenValue },\n );\n return (doc as unknown as ConsumableToken) ?? null;\n }\n\n public async findTokenById(tokenId: string): Promise<ConsumableToken | null> {\n this.assertTokenValueIsString(tokenId);\n\n // Adapter-neutral, like every other read on this service: the retired `getTokenCollection`\n // accessor reached the Mongo driver directly, so a raw `findOne` here would make this the one\n // token-lookup door a PostgreSQL-backed application cannot open. `readUnscopedByKey` is the same\n // primitive the token-VALUE lookups above already use; only the key differs.\n const tokenDoc = await this.repositoriesRegistry.readUnscopedByKey<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: tokenId },\n );\n return tokenDoc ?? null;\n }\n\n /**\n * Soft-revoke a token by setting revokedAt.\n * This is a soft invalidation — the record stays in DB for audit.\n * Hard deletion is handled by the cleanup cron job.\n *\n * CONDITIONAL on the row not already being revoked (`revokedAt: { $exists: false }`), mirroring\n * `revokeTokensByRelatedId`. This makes the transition atomic: two concurrent revocations of the SAME token\n * transition it exactly once, so a caller can emit its audit only on the real transition (returned `true`)\n * and never write a duplicate row under a race. Returns whether THIS call performed the revocation\n * (`false` = the token was already revoked, or does not exist).\n */\n /**\n * Record, on a redeemed FILE_UPLOAD_GRANT, the file its one upload produced (issue #312, D6/D10).\n *\n * Written AFTER the grant is consumed and the FILES row exists, so there is exactly one writer and\n * a plain replace of `metadata` is safe. Best-effort by contract: the upload has already succeeded\n * when this runs, so a failure here must not fail it — the caller logs and the status read falls\n * back to \"REDEEMED, file unknown; re-read the resource\". Returns whether a row was written.\n *\n * Replaces the whole `metadata` object rather than a dotted path so the write is adapter-neutral:\n * the PostgreSQL arm stores `metadata` as one JSON column.\n */\n public async recordFileUploadGrantProducedFile(tokenId: string, fileId: string): Promise<boolean> {\n const existing = await this.findTokenById(tokenId);\n if (!existing || existing.tokenType !== CoreConsumableTokenTypes.FILE_UPLOAD_GRANT) {\n return false;\n }\n const now = new Date();\n const written = await this.repositoriesRegistry.atomicGuardedMutation(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: tokenId, isConsumed: true },\n { set: { metadata: { ...(existing.metadata ?? {}), producedFileId: fileId }, updatedAt: now } },\n );\n return written !== null;\n }\n\n public async revokeToken(tokenId: string): Promise<boolean> {\n const now = new Date();\n\n // Adapter-neutral by construction: `atomicGuardedMutation` compiles the SAME conditional\n // transition on either adapter — the PostgreSQL arm translates `{ $exists: false }` to\n // `IS NULL` — and `clear` is the neutral spelling of the pipeline's `$$REMOVE`. Dropping the\n // active-generation key is what frees a later token of the same generation to be minted.\n // Deliberately the same idiom as `revokeTokensByRelatedId`, which the conditional mirrors:\n // a raw driver call here would make this the one revocation door PostgreSQL cannot open.\n const revoked = await this.repositoriesRegistry.atomicGuardedMutation(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n { _id: tokenId, revokedAt: { $exists: false } },\n { set: { revokedAt: now, updatedAt: now }, clear: ['activeGenerationKey'] },\n );\n\n // `null` is the neutral spelling of \"no row matched the guard\" — the same fact the driver\n // reported as `modifiedCount === 0`: already revoked, or no such token.\n const didRevoke = revoked !== null;\n if (didRevoke) {\n this.logger.info('Consumable token revoked', { tokenId });\n }\n return didRevoke;\n }\n\n /**\n * Revoke all tokens matching a relatedId and optionally a token type.\n * Uses repository directly (R6 — intentional, not routed through operation pipeline).\n *\n * @returns Count of revoked tokens\n */\n public async revokeTokensByRelatedId(\n relatedId: string,\n tokenType?: ConsumableTokenTypes,\n transaction?: TransactionContext,\n ): Promise<number> {\n const now = new Date();\n\n const filter: Record<string, any> = {\n relatedId,\n revokedAt: { $exists: false },\n };\n if (tokenType) {\n filter.tokenType = tokenType;\n }\n\n // The COUNT is the contract: callers report how many tokens were revoked, so the multi-row\n // primitive returns it rather than a boolean.\n const revokedCount = await this.repositoriesRegistry.bulkUpdateForInfrastructure(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n filter,\n { set: { revokedAt: now, updatedAt: now }, clear: ['activeGenerationKey'] },\n undefined, // no execution context: this is a framework-internal revocation, below the operation tier\n // JOIN THE CALLER'S TRANSACTION. Without this the revocation committed immediately even when the\n // caller was mid-transaction, so a driver retry could not roll it back — the retry then revoked\n // nothing and reported 0 for work that had already happened exactly once.\n { transaction },\n );\n if (revokedCount > 0) {\n const logRevocation = async (): Promise<void> => {\n this.logger.info('Consumable tokens revoked by relatedId', {\n relatedId,\n tokenType,\n revokedCount,\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key: `consumable-tokens-revoked:${relatedId}:${String(tokenType ?? 'all')}`,\n execute: logRevocation,\n });\n } else {\n await logRevocation();\n }\n }\n\n return revokedCount;\n }\n\n /**\n * Find all unconsumed, non-revoked, non-expired tokens for a given relatedId and token type.\n * Used by Email OTP verification (Step 10) to find matching OTP tokens.\n *\n * @returns Array of matching token documents (may be empty)\n */\n public async findTokensByRelatedId(\n relatedId: string,\n tokenType: ConsumableTokenTypes,\n ): Promise<ConsumableToken[]> {\n const now = new Date();\n\n const docs = await this.repositoriesRegistry.findManyForInfrastructure<ConsumableToken>(\n BackendResourceType.CONSUMABLE_TOKENS as never,\n {\n relatedId,\n tokenType: tokenType,\n revokedAt: { $exists: false },\n isConsumed: { $ne: true },\n expiresAt: { $gt: now },\n },\n );\n\n return docs;\n }\n\n // ==========================================================================\n // PIPELINE HELPERS — Called by services-registry-handler for declarative config\n // ==========================================================================\n\n /**\n * Process a declarative tokenGeneration config from an operation variant.\n * Called AFTER the core operation succeeds, BEFORE notification dispatch.\n *\n * Returns `{ tokenValue, tokenId }` for injection into notification context.\n */\n public async processTokenGeneration(\n config: TokenGenerationConfig,\n currentState: Record<string, any>,\n executionContext: {\n organizationId?: string;\n userId?: string;\n resourceType?: string;\n },\n transaction: TransactionContext,\n ): Promise<TokenGenerationResult> {\n const relatedId = currentState[config.relatedIdField || '_id'];\n if (config.revokeExistingForSameRelated && (typeof relatedId !== 'string' || relatedId.length === 0)\n ) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n context: {\n reason: 'replace_existing_token_related_id_missing',\n tokenType: config.tokenType,\n relatedIdField: config.relatedIdField || '_id',\n },\n });\n }\n\n const activeGenerationKey =\n config.revokeExistingForSameRelated && relatedId\n ? this.buildActiveGenerationKey(config.tokenType, relatedId)\n : undefined;\n\n // Revoke existing tokens if configured\n if (config.revokeExistingForSameRelated) {\n if (relatedId) {\n await this.revokeTokensByRelatedId(relatedId, config.tokenType, transaction);\n }\n }\n\n // Resolve static or derived values\n const resolvedExpiresIn = this.resolveStaticOrDerived(config.expiresIn, currentState);\n const resolvedGrantedRoles = config.grantedRoles\n ? this.resolveStaticOrDerived(config.grantedRoles, currentState)\n : undefined;\n\n // Build create params\n const createParams: CreateTokenParams = {\n tokenType: config.tokenType,\n consumptionMode: config.consumptionMode,\n expiresIn: resolvedExpiresIn,\n organizationId: currentState.organizationId || executionContext.organizationId,\n resourceIdentifier: executionContext.resourceType,\n relatedId,\n ...(activeGenerationKey && {\n activeGenerationKey,\n }),\n roles: resolvedGrantedRoles,\n maxUses: config.maxUses,\n };\n\n // Resolve userId if configured\n if (config.userIdField) {\n createParams.userId = currentState[config.userIdField];\n }\n\n // W7.3b: Bridge to one-off sessions when configured\n if (config.createsOneOffSession) {\n createParams.createsOneOffSession = true;\n createParams.consumeAt = config.consumeAt;\n }\n\n if (config.targetingFields) {\n const initiatorIds: Record<string, string> = {};\n const orgId = currentState.organizationId || executionContext.organizationId;\n if (orgId) initiatorIds.organizationId = orgId;\n for (const [fieldId, fieldPath] of Object.entries(config.targetingFields)) {\n const value = currentState[fieldPath];\n if (value) initiatorIds[fieldId] = String(value);\n }\n if (Object.keys(initiatorIds).length > 0) {\n createParams.targeting = { initiatorIds };\n }\n }\n\n const token = await this.createToken(createParams, transaction);\n\n return this.toTokenGenerationResult(token);\n }\n\n /**\n * Process a declarative tokenRevocation config from an operation variant.\n * Called BEFORE the core operation (pre-operation step).\n *\n * Revokes all tokens matching the related resource ID and configured token types.\n */\n public async processTokenRevocation(\n config: TokenRevocationConfig,\n currentState: Record<string, any>,\n _executionContext: { organizationId?: string },\n transaction?: TransactionContext,\n ): Promise<TokenRevocationResult> {\n const relatedId = currentState[config.relatedIdField || '_id'];\n\n if (!relatedId) {\n this.logger.warn('Token revocation skipped: no relatedId found', {\n relatedIdField: config.relatedIdField || '_id',\n });\n return { revokedCount: 0 };\n }\n\n let totalRevoked = 0;\n for (const tokenType of config.tokenTypes) {\n const count = await this.revokeTokensByRelatedId(\n relatedId,\n tokenType,\n transaction,\n );\n totalRevoked += count;\n }\n\n const logCompletion = async (): Promise<void> => {\n this.logger.info('Token revocation completed', {\n relatedId,\n tokenTypes: config.tokenTypes,\n totalRevoked,\n });\n };\n if (transaction) {\n registerTransactionPostCommitEffect(transaction, {\n key:\n `consumable-token-revocation-completed:${relatedId}:`\n + config.tokenTypes.map(String).sort().join(','),\n execute: logCompletion,\n });\n } else {\n await logCompletion();\n }\n\n return { revokedCount: totalRevoked };\n }\n\n // ==========================================================================\n // PRIVATE HELPERS\n // ==========================================================================\n\n private buildActiveGenerationKey(\n tokenType: ConsumableTokenTypes,\n relatedId: string,\n ): string {\n return crypto\n .createHash('sha256')\n .update(`${String(tokenType)}\\0${relatedId}`)\n .digest('hex');\n }\n\n private toTokenGenerationResult(token: ConsumableToken): TokenGenerationResult {\n return {\n tokenValue: token.token,\n tokenId: token._id,\n };\n }\n\n /**\n * Defense-in-depth against NoSQL operator injection. Every raw-collection lookup here keys on the\n * caller-supplied `token` value (`findOne({ token: tokenValue })`, `findOneAndUpdate({ token: … })`),\n * so a NON-STRING value (e.g. a `{$regex}` / `{$ne}` object that slipped a caller's boundary\n * validation) would be interpreted by Mongo as a query OPERATOR and match/consume an ARBITRARY token —\n * a remote token-destruction primitive (password-reset / invitation / magic-link). A real token value\n * is always a high-entropy string, so a non-string is by definition \"not found\"; we throw the same\n * `CONSUMABLE_TOKEN_NOT_FOUND` (kept non-oracle — the injection case is indistinguishable from a miss).\n * The OAuth provider already rejects such input at its HTTP boundary (400 `invalid_request`); this\n * guards EVERY other caller of the primitive too.\n */\n private assertTokenValueIsString(tokenValue: unknown): asserts tokenValue is string {\n if (typeof tokenValue !== 'string') {\n throw this.errorBuilder.buildError(ErrorType.AUTHENTICATION, undefined, {\n customMessageReference: ErrorCustomMessageReference.CONSUMABLE_TOKEN_NOT_FOUND,\n });\n }\n }\n\n /**\n * The persistence plane this service writes through.\n *\n * **Replaced a raw MongoDB collection handle.** This service used to reach\n * `connection.collection(resolveSharedPersistenceCollectionName(CONSUMABLE_TOKENS))` and issue\n * driver calls directly, which is why consumable-token persistence was \"a MongoDB-native\n * capability\" — and why every token-coupled operation carried a hard\n * `requiredAdapter: MONGODB`, making `organizationMembers | create · revoke · resend`\n * unresolvable on a PostgreSQL platform.\n *\n * The registry's framework-internal tier is the right home rather than the resource's declared\n * operations: those are the ADMINISTRATIVE surface (role-gated on `ORG_ADMIN`), whereas the token\n * lifecycle runs where there is NO principal — a verification email is a system action, and a\n * magic-link click is pre-authentication by definition. Routing it through the declared operations\n * would mean fabricating an administrator to authorize the very credential being established.\n *\n * The collection-identity concern the old accessor documented is now structural rather than\n * conventional: the registry resolves the resource's own storage, so there is no second physical\n * name for anything to diverge from.\n *\n * **Named `repositoriesRegistry` deliberately.** `guarded-write-registry-dispatch.guard.test.ts`\n * requires every guarded-write call to have a receiver whose last segment is exactly that, because\n * those primitives do NOT apply the retention hide themselves — it is applied once, at the registry\n * dispatch. An accessor named anything else would route correctly and still read, to that guard and\n * to a human, like a call on a bare repository handle.\n */\n private get repositoriesRegistry(): RepositoriesRegistryHandlerBackendService {\n if (!this.injectedRepositoriesRegistry) {\n throw this.errorBuilder.buildError(ErrorType.DATABASE, undefined, {\n context: { reason: 'Repositories registry not available for consumable tokens' },\n });\n }\n return this.injectedRepositoriesRegistry;\n }\n\n /**\n * Narrow the database-agnostic transaction before any MongoDB access.\n *\n * Consumable-token persistence is MongoDB-native. Casting another adapter's\n * opaque native transaction to `ClientSession` would turn a configuration\n * mismatch into driver-dependent behavior, so every transactional entry\n * path fails at this boundary first.\n */\n private getMongoSession(transaction?: TransactionContext): ClientSession | undefined {\n if (!transaction) return undefined;\n if (transaction.databaseType !== PersistenceAdapter.MONGODB) {\n throw this.errorBuilder.buildError(ErrorType.CONFIGURATION, undefined, {\n context: {\n reason: 'consumable_token_requires_mongodb_transaction',\n transactionDatabaseType: transaction.databaseType,\n },\n });\n }\n return transaction.nativeSession as ClientSession;\n }\n\n /**\n * Match only the sparse active-generation index. `createToken` also writes other unique fields\n * (notably the raw token), and collapsing their failures into a RESEND race would hide an\n * unrelated persistence defect.\n *\n * ## Branches on the CLASSIFIED conflict, never on driver internals\n *\n * This used to require a raw MongoDB error with `code: 11000` and a `keyPattern`, and could\n * therefore never fire. `insertRawDocument` translates the duplicate before it escapes —\n * `throw this.handleMongoDBError(error)` on the Mongo arm, `handlePostgresError` on the\n * PostgreSQL one — so what reaches this catch is the classified CONFLICT, carrying no `code` and\n * no `keyPattern`. The RESEND race surfaced as a generic CONFLICT and the specific\n * `consumable_token_active_generation_conflict` reference was unreachable through the real stack.\n *\n * The infrastructure tier's own comment says why detecting on driver internals was the wrong\n * shape in the first place: without the translation \"every caller would need adapter-specific\n * detection, which is precisely what this tier exists to remove\". On PostgreSQL there is no\n * `code: 11000` to match at ALL — a unique violation is SQLSTATE `23505` — so the old predicate\n * was not merely unreachable, it was unwritable for the adapter both example applications now run.\n *\n * `violatedFields` is the adapter-neutral answer both arms populate: Mongo from `keyPattern`\n * (falling back to the message), PostgreSQL from the constraint's columns.\n */\n private isActiveGenerationKeyDuplicate(error: unknown): boolean {\n if (!isWildoBackendError(error)) return false;\n if (error.type !== ErrorType.CONFLICT) return false;\n\n const violatedFields = error.context?.violatedFields;\n return Array.isArray(violatedFields) && violatedFields.includes('activeGenerationKey');\n }\n\n /**\n * Calculate the expiration date from a relative duration.\n */\n private calculateExpiresAt(expiresIn: DurationValue, from: Date = new Date()): Date {\n const ms = durationToSeconds(expiresIn) * 1000;\n return new Date(from.getTime() + ms);\n }\n\n /**\n * Resolve a StaticOrDerived value.\n * If the value is a function, call it with the currentObject.\n * If static, return as-is.\n */\n private resolveStaticOrDerived<T>(value: StaticOrDerived<T>, currentObject: Record<string, any>): T {\n if (typeof value === 'function') {\n return (value as (obj: Record<string, any>) => T)(currentObject);\n }\n return value;\n }\n}\n"]}
|
|
@@ -26,10 +26,15 @@ export declare function isRotationGraceWindowOpen(invalidationDate?: Date | null
|
|
|
26
26
|
* Whether a credential (api-key / OAuth client) has passed its `expiresAt`. `null`/`undefined` =
|
|
27
27
|
* no expiry set = never expires.
|
|
28
28
|
*
|
|
29
|
-
* Enforced at AUTH-TIME on every machine front
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
29
|
+
* Enforced at AUTH-TIME on every machine front, and that is where the enforcement STAYS.
|
|
30
|
+
*
|
|
31
|
+
* There IS an `EXPIRED` producer since 2026-09-08 — the nightly credential-expiry sweep (#413)
|
|
32
|
+
* dispatches each resource's `expire` verb — but it is BOOKKEEPING, never the control. It always
|
|
33
|
+
* lags: a credential that elapses at 09:00 still reads ACTIVE until 02:30 the next morning. This
|
|
34
|
+
* check is what makes that lag harmless, so a caller must never replace it with a `status` test.
|
|
35
|
+
* Do that and the sweep's lag becomes an authorization hole rather than a stale display, and
|
|
36
|
+
* `expiresAt` plus the `EXTEND_EXPIRY` operation go back to being decorative. Callers apply it
|
|
37
|
+
* alongside the ACTIVE gate:
|
|
33
38
|
* `!record || record.status !== ACTIVE || isCredentialExpired(record.expiresAt)`. SINGLE SOURCE OF
|
|
34
39
|
* TRUTH shared by the api-key + OAuth-client request-auth handlers and the `/oauth/token` exchange.
|
|
35
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-rotation-grace.backend.utils.d.ts","sourceRoot":"","sources":["../../../../src/security/credential-rotation-grace.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,gBAAgB,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAGjF;AAED
|
|
1
|
+
{"version":3,"file":"credential-rotation-grace.backend.utils.d.ts","sourceRoot":"","sources":["../../../../src/security/credential-rotation-grace.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,gBAAgB,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAGjF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,CAGpE"}
|
|
@@ -30,10 +30,15 @@ export function isRotationGraceWindowOpen(invalidationDate) {
|
|
|
30
30
|
* Whether a credential (api-key / OAuth client) has passed its `expiresAt`. `null`/`undefined` =
|
|
31
31
|
* no expiry set = never expires.
|
|
32
32
|
*
|
|
33
|
-
* Enforced at AUTH-TIME on every machine front
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* Enforced at AUTH-TIME on every machine front, and that is where the enforcement STAYS.
|
|
34
|
+
*
|
|
35
|
+
* There IS an `EXPIRED` producer since 2026-09-08 — the nightly credential-expiry sweep (#413)
|
|
36
|
+
* dispatches each resource's `expire` verb — but it is BOOKKEEPING, never the control. It always
|
|
37
|
+
* lags: a credential that elapses at 09:00 still reads ACTIVE until 02:30 the next morning. This
|
|
38
|
+
* check is what makes that lag harmless, so a caller must never replace it with a `status` test.
|
|
39
|
+
* Do that and the sweep's lag becomes an authorization hole rather than a stale display, and
|
|
40
|
+
* `expiresAt` plus the `EXTEND_EXPIRY` operation go back to being decorative. Callers apply it
|
|
41
|
+
* alongside the ACTIVE gate:
|
|
37
42
|
* `!record || record.status !== ACTIVE || isCredentialExpired(record.expiresAt)`. SINGLE SOURCE OF
|
|
38
43
|
* TRUTH shared by the api-key + OAuth-client request-auth handlers and the `/oauth/token` exchange.
|
|
39
44
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-rotation-grace.backend.utils.js","sourceRoot":"","sources":["../../../../src/security/credential-rotation-grace.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,yBAAyB,CAAC,gBAA8B;IACtE,IAAI,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAC3D,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"credential-rotation-grace.backend.utils.js","sourceRoot":"","sources":["../../../../src/security/credential-rotation-grace.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,yBAAyB,CAAC,gBAA8B;IACtE,IAAI,gBAAgB,KAAK,IAAI,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAuB;IACzD,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;AACrD,CAAC","sourcesContent":["/**\n * Whether a credential's PREVIOUS secret — moved into the rotation-grace slot when the credential\n * was reissued — is still inside its grace window and may therefore still authenticate.\n *\n * `invalidationDate` is written by the ROTATE / REGENERATE reissue handlers on both api-keys and\n * OAuth clients, and its three states carry distinct semantics:\n *\n * - `null` / `undefined` → **open-ended overlap**. This is what REGENERATE writes: the reissue is\n * ADDITIVE — it mints a new secret WITHOUT invalidating the prior one, so the prior secret keeps\n * authenticating until the NEXT reissue. REGENERATE is therefore NOT a way to cut off a leaked\n * secret: to revoke a compromised credential you must either REVOKE it (status → non-ACTIVE,\n * which fails the `status === ACTIVE` gate every caller applies to the resolved record) or ROTATE\n * with an explicit invalidation date. This open-endedness is deliberate, not a bug.\n * - a FUTURE date → still valid — a bounded overlap window (e.g. a ROTATE handover deadline).\n * - `now` / a PAST date → expired.\n *\n * Callers MUST additionally require the resolved record's `status === ACTIVE`, so a\n * deactivated/expired credential's previous secret never authenticates regardless of this window.\n *\n * SINGLE SOURCE OF TRUTH shared by the api-key request-auth handlers, the OAuth-client\n * direct-secret handlers, and the `/oauth/token` client-secret exchange — they MUST agree on grace\n * semantics, so the check lives here once rather than being copied per call site.\n */\nexport function isRotationGraceWindowOpen(invalidationDate?: Date | null): boolean {\n if (invalidationDate === null || invalidationDate === undefined) return true;\n return new Date(invalidationDate).getTime() > Date.now();\n}\n\n/**\n * Whether a credential (api-key / OAuth client) has passed its `expiresAt`. `null`/`undefined` =\n * no expiry set = never expires.\n *\n * Enforced at AUTH-TIME on every machine front, and that is where the enforcement STAYS.\n *\n * There IS an `EXPIRED` producer since 2026-09-08 — the nightly credential-expiry sweep (#413)\n * dispatches each resource's `expire` verb — but it is BOOKKEEPING, never the control. It always\n * lags: a credential that elapses at 09:00 still reads ACTIVE until 02:30 the next morning. This\n * check is what makes that lag harmless, so a caller must never replace it with a `status` test.\n * Do that and the sweep's lag becomes an authorization hole rather than a stale display, and\n * `expiresAt` plus the `EXTEND_EXPIRY` operation go back to being decorative. Callers apply it\n * alongside the ACTIVE gate:\n * `!record || record.status !== ACTIVE || isCredentialExpired(record.expiresAt)`. SINGLE SOURCE OF\n * TRUTH shared by the api-key + OAuth-client request-auth handlers and the `/oauth/token` exchange.\n */\nexport function isCredentialExpired(expiresAt?: Date | null): boolean {\n if (expiresAt === null || expiresAt === undefined) return false;\n return new Date(expiresAt).getTime() <= Date.now();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/security/jwt/services/jwt.backend.service.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,cAAc,CAAC;AAC/B,OAAO,EAAE,uBAAuB,EAAC,MAAM,sEAAsE,CAAC;AAC9G,OAAO,EAAE,aAAa,EAAE,MAAM,8DAA8D,CAAC;AAE7F,OAAO,EAAE,cAAc,EAA4B,iBAAiB,EAAoB,MAAM,wEAAwE,CAAC;AACvK,OAAO,EAAE,6BAA6B,EAAqB,kCAAkC,EAAE,kCAAkC,EAAE,MAAM,oFAAoF,CAAC;AAC9N,OAAO,EACL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"jwt.backend.service.d.ts","sourceRoot":"","sources":["../../../../../../src/security/jwt/services/jwt.backend.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,28 +16,11 @@ import { AppConfigurationService } from '../../../config/services/app-configurat
|
|
|
16
16
|
import { LoggerService } from '../../../monitoring/logger/services/logger.service.js';
|
|
17
17
|
import { SAAS_SERVICE_TYPES } from '../../../inject/models/service-types.js';
|
|
18
18
|
import { JwtPrivateKeys, JwtPrivateKeySignOptions, JwtVerifyOptions } from '../../../security/authentications/models/jwt.backend.schemas.js';
|
|
19
|
-
import { ErrorCustomMessageReference, ErrorType, } from '@wildo-ai/saas-models';
|
|
19
|
+
import { ErrorCustomMessageReference, ErrorType, OIDC_RESERVED_ID_TOKEN_CLAIM_NAMES, } from '@wildo-ai/saas-models';
|
|
20
20
|
import stringify from 'safe-stable-stringify';
|
|
21
21
|
import { createHash, createPublicKey } from 'crypto';
|
|
22
22
|
import { randomUUID } from 'crypto';
|
|
23
23
|
import { ErrorBuilderBackendService } from '../../../errors/services/error-builder.backend.service.js';
|
|
24
|
-
/**
|
|
25
|
-
* The OIDC / RFC 7519 protocol + security claim names the ID-token builder OWNS. `extraClaims` (the
|
|
26
|
-
* scope-gated IDENTITY claims from the userinfo/ID-token resolver) must carry ONLY identity claims — these
|
|
27
|
-
* reserved names are stripped BEFORE `extraClaims` is spread, so a same-named entry can never ride into the
|
|
28
|
-
* ID token uncontrolled: a smuggled `nbf` (which would later make the token fail verification), a forged
|
|
29
|
-
* `nonce` / `acr` / `amr` / `at_hash`, or a spoofed `iss` / `aud` / `sub` (the last are already overridden by
|
|
30
|
-
* the server-set claims below — these are the ones the builder does NOT otherwise re-set). ONE named source
|
|
31
|
-
* (closed vocabulary) so the strip list can never drift from the builder's own claim set.
|
|
32
|
-
* semantic-literal-boundary: OIDC Core / RFC 7519 registered claim names.
|
|
33
|
-
* assurance-control: WILDO.IDENTITY.TOKEN_INTEGRITY — an ID token's protocol/security claims are server-authored only.
|
|
34
|
-
*/
|
|
35
|
-
const OIDC_RESERVED_ID_TOKEN_CLAIM_NAMES = new Set([
|
|
36
|
-
// `sid` (OIDC Session Management / Front-Channel & Back-Channel Logout) is SERVER-AUTHORED here — it is
|
|
37
|
-
// the End-User's OP session id the RP-Initiated Logout endpoint keys on (revocation-C). Reserving it bars
|
|
38
|
-
// a client from smuggling its own `sid` via `extraClaims`, exactly like `nonce`/`acr`/`azp` below.
|
|
39
|
-
'iss', 'sub', 'aud', 'exp', 'nbf', 'iat', 'jti', 'azp', 'nonce', 'auth_time', 'at_hash', 'c_hash', 'acr', 'amr', 'sid',
|
|
40
|
-
]);
|
|
41
24
|
/**
|
|
42
25
|
* A rotated public key self-retires when its optional `notAfter` instant has passed — so an operator can
|
|
43
26
|
* schedule a compromised or aged prior key to STOP verifying (and drop out of the JWKS) WITHOUT a redeploy or a
|