@wildo-ai/saas-backend-lib 1.1.2 → 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.map +1 -1
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +27 -6
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.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 +47 -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 +96 -29
- 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/infrastructure-tier-contract.backend.d.ts.map +1 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js +9 -1
- package/dist/esm/base-classes/services/repositories/infrastructure-tier-contract.backend.js.map +1 -1
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +49 -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 +171 -18
- 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.map +1 -1
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +23 -3
- 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.map +1 -1
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +20 -0
- 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-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 +529 -41
- 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 +48 -7
- 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 +225 -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 +340 -62
- 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 +244 -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 +386 -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 +6 -2
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.d.ts.map +1 -1
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js +31 -9
- package/dist/esm/compliance/audit-trails/services/siem-export-config-cache-invalidation.custom-impl.backend.service.js.map +1 -1
- 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 +57 -1
- 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 +31 -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/models/app-config.backend.schemas.d.ts +142 -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 +33 -0
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -1
- package/dist/esm/config/services/app-configuration.backend.utils.js +39 -1
- 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/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/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 +129 -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/external-data-pipeline-run.backend.service.d.ts +59 -2
- 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 +52 -17
- package/dist/esm/external-data/external-data-pipeline-run.backend.service.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 +292 -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 +533 -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.map +1 -1
- package/dist/esm/files/controllers/file.controller.js +21 -13
- package/dist/esm/files/controllers/file.controller.js.map +1 -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 +39 -15
- package/dist/esm/files/handlers/resource-file-upload-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 +53 -2
- package/dist/esm/files/services/file-upload-grant.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/file-upload-grant.backend.service.js +127 -3
- package/dist/esm/files/services/file-upload-grant.backend.service.js.map +1 -1
- package/dist/esm/files/services/files.backend.service.d.ts +68 -0
- package/dist/esm/files/services/files.backend.service.d.ts.map +1 -1
- package/dist/esm/files/services/files.backend.service.js +175 -5
- 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/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 +196 -40
- 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 +28 -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 +204 -18
- 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.map +1 -1
- package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +8 -4
- 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 +11 -4
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +31 -4
- 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 +78 -10
- package/dist/esm/inject/models/container.js.map +1 -1
- package/dist/esm/inject/models/service-types.d.ts +17 -3
- package/dist/esm/inject/models/service-types.d.ts.map +1 -1
- package/dist/esm/inject/models/service-types.js +19 -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 +20 -0
- package/dist/esm/mcp/controllers/mcp.controller.js.map +1 -1
- package/dist/esm/mcp/services/mcp-server.backend.service.d.ts +56 -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 +107 -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.map +1 -1
- package/dist/esm/mcp/services/mcp-tool-adapter.backend.service.js +22 -0
- 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 +99 -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 +422 -66
- 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 +46 -1
- package/dist/esm/notifications/webhooks/outbound/batches/m2m-webhook-delivery.batch.backend.service.js.map +1 -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 +16 -6
- 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 +12 -12
- 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/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 +32 -8
- 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 +14 -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/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 +90 -6
- 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/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 +19 -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 +261 -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/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.map +1 -1
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +68 -1
- 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-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 +17 -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 +49 -17
- 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/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/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 +74 -8
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -1
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js +175 -19
- 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/services/consumable-token.backend.service.d.ts +21 -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 +26 -16
- 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/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 +11 -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":"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","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":"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","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"]}
|
|
@@ -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":"AAAA,OAAO,EAAE,cAAc,EAAE,2BAA2B,EAAE,SAAS,EAAE,8BAA8B,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAMjL,OAAO,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAiBpF;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CAAC,SAAoB;IAC9D,IAAI,qBAA+D,CAAC;IACpE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACrB,qBAAqB,KAAK,SAAS,CAAC,GAAG,CAA+B,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;QAChH,OAAO,qBAAqB,CAAC,gBAAgB,CAAC,IAAa,EAAE,KAAK,CAAC,CAAC;IACtE,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,MAAM,UAAU,uCAAuC,CACrD,gBAAuC,EACvC,cAA6C,EAC7C,YAAwC,EACxC,qBAA4C;IAE5C,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE3D,iGAAiG;IACjG,kGAAkG;IAClG,IAAI,gBAAgB,CAAC,aAAa,KAAK,8BAA8B,CAAC,4BAA4B,EAAE,CAAC;QACnG,OAAO;IACT,CAAC;IAED,oGAAoG;IACpG,gGAAgG;IAChG,4CAA4C;IAC5C,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/C,IAAI,uBAAuB,GAAG,KAAK,CAAC;IACpC,8FAA8F;IAC9F,8FAA8F;IAC9F,oGAAoG;IACpG,2BAA2B;IAC3B,KAAK,MAAM,QAAQ,IAAI,CAAC,gBAAgB,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,0BAA0B,CAAC,EAAE,CAAC;QAClG,MAAM,KAAK,GAAG,QAAQ,CAAC,mBAAmB,CAAC;QAC3C,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACtC,MAAM,cAAc,GAAG,qBAAqB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC9D,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;gBAC3C,oBAAoB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACxC,4EAA4E;gBAC5E,IAAI,KAAK,KAAK,oBAAoB,CAAC,WAAW,IAAI,aAAa,KAAK,cAAc,CAAC,qBAAqB,EAAE,CAAC;oBACzG,uBAAuB,GAAG,IAAI,CAAC;gBACjC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,sGAAsG;IACtG,iDAAiD;IACjD,IAAI,uBAAuB;QAAE,OAAO;IAEpC,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAExC,2GAA2G;IAC3G,sFAAsF;IACtF,MAAM,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,aAAa,EAAE,gBAAgB,EAAE;QACvE,sBAAsB,EAAE,2BAA2B,CAAC,4BAA4B;QAChF,OAAO,EAAE;YACP,MAAM,EAAE,uBAAuB;YAC/B,cAAc;YACd,WAAW,EAAE,CAAC,GAAG,oBAAoB,CAAC;SACvC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mCAAmC,CAAC,KAAc;IAChE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAI,KAA4B,CAAC,IAAI,CAAC;IAChD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC","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"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Role conferral — ONE derivation of "which role keys confer authority X, in scope S"
|
|
3
|
+
*
|
|
4
|
+
* assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — the shared derivation every authority floor
|
|
5
|
+
* measures its protected population with.
|
|
6
|
+
*
|
|
7
|
+
* ## The role-key vocabulary is genuinely OPEN, and closing it would be a defect
|
|
8
|
+
*
|
|
9
|
+
* Recorded here because the opposite is the obvious reading and was proposed as a finding: *"a
|
|
10
|
+
* membership's `roles` field is a free string, so an application-scope role value is storable in an
|
|
11
|
+
* organisation-scoped membership row."* Both halves of that are true. The conclusion — close the
|
|
12
|
+
* vocabulary — is not, and the evidence is in the framework's own contract:
|
|
13
|
+
*
|
|
14
|
+
* - `RolesSchema` is `union([enum(CORE_APP_ROLES), enum(CORE_ORG_ROLES), z.string().min(1)])`, and
|
|
15
|
+
* the third arm is the SUPPORTED feature, not an oversight: an application registers its own role
|
|
16
|
+
* keys at startup through `initializeRolesWithCustom`, and `RolesConfigurationSchema` is a
|
|
17
|
+
* `z.record(z.string(), RoleDefinitionSchema)`. A closed enum would delete custom roles.
|
|
18
|
+
* - So "is this string a valid role key?" has no static answer. It has a RUNTIME answer, per
|
|
19
|
+
* application, per scope — which is exactly what the role tables are.
|
|
20
|
+
*
|
|
21
|
+
* ## What IS closed, and where its one source lives
|
|
22
|
+
*
|
|
23
|
+
* The **scope partition**. Every role key belongs to exactly one `relatedPrimaryScope`, and
|
|
24
|
+
* `AuthorizationsBackendService.getRoleHierarchy(roleKey, scope)` is the single runtime source of
|
|
25
|
+
* that fact: it selects the APPLICATION table or the ORGANIZATIONS table and never consults both. A
|
|
26
|
+
* key unknown in the passed scope expands to the EMPTY chain, which is what makes an app-scope
|
|
27
|
+
* string written into an org-scoped membership row confer nothing — the safety comes from
|
|
28
|
+
* RESOLUTION, not from the field's type, and it must stay that way.
|
|
29
|
+
*
|
|
30
|
+
* ## What was duplicated, and is not any more
|
|
31
|
+
*
|
|
32
|
+
* The derivation BUILT ON that partition. `resolveSuperAdminConferringRoles` and
|
|
33
|
+
* `resolveOrganizationOwnerConferringRoles` were the same eleven lines twice, differing only in
|
|
34
|
+
* (table, scope, anchor) — each carrying its own paragraph re-establishing the partition argument
|
|
35
|
+
* above, in its own words, for its own reader. That is the shape `CLAUDE.md` asks to have one named
|
|
36
|
+
* runtime source for: not the role STRINGS, which cannot be closed, but the QUESTION asked of them.
|
|
37
|
+
*
|
|
38
|
+
* Two floors measure populations with it today ({@link resolveSuperAdminConferringRoles},
|
|
39
|
+
* {@link resolveOrganizationOwnerConferringRoles}); a third scope's floor is one call, not another
|
|
40
|
+
* copy.
|
|
41
|
+
*
|
|
42
|
+
* ## Why this module ships with NO test file of its own
|
|
43
|
+
*
|
|
44
|
+
* A direct suite was written and then DELETED, because measuring it showed every property it
|
|
45
|
+
* asserted was already covered — and its stated rationale was false. It claimed the floor suites
|
|
46
|
+
* "stub `getRoleHierarchy` as a function that IGNORES its scope"; both actually stub
|
|
47
|
+
* `(role, scope) => scope === <their own scope> ? table[role] : []`, and both tables already contain
|
|
48
|
+
* a CUSTOM, non-enum role key (`CUSTOM_PLATFORM_OWNER`, `CUSTOM_TENANT_PRINCIPAL`) reaching the
|
|
49
|
+
* anchor — so the open-vocabulary property is pinned too.
|
|
50
|
+
*
|
|
51
|
+
* Proven rather than assumed: binding the super-admin floor to `ORGANIZATIONS` scope instead of
|
|
52
|
+
* `APPLICATION` — the one regression the extraction newly makes possible — reddens THREE tests in
|
|
53
|
+
* `super-admin-floor.backend.utils.test.ts` on its own. The bindings are the coverage.
|
|
54
|
+
*
|
|
55
|
+
* So do not add a suite here to "cover the new module". If a THIRD binding appears, pin it in its
|
|
56
|
+
* own floor's suite the way these two are; that is where a wrong `scope` argument is observable.
|
|
57
|
+
*/
|
|
58
|
+
import type { ResourcePrimaryScope } from '@wildo-ai/saas-models';
|
|
59
|
+
/**
|
|
60
|
+
* Every role key in `declaredRoleKeys` whose `inheritFrom` chain reaches `anchorRole`, within
|
|
61
|
+
* `scope` — i.e. every role whose holder passes a gate that requires `anchorRole`.
|
|
62
|
+
*
|
|
63
|
+
* ## Why the derivation is shaped this way
|
|
64
|
+
*
|
|
65
|
+
* **It mirrors the authorization layer's own test.** `authorize` admits a caller when
|
|
66
|
+
* `getRoleHierarchy(heldRole, scope).includes(requiredRole)`. Deriving the set the same way is what
|
|
67
|
+
* keeps a floor counting exactly the principals the gates would let through; an independently
|
|
68
|
+
* written membership test is how the two drift, and a floor that measures a different population
|
|
69
|
+
* than the gate protects is worse than no floor — it reports a healthy count for an unprotected
|
|
70
|
+
* scope.
|
|
71
|
+
*
|
|
72
|
+
* **The anchor is seeded unconditionally rather than discovered by the walk.** If an application's
|
|
73
|
+
* role table somehow omitted the anchor key, `roleHierarchyResolver` would return an empty chain for
|
|
74
|
+
* every key, the conferring set would be empty, and the floor would then measure a population that
|
|
75
|
+
* is empty BY CONSTRUCTION — refusing every removal forever while protecting nothing.
|
|
76
|
+
*
|
|
77
|
+
* **`scope` is passed to the resolver, never assumed.** That single argument is what carries the
|
|
78
|
+
* closed half of the vocabulary (see this module's header): the caller states which table the keys
|
|
79
|
+
* are to be read against, and a key belonging to the other table expands to nothing. A caller that
|
|
80
|
+
* passed the wrong scope would silently get `[anchorRole]` — the seed — which is the fail-CLOSED
|
|
81
|
+
* direction for a floor (it under-counts the protected population and so refuses more, never less).
|
|
82
|
+
*
|
|
83
|
+
* @param declaredRoleKeys the keys of the LIVE role table for `scope`. Live, because the effective
|
|
84
|
+
* hierarchy is application-configurable and a statically-derived set would silently disagree with
|
|
85
|
+
* the roles the authorization layer actually honours.
|
|
86
|
+
*/
|
|
87
|
+
export declare function resolveRolesConferringAnchor(params: {
|
|
88
|
+
readonly anchorRole: string;
|
|
89
|
+
readonly scope: ResourcePrimaryScope;
|
|
90
|
+
readonly declaredRoleKeys: readonly string[];
|
|
91
|
+
readonly roleHierarchyResolver: (roleKey: string, scope: ResourcePrimaryScope) => string[];
|
|
92
|
+
}): string[];
|
|
93
|
+
//# sourceMappingURL=role-conferral.backend.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-conferral.backend.utils.d.ts","sourceRoot":"","sources":["../../../../../src/security/authorizations/role-conferral.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,qBAAqB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,KAAK,MAAM,EAAE,CAAC;CAC5F,GAAG,MAAM,EAAE,CAUX"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Role conferral — ONE derivation of "which role keys confer authority X, in scope S"
|
|
3
|
+
*
|
|
4
|
+
* assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — the shared derivation every authority floor
|
|
5
|
+
* measures its protected population with.
|
|
6
|
+
*
|
|
7
|
+
* ## The role-key vocabulary is genuinely OPEN, and closing it would be a defect
|
|
8
|
+
*
|
|
9
|
+
* Recorded here because the opposite is the obvious reading and was proposed as a finding: *"a
|
|
10
|
+
* membership's `roles` field is a free string, so an application-scope role value is storable in an
|
|
11
|
+
* organisation-scoped membership row."* Both halves of that are true. The conclusion — close the
|
|
12
|
+
* vocabulary — is not, and the evidence is in the framework's own contract:
|
|
13
|
+
*
|
|
14
|
+
* - `RolesSchema` is `union([enum(CORE_APP_ROLES), enum(CORE_ORG_ROLES), z.string().min(1)])`, and
|
|
15
|
+
* the third arm is the SUPPORTED feature, not an oversight: an application registers its own role
|
|
16
|
+
* keys at startup through `initializeRolesWithCustom`, and `RolesConfigurationSchema` is a
|
|
17
|
+
* `z.record(z.string(), RoleDefinitionSchema)`. A closed enum would delete custom roles.
|
|
18
|
+
* - So "is this string a valid role key?" has no static answer. It has a RUNTIME answer, per
|
|
19
|
+
* application, per scope — which is exactly what the role tables are.
|
|
20
|
+
*
|
|
21
|
+
* ## What IS closed, and where its one source lives
|
|
22
|
+
*
|
|
23
|
+
* The **scope partition**. Every role key belongs to exactly one `relatedPrimaryScope`, and
|
|
24
|
+
* `AuthorizationsBackendService.getRoleHierarchy(roleKey, scope)` is the single runtime source of
|
|
25
|
+
* that fact: it selects the APPLICATION table or the ORGANIZATIONS table and never consults both. A
|
|
26
|
+
* key unknown in the passed scope expands to the EMPTY chain, which is what makes an app-scope
|
|
27
|
+
* string written into an org-scoped membership row confer nothing — the safety comes from
|
|
28
|
+
* RESOLUTION, not from the field's type, and it must stay that way.
|
|
29
|
+
*
|
|
30
|
+
* ## What was duplicated, and is not any more
|
|
31
|
+
*
|
|
32
|
+
* The derivation BUILT ON that partition. `resolveSuperAdminConferringRoles` and
|
|
33
|
+
* `resolveOrganizationOwnerConferringRoles` were the same eleven lines twice, differing only in
|
|
34
|
+
* (table, scope, anchor) — each carrying its own paragraph re-establishing the partition argument
|
|
35
|
+
* above, in its own words, for its own reader. That is the shape `CLAUDE.md` asks to have one named
|
|
36
|
+
* runtime source for: not the role STRINGS, which cannot be closed, but the QUESTION asked of them.
|
|
37
|
+
*
|
|
38
|
+
* Two floors measure populations with it today ({@link resolveSuperAdminConferringRoles},
|
|
39
|
+
* {@link resolveOrganizationOwnerConferringRoles}); a third scope's floor is one call, not another
|
|
40
|
+
* copy.
|
|
41
|
+
*
|
|
42
|
+
* ## Why this module ships with NO test file of its own
|
|
43
|
+
*
|
|
44
|
+
* A direct suite was written and then DELETED, because measuring it showed every property it
|
|
45
|
+
* asserted was already covered — and its stated rationale was false. It claimed the floor suites
|
|
46
|
+
* "stub `getRoleHierarchy` as a function that IGNORES its scope"; both actually stub
|
|
47
|
+
* `(role, scope) => scope === <their own scope> ? table[role] : []`, and both tables already contain
|
|
48
|
+
* a CUSTOM, non-enum role key (`CUSTOM_PLATFORM_OWNER`, `CUSTOM_TENANT_PRINCIPAL`) reaching the
|
|
49
|
+
* anchor — so the open-vocabulary property is pinned too.
|
|
50
|
+
*
|
|
51
|
+
* Proven rather than assumed: binding the super-admin floor to `ORGANIZATIONS` scope instead of
|
|
52
|
+
* `APPLICATION` — the one regression the extraction newly makes possible — reddens THREE tests in
|
|
53
|
+
* `super-admin-floor.backend.utils.test.ts` on its own. The bindings are the coverage.
|
|
54
|
+
*
|
|
55
|
+
* So do not add a suite here to "cover the new module". If a THIRD binding appears, pin it in its
|
|
56
|
+
* own floor's suite the way these two are; that is where a wrong `scope` argument is observable.
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Every role key in `declaredRoleKeys` whose `inheritFrom` chain reaches `anchorRole`, within
|
|
60
|
+
* `scope` — i.e. every role whose holder passes a gate that requires `anchorRole`.
|
|
61
|
+
*
|
|
62
|
+
* ## Why the derivation is shaped this way
|
|
63
|
+
*
|
|
64
|
+
* **It mirrors the authorization layer's own test.** `authorize` admits a caller when
|
|
65
|
+
* `getRoleHierarchy(heldRole, scope).includes(requiredRole)`. Deriving the set the same way is what
|
|
66
|
+
* keeps a floor counting exactly the principals the gates would let through; an independently
|
|
67
|
+
* written membership test is how the two drift, and a floor that measures a different population
|
|
68
|
+
* than the gate protects is worse than no floor — it reports a healthy count for an unprotected
|
|
69
|
+
* scope.
|
|
70
|
+
*
|
|
71
|
+
* **The anchor is seeded unconditionally rather than discovered by the walk.** If an application's
|
|
72
|
+
* role table somehow omitted the anchor key, `roleHierarchyResolver` would return an empty chain for
|
|
73
|
+
* every key, the conferring set would be empty, and the floor would then measure a population that
|
|
74
|
+
* is empty BY CONSTRUCTION — refusing every removal forever while protecting nothing.
|
|
75
|
+
*
|
|
76
|
+
* **`scope` is passed to the resolver, never assumed.** That single argument is what carries the
|
|
77
|
+
* closed half of the vocabulary (see this module's header): the caller states which table the keys
|
|
78
|
+
* are to be read against, and a key belonging to the other table expands to nothing. A caller that
|
|
79
|
+
* passed the wrong scope would silently get `[anchorRole]` — the seed — which is the fail-CLOSED
|
|
80
|
+
* direction for a floor (it under-counts the protected population and so refuses more, never less).
|
|
81
|
+
*
|
|
82
|
+
* @param declaredRoleKeys the keys of the LIVE role table for `scope`. Live, because the effective
|
|
83
|
+
* hierarchy is application-configurable and a statically-derived set would silently disagree with
|
|
84
|
+
* the roles the authorization layer actually honours.
|
|
85
|
+
*/
|
|
86
|
+
export function resolveRolesConferringAnchor(params) {
|
|
87
|
+
const conferringRoles = new Set([params.anchorRole]);
|
|
88
|
+
for (const roleKey of params.declaredRoleKeys) {
|
|
89
|
+
if (params.roleHierarchyResolver(roleKey, params.scope).includes(params.anchorRole)) {
|
|
90
|
+
conferringRoles.add(roleKey);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return [...conferringRoles];
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=role-conferral.backend.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"role-conferral.backend.utils.js","sourceRoot":"","sources":["../../../../../src/security/authorizations/role-conferral.backend.utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAK5C;IACC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IAE7D,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC9C,IAAI,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACpF,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["/**\n * # Role conferral — ONE derivation of \"which role keys confer authority X, in scope S\"\n *\n * assurance-control: WILDO.ACCESS.LEAST_PRIVILEGE — the shared derivation every authority floor\n * measures its protected population with.\n *\n * ## The role-key vocabulary is genuinely OPEN, and closing it would be a defect\n *\n * Recorded here because the opposite is the obvious reading and was proposed as a finding: *\"a\n * membership's `roles` field is a free string, so an application-scope role value is storable in an\n * organisation-scoped membership row.\"* Both halves of that are true. The conclusion — close the\n * vocabulary — is not, and the evidence is in the framework's own contract:\n *\n * - `RolesSchema` is `union([enum(CORE_APP_ROLES), enum(CORE_ORG_ROLES), z.string().min(1)])`, and\n * the third arm is the SUPPORTED feature, not an oversight: an application registers its own role\n * keys at startup through `initializeRolesWithCustom`, and `RolesConfigurationSchema` is a\n * `z.record(z.string(), RoleDefinitionSchema)`. A closed enum would delete custom roles.\n * - So \"is this string a valid role key?\" has no static answer. It has a RUNTIME answer, per\n * application, per scope — which is exactly what the role tables are.\n *\n * ## What IS closed, and where its one source lives\n *\n * The **scope partition**. Every role key belongs to exactly one `relatedPrimaryScope`, and\n * `AuthorizationsBackendService.getRoleHierarchy(roleKey, scope)` is the single runtime source of\n * that fact: it selects the APPLICATION table or the ORGANIZATIONS table and never consults both. A\n * key unknown in the passed scope expands to the EMPTY chain, which is what makes an app-scope\n * string written into an org-scoped membership row confer nothing — the safety comes from\n * RESOLUTION, not from the field's type, and it must stay that way.\n *\n * ## What was duplicated, and is not any more\n *\n * The derivation BUILT ON that partition. `resolveSuperAdminConferringRoles` and\n * `resolveOrganizationOwnerConferringRoles` were the same eleven lines twice, differing only in\n * (table, scope, anchor) — each carrying its own paragraph re-establishing the partition argument\n * above, in its own words, for its own reader. That is the shape `CLAUDE.md` asks to have one named\n * runtime source for: not the role STRINGS, which cannot be closed, but the QUESTION asked of them.\n *\n * Two floors measure populations with it today ({@link resolveSuperAdminConferringRoles},\n * {@link resolveOrganizationOwnerConferringRoles}); a third scope's floor is one call, not another\n * copy.\n *\n * ## Why this module ships with NO test file of its own\n *\n * A direct suite was written and then DELETED, because measuring it showed every property it\n * asserted was already covered — and its stated rationale was false. It claimed the floor suites\n * \"stub `getRoleHierarchy` as a function that IGNORES its scope\"; both actually stub\n * `(role, scope) => scope === <their own scope> ? table[role] : []`, and both tables already contain\n * a CUSTOM, non-enum role key (`CUSTOM_PLATFORM_OWNER`, `CUSTOM_TENANT_PRINCIPAL`) reaching the\n * anchor — so the open-vocabulary property is pinned too.\n *\n * Proven rather than assumed: binding the super-admin floor to `ORGANIZATIONS` scope instead of\n * `APPLICATION` — the one regression the extraction newly makes possible — reddens THREE tests in\n * `super-admin-floor.backend.utils.test.ts` on its own. The bindings are the coverage.\n *\n * So do not add a suite here to \"cover the new module\". If a THIRD binding appears, pin it in its\n * own floor's suite the way these two are; that is where a wrong `scope` argument is observable.\n */\n\nimport type { ResourcePrimaryScope } from '@wildo-ai/saas-models';\n\n/**\n * Every role key in `declaredRoleKeys` whose `inheritFrom` chain reaches `anchorRole`, within\n * `scope` — i.e. every role whose holder passes a gate that requires `anchorRole`.\n *\n * ## Why the derivation is shaped this way\n *\n * **It mirrors the authorization layer's own test.** `authorize` admits a caller when\n * `getRoleHierarchy(heldRole, scope).includes(requiredRole)`. Deriving the set the same way is what\n * keeps a floor counting exactly the principals the gates would let through; an independently\n * written membership test is how the two drift, and a floor that measures a different population\n * than the gate protects is worse than no floor — it reports a healthy count for an unprotected\n * scope.\n *\n * **The anchor is seeded unconditionally rather than discovered by the walk.** If an application's\n * role table somehow omitted the anchor key, `roleHierarchyResolver` would return an empty chain for\n * every key, the conferring set would be empty, and the floor would then measure a population that\n * is empty BY CONSTRUCTION — refusing every removal forever while protecting nothing.\n *\n * **`scope` is passed to the resolver, never assumed.** That single argument is what carries the\n * closed half of the vocabulary (see this module's header): the caller states which table the keys\n * are to be read against, and a key belonging to the other table expands to nothing. A caller that\n * passed the wrong scope would silently get `[anchorRole]` — the seed — which is the fail-CLOSED\n * direction for a floor (it under-counts the protected population and so refuses more, never less).\n *\n * @param declaredRoleKeys the keys of the LIVE role table for `scope`. Live, because the effective\n * hierarchy is application-configurable and a statically-derived set would silently disagree with\n * the roles the authorization layer actually honours.\n */\nexport function resolveRolesConferringAnchor(params: {\n readonly anchorRole: string;\n readonly scope: ResourcePrimaryScope;\n readonly declaredRoleKeys: readonly string[];\n readonly roleHierarchyResolver: (roleKey: string, scope: ResourcePrimaryScope) => string[];\n}): string[] {\n const conferringRoles = new Set<string>([params.anchorRole]);\n\n for (const roleKey of params.declaredRoleKeys) {\n if (params.roleHierarchyResolver(roleKey, params.scope).includes(params.anchorRole)) {\n conferringRoles.add(roleKey);\n }\n }\n\n return [...conferringRoles];\n}\n"]}
|
|
@@ -50,9 +50,132 @@
|
|
|
50
50
|
* tenant, not over the tenant row, and every org-wide gate in the authorization service filters
|
|
51
51
|
* those out; counting one here would let a unit member enumerate the tenant they are narrowed inside.
|
|
52
52
|
*/
|
|
53
|
-
import { CoreResourceOperation, ExecutionContext_ExecutionType } from '@wildo-ai/saas-models';
|
|
53
|
+
import { CoreResourceOperation, ExecutionContext_ExecutionType, ResourcePrimaryScope } from '@wildo-ai/saas-models';
|
|
54
54
|
/** The queryable key a scope-root row is addressed by. Named once so no call site can typo it. */
|
|
55
55
|
export declare const SCOPE_ROOT_CONFINEMENT_FIELD = "_id";
|
|
56
|
+
/**
|
|
57
|
+
* WHY a given scope root is, or is not, row-confined.
|
|
58
|
+
*
|
|
59
|
+
* A named vocabulary rather than four prose comments, because "which roots owe confinement" is a
|
|
60
|
+
* closed semantic question and had been answered four times, in four files, in four different words
|
|
61
|
+
* — the shape `CLAUDE.md` asks to have one runtime source for. It also makes the answer READABLE
|
|
62
|
+
* from the authority itself instead of from the resource configs it governs.
|
|
63
|
+
*
|
|
64
|
+
* THE RULE THAT DECIDES MEMBERSHIP, stated once so the next scope is not settled by taste:
|
|
65
|
+
*
|
|
66
|
+
* > **A scope root owes row confinement exactly when a caller's authority for that scope names ONE
|
|
67
|
+
* > INSTANCE of it, while the collection holds every instance.**
|
|
68
|
+
*
|
|
69
|
+
* That is a fact about ROLE ENTRIES, and it is measurable rather than a judgement: only an
|
|
70
|
+
* `ORGANIZATIONS` entry carries a `relatedResourceId` selecting a particular scope instance. An
|
|
71
|
+
* `APPLICATION` entry names the deployment (there is one), and `USER_SELF` / `ANONYMOUS` have no
|
|
72
|
+
* role entries at all — their instance comes from `initiatorIds`, which the request supplies about
|
|
73
|
+
* ITSELF and which therefore cannot be an authority set. So on today's vocabulary exactly one root
|
|
74
|
+
* owes it, and that is a derivation, not a denominator someone chose.
|
|
75
|
+
*/
|
|
76
|
+
export declare enum ScopeRootConfinementDisposition {
|
|
77
|
+
/**
|
|
78
|
+
* Confined to the tenants the caller holds an organization-WIDE role entry for. The only
|
|
79
|
+
* disposition that produces a predicate.
|
|
80
|
+
*/
|
|
81
|
+
CONFINED_TO_CALLER_ORGANIZATIONS = "CONFINED_TO_CALLER_ORGANIZATIONS",
|
|
82
|
+
/**
|
|
83
|
+
* The root's HTTP collection surface is the APPLICATION-tier administrative directory, and the
|
|
84
|
+
* caller's authority for it is application-wide — so "all rows" is not wider than the authority
|
|
85
|
+
* that reached them. Narrower callers reach the same rows only through a route that confines them
|
|
86
|
+
* by a DIFFERENT mechanism (`users` is enumerated per tenant through
|
|
87
|
+
* `/organizations/{organizationId}/users/search`, whose junction filter intersects `_id` with the
|
|
88
|
+
* tenant's membership; the global routes stay admin-gated).
|
|
89
|
+
*
|
|
90
|
+
* ## ⚠️ The ELEVATION asymmetry this disposition carries, stated so nobody has to re-derive it
|
|
91
|
+
*
|
|
92
|
+
* Read against the per-row door, the sentence above is the whole of the control and it is a
|
|
93
|
+
* statement about a STANDING role. Measured 2026-09-09:
|
|
94
|
+
*
|
|
95
|
+
* | | per-row crossing | this directory read |
|
|
96
|
+
* |---|---|---|
|
|
97
|
+
* | declared per variant | `admitsCrossTenantPlatformAdministration` | nothing |
|
|
98
|
+
* | elevation required | a usable, time-bound, justified `platformAccessGrants` row | none |
|
|
99
|
+
* | role tier | `APP_ADMIN_SUPER_ADMIN` | `APP_ADMIN_VIEWER` (`users`), `ORG_MEMBER` (`applications` LIST) |
|
|
100
|
+
* | evidence | `CROSS_TENANT_ADMINISTRATIVE_ACCESS`, naming the authorizing grant | `PLATFORM_DIRECTORY_ACCESS`, naming no elevation |
|
|
101
|
+
*
|
|
102
|
+
* So the NARROW act is governed and the WIDE one is not, and the wide one sits at a strictly lower
|
|
103
|
+
* role tier. That is the correct reading of the finding, and it is worse than "not symmetric".
|
|
104
|
+
*
|
|
105
|
+
* ## Why the grant model cannot govern it, and what that does NOT mean
|
|
106
|
+
*
|
|
107
|
+
* `hasUsablePlatformAccessGrant` needs a TARGET tenant and answers `false` on an empty one; a
|
|
108
|
+
* collection call names none. So the EXISTING mechanism is structurally inapplicable here — but
|
|
109
|
+
* that is a fact about the mechanism, not a proof that prevention is impossible, and the
|
|
110
|
+
* distinction matters because the shipped `PLATFORM_DIRECTORY_ACCESS` JSDoc states the stronger
|
|
111
|
+
* form and a reader could take it as "do not try".
|
|
112
|
+
*
|
|
113
|
+
* An application-wide grant KIND is buildable. What blocks it is a decision, not structure, and the
|
|
114
|
+
* decision is WHO APPROVES: a tenant grant is approved by the tenant it names (Lockbox), and an
|
|
115
|
+
* application-wide one names none — so it is either self-service (auto-approved, which is the
|
|
116
|
+
* grant model's own default posture) or two-person, which
|
|
117
|
+
* `.claude/rules/administrative-continuity-floors.md` recommends for the widest acts. Nobody may
|
|
118
|
+
* pick that unilaterally.
|
|
119
|
+
*
|
|
120
|
+
* A related choice is already RECORDED and should not be quietly reversed: a browsable platform
|
|
121
|
+
* tenant directory was considered and rejected, on the reasoning that industry practice (Customer
|
|
122
|
+
* Lockbox, Access Approval) has the tenant id arrive out of band with the customer's support
|
|
123
|
+
* ticket. That reasoning also answers the grant flow's bootstrap gap — an operator needs an
|
|
124
|
+
* `organizationId` to request a grant and no surface yields one — so reopening the elevation
|
|
125
|
+
* question means reopening that decision too.
|
|
126
|
+
*
|
|
127
|
+
* ## What was rejected on MEASUREMENT rather than on cost
|
|
128
|
+
*
|
|
129
|
+
* Confining this read to tenants the caller holds a grant for is not merely undesirable here, it
|
|
130
|
+
* is structurally unavailable for the widest case: `users` rows carry NO tenant column at all
|
|
131
|
+
* (membership lives in `organizationMembers`), so there is nothing for a tenant predicate to bind
|
|
132
|
+
* to. Any such confinement would be a junction query that also removes the tenant-less user — the
|
|
133
|
+
* person who has just signed up and belongs to nobody — from the only surface that can find them.
|
|
134
|
+
*/
|
|
135
|
+
UNCONFINED_APPLICATION_TIER_DIRECTORY = "UNCONFINED_APPLICATION_TIER_DIRECTORY",
|
|
136
|
+
/**
|
|
137
|
+
* ONE DATABASE PER APPLICATION. "An application's organizations live in that application's own
|
|
138
|
+
* database" — so this collection holds this deployment's own row and a caller can only ever see
|
|
139
|
+
* the application they are already using. Safe by ARCHITECTURE, not by a predicate, which is why
|
|
140
|
+
* it is spelled out: the default LIST/SEARCH variants are gated `ORG_MEMBER`, one role tier BELOW
|
|
141
|
+
* the `organizations` hole, and would be a full directory the day a second row existed.
|
|
142
|
+
*
|
|
143
|
+
* The premise is ASSERTED rather than assumed, and only a lane with a real store can assert it:
|
|
144
|
+
* `examples/wonder-todos/e2e/applications-scope-root-list-confinement.e2e.ts` fails if the
|
|
145
|
+
* deployment ever holds more than one application row. (The unit probe beside this authority
|
|
146
|
+
* asserts the complementary half — that this declaration and the compiled filter agree.)
|
|
147
|
+
*/
|
|
148
|
+
UNCONFINED_SINGLE_ROW_BY_ARCHITECTURE = "UNCONFINED_SINGLE_ROW_BY_ARCHITECTURE",
|
|
149
|
+
/**
|
|
150
|
+
* There is NOTHING to confine to. An anonymous session is a pre-authentication visitor of the
|
|
151
|
+
* application; it has no organization, so a "confined" listing would name a relationship that does
|
|
152
|
+
* not exist. `APP_ADMIN_SUPER_ADMIN` is the whole of the control, and it is the right one.
|
|
153
|
+
*
|
|
154
|
+
* ⚠️ If anonymous sessions ever gain a tenant association this becomes an ORGANIZATIONS-axis
|
|
155
|
+
* question and the disposition moves to {@link ScopeRootConfinementDisposition.CONFINED_TO_CALLER_ORGANIZATIONS}.
|
|
156
|
+
*/
|
|
157
|
+
UNCONFINED_NO_CONFINING_RELATIONSHIP = "UNCONFINED_NO_CONFINING_RELATIONSHIP"
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The disposition of every scope root, TOTAL over `ResourcePrimaryScope`.
|
|
161
|
+
*
|
|
162
|
+
* Total on purpose (`.claude/rules/derive-before-you-ask.md` #3): a scope added to the vocabulary
|
|
163
|
+
* tomorrow is a COMPILE ERROR here, so someone has to answer the rule above for it rather than
|
|
164
|
+
* inheriting silence. The predicate this replaced was `resourcePrimaryScope !== ORGANIZATIONS` with
|
|
165
|
+
* a comment saying the other three "would change four surfaces this analysis did not measure" —
|
|
166
|
+
* true when written, and by then no longer true: all four had since been measured
|
|
167
|
+
* (`scope-root-collection-confinement.probe.test.ts`, the RESIDUAL sweep) and each answer recorded
|
|
168
|
+
* in a different resource config. This map is where that answer now lives, once.
|
|
169
|
+
*/
|
|
170
|
+
export declare const SCOPE_ROOT_CONFINEMENT_DISPOSITIONS: Readonly<Record<ResourcePrimaryScope, ScopeRootConfinementDisposition>>;
|
|
171
|
+
/**
|
|
172
|
+
* The disposition governing this resource, or `undefined` when it is not a scope root at all.
|
|
173
|
+
*
|
|
174
|
+
* Exported so a test — or a future gate — can ask the SAME question this authority answers instead
|
|
175
|
+
* of re-deriving it from the resource configs, which is how the four recorded answers came to be
|
|
176
|
+
* four separate paragraphs in the first place.
|
|
177
|
+
*/
|
|
178
|
+
export declare function resolveScopeRootConfinementDisposition(resource: ScopeRootCollectionConfinementResource): ScopeRootConfinementDisposition | undefined;
|
|
56
179
|
/** What this authority needs from the execution context. Deliberately narrow, like its siblings. */
|
|
57
180
|
export interface ScopeRootCollectionConfinementSignal {
|
|
58
181
|
readonly executionType: ExecutionContext_ExecutionType;
|