@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-access-grant-custom-implementation.backend.service.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grant-custom-implementation.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAEL,gBAAgB,EAChB,2BAA2B,EAC3B,SAAS,EACT,wCAAwC,EACxC,qCAAqC,EACrC,sCAAsC,EACtC,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAAE,mCAAmC,EAAE,MAAM,gEAAgE,CAAC;AACrH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8EAA8E,CAAC;AAEnH,OAAO,EAAE,yCAAyC,EAAE,MAAM,4GAA4G,CAAC;AAMvK,OAAO,EACL,wCAAwC,EACxC,6CAA6C,EAC7C,+BAA+B,GAChC,MAAM,mFAAmF,CAAC;AAE3F;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,mBAAmB,CAAC,MAMlC;IACC,MAAM,gBAAgB,GAAG,MAAM,6CAA6C,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACnG,MAAM,YAAY,GAAG,MAAM,+BAA+B,CAAC;QACzD,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB;QAChB,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,mBAAmB,EAAE,+BAA+B,CAAC,cAAc;KACpE,CAAC,CAAC;IACH,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,qBAAqB,CAAC,MAM9B;IACC,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;QACrC,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,gBAAgB,CAAC;gBAAE,OAAO;YAC7E,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAA0B,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;YAC5G,IAAI,OAAO,gBAAgB,EAAE,+BAA+B,KAAK,UAAU;gBAAE,OAAO;YAEpF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC3B,MAAM,gBAAgB,CAAC,+BAA+B,CAAC;gBACrD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;gBAChC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;gBACxD,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;gBAClD,aAAa,EAAE,KAAK,CAAC,aAAmC;gBACxD,eAAe,EAAE,KAAK,CAAC,MAAmC;gBAC1D,SAAS,EAAE,KAAK,CAAC,SAA6B;gBAC9C,kBAAkB,EAAE,KAAK,CAAC,kBAAuE;gBACjG,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,cAAc,EAAE,KAAK,CAAC,cAAoC;aAC3D,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,0DAA0D,EAAE;gBACvF,MAAM,EAAE,uDAAuD;gBAC/D,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC;IAC7D,IAAI,WAAW,EAAE,CAAC;QAChB,mCAAmC,CAAC,WAAoB,EAAE;YACxD,GAAG,EAAE,yBAAyB,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;YACnF,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kCAAkC;IAChD;;;;;OAKG;IACH,MAAM,oBAAoB,GAAG,CAC3B,yBAA0D,EAC1D,SAAoB,EACpB,EAAE;QACF,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAA4C,kBAAkB,CAAC,2BAA2B,CAAC,CAAC;QAC/H,MAAM,kCAAkC,GAAG,wCAAwC,CAAC,SAAS,CAAC,CAAC;QAC/F,OAAO,yCAAyC,CAAC;YAC/C,aAAa,EAAE;gBACb,kBAAkB,EAAE,gBAAgB,CAAC,sBAAsB;gBAC3D,mBAAmB,EAAE,+BAA+B,CAAC,cAAc;gBACnE,WAAW,EAAE,4BAA4B,CAAC,QAAQ;gBAClD,kBAAkB,EAAE,IAAI;aACzB;YACD,UAAU,EAAE,2CAA2C;YACvD,2FAA2F;YAC3F,0FAA0F;YAC1F,+FAA+F;YAC/F,+FAA+F;YAC/F,uFAAuF;YACvF,mBAAmB,EAAE,CAAC,gBAAgB,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,YAAY,CAAC;YAClG,iBAAiB,EAAE,IAAI;YACvB,uBAAuB,EAAE,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,aAAa,EAAE;YAC/E,QAAQ,EAAE;gBACR,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAClF,MAAM,OAAO,GAAG,KAAsE,CAAC;oBACvF,uFAAuF;oBACvF,sFAAsF;oBACtF,wFAAwF;oBACxF,0DAA0D;oBAC1D,MAAM,cAAc,GAAG,gBAAgB,CAAC,cAAc,CAAC;oBACvD,MAAM,cAAc,GAAG,gBAAgB,CAAC,YAAY,EAAE,MAAM,CAAC;oBAE7D,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,EAAE,CAAC;wBACvC,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE;4BAC1E,sBAAsB,EAAE,2BAA2B,CAAC,UAAU;4BAC9D,OAAO,EAAE,EAAE,MAAM,EAAE,oDAAoD,EAAE;yBAC1E,CAAC,CAAC;oBACL,CAAC;oBAED,0FAA0F;oBAC1F,2FAA2F;oBAC3F,oBAAoB;oBACpB,wFAAwF;oBACxF,4FAA4F;oBAC5F,2FAA2F;oBAC3F,sCAAsC;oBACtC,MAAM,QAAQ,GAAG,MAAM,6CAA6C,CAAC,aAAa,CAAC,CAAC;oBACpF,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,IAAI,CACpD,gBAAgB,CAAC,aAAa,EAC9B,QAAQ,EACR,EAAE,GAAG,EAAE,cAAc,EAAE,EACvB,KAAK,CAAC,cAAc,CACrB,CAAC;oBACF,IAAI,CAAC,YAAY,EAAE,CAAC;wBAClB,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE;4BACzE,sBAAsB,EAAE,2BAA2B,CAAC,SAAS;4BAC7D,OAAO,EAAE,EAAE,MAAM,EAAE,qDAAqD,EAAE;yBAC3E,CAAC,CAAC;oBACL,CAAC;oBAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,gBAAgB,GAAI,YAA6D,CAAC,8BAA8B,KAAK,IAAI,CAAC;oBAEhI,uFAAuF;oBACvF,uFAAuF;oBACvF,0FAA0F;oBAC1F,0FAA0F;oBAC1F,MAAM,UAAU,GAAG,gBAAgB;wBACjC,CAAC,CAAC,MAAM,mBAAmB,CAAC;4BAC1B,cAAc;4BACd,aAAa;4BACb,eAAe,EAAE,kCAAkC,EAAE;4BACrD,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;4BAChD,YAAY,EAAE,KAAK,CAAC,YAAY;yBACjC,CAAC;wBACF,CAAC,CAAC,KAAK,CAAC;oBAEV,MAAM,kBAAkB,GAAG,CAAC,gBAAgB;wBAC1C,CAAC,CAAC,qCAAqC,CAAC,4BAA4B;wBACpE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qCAAqC,CAAC,qBAAqB,CAAC,CAAC;oBAE3F,MAAM,MAAM,GAAG,kBAAkB;wBAC/B,CAAC,CAAC,yBAAyB,CAAC,MAAM;wBAClC,CAAC,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;oBAE/C,OAAO;wBACL,cAAc;wBACd,aAAa,EAAE,OAAO,CAAC,aAAa;wBACpC,cAAc;wBACd,MAAM;wBACN,SAAS,EAAE,gCAAgC,CAAC,OAAO,CAAC,wBAAwB,EAAE,GAAG,CAAC;wBAClF,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACvE,CAAC;gBACJ,CAAC;gBACD,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAC3F,qBAAqB,CAAC;wBACpB,SAAS;wBACT,KAAK;wBACL,UAAU,EAAE,sCAAsC,CAAC,SAAS;wBAC5D,KAAK,EAAE,CAAC,YAAY,IAAI,EAAE,CAA4B;qBACvD,CAAC,CAAC;oBACH,OAAO,YAAY,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;;;;;;;;;OASG;IACH,MAAM,mBAAmB,GAAG;IAC1B,kGAAkG;IAClG,iGAAiG;IACjG,8DAA8D;IAC9D,mBAAoD,EACpD,OAMC,EAC2C,EAAE,CAC9C,CAAC,yBAA0D,EAAE,SAAoB,EAAE,EAAE;QACrF,MAAM,YAAY,GAAG,SAAS,CAAC;QAC/B,OAAO,yCAAyC,CAAC;YAC/C,aAAa,EAAE;gBACb,kBAAkB,EAAE,gBAAgB,CAAC,sBAAsB;gBAC3D,mBAAmB;gBACnB,WAAW,EAAE,4BAA4B,CAAC,QAAQ;gBAClD,kBAAkB,EAAE,IAAI;aACzB;YACD,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,mBAAmB,EAAE,OAAO,CAAC,cAAc;gBACzC,CAAC,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,CAAC;gBAChE,CAAC,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC;YAChC,iBAAiB,EAAE,IAAI;YACvB,+FAA+F;YAC/F,0FAA0F;YAC1F,gGAAgG;YAChG,iCAAiC;YACjC,uBAAuB,EAAE,EAAE;YAC3B,QAAQ,EAAE;gBACR,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAClF,MAAM,aAAa,GAAG,KAAK,CAAC,aAAgE,CAAC;oBAC7F,MAAM,aAAa,GAAG,aAAa,EAAE,MAAM,CAAC;oBAE5C,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;wBACrE,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,EAAE;4BACxE,sBAAsB,EAAE,2BAA2B,CAAC,QAAQ;4BAC5D,OAAO,EAAE;gCACP,MAAM,EAAE,oEAAoE;gCAC5E,aAAa,EAAE,aAAa,IAAI,IAAI;gCACpC,aAAa,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;gCACzC,mBAAmB;6BACpB;yBACF,CAAC,CAAC;oBACL,CAAC;oBAED,MAAM,cAAc,GAAI,KAAqC,EAAE,cAAc,CAAC;oBAC9E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;oBAEvB,OAAO;wBACL,MAAM,EAAE,OAAO,CAAC,UAAU;wBAC1B,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC7C,uFAAuF;wBACvF,wFAAwF;wBACxF,mDAAmD;wBACnD,GAAG,CAAC,OAAO,CAAC,cAAc;4BACxB,CAAC,CAAC,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE;4BAC9E,CAAC,CAAC,EAAE,CAAC;qBACR,CAAC;gBACJ,CAAC;gBACD,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAC1F,qBAAqB,CAAC;wBACpB,SAAS,EAAE,YAAa;wBACxB,KAAK;wBACL,UAAU,EAAE,OAAO,CAAC,eAAe;wBACnC,KAAK,EAAE,CAAC,YAAY,IAAI,EAAE,CAA4B;wBACtD,yFAAyF;wBACzF,yFAAyF;wBACzF,YAAY;wBACZ,eAAe,EAAE,gBAAgB,CAAC,YAAY,EAAE,MAAM;qBACvD,CAAC,CAAC;oBACH,OAAO,YAAY,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;QACL,oBAAoB;QACpB,mBAAmB,CAAC,+BAA+B,CAAC,OAAO,EAAE;YAC3D,UAAU,EAAE,oCAAoC;YAChD,eAAe,EAAE,sCAAsC,CAAC,QAAQ;YAChE,UAAU,EAAE,yBAAyB,CAAC,MAAM;YAC5C,aAAa,EAAE,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;YAC3D,cAAc,EAAE,IAAI;SACrB,CAAC;QACF,mBAAmB,CAAC,+BAA+B,CAAC,IAAI,EAAE;YACxD,UAAU,EAAE,iCAAiC;YAC7C,eAAe,EAAE,sCAAsC,CAAC,MAAM;YAC9D,UAAU,EAAE,yBAAyB,CAAC,MAAM;YAC5C,aAAa,EAAE,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;YAC3D,cAAc,EAAE,KAAK;SACtB,CAAC;QACF,mBAAmB,CAAC,+BAA+B,CAAC,MAAM,EAAE;YAC1D,UAAU,EAAE,mCAAmC;YAC/C,eAAe,EAAE,sCAAsC,CAAC,OAAO;YAC/D,UAAU,EAAE,yBAAyB,CAAC,OAAO;YAC7C,yFAAyF;YACzF,2DAA2D;YAC3D,aAAa,EAAE,wCAAwC;YACvD,cAAc,EAAE,KAAK;SACtB,CAAC;KACH,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Platform access grants — the four lifecycle transitions.\n *\n * The whole resource exists to turn a STANDING platform privilege into a requested, justified,\n * tenant-scoped, self-expiring one (rungs 4–5 of the ladder in\n * `.claude/rules/administrative-continuity-floors.md`). These implementations are where the fields\n * that carry that guarantee — `operatorUserId`, `status`, `expiresAt`, `approvedByUserId` — are\n * AUTHORED BY THE SERVER. Every one of them is `.excludeFromCreate()` / `.excludeFromUpdate()`, so a\n * client cannot supply them; the strict request DTO drops them and these prefixes put them back.\n *\n * That is also why the resource exposes no generic CREATE or UPDATE door: a second write path would\n * be a second way to mint an elevation, which is the one thing this resource exists to prevent.\n */\n\nimport type { Container } from 'inversify';\nimport {\n CoreResourceOperation,\n CoreResourceType,\n ErrorCustomMessageReference,\n ErrorType,\n PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES,\n PlatformAccessGrantAutoApprovalReason,\n PlatformAccessGrantLifecycleTransition,\n PlatformAccessGrantStatus,\n PlatformAccessGrants_Operations,\n ResourceOperationVariantType,\n resolvePlatformAccessGrantExpiry,\n} from '@wildo-ai/saas-models';\nimport type { Organization, PlatformAccessGrant } from '@wildo-ai/saas-models';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { registerTransactionPostCommitEffect } from '~wildo-backend-lib/databases/models/transaction.shared.schemas';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport type { AuditLogsBackendService } from '~wildo-backend-lib/compliance/audit-trails/services/audit-logs.backend.service';\nimport { createResourceCustomServiceImplementation } from '~wildo-backend-lib/base-classes/services/services/resource-operation-custom-implementation.factory.backend';\nimport type { ResourceCustomServiceImplementationFactory } from '~wildo-backend-lib/base-classes/services/services/resource-operation-custom-implementation.factory.backend';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport type { AuthExecutionContextFactoryBackendService } from '~wildo-backend-lib/security/authentications/services/auth-execution-context-factory.backend.service';\nimport type { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport {\n createOrganizationOwnerConferralResolver,\n createOrganizationOwnerFloorPopulationContext,\n measureUsableOrganizationOwners,\n} from '~wildo-backend-lib/security/authorizations/organization-owner-floor.backend.utils';\n\n/**\n * Can this tenant currently supply a human who could approve?\n *\n * Deliberately delegates to {@link measureUsableOrganizationOwners} — the OWNER FLOOR's own\n * measurement — rather than asking a similar-looking question here. The floor already answers\n * \"does this tenant have an administratively usable owner?\" across three axes (the role confers\n * ownership through the live table, the membership is ACTIVE, and the linked user is ACTIVE), and a\n * second implementation would drift from it the first time any axis changed.\n *\n * Drift here would be quiet and bad in both directions: over-counting makes a stranded tenant wait\n * forever for an approver who cannot act, and under-counting auto-approves operator access into a\n * tenant that could have consented.\n */\nasync function tenantHasAnApprover(params: {\n organizationId: string;\n authEcFactory: AuthExecutionContextFactoryBackendService;\n conferringRoles: readonly string[];\n repositoriesRegistry: RepositoriesRegistryHandlerBackendService;\n errorBuilder: ErrorBuilderBackendService;\n}): Promise<boolean> {\n const executionContext = await createOrganizationOwnerFloorPopulationContext(params.authEcFactory);\n const usableOwners = await measureUsableOrganizationOwners({\n organizationId: params.organizationId,\n executionContext,\n repositoriesRegistry: params.repositoriesRegistry,\n errorBuilder: params.errorBuilder,\n conferringRoles: params.conferringRoles,\n operationIdentifier: PlatformAccessGrants_Operations.REQUEST_ACCESS,\n });\n return usableOwners.length > 0;\n}\n\n/**\n * Record one grant transition, AFTER the write is durable.\n *\n * Deferred to commit rather than emitted from the postfix hook directly. A postfix runs INSIDE the\n * declared transaction, so an audit row written there survives a rollback — the trail would then\n * claim an elevation that does not exist, which is worse than no trail at all.\n *\n * Best-effort in every other respect: feature-detected against the audit service (adding a `log*`\n * method breaks partially-mocked doubles, and the absent property throws synchronously before any\n * `.catch()` can help) and never allowed to fail the transition it observes.\n */\nfunction recordGrantTransition(params: {\n container: Container;\n utils: { serviceOptions?: { transaction?: unknown }; logger?: { error?: (message: string, meta: unknown) => void } };\n transition: PlatformAccessGrantLifecycleTransition;\n grant: Record<string, unknown>;\n decidedByUserId?: string;\n}): void {\n const emit = async (): Promise<void> => {\n try {\n if (!params.container.isBound?.(SAAS_SERVICE_TYPES.AuditLogsService)) return;\n const auditLogsService = params.container.get<AuditLogsBackendService>(SAAS_SERVICE_TYPES.AuditLogsService);\n if (typeof auditLogsService?.logPlatformAccessGrantLifecycle !== 'function') return;\n\n const grant = params.grant;\n await auditLogsService.logPlatformAccessGrantLifecycle({\n transition: params.transition,\n grantId: String(grant._id ?? ''),\n targetOrganizationId: String(grant.organizationId ?? ''),\n operatorUserId: String(grant.operatorUserId ?? ''),\n justification: grant.justification as string | undefined,\n resultingStatus: grant.status as PlatformAccessGrantStatus,\n expiresAt: grant.expiresAt as Date | undefined,\n autoApprovalReason: grant.autoApprovalReason as PlatformAccessGrantAutoApprovalReason | undefined,\n decidedByUserId: params.decidedByUserId,\n decisionReason: grant.decisionReason as string | undefined,\n });\n } catch (error) {\n params.utils.logger?.error?.('Failed to record a platform-access-grant lifecycle event', {\n reason: 'platform_access_grant_lifecycle_audit_emission_failed',\n transition: params.transition,\n error: describeCaughtError(error),\n });\n }\n };\n\n const transaction = params.utils.serviceOptions?.transaction;\n if (transaction) {\n registerTransactionPostCommitEffect(transaction as never, {\n key: `platform-access-grant:${params.transition}:${String(params.grant._id ?? '')}`,\n execute: emit,\n });\n } else {\n void emit();\n }\n}\n\nexport function createPlatformAccessGrantFactories(): ResourceCustomServiceImplementationFactory[] {\n /**\n * REQUEST — the bootstrap verb, and the only one reachable without an existing grant.\n *\n * Requesting is not accessing: this writes one row and touches nothing else in the tenant, which is\n * what makes the exemption safe when the admission predicate starts requiring a grant (Step 4).\n */\n const requestAccessFactory = (\n _resourcesRegistryService: ResourcesRegistryBackendService,\n container: Container,\n ) => {\n const authEcFactory = container.get<AuthExecutionContextFactoryBackendService>(SAAS_SERVICE_TYPES.AuthExecutionContextFactory);\n const organizationOwnerConferralResolver = createOrganizationOwnerConferralResolver(container);\n return createResourceCustomServiceImplementation({\n operationPath: {\n resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,\n operationIdentifier: PlatformAccessGrants_Operations.REQUEST_ACCESS,\n variantType: ResourceOperationVariantType.API_CALL,\n isOperationDefault: true,\n },\n debugLabel: 'platform-access-grants.request-access.api',\n // Every one of these is `.excludeFromCreate()`, so the strict request DTO drops whatever a\n // caller sent and the prefix's value is authoritative. Declaring them makes that explicit\n // rather than inferred — the inference has a hole for callers that reach the service tier with\n // the key already present (MCP `callTool` forwards arguments unparsed), and on THIS resource a\n // caller choosing their own `status` or `expiresAt` would defeat the entire mechanism.\n authoritativeFields: ['operatorUserId', 'status', 'expiresAt', 'autoApprovalReason', 'approvedAt'],\n transactionalCore: true,\n transactionParticipants: { targetOrganization: CoreResourceType.ORGANIZATIONS },\n handlers: {\n prefixCoreOperations: async (_id, input, executionContext, _operationPath, utils) => {\n const payload = input as { justification?: string; requestedDurationMinutes?: number };\n // The primary-scope URL is the one target authority. The execution-context creator has\n // already validated the mandatory `organizationId` path parameter and placed it here;\n // reading a second body value would make callers author the security boundary twice and\n // would preserve an unnecessary path/body mismatch state.\n const organizationId = executionContext.organizationId;\n const operatorUserId = executionContext.initiatorIds?.userId;\n\n if (!organizationId || !operatorUserId) {\n throw utils.errorBuilder.buildError(ErrorType.VALIDATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.VALIDATION,\n context: { reason: 'platform_access_grant_requires_target_and_operator' },\n });\n }\n\n // Read the tenant's posture in the same unit of work as the write. Reading it outside the\n // transaction would let a tenant that just switched Lockbox ON have a request slip through\n // as auto-approved.\n // Reuses the floor's own population context rather than inventing an organizations-read\n // helper: it is already a system context authorized for the tenant-scoped reads this needs,\n // and adding a second system-context factory for one call site is how two subtly different\n // privileged contexts start to exist.\n const systemEc = await createOrganizationOwnerFloorPopulationContext(authEcFactory);\n const organization = await utils.servicesRegistry.read<Organization>(\n CoreResourceType.ORGANIZATIONS,\n systemEc,\n { _id: organizationId },\n utils.serviceOptions,\n );\n if (!organization) {\n throw utils.errorBuilder.buildError(ErrorType.NOT_FOUND, executionContext, {\n customMessageReference: ErrorCustomMessageReference.NOT_FOUND,\n context: { reason: 'platform_access_grant_target_organization_not_found' },\n });\n }\n\n const now = new Date();\n const approvalRequired = (organization as { platformAccessApprovalRequired?: boolean }).platformAccessApprovalRequired === true;\n\n // The circularity guard. A tenant with no administratively usable owner cannot approve\n // anything, so requiring its approval would make its own repair impossible — the exact\n // deadlock `organizationMembers.grantOwnership` exists to break. Measured, never assumed,\n // and never manufacturable by the operator: stranding a tenant is what the floors refuse.\n const canApprove = approvalRequired\n ? await tenantHasAnApprover({\n organizationId,\n authEcFactory,\n conferringRoles: organizationOwnerConferralResolver(),\n repositoriesRegistry: utils.repositoriesRegistry,\n errorBuilder: utils.errorBuilder,\n })\n : false;\n\n const autoApprovalReason = !approvalRequired\n ? PlatformAccessGrantAutoApprovalReason.TENANT_APPROVAL_NOT_REQUIRED\n : (canApprove ? undefined : PlatformAccessGrantAutoApprovalReason.TENANT_CANNOT_APPROVE);\n\n const status = autoApprovalReason\n ? PlatformAccessGrantStatus.ACTIVE\n : PlatformAccessGrantStatus.PENDING_APPROVAL;\n\n return {\n organizationId,\n justification: payload.justification,\n operatorUserId,\n status,\n expiresAt: resolvePlatformAccessGrantExpiry(payload.requestedDurationMinutes, now),\n ...(autoApprovalReason ? { autoApprovalReason, approvedAt: now } : {}),\n };\n },\n postfixCoreOperations: async (_id, createdGrant, _executionContext, _operationPath, utils) => {\n recordGrantTransition({\n container,\n utils,\n transition: PlatformAccessGrantLifecycleTransition.REQUESTED,\n grant: (createdGrant ?? {}) as Record<string, unknown>,\n });\n return createdGrant;\n },\n },\n });\n };\n\n /**\n * The three decision verbs share a shape: refuse unless the current status permits the transition,\n * then write exactly the fields that transition owns.\n *\n * `enabledCondition` on the operation config already gates each verb, but that guard is evaluated\n * against the row the framework fetched and is a UI-and-dispatch concern. Re-checking here is the\n * fail-closed half: a custom implementation is addressed by an exact operation path and inherits\n * nothing, so a future variant added without an `enabledCondition` would otherwise transition a\n * terminal grant silently.\n */\n const makeDecisionFactory = (\n // The whole enum rather than a three-member union: `ResourceConfiguration_OperationPath` does not\n // accept a union of enum members, and narrowing it here would buy nothing — the three call sites\n // below are the only ones and each names its verb explicitly.\n operationIdentifier: PlatformAccessGrants_Operations,\n options: {\n debugLabel: string;\n nextStatus: PlatformAccessGrantStatus;\n permittedFrom: readonly PlatformAccessGrantStatus[];\n stampsApprover: boolean;\n auditTransition: PlatformAccessGrantLifecycleTransition;\n },\n ): ResourceCustomServiceImplementationFactory =>\n (_resourcesRegistryService: ResourcesRegistryBackendService, container: Container) => {\n const containerRef = container;\n return createResourceCustomServiceImplementation({\n operationPath: {\n resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,\n operationIdentifier,\n variantType: ResourceOperationVariantType.API_CALL,\n isOperationDefault: true,\n },\n debugLabel: options.debugLabel,\n authoritativeFields: options.stampsApprover\n ? ['status', 'approvedByUserId', 'approvedAt', 'decisionReason']\n : ['status', 'decisionReason'],\n transactionalCore: true,\n // No additional participants: a decision writes only the grant row itself, which the operation\n // resource contributes automatically. Declaring the set explicitly (even as empty) is the\n // authoring contract — startup proves adapter compatibility for what is declared, and it cannot\n // detect an omitted participant.\n transactionParticipants: {},\n handlers: {\n prefixCoreOperations: async (_id, input, executionContext, _operationPath, utils) => {\n const currentObject = utils.currentObject as Pick<PlatformAccessGrant, 'status'> | undefined;\n const currentStatus = currentObject?.status;\n\n if (!currentStatus || !options.permittedFrom.includes(currentStatus)) {\n throw utils.errorBuilder.buildError(ErrorType.CONFLICT, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFLICT,\n context: {\n reason: 'platform_access_grant_transition_not_permitted_from_current_status',\n currentStatus: currentStatus ?? null,\n permittedFrom: [...options.permittedFrom],\n operationIdentifier,\n },\n });\n }\n\n const decisionReason = (input as { decisionReason?: string })?.decisionReason;\n const now = new Date();\n\n return {\n status: options.nextStatus,\n ...(decisionReason ? { decisionReason } : {}),\n // Only an APPROVAL names a human approver. A revocation or a denial is a decision too,\n // but recording either in `approvedByUserId` would corrupt the one field an audit reads\n // to answer \"did somebody in the tenant say yes?\".\n ...(options.stampsApprover\n ? { approvedByUserId: executionContext.initiatorIds?.userId, approvedAt: now }\n : {}),\n };\n },\n postfixCoreOperations: async (_id, updatedGrant, executionContext, _operationPath, utils) => {\n recordGrantTransition({\n container: containerRef!,\n utils,\n transition: options.auditTransition,\n grant: (updatedGrant ?? {}) as Record<string, unknown>,\n // The tenant administrator who acted — distinct from the grant's `operatorUserId`, which\n // stays the operator who asked. Conflating them would make an audit unable to answer who\n // said yes.\n decidedByUserId: executionContext.initiatorIds?.userId,\n });\n return updatedGrant;\n },\n },\n });\n };\n\n return [\n requestAccessFactory,\n makeDecisionFactory(PlatformAccessGrants_Operations.APPROVE, {\n debugLabel: 'platform-access-grants.approve.api',\n auditTransition: PlatformAccessGrantLifecycleTransition.APPROVED,\n nextStatus: PlatformAccessGrantStatus.ACTIVE,\n permittedFrom: [PlatformAccessGrantStatus.PENDING_APPROVAL],\n stampsApprover: true,\n }),\n makeDecisionFactory(PlatformAccessGrants_Operations.DENY, {\n debugLabel: 'platform-access-grants.deny.api',\n auditTransition: PlatformAccessGrantLifecycleTransition.DENIED,\n nextStatus: PlatformAccessGrantStatus.DENIED,\n permittedFrom: [PlatformAccessGrantStatus.PENDING_APPROVAL],\n stampsApprover: false,\n }),\n makeDecisionFactory(PlatformAccessGrants_Operations.REVOKE, {\n debugLabel: 'platform-access-grants.revoke.api',\n auditTransition: PlatformAccessGrantLifecycleTransition.REVOKED,\n nextStatus: PlatformAccessGrantStatus.REVOKED,\n // Both a pending request and a live elevation can be withdrawn; a terminal one cannot be\n // re-terminated, which would rewrite the decision history.\n permittedFrom: PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES,\n stampsApprover: false,\n }),\n ];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"platform-access-grant-custom-implementation.backend.service.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/platform-access-grant-custom-implementation.backend.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAEL,gBAAgB,EAChB,2BAA2B,EAC3B,SAAS,EACT,wCAAwC,EACxC,qCAAqC,EACrC,sCAAsC,EACtC,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AACpF,OAAO,EAAE,mCAAmC,EAAE,MAAM,gEAAgE,CAAC;AACrH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8EAA8E,CAAC;AACnH,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,GAE3B,MAAM,gFAAgF,CAAC;AAExF,OAAO,EAAE,yCAAyC,EAAE,MAAM,4GAA4G,CAAC;AAMvK,OAAO,EACL,wCAAwC,EACxC,6CAA6C,EAC7C,+BAA+B,GAChC,MAAM,mFAAmF,CAAC;AAE3F;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,mBAAmB,CAAC,MAMlC;IACC,MAAM,gBAAgB,GAAG,MAAM,6CAA6C,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACnG,MAAM,YAAY,GAAG,MAAM,+BAA+B,CAAC;QACzD,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB;QAChB,oBAAoB,EAAE,MAAM,CAAC,oBAAoB;QACjD,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,mBAAmB,EAAE,+BAA+B,CAAC,cAAc;KACpE,CAAC,CAAC;IACH,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAS,qBAAqB,CAAC,MAM9B;IACC;;;;;;OAMG;IACH,MAAM,qBAAqB,GAAG,GAAoD,EAAE;QAClF,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,cAAc,CAAC;gBAAE,OAAO,SAAS,CAAC;YACrF,OAAO,MAAM,CAAC,SAAS,CAAC,GAAG,CAAsC,kBAAkB,CAAC,cAAc,CAAC,CAAC;QACtG,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,UAAU,GAAG,CAAC,MAAkC,EAAE,KAAe,EAAQ,EAAE,CAC/E,0BAA0B,CAAC;QACzB,WAAW,EAAE,oBAAoB,CAAC,+BAA+B;QACjE,MAAM;QACN,cAAc,EAAE,qBAAqB,EAAE;QACvC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;QAC3B,KAAK;QACL,8FAA8F;QAC9F,2EAA2E;QAC3E,OAAO,EAAE;YACP,kBAAkB,EAAE,MAAM,CAAC,UAAU;YACrC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;YAC/C,4BAA4B,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;SACxE;KACF,CAAC,CAAC;IAEL,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;QACrC,IAAI,CAAC;YACH,+FAA+F;YAC/F,6FAA6F;YAC7F,sDAAsD;YACtD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACrE,UAAU,CAAC,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YACD,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAA0B,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;YAC5G,IAAI,OAAO,gBAAgB,EAAE,+BAA+B,KAAK,UAAU,EAAE,CAAC;gBAC5E,UAAU,CAAC,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC3B,MAAM,gBAAgB,CAAC,+BAA+B,CAAC;gBACrD,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC;gBAChC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;gBACxD,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;gBAClD,aAAa,EAAE,KAAK,CAAC,aAAmC;gBACxD,eAAe,EAAE,KAAK,CAAC,MAAmC;gBAC1D,SAAS,EAAE,KAAK,CAAC,SAA6B;gBAC9C,kBAAkB,EAAE,KAAK,CAAC,kBAAuE;gBACjG,eAAe,EAAE,MAAM,CAAC,eAAe;gBACvC,cAAc,EAAE,KAAK,CAAC,cAAoC;aAC3D,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,0DAA0D,EAAE;gBACvF,MAAM,EAAE,uDAAuD;gBAC/D,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC;aAClC,CAAC,CAAC;YACH,2FAA2F;YAC3F,0FAA0F;YAC1F,0FAA0F;YAC1F,iFAAiF;YACjF,UAAU,CAAC,0BAA0B,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC;IAC7D,IAAI,WAAW,EAAE,CAAC;QAChB,mCAAmC,CAAC,WAAoB,EAAE;YACxD,GAAG,EAAE,yBAAyB,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;YACnF,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kCAAkC;IAChD;;;;;OAKG;IACH,MAAM,oBAAoB,GAAG,CAC3B,yBAA0D,EAC1D,SAAoB,EACpB,EAAE;QACF,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAA4C,kBAAkB,CAAC,2BAA2B,CAAC,CAAC;QAC/H,MAAM,kCAAkC,GAAG,wCAAwC,CAAC,SAAS,CAAC,CAAC;QAC/F,OAAO,yCAAyC,CAAC;YAC/C,aAAa,EAAE;gBACb,kBAAkB,EAAE,gBAAgB,CAAC,sBAAsB;gBAC3D,mBAAmB,EAAE,+BAA+B,CAAC,cAAc;gBACnE,WAAW,EAAE,4BAA4B,CAAC,QAAQ;gBAClD,kBAAkB,EAAE,IAAI;aACzB;YACD,UAAU,EAAE,2CAA2C;YACvD,2FAA2F;YAC3F,0FAA0F;YAC1F,+FAA+F;YAC/F,+FAA+F;YAC/F,uFAAuF;YACvF,mBAAmB,EAAE,CAAC,gBAAgB,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,YAAY,CAAC;YAClG,iBAAiB,EAAE,IAAI;YACvB,uBAAuB,EAAE,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,aAAa,EAAE;YAC/E,QAAQ,EAAE;gBACR,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAClF,MAAM,OAAO,GAAG,KAAsE,CAAC;oBACvF,uFAAuF;oBACvF,sFAAsF;oBACtF,wFAAwF;oBACxF,0DAA0D;oBAC1D,MAAM,cAAc,GAAG,gBAAgB,CAAC,cAAc,CAAC;oBACvD,MAAM,cAAc,GAAG,gBAAgB,CAAC,YAAY,EAAE,MAAM,CAAC;oBAE7D,IAAI,CAAC,cAAc,IAAI,CAAC,cAAc,EAAE,CAAC;wBACvC,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE;4BAC1E,sBAAsB,EAAE,2BAA2B,CAAC,UAAU;4BAC9D,OAAO,EAAE,EAAE,MAAM,EAAE,oDAAoD,EAAE;yBAC1E,CAAC,CAAC;oBACL,CAAC;oBAED,0FAA0F;oBAC1F,2FAA2F;oBAC3F,oBAAoB;oBACpB,wFAAwF;oBACxF,4FAA4F;oBAC5F,2FAA2F;oBAC3F,sCAAsC;oBACtC,MAAM,QAAQ,GAAG,MAAM,6CAA6C,CAAC,aAAa,CAAC,CAAC;oBACpF,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,IAAI,CACpD,gBAAgB,CAAC,aAAa,EAC9B,QAAQ,EACR,EAAE,GAAG,EAAE,cAAc,EAAE,EACvB,KAAK,CAAC,cAAc,CACrB,CAAC;oBACF,IAAI,CAAC,YAAY,EAAE,CAAC;wBAClB,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE;4BACzE,sBAAsB,EAAE,2BAA2B,CAAC,SAAS;4BAC7D,OAAO,EAAE,EAAE,MAAM,EAAE,qDAAqD,EAAE;yBAC3E,CAAC,CAAC;oBACL,CAAC;oBAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,gBAAgB,GAAI,YAA6D,CAAC,8BAA8B,KAAK,IAAI,CAAC;oBAEhI,uFAAuF;oBACvF,uFAAuF;oBACvF,0FAA0F;oBAC1F,0FAA0F;oBAC1F,MAAM,UAAU,GAAG,gBAAgB;wBACjC,CAAC,CAAC,MAAM,mBAAmB,CAAC;4BAC1B,cAAc;4BACd,aAAa;4BACb,eAAe,EAAE,kCAAkC,EAAE;4BACrD,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;4BAChD,YAAY,EAAE,KAAK,CAAC,YAAY;yBACjC,CAAC;wBACF,CAAC,CAAC,KAAK,CAAC;oBAEV,MAAM,kBAAkB,GAAG,CAAC,gBAAgB;wBAC1C,CAAC,CAAC,qCAAqC,CAAC,4BAA4B;wBACpE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qCAAqC,CAAC,qBAAqB,CAAC,CAAC;oBAE3F,MAAM,MAAM,GAAG,kBAAkB;wBAC/B,CAAC,CAAC,yBAAyB,CAAC,MAAM;wBAClC,CAAC,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;oBAE/C,OAAO;wBACL,cAAc;wBACd,aAAa,EAAE,OAAO,CAAC,aAAa;wBACpC,cAAc;wBACd,MAAM;wBACN,SAAS,EAAE,gCAAgC,CAAC,OAAO,CAAC,wBAAwB,EAAE,GAAG,CAAC;wBAClF,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACvE,CAAC;gBACJ,CAAC;gBACD,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAC3F,qBAAqB,CAAC;wBACpB,SAAS;wBACT,KAAK;wBACL,UAAU,EAAE,sCAAsC,CAAC,SAAS;wBAC5D,KAAK,EAAE,CAAC,YAAY,IAAI,EAAE,CAA4B;qBACvD,CAAC,CAAC;oBACH,OAAO,YAAY,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;;;;;;;;;OASG;IACH,MAAM,mBAAmB,GAAG;IAC1B,kGAAkG;IAClG,iGAAiG;IACjG,8DAA8D;IAC9D,mBAAoD,EACpD,OAaC,EAC2C,EAAE,CAC9C,CAAC,yBAA0D,EAAE,SAAoB,EAAE,EAAE;QACrF,MAAM,YAAY,GAAG,SAAS,CAAC;QAC/B,OAAO,yCAAyC,CAAC;YAC/C,aAAa,EAAE;gBACb,kBAAkB,EAAE,gBAAgB,CAAC,sBAAsB;gBAC3D,mBAAmB;gBACnB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,4BAA4B,CAAC,QAAQ;gBACzE,kBAAkB,EAAE,IAAI;aACzB;YACD,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,mBAAmB,EAAE,OAAO,CAAC,cAAc;gBACzC,CAAC,CAAC,CAAC,QAAQ,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,CAAC;gBAChE,CAAC,CAAC,CAAC,QAAQ,EAAE,gBAAgB,CAAC;YAChC,iBAAiB,EAAE,IAAI;YACvB,+FAA+F;YAC/F,0FAA0F;YAC1F,gGAAgG;YAChG,iCAAiC;YACjC,uBAAuB,EAAE,EAAE;YAC3B,QAAQ,EAAE;gBACR,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAClF,MAAM,aAAa,GAAG,KAAK,CAAC,aAAgE,CAAC;oBAC7F,MAAM,aAAa,GAAG,aAAa,EAAE,MAAM,CAAC;oBAE5C,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;wBACrE,MAAM,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,EAAE;4BACxE,sBAAsB,EAAE,2BAA2B,CAAC,QAAQ;4BAC5D,OAAO,EAAE;gCACP,MAAM,EAAE,oEAAoE;gCAC5E,aAAa,EAAE,aAAa,IAAI,IAAI;gCACpC,aAAa,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;gCACzC,mBAAmB;6BACpB;yBACF,CAAC,CAAC;oBACL,CAAC;oBAED,MAAM,cAAc,GAAI,KAAqC,EAAE,cAAc,CAAC;oBAC9E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;oBAEvB,OAAO;wBACL,MAAM,EAAE,OAAO,CAAC,UAAU;wBAC1B,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBAC7C,uFAAuF;wBACvF,wFAAwF;wBACxF,mDAAmD;wBACnD,GAAG,CAAC,OAAO,CAAC,cAAc;4BACxB,CAAC,CAAC,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE;4BAC9E,CAAC,CAAC,EAAE,CAAC;qBACR,CAAC;gBACJ,CAAC;gBACD,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE;oBAC1F,qBAAqB,CAAC;wBACpB,SAAS,EAAE,YAAa;wBACxB,KAAK;wBACL,UAAU,EAAE,OAAO,CAAC,eAAe;wBACnC,KAAK,EAAE,CAAC,YAAY,IAAI,EAAE,CAA4B;wBACtD,yFAAyF;wBACzF,yFAAyF;wBACzF,YAAY;wBACZ,eAAe,EAAE,gBAAgB,CAAC,YAAY,EAAE,MAAM;qBACvD,CAAC,CAAC;oBACH,OAAO,YAAY,CAAC;gBACtB,CAAC;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;QACL,oBAAoB;QACpB,mBAAmB,CAAC,+BAA+B,CAAC,OAAO,EAAE;YAC3D,UAAU,EAAE,oCAAoC;YAChD,eAAe,EAAE,sCAAsC,CAAC,QAAQ;YAChE,UAAU,EAAE,yBAAyB,CAAC,MAAM;YAC5C,aAAa,EAAE,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;YAC3D,cAAc,EAAE,IAAI;SACrB,CAAC;QACF,mBAAmB,CAAC,+BAA+B,CAAC,IAAI,EAAE;YACxD,UAAU,EAAE,iCAAiC;YAC7C,eAAe,EAAE,sCAAsC,CAAC,MAAM;YAC9D,UAAU,EAAE,yBAAyB,CAAC,MAAM;YAC5C,aAAa,EAAE,CAAC,yBAAyB,CAAC,gBAAgB,CAAC;YAC3D,cAAc,EAAE,KAAK;SACtB,CAAC;QACF,mBAAmB,CAAC,+BAA+B,CAAC,MAAM,EAAE;YAC1D,UAAU,EAAE,mCAAmC;YAC/C,eAAe,EAAE,sCAAsC,CAAC,OAAO;YAC/D,UAAU,EAAE,yBAAyB,CAAC,OAAO;YAC7C,yFAAyF;YACzF,2DAA2D;YAC3D,aAAa,EAAE,wCAAwC;YACvD,cAAc,EAAE,KAAK;SACtB,CAAC;QACF;;;;;;;;WAQG;QACH,mBAAmB,CAAC,+BAA+B,CAAC,MAAM,EAAE;YAC1D,UAAU,EAAE,wCAAwC;YACpD,eAAe,EAAE,sCAAsC,CAAC,OAAO;YAC/D,UAAU,EAAE,yBAAyB,CAAC,OAAO;YAC7C,aAAa,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC;YACjD,cAAc,EAAE,KAAK;YACrB,WAAW,EAAE,4BAA4B,CAAC,aAAa;SACxD,CAAC;KACH,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Platform access grants — the four lifecycle transitions.\n *\n * The whole resource exists to turn a STANDING platform privilege into a requested, justified,\n * tenant-scoped, self-expiring one (rungs 4–5 of the ladder in\n * `.claude/rules/administrative-continuity-floors.md`). These implementations are where the fields\n * that carry that guarantee — `operatorUserId`, `status`, `expiresAt`, `approvedByUserId` — are\n * AUTHORED BY THE SERVER. Every one of them is `.excludeFromCreate()` / `.excludeFromUpdate()`, so a\n * client cannot supply them; the strict request DTO drops them and these prefixes put them back.\n *\n * That is also why the resource exposes no generic CREATE or UPDATE door: a second write path would\n * be a second way to mint an elevation, which is the one thing this resource exists to prevent.\n */\n\nimport type { Container } from 'inversify';\nimport {\n CoreResourceOperation,\n CoreResourceType,\n ErrorCustomMessageReference,\n ErrorType,\n PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES,\n PlatformAccessGrantAutoApprovalReason,\n PlatformAccessGrantLifecycleTransition,\n PlatformAccessGrantStatus,\n PlatformAccessGrants_Operations,\n ResourceOperationVariantType,\n resolvePlatformAccessGrantExpiry,\n} from '@wildo-ai/saas-models';\nimport type { Organization, PlatformAccessGrant } from '@wildo-ai/saas-models';\n\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\nimport { registerTransactionPostCommitEffect } from '~wildo-backend-lib/databases/models/transaction.shared.schemas';\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\nimport {\n AuditObservationKind,\n AuditObservationLossReason,\n recordAuditObservationLoss,\n type AuditObservationLossMetricsRecorder,\n} from '~wildo-backend-lib/monitoring/observability/audit-observation-emission.backend';\nimport type { AuditLogsBackendService } from '~wildo-backend-lib/compliance/audit-trails/services/audit-logs.backend.service';\nimport { createResourceCustomServiceImplementation } from '~wildo-backend-lib/base-classes/services/services/resource-operation-custom-implementation.factory.backend';\nimport type { ResourceCustomServiceImplementationFactory } from '~wildo-backend-lib/base-classes/services/services/resource-operation-custom-implementation.factory.backend';\nimport type { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';\nimport type { AuthExecutionContextFactoryBackendService } from '~wildo-backend-lib/security/authentications/services/auth-execution-context-factory.backend.service';\nimport type { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport {\n createOrganizationOwnerConferralResolver,\n createOrganizationOwnerFloorPopulationContext,\n measureUsableOrganizationOwners,\n} from '~wildo-backend-lib/security/authorizations/organization-owner-floor.backend.utils';\n\n/**\n * Can this tenant currently supply a human who could approve?\n *\n * Deliberately delegates to {@link measureUsableOrganizationOwners} — the OWNER FLOOR's own\n * measurement — rather than asking a similar-looking question here. The floor already answers\n * \"does this tenant have an administratively usable owner?\" across three axes (the role confers\n * ownership through the live table, the membership is ACTIVE, and the linked user is ACTIVE), and a\n * second implementation would drift from it the first time any axis changed.\n *\n * Drift here would be quiet and bad in both directions: over-counting makes a stranded tenant wait\n * forever for an approver who cannot act, and under-counting auto-approves operator access into a\n * tenant that could have consented.\n */\nasync function tenantHasAnApprover(params: {\n organizationId: string;\n authEcFactory: AuthExecutionContextFactoryBackendService;\n conferringRoles: readonly string[];\n repositoriesRegistry: RepositoriesRegistryHandlerBackendService;\n errorBuilder: ErrorBuilderBackendService;\n}): Promise<boolean> {\n const executionContext = await createOrganizationOwnerFloorPopulationContext(params.authEcFactory);\n const usableOwners = await measureUsableOrganizationOwners({\n organizationId: params.organizationId,\n executionContext,\n repositoriesRegistry: params.repositoriesRegistry,\n errorBuilder: params.errorBuilder,\n conferringRoles: params.conferringRoles,\n operationIdentifier: PlatformAccessGrants_Operations.REQUEST_ACCESS,\n });\n return usableOwners.length > 0;\n}\n\n/**\n * Record one grant transition, AFTER the write is durable.\n *\n * Deferred to commit rather than emitted from the postfix hook directly. A postfix runs INSIDE the\n * declared transaction, so an audit row written there survives a rollback — the trail would then\n * claim an elevation that does not exist, which is worse than no trail at all.\n *\n * Best-effort in every other respect: feature-detected against the audit service (adding a `log*`\n * method breaks partially-mocked doubles, and the absent property throws synchronously before any\n * `.catch()` can help) and never allowed to fail the transition it observes.\n *\n * ## The loss is COUNTED — added 2026-09-09\n *\n * Both best-effort exits used to be quiet in the way that matters. The `catch` logged one line per\n * occurrence, which cannot answer \"has this been failing all afternoon?\"; the unbound-service and\n * absent-method exits logged nothing at all, and `audit_store_failure_total` cannot see them either\n * (it fires inside `_createAuditLog`, which those paths never reach). So a grant trail with no\n * transitions in it read identically whether no elevation was requested or the audit service had\n * been unbound since boot — and for THIS resource that is the whole evidentiary claim: an elevation\n * with no recorded request and approval is a standing privilege wearing a lifecycle's clothes.\n *\n * `recordAuditObservationLoss` now counts every exit into `audit_observation_dropped_total` and\n * emits one throttled `error` line per loss shape. It never throws, so best-effort is preserved.\n */\nfunction recordGrantTransition(params: {\n container: Container;\n utils: { serviceOptions?: { transaction?: unknown }; logger?: { error?: (message: string, meta: unknown) => void } };\n transition: PlatformAccessGrantLifecycleTransition;\n grant: Record<string, unknown>;\n decidedByUserId?: string;\n}): void {\n /**\n * The metrics recorder behind the loss counter, or `undefined` when nothing is bound.\n *\n * Wrapped: this runs on the observation path, so a container that throws while resolving must not\n * be able to fail the transition. Losing the metric channel degrades the signal to its log line,\n * which is the correct direction — an observability gap is never a reason to refuse.\n */\n const resolveMetricsService = (): AuditObservationLossMetricsRecorder | undefined => {\n try {\n if (!params.container.isBound?.(SAAS_SERVICE_TYPES.MetricsService)) return undefined;\n return params.container.get<AuditObservationLossMetricsRecorder>(SAAS_SERVICE_TYPES.MetricsService);\n } catch {\n return undefined;\n }\n };\n\n const reportLoss = (reason: AuditObservationLossReason, error?: unknown): void =>\n recordAuditObservationLoss({\n observation: AuditObservationKind.PLATFORM_ACCESS_GRANT_LIFECYCLE,\n reason,\n metricsService: resolveMetricsService(),\n logger: params.utils.logger,\n error,\n // Names WHICH transition on WHICH grant went unrecorded, so the gap can be reconstructed from\n // the grant row rather than being known only as \"a transition, somewhere\".\n context: {\n observedTransition: params.transition,\n observedGrantId: String(params.grant._id ?? ''),\n observedTargetOrganizationId: String(params.grant.organizationId ?? ''),\n },\n });\n\n const emit = async (): Promise<void> => {\n try {\n // One report for both halves of \"the audit service cannot take this\": an unbound service and a\n // bound service missing the method are the same loss to a reviewer, and splitting them would\n // add a metric label nobody could act on differently.\n if (!params.container.isBound?.(SAAS_SERVICE_TYPES.AuditLogsService)) {\n reportLoss(AuditObservationLossReason.SERVICE_UNAVAILABLE);\n return;\n }\n const auditLogsService = params.container.get<AuditLogsBackendService>(SAAS_SERVICE_TYPES.AuditLogsService);\n if (typeof auditLogsService?.logPlatformAccessGrantLifecycle !== 'function') {\n reportLoss(AuditObservationLossReason.SERVICE_UNAVAILABLE);\n return;\n }\n\n const grant = params.grant;\n await auditLogsService.logPlatformAccessGrantLifecycle({\n transition: params.transition,\n grantId: String(grant._id ?? ''),\n targetOrganizationId: String(grant.organizationId ?? ''),\n operatorUserId: String(grant.operatorUserId ?? ''),\n justification: grant.justification as string | undefined,\n resultingStatus: grant.status as PlatformAccessGrantStatus,\n expiresAt: grant.expiresAt as Date | undefined,\n autoApprovalReason: grant.autoApprovalReason as PlatformAccessGrantAutoApprovalReason | undefined,\n decidedByUserId: params.decidedByUserId,\n decisionReason: grant.decisionReason as string | undefined,\n });\n } catch (error) {\n params.utils.logger?.error?.('Failed to record a platform-access-grant lifecycle event', {\n reason: 'platform_access_grant_lifecycle_audit_emission_failed',\n transition: params.transition,\n error: describeCaughtError(error),\n });\n // The line above names ONE lost transition; this names the RATE, on the same counter every\n // other dropped security observation lands on. `EMISSION_THREW`: this path `await`s, so a\n // rejection and a synchronous throw arrive at the same `catch` and cannot be told apart —\n // claiming the more specific member would be a distinction the code cannot make.\n reportLoss(AuditObservationLossReason.EMISSION_THREW, error);\n }\n };\n\n const transaction = params.utils.serviceOptions?.transaction;\n if (transaction) {\n registerTransactionPostCommitEffect(transaction as never, {\n key: `platform-access-grant:${params.transition}:${String(params.grant._id ?? '')}`,\n execute: emit,\n });\n } else {\n void emit();\n }\n}\n\nexport function createPlatformAccessGrantFactories(): ResourceCustomServiceImplementationFactory[] {\n /**\n * REQUEST — the bootstrap verb, and the only one reachable without an existing grant.\n *\n * Requesting is not accessing: this writes one row and touches nothing else in the tenant, which is\n * what makes the exemption safe when the admission predicate starts requiring a grant (Step 4).\n */\n const requestAccessFactory = (\n _resourcesRegistryService: ResourcesRegistryBackendService,\n container: Container,\n ) => {\n const authEcFactory = container.get<AuthExecutionContextFactoryBackendService>(SAAS_SERVICE_TYPES.AuthExecutionContextFactory);\n const organizationOwnerConferralResolver = createOrganizationOwnerConferralResolver(container);\n return createResourceCustomServiceImplementation({\n operationPath: {\n resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,\n operationIdentifier: PlatformAccessGrants_Operations.REQUEST_ACCESS,\n variantType: ResourceOperationVariantType.API_CALL,\n isOperationDefault: true,\n },\n debugLabel: 'platform-access-grants.request-access.api',\n // Every one of these is `.excludeFromCreate()`, so the strict request DTO drops whatever a\n // caller sent and the prefix's value is authoritative. Declaring them makes that explicit\n // rather than inferred — the inference has a hole for callers that reach the service tier with\n // the key already present (MCP `callTool` forwards arguments unparsed), and on THIS resource a\n // caller choosing their own `status` or `expiresAt` would defeat the entire mechanism.\n authoritativeFields: ['operatorUserId', 'status', 'expiresAt', 'autoApprovalReason', 'approvedAt'],\n transactionalCore: true,\n transactionParticipants: { targetOrganization: CoreResourceType.ORGANIZATIONS },\n handlers: {\n prefixCoreOperations: async (_id, input, executionContext, _operationPath, utils) => {\n const payload = input as { justification?: string; requestedDurationMinutes?: number };\n // The primary-scope URL is the one target authority. The execution-context creator has\n // already validated the mandatory `organizationId` path parameter and placed it here;\n // reading a second body value would make callers author the security boundary twice and\n // would preserve an unnecessary path/body mismatch state.\n const organizationId = executionContext.organizationId;\n const operatorUserId = executionContext.initiatorIds?.userId;\n\n if (!organizationId || !operatorUserId) {\n throw utils.errorBuilder.buildError(ErrorType.VALIDATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.VALIDATION,\n context: { reason: 'platform_access_grant_requires_target_and_operator' },\n });\n }\n\n // Read the tenant's posture in the same unit of work as the write. Reading it outside the\n // transaction would let a tenant that just switched Lockbox ON have a request slip through\n // as auto-approved.\n // Reuses the floor's own population context rather than inventing an organizations-read\n // helper: it is already a system context authorized for the tenant-scoped reads this needs,\n // and adding a second system-context factory for one call site is how two subtly different\n // privileged contexts start to exist.\n const systemEc = await createOrganizationOwnerFloorPopulationContext(authEcFactory);\n const organization = await utils.servicesRegistry.read<Organization>(\n CoreResourceType.ORGANIZATIONS,\n systemEc,\n { _id: organizationId },\n utils.serviceOptions,\n );\n if (!organization) {\n throw utils.errorBuilder.buildError(ErrorType.NOT_FOUND, executionContext, {\n customMessageReference: ErrorCustomMessageReference.NOT_FOUND,\n context: { reason: 'platform_access_grant_target_organization_not_found' },\n });\n }\n\n const now = new Date();\n const approvalRequired = (organization as { platformAccessApprovalRequired?: boolean }).platformAccessApprovalRequired === true;\n\n // The circularity guard. A tenant with no administratively usable owner cannot approve\n // anything, so requiring its approval would make its own repair impossible — the exact\n // deadlock `organizationMembers.grantOwnership` exists to break. Measured, never assumed,\n // and never manufacturable by the operator: stranding a tenant is what the floors refuse.\n const canApprove = approvalRequired\n ? await tenantHasAnApprover({\n organizationId,\n authEcFactory,\n conferringRoles: organizationOwnerConferralResolver(),\n repositoriesRegistry: utils.repositoriesRegistry,\n errorBuilder: utils.errorBuilder,\n })\n : false;\n\n const autoApprovalReason = !approvalRequired\n ? PlatformAccessGrantAutoApprovalReason.TENANT_APPROVAL_NOT_REQUIRED\n : (canApprove ? undefined : PlatformAccessGrantAutoApprovalReason.TENANT_CANNOT_APPROVE);\n\n const status = autoApprovalReason\n ? PlatformAccessGrantStatus.ACTIVE\n : PlatformAccessGrantStatus.PENDING_APPROVAL;\n\n return {\n organizationId,\n justification: payload.justification,\n operatorUserId,\n status,\n expiresAt: resolvePlatformAccessGrantExpiry(payload.requestedDurationMinutes, now),\n ...(autoApprovalReason ? { autoApprovalReason, approvedAt: now } : {}),\n };\n },\n postfixCoreOperations: async (_id, createdGrant, _executionContext, _operationPath, utils) => {\n recordGrantTransition({\n container,\n utils,\n transition: PlatformAccessGrantLifecycleTransition.REQUESTED,\n grant: (createdGrant ?? {}) as Record<string, unknown>,\n });\n return createdGrant;\n },\n },\n });\n };\n\n /**\n * The three decision verbs share a shape: refuse unless the current status permits the transition,\n * then write exactly the fields that transition owns.\n *\n * `enabledCondition` on the operation config already gates each verb, but that guard is evaluated\n * against the row the framework fetched and is a UI-and-dispatch concern. Re-checking here is the\n * fail-closed half: a custom implementation is addressed by an exact operation path and inherits\n * nothing, so a future variant added without an `enabledCondition` would otherwise transition a\n * terminal grant silently.\n */\n const makeDecisionFactory = (\n // The whole enum rather than a three-member union: `ResourceConfiguration_OperationPath` does not\n // accept a union of enum members, and narrowing it here would buy nothing — the three call sites\n // below are the only ones and each names its verb explicitly.\n operationIdentifier: PlatformAccessGrants_Operations,\n options: {\n debugLabel: string;\n nextStatus: PlatformAccessGrantStatus;\n permittedFrom: readonly PlatformAccessGrantStatus[];\n stampsApprover: boolean;\n auditTransition: PlatformAccessGrantLifecycleTransition;\n /**\n * Defaults to API_CALL — every operator-facing decision. EXPIRE is INTERNAL_CALL, and the\n * lookup key is built from the RUNNING operation's variant type, so a mismatch here does not\n * fail loudly: the implementation is simply never found and the core UPDATE runs with no\n * transition guard and no audit row.\n */\n variantType?: ResourceOperationVariantType;\n },\n ): ResourceCustomServiceImplementationFactory =>\n (_resourcesRegistryService: ResourcesRegistryBackendService, container: Container) => {\n const containerRef = container;\n return createResourceCustomServiceImplementation({\n operationPath: {\n resourceIdentifier: CoreResourceType.PLATFORM_ACCESS_GRANTS,\n operationIdentifier,\n variantType: options.variantType ?? ResourceOperationVariantType.API_CALL,\n isOperationDefault: true,\n },\n debugLabel: options.debugLabel,\n authoritativeFields: options.stampsApprover\n ? ['status', 'approvedByUserId', 'approvedAt', 'decisionReason']\n : ['status', 'decisionReason'],\n transactionalCore: true,\n // No additional participants: a decision writes only the grant row itself, which the operation\n // resource contributes automatically. Declaring the set explicitly (even as empty) is the\n // authoring contract — startup proves adapter compatibility for what is declared, and it cannot\n // detect an omitted participant.\n transactionParticipants: {},\n handlers: {\n prefixCoreOperations: async (_id, input, executionContext, _operationPath, utils) => {\n const currentObject = utils.currentObject as Pick<PlatformAccessGrant, 'status'> | undefined;\n const currentStatus = currentObject?.status;\n\n if (!currentStatus || !options.permittedFrom.includes(currentStatus)) {\n throw utils.errorBuilder.buildError(ErrorType.CONFLICT, executionContext, {\n customMessageReference: ErrorCustomMessageReference.CONFLICT,\n context: {\n reason: 'platform_access_grant_transition_not_permitted_from_current_status',\n currentStatus: currentStatus ?? null,\n permittedFrom: [...options.permittedFrom],\n operationIdentifier,\n },\n });\n }\n\n const decisionReason = (input as { decisionReason?: string })?.decisionReason;\n const now = new Date();\n\n return {\n status: options.nextStatus,\n ...(decisionReason ? { decisionReason } : {}),\n // Only an APPROVAL names a human approver. A revocation or a denial is a decision too,\n // but recording either in `approvedByUserId` would corrupt the one field an audit reads\n // to answer \"did somebody in the tenant say yes?\".\n ...(options.stampsApprover\n ? { approvedByUserId: executionContext.initiatorIds?.userId, approvedAt: now }\n : {}),\n };\n },\n postfixCoreOperations: async (_id, updatedGrant, executionContext, _operationPath, utils) => {\n recordGrantTransition({\n container: containerRef!,\n utils,\n transition: options.auditTransition,\n grant: (updatedGrant ?? {}) as Record<string, unknown>,\n // The tenant administrator who acted — distinct from the grant's `operatorUserId`, which\n // stays the operator who asked. Conflating them would make an audit unable to answer who\n // said yes.\n decidedByUserId: executionContext.initiatorIds?.userId,\n });\n return updatedGrant;\n },\n },\n });\n };\n\n return [\n requestAccessFactory,\n makeDecisionFactory(PlatformAccessGrants_Operations.APPROVE, {\n debugLabel: 'platform-access-grants.approve.api',\n auditTransition: PlatformAccessGrantLifecycleTransition.APPROVED,\n nextStatus: PlatformAccessGrantStatus.ACTIVE,\n permittedFrom: [PlatformAccessGrantStatus.PENDING_APPROVAL],\n stampsApprover: true,\n }),\n makeDecisionFactory(PlatformAccessGrants_Operations.DENY, {\n debugLabel: 'platform-access-grants.deny.api',\n auditTransition: PlatformAccessGrantLifecycleTransition.DENIED,\n nextStatus: PlatformAccessGrantStatus.DENIED,\n permittedFrom: [PlatformAccessGrantStatus.PENDING_APPROVAL],\n stampsApprover: false,\n }),\n makeDecisionFactory(PlatformAccessGrants_Operations.REVOKE, {\n debugLabel: 'platform-access-grants.revoke.api',\n auditTransition: PlatformAccessGrantLifecycleTransition.REVOKED,\n nextStatus: PlatformAccessGrantStatus.REVOKED,\n // Both a pending request and a live elevation can be withdrawn; a terminal one cannot be\n // re-terminated, which would rewrite the decision history.\n permittedFrom: PLATFORM_ACCESS_GRANT_REVOCABLE_STATUSES,\n stampsApprover: false,\n }),\n /**\n * The one transition with no human actor (#413). Everything else here records a decision\n * somebody made; this records that a window closed, so `decidedByUserId` resolves to nothing and\n * that absence is the fact.\n *\n * Permitted from ACTIVE alone. A grant the tenant DENIED or REVOKED is terminal and must keep\n * saying which — relabelling it EXPIRED would rewrite the decision history a customer audit\n * reads, which is the opposite of why this sweep exists.\n */\n makeDecisionFactory(PlatformAccessGrants_Operations.EXPIRE, {\n debugLabel: 'platform-access-grants.expire.internal',\n auditTransition: PlatformAccessGrantLifecycleTransition.EXPIRED,\n nextStatus: PlatformAccessGrantStatus.EXPIRED,\n permittedFrom: [PlatformAccessGrantStatus.ACTIVE],\n stampsApprover: false,\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n }),\n ];\n}\n"]}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type User } from '@wildo-ai/saas-models';
|
|
2
|
+
import type { AuthExecutionContextFactoryBackendService } from '../../security/authentications/services/auth-execution-context-factory.backend.service';
|
|
3
|
+
import type { ErrorBuilderBackendService } from '../../errors/services/error-builder.backend.service';
|
|
4
|
+
import type { RepositoriesRegistryHandlerBackendService } from '../../base-classes/services/repositories/repositories-registry-handler.backend.service';
|
|
5
|
+
/**
|
|
6
|
+
* WHO currently holds privileged access — the enumeration a periodic privileged-access review reads.
|
|
7
|
+
*
|
|
8
|
+
* assurance-control: WILDO.ACCESS.PRIVILEGED_REVIEW — enumerate the principals holding privileged
|
|
9
|
+
* access, at both scopes, so a review has an explicitly scoped population to decide over.
|
|
10
|
+
*
|
|
11
|
+
* ## What this is, and the three things it deliberately is NOT
|
|
12
|
+
*
|
|
13
|
+
* The objective demands four things of an application: privileged access is explicitly SCOPED, it is
|
|
14
|
+
* PERIODICALLY REVIEWED, the review is DECIDED BY AUTHORIZED PEOPLE, and the outcome is RETAINED as
|
|
15
|
+
* traceable evidence. Wildo supplies the first honestly and can supply the raw material for the
|
|
16
|
+
* second. It supplies neither of the last two, and this module must not look as though it does.
|
|
17
|
+
*
|
|
18
|
+
* - **It does not schedule.** Nothing here fires periodically; a caller decides when to look.
|
|
19
|
+
* - **It does not decide.** No row is marked reviewed, approved or revoked. A reviewer's judgement is
|
|
20
|
+
* a human act with named accountability, and a framework that recorded one would be asserting a
|
|
21
|
+
* decision nobody made — the same line the governed-document fact families draw.
|
|
22
|
+
* - **It records no evidence.** The review OCCURRENCE — who reviewed, when, what they concluded — is
|
|
23
|
+
* the application's to supply as a declared host artifact, because Wildo cannot witness it. The
|
|
24
|
+
* general question of where a control's evidence lives is a separate design (#269), and answering
|
|
25
|
+
* it here for one control is exactly the one-off this route was chosen to avoid.
|
|
26
|
+
*
|
|
27
|
+
* The objective's own caveat survives all of this and is worth restating where the code is: evidence
|
|
28
|
+
* is retained *without implying remediation completion*. A review record proves a review happened,
|
|
29
|
+
* never that what it found was fixed. Nothing this module returns should be read as remediation.
|
|
30
|
+
*
|
|
31
|
+
* ## Why it OWNS its execution context
|
|
32
|
+
*
|
|
33
|
+
* Same reason as `measureOrganizationsMissingUsableOwner`, and the failure recorded there is exactly
|
|
34
|
+
* the one that would bite here: an estate-wide read needs an `INTERNALLY_INITIATED_REQUEST` context to
|
|
35
|
+
* escape scope-root collection confinement, and a caller-supplied context that is role-less — or that
|
|
36
|
+
* carries a plausible-but-wrong execution-type string — silently confines the read to no tenants and
|
|
37
|
+
* returns an EMPTY population. An empty privileged-access review is indistinguishable from a healthy
|
|
38
|
+
* one, and it is the direction that reads as good news.
|
|
39
|
+
*
|
|
40
|
+
* ## Conferring roles come from the LIVE table, and are the caller's to resolve
|
|
41
|
+
*
|
|
42
|
+
* Both floors resolve their conferring set from the role table through `inheritFrom` rather than
|
|
43
|
+
* comparing role strings, because a custom role that inherits the authority confers it. This takes
|
|
44
|
+
* both sets as parameters for the same reason those functions do: the resolvers are lazy container
|
|
45
|
+
* bindings, and taking the answer keeps this module free of the container.
|
|
46
|
+
*/
|
|
47
|
+
/** One principal holding APPLICATION-scope privileged access. */
|
|
48
|
+
export interface PrivilegedApplicationAccessHolder {
|
|
49
|
+
readonly userId: string;
|
|
50
|
+
readonly email?: string;
|
|
51
|
+
/** The roles this principal holds that confer the authority — what a reviewer decides about. */
|
|
52
|
+
readonly conferringRolesHeld: readonly string[];
|
|
53
|
+
}
|
|
54
|
+
/** One principal holding ORGANIZATION-scope privileged access, and where. */
|
|
55
|
+
export interface PrivilegedOrganizationAccessHolder {
|
|
56
|
+
readonly organizationId: string;
|
|
57
|
+
readonly organizationName?: string;
|
|
58
|
+
readonly membershipId: string;
|
|
59
|
+
readonly userId?: string;
|
|
60
|
+
readonly conferringRolesHeld: readonly string[];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The privileged-access population as it stands, at both scopes.
|
|
64
|
+
*
|
|
65
|
+
* `observedAt` is the instant the enumeration was taken, and it is the caller's to supply — this
|
|
66
|
+
* module reads no clock, so the same estate enumerates to the same value twice. A report that stamped
|
|
67
|
+
* its own "now" would be a different artifact on every run for reasons unrelated to access.
|
|
68
|
+
*/
|
|
69
|
+
export interface PrivilegedAccessPopulation {
|
|
70
|
+
readonly observedAt: string;
|
|
71
|
+
readonly applicationScopeConferringRoles: readonly string[];
|
|
72
|
+
readonly organizationScopeConferringRoles: readonly string[];
|
|
73
|
+
readonly applicationScopeHolders: readonly PrivilegedApplicationAccessHolder[];
|
|
74
|
+
readonly organizationScopeHolders: readonly PrivilegedOrganizationAccessHolder[];
|
|
75
|
+
/**
|
|
76
|
+
* Tenants the enumeration could not read a membership list for.
|
|
77
|
+
*
|
|
78
|
+
* REPORTED rather than skipped: a tenant silently absent from a privileged-access review reads as a
|
|
79
|
+
* tenant with no privileged access, which is the wrong direction to be wrong in
|
|
80
|
+
* (`.claude/rules/negative-results-require-a-positive-probe.md`). A reviewer must be told what was
|
|
81
|
+
* not looked at.
|
|
82
|
+
*/
|
|
83
|
+
readonly unreadableOrganizationIds: readonly string[];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Enumerate every principal holding privileged access, at both scopes.
|
|
87
|
+
*
|
|
88
|
+
* Fail-closed on the APPLICATION scope and best-effort per tenant on the ORGANIZATION scope, and the
|
|
89
|
+
* asymmetry is deliberate. A missing users repository makes the whole population unknowable, so
|
|
90
|
+
* answering at all would be a guess; one unreadable tenant leaves the rest of the review perfectly
|
|
91
|
+
* usable, provided the reviewer is told which tenant is missing — which `unreadableOrganizationIds`
|
|
92
|
+
* is for.
|
|
93
|
+
*/
|
|
94
|
+
export declare function enumeratePrivilegedAccessPopulation(params: {
|
|
95
|
+
authExecutionContextFactory: AuthExecutionContextFactoryBackendService;
|
|
96
|
+
repositoriesRegistry: RepositoriesRegistryHandlerBackendService;
|
|
97
|
+
errorBuilder: ErrorBuilderBackendService;
|
|
98
|
+
/** From `resolveSuperAdminConferringRoles` — the live table's answer, not a role-string comparison. */
|
|
99
|
+
applicationScopeConferringRoles: readonly string[];
|
|
100
|
+
/** From `resolveOrganizationOwnerConferringRoles`. */
|
|
101
|
+
organizationScopeConferringRoles: readonly string[];
|
|
102
|
+
/** The instant this enumeration describes. Supplied, never read from a clock here. */
|
|
103
|
+
observedAt: string;
|
|
104
|
+
}): Promise<PrivilegedAccessPopulation>;
|
|
105
|
+
/**
|
|
106
|
+
* Whether a membership's LINKED USER can still authenticate.
|
|
107
|
+
*
|
|
108
|
+
* Exported because a reviewer's most common question about an organization-scope holder is whether
|
|
109
|
+
* the person behind it is still able to act, and the answer lives on a different row than the one the
|
|
110
|
+
* enumeration returns. Kept as a predicate over a supplied user rather than a second read, so a
|
|
111
|
+
* caller batches the lookup it already needs.
|
|
112
|
+
*
|
|
113
|
+
* The two statuses are the owner floor's own vocabulary
|
|
114
|
+
* ({@link ADMINISTRATIVELY_USABLE_OWNER_USER_STATUSES}), not a second list.
|
|
115
|
+
*/
|
|
116
|
+
export declare function privilegedOrganizationHolderCanAuthenticate(user: Pick<User, 'status'> | undefined | null): boolean;
|
|
117
|
+
//# sourceMappingURL=privileged-access-review.backend.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privileged-access-review.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/privileged-access-review.backend.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,KAAK,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAEhH,OAAO,KAAK,EAAE,yCAAyC,EAAE,MAAM,qGAAqG,CAAC;AACrK,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAGnH,OAAO,KAAK,EAAE,yCAAyC,EAAE,MAAM,qGAAqG,CAAC;AAYrK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,iEAAiE;AACjE,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,gGAAgG;IAChG,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;CACjD;AAED,6EAA6E;AAC7E,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;CACjD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,+BAA+B,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5D,QAAQ,CAAC,gCAAgC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7D,QAAQ,CAAC,uBAAuB,EAAE,SAAS,iCAAiC,EAAE,CAAC;IAC/E,QAAQ,CAAC,wBAAwB,EAAE,SAAS,kCAAkC,EAAE,CAAC;IACjF;;;;;;;OAOG;IACH,QAAQ,CAAC,yBAAyB,EAAE,SAAS,MAAM,EAAE,CAAC;CACvD;AAUD;;;;;;;;GAQG;AACH,wBAAsB,mCAAmC,CAAC,MAAM,EAAE;IAChE,2BAA2B,EAAE,yCAAyC,CAAC;IACvE,oBAAoB,EAAE,yCAAyC,CAAC;IAChE,YAAY,EAAE,0BAA0B,CAAC;IACzC,uGAAuG;IACvG,+BAA+B,EAAE,SAAS,MAAM,EAAE,CAAC;IACnD,sDAAsD;IACtD,gCAAgC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpD,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAqFtC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2CAA2C,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAElH"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { CoreResourceType } from '@wildo-ai/saas-models';
|
|
2
|
+
import { ErrorType } from '@wildo-ai/saas-models';
|
|
3
|
+
import { ADMINISTRATIVELY_USABLE_ORGANIZATION_MEMBER_STATUSES, createOrganizationOwnerFloorPopulationContext, isAdministrativelyUsableMembershipStatus, isAdministrativelyUsableOwnerUserStatus, rolesConferOrganizationOwner, } from './organization-owner-floor.backend.utils.js';
|
|
4
|
+
import { ADMINISTRATIVELY_USABLE_USER_STATUSES, isUsableSuperAdmin } from './super-admin-floor.backend.utils.js';
|
|
5
|
+
function readRows(candidates) {
|
|
6
|
+
return Array.isArray(candidates) ? candidates : [];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Enumerate every principal holding privileged access, at both scopes.
|
|
10
|
+
*
|
|
11
|
+
* Fail-closed on the APPLICATION scope and best-effort per tenant on the ORGANIZATION scope, and the
|
|
12
|
+
* asymmetry is deliberate. A missing users repository makes the whole population unknowable, so
|
|
13
|
+
* answering at all would be a guess; one unreadable tenant leaves the rest of the review perfectly
|
|
14
|
+
* usable, provided the reviewer is told which tenant is missing — which `unreadableOrganizationIds`
|
|
15
|
+
* is for.
|
|
16
|
+
*/
|
|
17
|
+
export async function enumeratePrivilegedAccessPopulation(params) {
|
|
18
|
+
const executionContext = await createOrganizationOwnerFloorPopulationContext(params.authExecutionContextFactory);
|
|
19
|
+
const userRepository = params.repositoriesRegistry.getRepository(CoreResourceType.USERS);
|
|
20
|
+
if (!userRepository) {
|
|
21
|
+
throw params.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {
|
|
22
|
+
context: {
|
|
23
|
+
message: 'Cannot enumerate privileged access: the users repository is not registered',
|
|
24
|
+
resourceType: CoreResourceType.USERS,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/*
|
|
29
|
+
* The query narrows on the conferring roles and the usable statuses, and the predicate re-checks
|
|
30
|
+
* both. Not redundant: the query is what keeps this from materialising every user, and the
|
|
31
|
+
* predicate is what makes the answer exact when a row's status is out of vocabulary — the second
|
|
32
|
+
* way an ownerless tenant escaped the owner-floor backstop, recorded there.
|
|
33
|
+
*/
|
|
34
|
+
const applicationCandidates = await userRepository.list(executionContext, {
|
|
35
|
+
appRoles: { $in: [...params.applicationScopeConferringRoles] },
|
|
36
|
+
status: { $in: [...ADMINISTRATIVELY_USABLE_USER_STATUSES] },
|
|
37
|
+
});
|
|
38
|
+
const applicationScopeHolders = readRows(applicationCandidates)
|
|
39
|
+
.filter((user) => isUsableSuperAdmin(user, params.applicationScopeConferringRoles))
|
|
40
|
+
.map((user) => ({
|
|
41
|
+
userId: String(user._id),
|
|
42
|
+
...(typeof user.email === 'string' ? { email: user.email } : {}),
|
|
43
|
+
conferringRolesHeld: (Array.isArray(user.appRoles) ? user.appRoles : []).filter((role) => typeof role === 'string' && params.applicationScopeConferringRoles.includes(role)),
|
|
44
|
+
}));
|
|
45
|
+
const organizationRepository = params.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATIONS);
|
|
46
|
+
const membershipRepository = params.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATION_MEMBERS);
|
|
47
|
+
const organizationScopeHolders = [];
|
|
48
|
+
const unreadableOrganizationIds = [];
|
|
49
|
+
if (organizationRepository && membershipRepository) {
|
|
50
|
+
const organizations = readRows(await organizationRepository.list(executionContext, {}));
|
|
51
|
+
const nameByOrganizationId = new Map(organizations.map((organization) => [String(organization._id), organization.name]));
|
|
52
|
+
for (const organization of organizations) {
|
|
53
|
+
const organizationId = String(organization._id);
|
|
54
|
+
let memberships;
|
|
55
|
+
try {
|
|
56
|
+
memberships = readRows(await membershipRepository.list(executionContext, {
|
|
57
|
+
organizationId,
|
|
58
|
+
roles: { $in: [...params.organizationScopeConferringRoles] },
|
|
59
|
+
status: { $in: [...ADMINISTRATIVELY_USABLE_ORGANIZATION_MEMBER_STATUSES] },
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
unreadableOrganizationIds.push(organizationId);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
for (const membership of memberships) {
|
|
67
|
+
if (!rolesConferOrganizationOwner(membership.roles, params.organizationScopeConferringRoles))
|
|
68
|
+
continue;
|
|
69
|
+
if (!isAdministrativelyUsableMembershipStatus(membership.status))
|
|
70
|
+
continue;
|
|
71
|
+
organizationScopeHolders.push({
|
|
72
|
+
organizationId,
|
|
73
|
+
...(nameByOrganizationId.get(organizationId) ? { organizationName: nameByOrganizationId.get(organizationId) } : {}),
|
|
74
|
+
membershipId: String(membership._id),
|
|
75
|
+
...(membership.userId ? { userId: String(membership.userId) } : {}),
|
|
76
|
+
conferringRolesHeld: (Array.isArray(membership.roles) ? membership.roles : []).filter((role) => typeof role === 'string' && params.organizationScopeConferringRoles.includes(role)),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
observedAt: params.observedAt,
|
|
83
|
+
applicationScopeConferringRoles: [...params.applicationScopeConferringRoles],
|
|
84
|
+
organizationScopeConferringRoles: [...params.organizationScopeConferringRoles],
|
|
85
|
+
applicationScopeHolders,
|
|
86
|
+
organizationScopeHolders,
|
|
87
|
+
unreadableOrganizationIds,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Whether a membership's LINKED USER can still authenticate.
|
|
92
|
+
*
|
|
93
|
+
* Exported because a reviewer's most common question about an organization-scope holder is whether
|
|
94
|
+
* the person behind it is still able to act, and the answer lives on a different row than the one the
|
|
95
|
+
* enumeration returns. Kept as a predicate over a supplied user rather than a second read, so a
|
|
96
|
+
* caller batches the lookup it already needs.
|
|
97
|
+
*
|
|
98
|
+
* The two statuses are the owner floor's own vocabulary
|
|
99
|
+
* ({@link ADMINISTRATIVELY_USABLE_OWNER_USER_STATUSES}), not a second list.
|
|
100
|
+
*/
|
|
101
|
+
export function privilegedOrganizationHolderCanAuthenticate(user) {
|
|
102
|
+
return isAdministrativelyUsableOwnerUserStatus(user?.status);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=privileged-access-review.backend.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privileged-access-review.backend.utils.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/privileged-access-review.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { CoreResourceType, type Organization, type OrganizationMember, type User } from '@wildo-ai/saas-models';\n\nimport type { AuthExecutionContextFactoryBackendService } from '~wildo-backend-lib/security/authentications/services/auth-execution-context-factory.backend.service';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport { ErrorType } from '@wildo-ai/saas-models';\nimport type { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport type { RepositoriesRegistryHandlerBackendService } from '~wildo-backend-lib/base-classes/services/repositories/repositories-registry-handler.backend.service';\n\nimport {\n ADMINISTRATIVELY_USABLE_ORGANIZATION_MEMBER_STATUSES,\n ADMINISTRATIVELY_USABLE_OWNER_USER_STATUSES,\n createOrganizationOwnerFloorPopulationContext,\n isAdministrativelyUsableMembershipStatus,\n isAdministrativelyUsableOwnerUserStatus,\n rolesConferOrganizationOwner,\n} from './organization-owner-floor.backend.utils';\nimport { ADMINISTRATIVELY_USABLE_USER_STATUSES, isUsableSuperAdmin } from './super-admin-floor.backend.utils';\n\n/**\n * WHO currently holds privileged access — the enumeration a periodic privileged-access review reads.\n *\n * assurance-control: WILDO.ACCESS.PRIVILEGED_REVIEW — enumerate the principals holding privileged\n * access, at both scopes, so a review has an explicitly scoped population to decide over.\n *\n * ## What this is, and the three things it deliberately is NOT\n *\n * The objective demands four things of an application: privileged access is explicitly SCOPED, it is\n * PERIODICALLY REVIEWED, the review is DECIDED BY AUTHORIZED PEOPLE, and the outcome is RETAINED as\n * traceable evidence. Wildo supplies the first honestly and can supply the raw material for the\n * second. It supplies neither of the last two, and this module must not look as though it does.\n *\n * - **It does not schedule.** Nothing here fires periodically; a caller decides when to look.\n * - **It does not decide.** No row is marked reviewed, approved or revoked. A reviewer's judgement is\n * a human act with named accountability, and a framework that recorded one would be asserting a\n * decision nobody made — the same line the governed-document fact families draw.\n * - **It records no evidence.** The review OCCURRENCE — who reviewed, when, what they concluded — is\n * the application's to supply as a declared host artifact, because Wildo cannot witness it. The\n * general question of where a control's evidence lives is a separate design (#269), and answering\n * it here for one control is exactly the one-off this route was chosen to avoid.\n *\n * The objective's own caveat survives all of this and is worth restating where the code is: evidence\n * is retained *without implying remediation completion*. A review record proves a review happened,\n * never that what it found was fixed. Nothing this module returns should be read as remediation.\n *\n * ## Why it OWNS its execution context\n *\n * Same reason as `measureOrganizationsMissingUsableOwner`, and the failure recorded there is exactly\n * the one that would bite here: an estate-wide read needs an `INTERNALLY_INITIATED_REQUEST` context to\n * escape scope-root collection confinement, and a caller-supplied context that is role-less — or that\n * carries a plausible-but-wrong execution-type string — silently confines the read to no tenants and\n * returns an EMPTY population. An empty privileged-access review is indistinguishable from a healthy\n * one, and it is the direction that reads as good news.\n *\n * ## Conferring roles come from the LIVE table, and are the caller's to resolve\n *\n * Both floors resolve their conferring set from the role table through `inheritFrom` rather than\n * comparing role strings, because a custom role that inherits the authority confers it. This takes\n * both sets as parameters for the same reason those functions do: the resolvers are lazy container\n * bindings, and taking the answer keeps this module free of the container.\n */\n\n/** One principal holding APPLICATION-scope privileged access. */\nexport interface PrivilegedApplicationAccessHolder {\n readonly userId: string;\n readonly email?: string;\n /** The roles this principal holds that confer the authority — what a reviewer decides about. */\n readonly conferringRolesHeld: readonly string[];\n}\n\n/** One principal holding ORGANIZATION-scope privileged access, and where. */\nexport interface PrivilegedOrganizationAccessHolder {\n readonly organizationId: string;\n readonly organizationName?: string;\n readonly membershipId: string;\n readonly userId?: string;\n readonly conferringRolesHeld: readonly string[];\n}\n\n/**\n * The privileged-access population as it stands, at both scopes.\n *\n * `observedAt` is the instant the enumeration was taken, and it is the caller's to supply — this\n * module reads no clock, so the same estate enumerates to the same value twice. A report that stamped\n * its own \"now\" would be a different artifact on every run for reasons unrelated to access.\n */\nexport interface PrivilegedAccessPopulation {\n readonly observedAt: string;\n readonly applicationScopeConferringRoles: readonly string[];\n readonly organizationScopeConferringRoles: readonly string[];\n readonly applicationScopeHolders: readonly PrivilegedApplicationAccessHolder[];\n readonly organizationScopeHolders: readonly PrivilegedOrganizationAccessHolder[];\n /**\n * Tenants the enumeration could not read a membership list for.\n *\n * REPORTED rather than skipped: a tenant silently absent from a privileged-access review reads as a\n * tenant with no privileged access, which is the wrong direction to be wrong in\n * (`.claude/rules/negative-results-require-a-positive-probe.md`). A reviewer must be told what was\n * not looked at.\n */\n readonly unreadableOrganizationIds: readonly string[];\n}\n\ntype PrivilegedUserRow = Pick<User, '_id' | 'appRoles' | 'status' | 'email'>;\ntype PrivilegedMembershipRow = Pick<OrganizationMember, '_id' | 'roles' | 'status' | 'userId' | 'organizationId'>;\ntype PrivilegedOrganizationRow = Pick<Organization, '_id' | 'name'>;\n\nfunction readRows<TRow>(candidates: unknown): TRow[] {\n return Array.isArray(candidates) ? (candidates as TRow[]) : [];\n}\n\n/**\n * Enumerate every principal holding privileged access, at both scopes.\n *\n * Fail-closed on the APPLICATION scope and best-effort per tenant on the ORGANIZATION scope, and the\n * asymmetry is deliberate. A missing users repository makes the whole population unknowable, so\n * answering at all would be a guess; one unreadable tenant leaves the rest of the review perfectly\n * usable, provided the reviewer is told which tenant is missing — which `unreadableOrganizationIds`\n * is for.\n */\nexport async function enumeratePrivilegedAccessPopulation(params: {\n authExecutionContextFactory: AuthExecutionContextFactoryBackendService;\n repositoriesRegistry: RepositoriesRegistryHandlerBackendService;\n errorBuilder: ErrorBuilderBackendService;\n /** From `resolveSuperAdminConferringRoles` — the live table's answer, not a role-string comparison. */\n applicationScopeConferringRoles: readonly string[];\n /** From `resolveOrganizationOwnerConferringRoles`. */\n organizationScopeConferringRoles: readonly string[];\n /** The instant this enumeration describes. Supplied, never read from a clock here. */\n observedAt: string;\n}): Promise<PrivilegedAccessPopulation> {\n const executionContext: ExecutionContext<any> = await createOrganizationOwnerFloorPopulationContext(\n params.authExecutionContextFactory,\n );\n\n const userRepository = params.repositoriesRegistry.getRepository(CoreResourceType.USERS);\n if (!userRepository) {\n throw params.errorBuilder.buildError(ErrorType.CONFIGURATION, executionContext, {\n context: {\n message: 'Cannot enumerate privileged access: the users repository is not registered',\n resourceType: CoreResourceType.USERS,\n },\n });\n }\n\n /*\n * The query narrows on the conferring roles and the usable statuses, and the predicate re-checks\n * both. Not redundant: the query is what keeps this from materialising every user, and the\n * predicate is what makes the answer exact when a row's status is out of vocabulary — the second\n * way an ownerless tenant escaped the owner-floor backstop, recorded there.\n */\n const applicationCandidates = await userRepository.list<PrivilegedUserRow>(executionContext, {\n appRoles: { $in: [...params.applicationScopeConferringRoles] },\n status: { $in: [...ADMINISTRATIVELY_USABLE_USER_STATUSES] },\n });\n\n const applicationScopeHolders: PrivilegedApplicationAccessHolder[] = readRows<PrivilegedUserRow>(applicationCandidates)\n .filter((user) => isUsableSuperAdmin(user, params.applicationScopeConferringRoles))\n .map((user) => ({\n userId: String(user._id),\n ...(typeof user.email === 'string' ? { email: user.email } : {}),\n conferringRolesHeld: (Array.isArray(user.appRoles) ? user.appRoles : []).filter(\n (role): role is string => typeof role === 'string' && params.applicationScopeConferringRoles.includes(role),\n ),\n }));\n\n const organizationRepository = params.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATIONS);\n const membershipRepository = params.repositoriesRegistry.getRepository(CoreResourceType.ORGANIZATION_MEMBERS);\n const organizationScopeHolders: PrivilegedOrganizationAccessHolder[] = [];\n const unreadableOrganizationIds: string[] = [];\n\n if (organizationRepository && membershipRepository) {\n const organizations = readRows<PrivilegedOrganizationRow>(await organizationRepository.list<PrivilegedOrganizationRow>(executionContext, {}));\n const nameByOrganizationId = new Map(organizations.map((organization) => [String(organization._id), organization.name]));\n\n for (const organization of organizations) {\n const organizationId = String(organization._id);\n let memberships: PrivilegedMembershipRow[];\n try {\n memberships = readRows<PrivilegedMembershipRow>(\n await membershipRepository.list<PrivilegedMembershipRow>(executionContext, {\n organizationId,\n roles: { $in: [...params.organizationScopeConferringRoles] },\n status: { $in: [...ADMINISTRATIVELY_USABLE_ORGANIZATION_MEMBER_STATUSES] },\n }),\n );\n } catch {\n unreadableOrganizationIds.push(organizationId);\n continue;\n }\n\n for (const membership of memberships) {\n if (!rolesConferOrganizationOwner(membership.roles, params.organizationScopeConferringRoles)) continue;\n if (!isAdministrativelyUsableMembershipStatus(membership.status)) continue;\n organizationScopeHolders.push({\n organizationId,\n ...(nameByOrganizationId.get(organizationId) ? { organizationName: nameByOrganizationId.get(organizationId)! } : {}),\n membershipId: String(membership._id),\n ...(membership.userId ? { userId: String(membership.userId) } : {}),\n conferringRolesHeld: (Array.isArray(membership.roles) ? membership.roles : []).filter(\n (role): role is string => typeof role === 'string' && params.organizationScopeConferringRoles.includes(role),\n ),\n });\n }\n }\n }\n\n return {\n observedAt: params.observedAt,\n applicationScopeConferringRoles: [...params.applicationScopeConferringRoles],\n organizationScopeConferringRoles: [...params.organizationScopeConferringRoles],\n applicationScopeHolders,\n organizationScopeHolders,\n unreadableOrganizationIds,\n };\n}\n\n/**\n * Whether a membership's LINKED USER can still authenticate.\n *\n * Exported because a reviewer's most common question about an organization-scope holder is whether\n * the person behind it is still able to act, and the answer lives on a different row than the one the\n * enumeration returns. Kept as a predicate over a supplied user rather than a second read, so a\n * caller batches the lookup it already needs.\n *\n * The two statuses are the owner floor's own vocabulary\n * ({@link ADMINISTRATIVELY_USABLE_OWNER_USER_STATUSES}), not a second list.\n */\nexport function privilegedOrganizationHolderCanAuthenticate(user: Pick<User, 'status'> | undefined | null): boolean {\n return isAdministrativelyUsableOwnerUserStatus(user?.status);\n}\n"]}
|
|
@@ -28,6 +28,8 @@ export type RoleHierarchyResolver = (role: string, scope: ResourcePrimaryScope)
|
|
|
28
28
|
*/
|
|
29
29
|
export declare function createRoleHierarchyResolver(container: Container): RoleHierarchyResolver;
|
|
30
30
|
/**
|
|
31
|
+
* @wildo_source:part:start saas.backend.authorization.role-ceiling facet:layer:backend facet:audience:app-developer
|
|
32
|
+
*
|
|
31
33
|
* Role-ceiling gate — a principal may only grant roles it itself holds.
|
|
32
34
|
*
|
|
33
35
|
* WHY THIS EXISTS. Several resources carry a caller-settable `roles` array that becomes a principal's
|
|
@@ -88,6 +90,8 @@ export declare function createRoleHierarchyResolver(container: Container): RoleH
|
|
|
88
90
|
*
|
|
89
91
|
* assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — prevents a principal from granting authority it
|
|
90
92
|
* does not itself hold. The denial is an access-control decision.
|
|
93
|
+
*
|
|
94
|
+
* @wildo_source:part:end saas.backend.authorization.role-ceiling
|
|
91
95
|
*/
|
|
92
96
|
export declare function assertRequestedRolesWithinCallerCeiling(executionContext: ExecutionContext<any>, requestedRoles: readonly string[] | undefined, errorBuilder: ErrorBuilderBackendService, roleHierarchyResolver: RoleHierarchyResolver): void;
|
|
93
97
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-ceiling.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/role-ceiling.backend.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0F,oBAAoB,EAA8B,MAAM,uBAAuB,CAAC;AAEjL,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qEAAqE,CAAC;AAC5G,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAInH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,KAAK,MAAM,EAAE,CAAC;AAE5F;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,SAAS,GAAG,qBAAqB,CAMvF;AAED
|
|
1
|
+
{"version":3,"file":"role-ceiling.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/role-ceiling.backend.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0F,oBAAoB,EAA8B,MAAM,uBAAuB,CAAC;AAEjL,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qEAAqE,CAAC;AAC5G,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kEAAkE,CAAC;AAInH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,KAAK,MAAM,EAAE,CAAC;AAE5F;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,SAAS,GAAG,qBAAqB,CAMvF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,wBAAgB,uCAAuC,CACrD,gBAAgB,EAAE,gBAAgB,CAAC,GAAG,CAAC,EACvC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC7C,YAAY,EAAE,0BAA0B,EACxC,qBAAqB,EAAE,qBAAqB,GAC3C,IAAI,CAiDN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAI5E"}
|
|
@@ -18,6 +18,8 @@ export function createRoleHierarchyResolver(container) {
|
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
+
* @wildo_source:part:start saas.backend.authorization.role-ceiling facet:layer:backend facet:audience:app-developer
|
|
22
|
+
*
|
|
21
23
|
* Role-ceiling gate — a principal may only grant roles it itself holds.
|
|
22
24
|
*
|
|
23
25
|
* WHY THIS EXISTS. Several resources carry a caller-settable `roles` array that becomes a principal's
|
|
@@ -78,6 +80,8 @@ export function createRoleHierarchyResolver(container) {
|
|
|
78
80
|
*
|
|
79
81
|
* assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — prevents a principal from granting authority it
|
|
80
82
|
* does not itself hold. The denial is an access-control decision.
|
|
83
|
+
*
|
|
84
|
+
* @wildo_source:part:end saas.backend.authorization.role-ceiling
|
|
81
85
|
*/
|
|
82
86
|
export function assertRequestedRolesWithinCallerCeiling(executionContext, requestedRoles, errorBuilder, roleHierarchyResolver) {
|
|
83
87
|
if (!requestedRoles || requestedRoles.length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-ceiling.backend.utils.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/role-ceiling.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { CORE_APP_ROLES, ErrorCustomMessageReference, ErrorType, ExecutionContext_ExecutionType, ResourcePrimaryScope, isOrganizationWideRoleInfo } from '@wildo-ai/saas-models';\nimport type { Roles } from '@wildo-ai/saas-models';\nimport type { Container } from 'inversify';\nimport type { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { AuthorizationsBackendService } from '~wildo-backend-lib/security/authorizations/services/authorizations.backend.service';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\n\n/**\n * Expands one role into the full set of roles it effectively confers, within a given primary scope.\n *\n * This is the `inheritFrom` chain of the runtime role configuration — supply\n * `AuthorizationsBackendService.getRoleHierarchy` bound to its service instance. It is injected\n * rather than imported because the effective hierarchy is APPLICATION-CONFIGURABLE (apps register\n * custom roles at startup via `initializeRolesWithCustom`), so a statically-imported default table\n * would silently disagree with the roles the authorization layer actually enforces.\n *\n * The scope argument matters: `getRoleHierarchy` resolves against the APPLICATION role table or the\n * ORGANIZATIONS one, never both. A role string that is unknown in the passed scope expands to the\n * empty set — which is exactly the fail-closed behaviour this gate wants.\n */\nexport type RoleHierarchyResolver = (role: string, scope: ResourcePrimaryScope) => string[];\n\n/**\n * Bind a {@link RoleHierarchyResolver} to the container's live `AuthorizationsBackendService`.\n *\n * Resolution is LAZY (on first gate evaluation, then memoized) rather than at factory-construction\n * time: custom-implementation factories are built during module registration, which can run before\n * the authorization service is bound, and an eager `container.get` there would turn a role-gate into\n * a startup crash. Holding the service instance is safe across role reconfiguration —\n * `initializeRolesWithCustom` mutates the singleton's tables in place, and the hierarchy is read per\n * call, so a resolver captured at startup still sees roles registered afterwards.\n */\nexport function createRoleHierarchyResolver(container: Container): RoleHierarchyResolver {\n let authorizationsService: AuthorizationsBackendService | undefined;\n return (role, scope) => {\n authorizationsService ??= container.get<AuthorizationsBackendService>(SAAS_SERVICE_TYPES.AuthorizationsService);\n return authorizationsService.getRoleHierarchy(role as Roles, scope);\n };\n}\n\n/**\n * Role-ceiling gate — a principal may only grant roles it itself holds.\n *\n * WHY THIS EXISTS. Several resources carry a caller-settable `roles` array that becomes a principal's\n * live authority. Two families:\n *\n * - **Machine credentials** (`organizationOAuthClients` / `applicationOAuthClients` and their api-key\n * twins): the roles written at CREATE are exactly the roles every token minted for that client/key\n * carries at the request-auth choke point (`oauth-provider-token` → `machine-token-issuer`).\n * - **Organization membership** (`organizationMembers.roles`, and the per-unit roles nested in\n * `organizationUnitsMembership`): a membership row's `roles` array is read verbatim by\n * `execution-context-creator` to build `initiatorRoles` — the member's live authority on their very\n * next request.\n *\n * The operation-authorization layer only checks whether the CALLER may run the write at all — it never\n * compares the *requested* roles against the caller's own. Without this gate an `ORG_ADMIN` (the gate\n * for both member UPDATE and org-client CREATE) could grant `ORG_OWNER` to themselves, or mint a\n * credential carrying `APP_ADMIN_SUPER_ADMIN`. This is the missing \"you cannot grant authority you do\n * not hold\" check.\n *\n * SEMANTICS. Every requested role must lie within the caller's EFFECTIVE authority — the union of the\n * `inheritFrom` hierarchies of the roles the caller actually holds, each expanded within the scope of\n * the membership that granted it. Hierarchy-awareness is not a convenience: with the default table\n * (`ORG_OWNER → ORG_ADMIN → ORG_MANAGER → ORG_MEMBER → ORG_GUEST`) an `ORG_ADMIN`'s membership row\n * holds the literal string `ORG_ADMIN` and nothing else, so a raw set-membership test would reject\n * that admin granting the DEFAULT `ORG_MEMBER` role and break the entire invite flow — while still\n * correctly rejecting a grant of `ORG_OWNER`, which is UPSTREAM of the caller and therefore outside\n * the expansion.\n *\n * Fail-closed: a caller whose roles cannot be resolved is treated as holding none, so any requested\n * role is rejected.\n *\n * TWO DELIBERATE BYPASSES:\n * - **Platform super-admin** — a caller holding `APP_ADMIN_SUPER_ADMIN` *at APPLICATION scope* may\n * assign any role (that role IS the top of the ceiling). This also cleanly covers the cross-tenant\n * `admin` operation variant of the machine-credential resources, which is itself gated by\n * `APP_ADMIN_SUPER_ADMIN` and is meant to provision clients \"for any org\" — so no separate\n * variant-detection is needed. The scope qualifier is load-bearing: `roles` on a membership row is\n * a free-form string (`OrgRolesSchema` admits any `z.string().min(1)`), so without it a tenant\n * admin who wrote the literal text `APP_ADMIN_SUPER_ADMIN` into an ORGANIZATIONS-scoped membership\n * would unlock this bypass. The authorization layer already refuses to honour that string\n * cross-scope (`getRoleHierarchy` partitions the two role tables); this gate must not be the\n * weaker link.\n * - **System / internal writes** — an `INTERNALLY_INITIATED_REQUEST` execution (seeds, provisioning,\n * `createAsSystem`) is the framework itself, not a user principal (it synthesises a super-admin\n * system EC), and carries no human ceiling — it is trusted to assign any role.\n *\n * SCOPE OF THE COMPARISON. The caller's effective roles are unioned across every membership they\n * hold, without checking that the granting membership targets the same organization as the write.\n * That is deliberate and safe HERE because the operation-authorization layer has already confined the\n * write to a scope the caller may act in (`authorizeOrganizations` / the parent-scope filter); this\n * gate answers \"how high\", not \"where\". A future units-aware authorization axis that narrows *within*\n * an organization must revisit that assumption.\n *\n * EXTENDING. Wire this into the CREATE (and any roles-mutating UPDATE) path of ANY resource whose\n * `roles` field is caller-settable, passing the roles AS AUTHORED BY THE CALLER — not the\n * post-resolution set. Framework-injected defaults (e.g. an organization type's `defaultMemberRole`)\n * are policy-derived, not a caller request, and must not be measured against the caller's ceiling.\n *\n * assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — prevents a principal from granting authority it\n * does not itself hold. The denial is an access-control decision.\n */\nexport function assertRequestedRolesWithinCallerCeiling(\n executionContext: ExecutionContext<any>,\n requestedRoles: readonly string[] | undefined,\n errorBuilder: ErrorBuilderBackendService,\n roleHierarchyResolver: RoleHierarchyResolver,\n): void {\n if (!requestedRoles || requestedRoles.length === 0) return;\n\n // System / internal writes (seeds, provisioning, `createAsSystem`) are the framework, not a user\n // principal — they synthesise an INTERNALLY_INITIATED_REQUEST super-admin EC and assign any role.\n if (executionContext.executionType === ExecutionContext_ExecutionType.INTERNALLY_INITIATED_REQUEST) {\n return;\n }\n\n // Expand each held role into everything it confers, WITHIN the scope of the membership that granted\n // it. Cross-scope contamination is impossible by construction: an ORGANIZATIONS-scoped entry is\n // resolved against the org role table only.\n const effectiveCallerRoles = new Set<string>();\n let holdsPlatformSuperAdmin = false;\n // ORGANIZATION-WIDE GRANTS ONLY. A unit-scoped role confers authority inside ONE organization\n // unit; counting it toward the ceiling would let a member who is merely ORG_ADMIN of one team\n // grant ORG_ADMIN across the whole tenant — the exact escalation this gate exists to stop, arriving\n // through the gate itself.\n for (const roleInfo of (executionContext.initiatorRoles ?? []).filter(isOrganizationWideRoleInfo)) {\n const scope = roleInfo.relatedPrimaryScope;\n for (const heldRole of roleInfo.roles) {\n const conferredRoles = roleHierarchyResolver(heldRole, scope);\n for (const conferredRole of conferredRoles) {\n effectiveCallerRoles.add(conferredRole);\n // The platform bypass is APPLICATION-scoped ONLY — see the doc block above.\n if (scope === ResourcePrimaryScope.APPLICATION && conferredRole === CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN) {\n holdsPlatformSuperAdmin = true;\n }\n }\n }\n }\n\n // The platform / cross-tenant super-admin may assign any role (this also covers the `admin` operation\n // variant, which is gated by exactly this role).\n if (holdsPlatformSuperAdmin) return;\n\n const escalatedRoles = requestedRoles.filter((role) => !effectiveCallerRoles.has(role));\n if (escalatedRoles.length === 0) return;\n\n // assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — deny an attempt to grant authority the caller does not\n // itself hold. Fail-closed privilege-escalation prevention on role-conferring writes.\n throw errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,\n context: {\n reason: 'role_ceiling_exceeded',\n escalatedRoles,\n callerRoles: [...effectiveCallerRoles],\n },\n });\n}\n\n/**\n * Collect the single authored `role` from an `ORGANIZATION_UNIT_MEMBERS` payload so it faces the\n * same ceiling as an organization-wide role grant.\n *\n * WHY THIS EXISTS. A unit assignment IS a role grant — it is the per-unit twin of\n * `OrganizationMember.roles`. It is not read by any authorization path yet (units become an\n * authorization axis in WS-C), but it is persisted and admin-editable, so an unchecked `ORG_OWNER`\n * written into an assignment is a pre-planted escalation that goes live the moment units are wired\n * into roles resolution. Gating it now removes that step.\n *\n * This replaced an array collector: until D-B5 the per-unit roles rode along inside an embedded\n * `organizationUnitsMembership` array on the members payload, so the gate had to sweep a list. As a\n * junction row there is exactly one role per payload.\n *\n * Defensive by design: this runs on UNPARSED caller input (custom-impl prefixes see the payload\n * before strict DTO validation), so a non-string role yields nothing rather than being trusted —\n * malformed input is rejected by schema validation further down the pipeline, and under-reporting\n * here can only ever deny, never grant.\n */\nexport function collectAuthoredOrganizationUnitRole(input: unknown): string[] {\n if (input === null || typeof input !== 'object') return [];\n const role = (input as { role?: unknown }).role;\n return typeof role === 'string' && role.length > 0 ? [role] : [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"role-ceiling.backend.utils.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/role-ceiling.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { CORE_APP_ROLES, ErrorCustomMessageReference, ErrorType, ExecutionContext_ExecutionType, ResourcePrimaryScope, isOrganizationWideRoleInfo } from '@wildo-ai/saas-models';\nimport type { Roles } from '@wildo-ai/saas-models';\nimport type { Container } from 'inversify';\nimport type { ExecutionContext } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';\nimport type { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';\nimport type { AuthorizationsBackendService } from '~wildo-backend-lib/security/authorizations/services/authorizations.backend.service';\nimport { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';\n\n/**\n * Expands one role into the full set of roles it effectively confers, within a given primary scope.\n *\n * This is the `inheritFrom` chain of the runtime role configuration — supply\n * `AuthorizationsBackendService.getRoleHierarchy` bound to its service instance. It is injected\n * rather than imported because the effective hierarchy is APPLICATION-CONFIGURABLE (apps register\n * custom roles at startup via `initializeRolesWithCustom`), so a statically-imported default table\n * would silently disagree with the roles the authorization layer actually enforces.\n *\n * The scope argument matters: `getRoleHierarchy` resolves against the APPLICATION role table or the\n * ORGANIZATIONS one, never both. A role string that is unknown in the passed scope expands to the\n * empty set — which is exactly the fail-closed behaviour this gate wants.\n */\nexport type RoleHierarchyResolver = (role: string, scope: ResourcePrimaryScope) => string[];\n\n/**\n * Bind a {@link RoleHierarchyResolver} to the container's live `AuthorizationsBackendService`.\n *\n * Resolution is LAZY (on first gate evaluation, then memoized) rather than at factory-construction\n * time: custom-implementation factories are built during module registration, which can run before\n * the authorization service is bound, and an eager `container.get` there would turn a role-gate into\n * a startup crash. Holding the service instance is safe across role reconfiguration —\n * `initializeRolesWithCustom` mutates the singleton's tables in place, and the hierarchy is read per\n * call, so a resolver captured at startup still sees roles registered afterwards.\n */\nexport function createRoleHierarchyResolver(container: Container): RoleHierarchyResolver {\n let authorizationsService: AuthorizationsBackendService | undefined;\n return (role, scope) => {\n authorizationsService ??= container.get<AuthorizationsBackendService>(SAAS_SERVICE_TYPES.AuthorizationsService);\n return authorizationsService.getRoleHierarchy(role as Roles, scope);\n };\n}\n\n/**\n * @wildo_source:part:start saas.backend.authorization.role-ceiling facet:layer:backend facet:audience:app-developer\n *\n * Role-ceiling gate — a principal may only grant roles it itself holds.\n *\n * WHY THIS EXISTS. Several resources carry a caller-settable `roles` array that becomes a principal's\n * live authority. Two families:\n *\n * - **Machine credentials** (`organizationOAuthClients` / `applicationOAuthClients` and their api-key\n * twins): the roles written at CREATE are exactly the roles every token minted for that client/key\n * carries at the request-auth choke point (`oauth-provider-token` → `machine-token-issuer`).\n * - **Organization membership** (`organizationMembers.roles`, and the per-unit roles nested in\n * `organizationUnitsMembership`): a membership row's `roles` array is read verbatim by\n * `execution-context-creator` to build `initiatorRoles` — the member's live authority on their very\n * next request.\n *\n * The operation-authorization layer only checks whether the CALLER may run the write at all — it never\n * compares the *requested* roles against the caller's own. Without this gate an `ORG_ADMIN` (the gate\n * for both member UPDATE and org-client CREATE) could grant `ORG_OWNER` to themselves, or mint a\n * credential carrying `APP_ADMIN_SUPER_ADMIN`. This is the missing \"you cannot grant authority you do\n * not hold\" check.\n *\n * SEMANTICS. Every requested role must lie within the caller's EFFECTIVE authority — the union of the\n * `inheritFrom` hierarchies of the roles the caller actually holds, each expanded within the scope of\n * the membership that granted it. Hierarchy-awareness is not a convenience: with the default table\n * (`ORG_OWNER → ORG_ADMIN → ORG_MANAGER → ORG_MEMBER → ORG_GUEST`) an `ORG_ADMIN`'s membership row\n * holds the literal string `ORG_ADMIN` and nothing else, so a raw set-membership test would reject\n * that admin granting the DEFAULT `ORG_MEMBER` role and break the entire invite flow — while still\n * correctly rejecting a grant of `ORG_OWNER`, which is UPSTREAM of the caller and therefore outside\n * the expansion.\n *\n * Fail-closed: a caller whose roles cannot be resolved is treated as holding none, so any requested\n * role is rejected.\n *\n * TWO DELIBERATE BYPASSES:\n * - **Platform super-admin** — a caller holding `APP_ADMIN_SUPER_ADMIN` *at APPLICATION scope* may\n * assign any role (that role IS the top of the ceiling). This also cleanly covers the cross-tenant\n * `admin` operation variant of the machine-credential resources, which is itself gated by\n * `APP_ADMIN_SUPER_ADMIN` and is meant to provision clients \"for any org\" — so no separate\n * variant-detection is needed. The scope qualifier is load-bearing: `roles` on a membership row is\n * a free-form string (`OrgRolesSchema` admits any `z.string().min(1)`), so without it a tenant\n * admin who wrote the literal text `APP_ADMIN_SUPER_ADMIN` into an ORGANIZATIONS-scoped membership\n * would unlock this bypass. The authorization layer already refuses to honour that string\n * cross-scope (`getRoleHierarchy` partitions the two role tables); this gate must not be the\n * weaker link.\n * - **System / internal writes** — an `INTERNALLY_INITIATED_REQUEST` execution (seeds, provisioning,\n * `createAsSystem`) is the framework itself, not a user principal (it synthesises a super-admin\n * system EC), and carries no human ceiling — it is trusted to assign any role.\n *\n * SCOPE OF THE COMPARISON. The caller's effective roles are unioned across every membership they\n * hold, without checking that the granting membership targets the same organization as the write.\n * That is deliberate and safe HERE because the operation-authorization layer has already confined the\n * write to a scope the caller may act in (`authorizeOrganizations` / the parent-scope filter); this\n * gate answers \"how high\", not \"where\". A future units-aware authorization axis that narrows *within*\n * an organization must revisit that assumption.\n *\n * EXTENDING. Wire this into the CREATE (and any roles-mutating UPDATE) path of ANY resource whose\n * `roles` field is caller-settable, passing the roles AS AUTHORED BY THE CALLER — not the\n * post-resolution set. Framework-injected defaults (e.g. an organization type's `defaultMemberRole`)\n * are policy-derived, not a caller request, and must not be measured against the caller's ceiling.\n *\n * assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — prevents a principal from granting authority it\n * does not itself hold. The denial is an access-control decision.\n *\n * @wildo_source:part:end saas.backend.authorization.role-ceiling\n */\nexport function assertRequestedRolesWithinCallerCeiling(\n executionContext: ExecutionContext<any>,\n requestedRoles: readonly string[] | undefined,\n errorBuilder: ErrorBuilderBackendService,\n roleHierarchyResolver: RoleHierarchyResolver,\n): void {\n if (!requestedRoles || requestedRoles.length === 0) return;\n\n // System / internal writes (seeds, provisioning, `createAsSystem`) are the framework, not a user\n // principal — they synthesise an INTERNALLY_INITIATED_REQUEST super-admin EC and assign any role.\n if (executionContext.executionType === ExecutionContext_ExecutionType.INTERNALLY_INITIATED_REQUEST) {\n return;\n }\n\n // Expand each held role into everything it confers, WITHIN the scope of the membership that granted\n // it. Cross-scope contamination is impossible by construction: an ORGANIZATIONS-scoped entry is\n // resolved against the org role table only.\n const effectiveCallerRoles = new Set<string>();\n let holdsPlatformSuperAdmin = false;\n // ORGANIZATION-WIDE GRANTS ONLY. A unit-scoped role confers authority inside ONE organization\n // unit; counting it toward the ceiling would let a member who is merely ORG_ADMIN of one team\n // grant ORG_ADMIN across the whole tenant — the exact escalation this gate exists to stop, arriving\n // through the gate itself.\n for (const roleInfo of (executionContext.initiatorRoles ?? []).filter(isOrganizationWideRoleInfo)) {\n const scope = roleInfo.relatedPrimaryScope;\n for (const heldRole of roleInfo.roles) {\n const conferredRoles = roleHierarchyResolver(heldRole, scope);\n for (const conferredRole of conferredRoles) {\n effectiveCallerRoles.add(conferredRole);\n // The platform bypass is APPLICATION-scoped ONLY — see the doc block above.\n if (scope === ResourcePrimaryScope.APPLICATION && conferredRole === CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN) {\n holdsPlatformSuperAdmin = true;\n }\n }\n }\n }\n\n // The platform / cross-tenant super-admin may assign any role (this also covers the `admin` operation\n // variant, which is gated by exactly this role).\n if (holdsPlatformSuperAdmin) return;\n\n const escalatedRoles = requestedRoles.filter((role) => !effectiveCallerRoles.has(role));\n if (escalatedRoles.length === 0) return;\n\n // assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — deny an attempt to grant authority the caller does not\n // itself hold. Fail-closed privilege-escalation prevention on role-conferring writes.\n throw errorBuilder.buildError(ErrorType.AUTHORIZATION, executionContext, {\n customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,\n context: {\n reason: 'role_ceiling_exceeded',\n escalatedRoles,\n callerRoles: [...effectiveCallerRoles],\n },\n });\n}\n\n/**\n * Collect the single authored `role` from an `ORGANIZATION_UNIT_MEMBERS` payload so it faces the\n * same ceiling as an organization-wide role grant.\n *\n * WHY THIS EXISTS. A unit assignment IS a role grant — it is the per-unit twin of\n * `OrganizationMember.roles`. It is not read by any authorization path yet (units become an\n * authorization axis in WS-C), but it is persisted and admin-editable, so an unchecked `ORG_OWNER`\n * written into an assignment is a pre-planted escalation that goes live the moment units are wired\n * into roles resolution. Gating it now removes that step.\n *\n * This replaced an array collector: until D-B5 the per-unit roles rode along inside an embedded\n * `organizationUnitsMembership` array on the members payload, so the gate had to sweep a list. As a\n * junction row there is exactly one role per payload.\n *\n * Defensive by design: this runs on UNPARSED caller input (custom-impl prefixes see the payload\n * before strict DTO validation), so a non-string role yields nothing rather than being trusted —\n * malformed input is rejected by schema validation further down the pipeline, and under-reporting\n * here can only ever deny, never grant.\n */\nexport function collectAuthoredOrganizationUnitRole(input: unknown): string[] {\n if (input === null || typeof input !== 'object') return [];\n const role = (input as { role?: unknown }).role;\n return typeof role === 'string' && role.length > 0 ? [role] : [];\n}\n"]}
|