@wildo-ai/saas-backend-lib 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/__tests__/setup.d.ts +7 -0
- package/dist/esm/__tests__/setup.d.ts.map +1 -0
- package/dist/esm/__tests__/setup.js +14 -0
- package/dist/esm/__tests__/setup.js.map +1 -0
- package/dist/esm/__tests__/test-container.d.ts +39 -0
- package/dist/esm/__tests__/test-container.d.ts.map +1 -0
- package/dist/esm/__tests__/test-container.js +94 -0
- package/dist/esm/__tests__/test-container.js.map +1 -0
- package/dist/esm/applications/models/applications.backend.schemas.d.ts +11 -0
- package/dist/esm/applications/models/applications.backend.schemas.d.ts.map +1 -0
- package/dist/esm/applications/models/applications.backend.schemas.js +15 -0
- package/dist/esm/applications/models/applications.backend.schemas.js.map +1 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts +12 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +30 -0
- package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -0
- package/dist/esm/base-classes/models/repositories.backend.schemas.d.ts +98 -0
- package/dist/esm/base-classes/models/repositories.backend.schemas.d.ts.map +1 -0
- package/dist/esm/base-classes/models/repositories.backend.schemas.js +11 -0
- package/dist/esm/base-classes/models/repositories.backend.schemas.js.map +1 -0
- package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.d.ts +31 -0
- package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.js +52 -0
- package/dist/esm/base-classes/services/__tests__/mock-resource-operation-helper.service.js.map +1 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-custom-execution.service.d.ts +56 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-custom-execution.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-custom-execution.service.js +52 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-custom-execution.service.js.map +1 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-executor.backend.service.d.ts +33 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-executor.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-executor.backend.service.js +125 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-executor.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.d.ts +20 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.js +45 -0
- package/dist/esm/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/controllers/abstract-controller.backend.service.d.ts +133 -0
- package/dist/esm/base-classes/services/controllers/abstract-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/controllers/abstract-controller.backend.service.js +280 -0
- package/dist/esm/base-classes/services/controllers/abstract-controller.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts +147 -0
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js +1320 -0
- package/dist/esm/base-classes/services/controllers/controller-resource.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts +107 -0
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js +369 -0
- package/dist/esm/base-classes/services/controllers/controllers-registry-handler.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/controllers/validate-field-handler.backend.service.d.ts +194 -0
- package/dist/esm/base-classes/services/controllers/validate-field-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/controllers/validate-field-handler.backend.service.js +417 -0
- package/dist/esm/base-classes/services/controllers/validate-field-handler.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.d.ts +9 -0
- package/dist/esm/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.js +35 -0
- package/dist/esm/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.js.map +1 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts +107 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js +800 -0
- package/dist/esm/base-classes/services/repositories/postgresql-resource-repository.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts +181 -0
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js +529 -0
- package/dist/esm/base-classes/services/repositories/repositories-registry-handler.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts +245 -0
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js +1509 -0
- package/dist/esm/base-classes/services/repositories/repository-resource.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/resource-operations-helper.backend.service.d.ts +134 -0
- package/dist/esm/base-classes/services/resource-operations-helper.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/resource-operations-helper.backend.service.js +388 -0
- package/dist/esm/base-classes/services/resource-operations-helper.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/services/__tests__/mock-services-registry-handler.service.d.ts +9 -0
- package/dist/esm/base-classes/services/services/__tests__/mock-services-registry-handler.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/services/__tests__/mock-services-registry-handler.service.js +26 -0
- package/dist/esm/base-classes/services/services/__tests__/mock-services-registry-handler.service.js.map +1 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts +144 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.js +49 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts +84 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js +156 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js.map +1 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts +42 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js +94 -0
- package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js.map +1 -0
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +593 -0
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +4015 -0
- package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -0
- package/dist/esm/base-classes/utils/backend-type-utils.d.ts +43 -0
- package/dist/esm/base-classes/utils/backend-type-utils.d.ts.map +1 -0
- package/dist/esm/base-classes/utils/backend-type-utils.js +10 -0
- package/dist/esm/base-classes/utils/backend-type-utils.js.map +1 -0
- package/dist/esm/billing/services/back-office/abstract-billing.backend.service.d.ts +44 -0
- package/dist/esm/billing/services/back-office/abstract-billing.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/back-office/abstract-billing.backend.service.js +94 -0
- package/dist/esm/billing/services/back-office/abstract-billing.backend.service.js.map +1 -0
- package/dist/esm/billing/services/back-office/billing-feature-sync.backend.service.d.ts +102 -0
- package/dist/esm/billing/services/back-office/billing-feature-sync.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/back-office/billing-feature-sync.backend.service.js +405 -0
- package/dist/esm/billing/services/back-office/billing-feature-sync.backend.service.js.map +1 -0
- package/dist/esm/billing/services/back-office/billing-state.backend.service.d.ts +55 -0
- package/dist/esm/billing/services/back-office/billing-state.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/back-office/billing-state.backend.service.js +268 -0
- package/dist/esm/billing/services/back-office/billing-state.backend.service.js.map +1 -0
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts +83 -0
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js +371 -0
- package/dist/esm/billing/services/back-office/product-catalog-sync.backend.service.js.map +1 -0
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts +80 -0
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.js +255 -0
- package/dist/esm/billing/services/back-office/usage-metering.backend.service.js.map +1 -0
- package/dist/esm/billing/services/billing.utils.d.ts +17 -0
- package/dist/esm/billing/services/billing.utils.d.ts.map +1 -0
- package/dist/esm/billing/services/billing.utils.js +25 -0
- package/dist/esm/billing/services/billing.utils.js.map +1 -0
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.d.ts +50 -0
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js +290 -0
- package/dist/esm/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts +92 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.d.ts.map +1 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js +193 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-impl-utils.backend.js.map +1 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts +66 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.d.ts.map +1 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js +180 -0
- package/dist/esm/billing/services/custom-impl/billing-custom-implementations.backend.js.map +1 -0
- package/dist/esm/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.d.ts +31 -0
- package/dist/esm/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.js +100 -0
- package/dist/esm/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts +33 -0
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js +200 -0
- package/dist/esm/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.d.ts +58 -0
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js +362 -0
- package/dist/esm/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-adapter.backend.service.d.ts +19 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-adapter.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-adapter.backend.service.js +50 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-adapter.backend.service.js.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-capability-handler.backend.service.d.ts +21 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-capability-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-capability-handler.backend.service.js +32 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-capability-handler.backend.service.js.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts +114 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.d.ts.map +1 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js +569 -0
- package/dist/esm/billing/services/webhooks/billing-webhook-event-router.backend.service.js.map +1 -0
- package/dist/esm/billing/testing/billing-test-fixtures.d.ts +109 -0
- package/dist/esm/billing/testing/billing-test-fixtures.d.ts.map +1 -0
- package/dist/esm/billing/testing/billing-test-fixtures.js +200 -0
- package/dist/esm/billing/testing/billing-test-fixtures.js.map +1 -0
- package/dist/esm/billing/testing/mock-billing-provider.d.ts +152 -0
- package/dist/esm/billing/testing/mock-billing-provider.d.ts.map +1 -0
- package/dist/esm/billing/testing/mock-billing-provider.js +394 -0
- package/dist/esm/billing/testing/mock-billing-provider.js.map +1 -0
- package/dist/esm/charts/controllers/chart.backend.controller.d.ts +46 -0
- package/dist/esm/charts/controllers/chart.backend.controller.d.ts.map +1 -0
- package/dist/esm/charts/controllers/chart.backend.controller.js +214 -0
- package/dist/esm/charts/controllers/chart.backend.controller.js.map +1 -0
- package/dist/esm/charts/services/chart-registry.backend.service.d.ts +55 -0
- package/dist/esm/charts/services/chart-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/charts/services/chart-registry.backend.service.js +102 -0
- package/dist/esm/charts/services/chart-registry.backend.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/audit-logs.custom-impl.backend.service.d.ts +9 -0
- package/dist/esm/compliance/audit-trails/audit-logs.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/audit-logs.custom-impl.backend.service.js +80 -0
- package/dist/esm/compliance/audit-trails/audit-logs.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/__tests__/mock-audit-logs.service.d.ts +23 -0
- package/dist/esm/compliance/audit-trails/services/__tests__/mock-audit-logs.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/__tests__/mock-audit-logs.service.js +46 -0
- package/dist/esm/compliance/audit-trails/services/__tests__/mock-audit-logs.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts +73 -0
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js +291 -0
- package/dist/esm/compliance/audit-trails/services/audit-event-dispatcher.backend.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts +447 -0
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js +898 -0
- package/dist/esm/compliance/audit-trails/services/audit-logs.backend.service.js.map +1 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts +127 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.d.ts.map +1 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js +462 -0
- package/dist/esm/compliance/audit-trails/services/siem-webhook-delivery.backend.service.js.map +1 -0
- package/dist/esm/compliance/index.d.ts +2 -0
- package/dist/esm/compliance/index.d.ts.map +1 -0
- package/dist/esm/compliance/index.js +1 -0
- package/dist/esm/compliance/index.js.map +1 -0
- package/dist/esm/config/custom/application-config-controller.backend.service.d.ts +31 -0
- package/dist/esm/config/custom/application-config-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/config/custom/application-config-controller.backend.service.js +112 -0
- package/dist/esm/config/custom/application-config-controller.backend.service.js.map +1 -0
- package/dist/esm/config/models/app-config-overrides.backend.definitions.d.ts +29 -0
- package/dist/esm/config/models/app-config-overrides.backend.definitions.d.ts.map +1 -0
- package/dist/esm/config/models/app-config-overrides.backend.definitions.js +143 -0
- package/dist/esm/config/models/app-config-overrides.backend.definitions.js.map +1 -0
- package/dist/esm/config/models/app-config-secrets.backend.schemas.d.ts +56 -0
- package/dist/esm/config/models/app-config-secrets.backend.schemas.d.ts.map +1 -0
- package/dist/esm/config/models/app-config-secrets.backend.schemas.js +121 -0
- package/dist/esm/config/models/app-config-secrets.backend.schemas.js.map +1 -0
- package/dist/esm/config/models/app-config.backend-authored.definitions.d.ts +35 -0
- package/dist/esm/config/models/app-config.backend-authored.definitions.d.ts.map +1 -0
- package/dist/esm/config/models/app-config.backend-authored.definitions.js +89 -0
- package/dist/esm/config/models/app-config.backend-authored.definitions.js.map +1 -0
- package/dist/esm/config/models/app-config.backend.schemas.d.ts +1651 -0
- package/dist/esm/config/models/app-config.backend.schemas.d.ts.map +1 -0
- package/dist/esm/config/models/app-config.backend.schemas.js +478 -0
- package/dist/esm/config/models/app-config.backend.schemas.js.map +1 -0
- package/dist/esm/config/models/app-env-config.backend.schemas.d.ts +74 -0
- package/dist/esm/config/models/app-env-config.backend.schemas.d.ts.map +1 -0
- package/dist/esm/config/models/app-env-config.backend.schemas.js +115 -0
- package/dist/esm/config/models/app-env-config.backend.schemas.js.map +1 -0
- package/dist/esm/config/models/config-mutation-boundary.utils.d.ts +11 -0
- package/dist/esm/config/models/config-mutation-boundary.utils.d.ts.map +1 -0
- package/dist/esm/config/models/config-mutation-boundary.utils.js +50 -0
- package/dist/esm/config/models/config-mutation-boundary.utils.js.map +1 -0
- package/dist/esm/config/models/postgresql-env-config.backend.schemas.d.ts +48 -0
- package/dist/esm/config/models/postgresql-env-config.backend.schemas.d.ts.map +1 -0
- package/dist/esm/config/models/postgresql-env-config.backend.schemas.js +106 -0
- package/dist/esm/config/models/postgresql-env-config.backend.schemas.js.map +1 -0
- package/dist/esm/config/models/runtime-topology.backend.contracts.d.ts +12 -0
- package/dist/esm/config/models/runtime-topology.backend.contracts.d.ts.map +1 -0
- package/dist/esm/config/models/runtime-topology.backend.contracts.js +23 -0
- package/dist/esm/config/models/runtime-topology.backend.contracts.js.map +1 -0
- package/dist/esm/config/services/__tests__/mock-app-configuration.service.d.ts +39 -0
- package/dist/esm/config/services/__tests__/mock-app-configuration.service.d.ts.map +1 -0
- package/dist/esm/config/services/__tests__/mock-app-configuration.service.js +124 -0
- package/dist/esm/config/services/__tests__/mock-app-configuration.service.js.map +1 -0
- package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts +76 -0
- package/dist/esm/config/services/app-configuration-loader.backend.service.d.ts.map +1 -0
- package/dist/esm/config/services/app-configuration-loader.backend.service.js +375 -0
- package/dist/esm/config/services/app-configuration-loader.backend.service.js.map +1 -0
- package/dist/esm/config/services/app-configuration.backend.service.d.ts +148 -0
- package/dist/esm/config/services/app-configuration.backend.service.d.ts.map +1 -0
- package/dist/esm/config/services/app-configuration.backend.service.js +494 -0
- package/dist/esm/config/services/app-configuration.backend.service.js.map +1 -0
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts +17 -0
- package/dist/esm/config/services/app-configuration.backend.utils.d.ts.map +1 -0
- package/dist/esm/config/services/app-configuration.backend.utils.js +61 -0
- package/dist/esm/config/services/app-configuration.backend.utils.js.map +1 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts +70 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.d.ts.map +1 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.js +470 -0
- package/dist/esm/config/services/application-startup-config-validator.backend.service.js.map +1 -0
- package/dist/esm/databases/models/aggregation.backend.schemas.d.ts +136 -0
- package/dist/esm/databases/models/aggregation.backend.schemas.d.ts.map +1 -0
- package/dist/esm/databases/models/aggregation.backend.schemas.js +9 -0
- package/dist/esm/databases/models/aggregation.backend.schemas.js.map +1 -0
- package/dist/esm/databases/models/databases.backend.schemas.d.ts +32 -0
- package/dist/esm/databases/models/databases.backend.schemas.d.ts.map +1 -0
- package/dist/esm/databases/models/databases.backend.schemas.js +60 -0
- package/dist/esm/databases/models/databases.backend.schemas.js.map +1 -0
- package/dist/esm/databases/models/filter.backend.schemas.d.ts +83 -0
- package/dist/esm/databases/models/filter.backend.schemas.d.ts.map +1 -0
- package/dist/esm/databases/models/filter.backend.schemas.js +27 -0
- package/dist/esm/databases/models/filter.backend.schemas.js.map +1 -0
- package/dist/esm/databases/models/sql.backend.schemas.d.ts +75 -0
- package/dist/esm/databases/models/sql.backend.schemas.d.ts.map +1 -0
- package/dist/esm/databases/models/sql.backend.schemas.js +31 -0
- package/dist/esm/databases/models/sql.backend.schemas.js.map +1 -0
- package/dist/esm/databases/models/transaction.shared.schemas.d.ts +120 -0
- package/dist/esm/databases/models/transaction.shared.schemas.d.ts.map +1 -0
- package/dist/esm/databases/models/transaction.shared.schemas.js +30 -0
- package/dist/esm/databases/models/transaction.shared.schemas.js.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-mongo-transaction-registry.service.d.ts +15 -0
- package/dist/esm/databases/services/__tests__/mock-mongo-transaction-registry.service.d.ts.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-mongo-transaction-registry.service.js +60 -0
- package/dist/esm/databases/services/__tests__/mock-mongo-transaction-registry.service.js.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-mongodb.service.d.ts +19 -0
- package/dist/esm/databases/services/__tests__/mock-mongodb.service.d.ts.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-mongodb.service.js +69 -0
- package/dist/esm/databases/services/__tests__/mock-mongodb.service.js.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-mongoose-model.service.d.ts +11 -0
- package/dist/esm/databases/services/__tests__/mock-mongoose-model.service.d.ts.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-mongoose-model.service.js +315 -0
- package/dist/esm/databases/services/__tests__/mock-mongoose-model.service.js.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-redis.service.d.ts +29 -0
- package/dist/esm/databases/services/__tests__/mock-redis.service.d.ts.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-redis.service.js +65 -0
- package/dist/esm/databases/services/__tests__/mock-redis.service.js.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.d.ts +19 -0
- package/dist/esm/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.d.ts.map +1 -0
- package/dist/esm/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.js +44 -0
- package/dist/esm/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts +74 -0
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js +369 -0
- package/dist/esm/databases/services/aggregation/aggregation-authorization.backend.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/aggregation-query.backend.service.d.ts +110 -0
- package/dist/esm/databases/services/aggregation/aggregation-query.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/aggregation-query.backend.service.js +444 -0
- package/dist/esm/databases/services/aggregation/aggregation-query.backend.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/computed-measure-evaluator.backend.service.d.ts +38 -0
- package/dist/esm/databases/services/aggregation/computed-measure-evaluator.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/computed-measure-evaluator.backend.service.js +180 -0
- package/dist/esm/databases/services/aggregation/computed-measure-evaluator.backend.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/field-access-validator.backend.service.d.ts +42 -0
- package/dist/esm/databases/services/aggregation/field-access-validator.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/field-access-validator.backend.service.js +183 -0
- package/dist/esm/databases/services/aggregation/field-access-validator.backend.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/time-series-densifier.backend.service.d.ts +48 -0
- package/dist/esm/databases/services/aggregation/time-series-densifier.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/time-series-densifier.backend.service.js +320 -0
- package/dist/esm/databases/services/aggregation/time-series-densifier.backend.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/topn-processor.backend.service.d.ts +47 -0
- package/dist/esm/databases/services/aggregation/topn-processor.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/topn-processor.backend.service.js +187 -0
- package/dist/esm/databases/services/aggregation/topn-processor.backend.service.js.map +1 -0
- package/dist/esm/databases/services/aggregation/window-function-processor.backend.service.d.ts +47 -0
- package/dist/esm/databases/services/aggregation/window-function-processor.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/aggregation/window-function-processor.backend.service.js +250 -0
- package/dist/esm/databases/services/aggregation/window-function-processor.backend.service.js.map +1 -0
- package/dist/esm/databases/services/db-utils.d.ts +56 -0
- package/dist/esm/databases/services/db-utils.d.ts.map +1 -0
- package/dist/esm/databases/services/db-utils.js +66 -0
- package/dist/esm/databases/services/db-utils.js.map +1 -0
- package/dist/esm/databases/services/mongo-aggregation.backend.service.d.ts +91 -0
- package/dist/esm/databases/services/mongo-aggregation.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/mongo-aggregation.backend.service.js +652 -0
- package/dist/esm/databases/services/mongo-aggregation.backend.service.js.map +1 -0
- package/dist/esm/databases/services/mongodb.service.d.ts +132 -0
- package/dist/esm/databases/services/mongodb.service.d.ts.map +1 -0
- package/dist/esm/databases/services/mongodb.service.js +630 -0
- package/dist/esm/databases/services/mongodb.service.js.map +1 -0
- package/dist/esm/databases/services/postgresql-aggregation.backend.service.d.ts +113 -0
- package/dist/esm/databases/services/postgresql-aggregation.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/postgresql-aggregation.backend.service.js +635 -0
- package/dist/esm/databases/services/postgresql-aggregation.backend.service.js.map +1 -0
- package/dist/esm/databases/services/postgresql-database.backend.service.d.ts +75 -0
- package/dist/esm/databases/services/postgresql-database.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/postgresql-database.backend.service.js +255 -0
- package/dist/esm/databases/services/postgresql-database.backend.service.js.map +1 -0
- package/dist/esm/databases/services/postgresql-filter.backend.service.d.ts +116 -0
- package/dist/esm/databases/services/postgresql-filter.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/postgresql-filter.backend.service.js +624 -0
- package/dist/esm/databases/services/postgresql-filter.backend.service.js.map +1 -0
- package/dist/esm/databases/services/redis.service.d.ts +143 -0
- package/dist/esm/databases/services/redis.service.d.ts.map +1 -0
- package/dist/esm/databases/services/redis.service.js +429 -0
- package/dist/esm/databases/services/redis.service.js.map +1 -0
- package/dist/esm/databases/services/zod-to-mongoose-schema-convertor.backend.service.d.ts +302 -0
- package/dist/esm/databases/services/zod-to-mongoose-schema-convertor.backend.service.d.ts.map +1 -0
- package/dist/esm/databases/services/zod-to-mongoose-schema-convertor.backend.service.js +1787 -0
- package/dist/esm/databases/services/zod-to-mongoose-schema-convertor.backend.service.js.map +1 -0
- package/dist/esm/databases/services/zod-to-sql-hybrid-schema.planner.d.ts +65 -0
- package/dist/esm/databases/services/zod-to-sql-hybrid-schema.planner.d.ts.map +1 -0
- package/dist/esm/databases/services/zod-to-sql-hybrid-schema.planner.js +237 -0
- package/dist/esm/databases/services/zod-to-sql-hybrid-schema.planner.js.map +1 -0
- package/dist/esm/errors/services/__tests__/mock-error-builder.service.d.ts +339 -0
- package/dist/esm/errors/services/__tests__/mock-error-builder.service.d.ts.map +1 -0
- package/dist/esm/errors/services/__tests__/mock-error-builder.service.js +209 -0
- package/dist/esm/errors/services/__tests__/mock-error-builder.service.js.map +1 -0
- package/dist/esm/errors/services/error-builder.backend.service.d.ts +95 -0
- package/dist/esm/errors/services/error-builder.backend.service.d.ts.map +1 -0
- package/dist/esm/errors/services/error-builder.backend.service.js +334 -0
- package/dist/esm/errors/services/error-builder.backend.service.js.map +1 -0
- package/dist/esm/errors/services/error-handler.backend.service.d.ts +43 -0
- package/dist/esm/errors/services/error-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/errors/services/error-handler.backend.service.js +219 -0
- package/dist/esm/errors/services/error-handler.backend.service.js.map +1 -0
- package/dist/esm/errors/services/rate-limit.backend.service.d.ts +23 -0
- package/dist/esm/errors/services/rate-limit.backend.service.d.ts.map +1 -0
- package/dist/esm/errors/services/rate-limit.backend.service.js +59 -0
- package/dist/esm/errors/services/rate-limit.backend.service.js.map +1 -0
- package/dist/esm/external-providers/models/external-providers.backend.schemas.d.ts +135 -0
- package/dist/esm/external-providers/models/external-providers.backend.schemas.d.ts.map +1 -0
- package/dist/esm/external-providers/models/external-providers.backend.schemas.js +129 -0
- package/dist/esm/external-providers/models/external-providers.backend.schemas.js.map +1 -0
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts +18 -0
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js +38 -0
- package/dist/esm/external-providers/services/__tests__/mock-external-providers-registry.service.js.map +1 -0
- package/dist/esm/external-providers/services/__tests__/mock-lazy-provider-registry.service.d.ts +20 -0
- package/dist/esm/external-providers/services/__tests__/mock-lazy-provider-registry.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/__tests__/mock-lazy-provider-registry.service.js +44 -0
- package/dist/esm/external-providers/services/__tests__/mock-lazy-provider-registry.service.js.map +1 -0
- package/dist/esm/external-providers/services/external-api-handler.backend.service.d.ts +9 -0
- package/dist/esm/external-providers/services/external-api-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/external-api-handler.backend.service.js +36 -0
- package/dist/esm/external-providers/services/external-api-handler.backend.service.js.map +1 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +83 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +422 -0
- package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -0
- package/dist/esm/external-providers/services/feature-bindings.backend.service.d.ts +102 -0
- package/dist/esm/external-providers/services/feature-bindings.backend.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/feature-bindings.backend.service.js +352 -0
- package/dist/esm/external-providers/services/feature-bindings.backend.service.js.map +1 -0
- package/dist/esm/external-providers/services/lazy-provider-registry.backend.service.d.ts +141 -0
- package/dist/esm/external-providers/services/lazy-provider-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/external-providers/services/lazy-provider-registry.backend.service.js +391 -0
- package/dist/esm/external-providers/services/lazy-provider-registry.backend.service.js.map +1 -0
- package/dist/esm/features/controllers/features.backend.controller.d.ts +35 -0
- package/dist/esm/features/controllers/features.backend.controller.d.ts.map +1 -0
- package/dist/esm/features/controllers/features.backend.controller.js +179 -0
- package/dist/esm/features/controllers/features.backend.controller.js.map +1 -0
- package/dist/esm/features/services/__tests__/mock-capability-bindings.service.d.ts +8 -0
- package/dist/esm/features/services/__tests__/mock-capability-bindings.service.d.ts.map +1 -0
- package/dist/esm/features/services/__tests__/mock-capability-bindings.service.js +31 -0
- package/dist/esm/features/services/__tests__/mock-capability-bindings.service.js.map +1 -0
- package/dist/esm/features/services/__tests__/mock-feature-definition-registry.service.d.ts +22 -0
- package/dist/esm/features/services/__tests__/mock-feature-definition-registry.service.d.ts.map +1 -0
- package/dist/esm/features/services/__tests__/mock-feature-definition-registry.service.js +52 -0
- package/dist/esm/features/services/__tests__/mock-feature-definition-registry.service.js.map +1 -0
- package/dist/esm/features/services/__tests__/mock-feature-resolution.service.d.ts +13 -0
- package/dist/esm/features/services/__tests__/mock-feature-resolution.service.d.ts.map +1 -0
- package/dist/esm/features/services/__tests__/mock-feature-resolution.service.js +36 -0
- package/dist/esm/features/services/__tests__/mock-feature-resolution.service.js.map +1 -0
- package/dist/esm/features/services/feature-definition-registry.backend.service.d.ts +111 -0
- package/dist/esm/features/services/feature-definition-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/features/services/feature-definition-registry.backend.service.js +437 -0
- package/dist/esm/features/services/feature-definition-registry.backend.service.js.map +1 -0
- package/dist/esm/features/services/feature-gate.backend.service.d.ts +110 -0
- package/dist/esm/features/services/feature-gate.backend.service.d.ts.map +1 -0
- package/dist/esm/features/services/feature-gate.backend.service.js +414 -0
- package/dist/esm/features/services/feature-gate.backend.service.js.map +1 -0
- package/dist/esm/features/services/feature-resolution.backend.service.d.ts +163 -0
- package/dist/esm/features/services/feature-resolution.backend.service.d.ts.map +1 -0
- package/dist/esm/features/services/feature-resolution.backend.service.js +550 -0
- package/dist/esm/features/services/feature-resolution.backend.service.js.map +1 -0
- package/dist/esm/features/testing/feature-test-utils.d.ts +85 -0
- package/dist/esm/features/testing/feature-test-utils.d.ts.map +1 -0
- package/dist/esm/features/testing/feature-test-utils.js +127 -0
- package/dist/esm/features/testing/feature-test-utils.js.map +1 -0
- package/dist/esm/files/batches/files-cleanup.batch.backend.service.d.ts +34 -0
- package/dist/esm/files/batches/files-cleanup.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/files/batches/files-cleanup.batch.backend.service.js +226 -0
- package/dist/esm/files/batches/files-cleanup.batch.backend.service.js.map +1 -0
- package/dist/esm/files/constraints/file-analyzers.types.d.ts +76 -0
- package/dist/esm/files/constraints/file-analyzers.types.d.ts.map +1 -0
- package/dist/esm/files/constraints/file-analyzers.types.js +16 -0
- package/dist/esm/files/constraints/file-analyzers.types.js.map +1 -0
- package/dist/esm/files/constraints/file-constraint-resolver-chain.backend.service.d.ts +38 -0
- package/dist/esm/files/constraints/file-constraint-resolver-chain.backend.service.d.ts.map +1 -0
- package/dist/esm/files/constraints/file-constraint-resolver-chain.backend.service.js +99 -0
- package/dist/esm/files/constraints/file-constraint-resolver-chain.backend.service.js.map +1 -0
- package/dist/esm/files/constraints/file-constraint.types.d.ts +77 -0
- package/dist/esm/files/constraints/file-constraint.types.d.ts.map +1 -0
- package/dist/esm/files/constraints/file-constraint.types.js +16 -0
- package/dist/esm/files/constraints/file-constraint.types.js.map +1 -0
- package/dist/esm/files/constraints/file-validation.backend.service.d.ts +63 -0
- package/dist/esm/files/constraints/file-validation.backend.service.d.ts.map +1 -0
- package/dist/esm/files/constraints/file-validation.backend.service.js +317 -0
- package/dist/esm/files/constraints/file-validation.backend.service.js.map +1 -0
- package/dist/esm/files/constraints/resource-field-constraint-resolver.backend.service.d.ts +33 -0
- package/dist/esm/files/constraints/resource-field-constraint-resolver.backend.service.d.ts.map +1 -0
- package/dist/esm/files/constraints/resource-field-constraint-resolver.backend.service.js +126 -0
- package/dist/esm/files/constraints/resource-field-constraint-resolver.backend.service.js.map +1 -0
- package/dist/esm/files/controllers/file.controller.d.ts +145 -0
- package/dist/esm/files/controllers/file.controller.d.ts.map +1 -0
- package/dist/esm/files/controllers/file.controller.js +806 -0
- package/dist/esm/files/controllers/file.controller.js.map +1 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts +85 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js +512 -0
- package/dist/esm/files/handlers/resource-file-upload-handler.backend.service.js.map +1 -0
- package/dist/esm/files/rag/weaviate-vector-store.backend.service.d.ts +84 -0
- package/dist/esm/files/rag/weaviate-vector-store.backend.service.d.ts.map +1 -0
- package/dist/esm/files/rag/weaviate-vector-store.backend.service.js +224 -0
- package/dist/esm/files/rag/weaviate-vector-store.backend.service.js.map +1 -0
- package/dist/esm/files/scanning/clamav-scanner.backend.service.d.ts +55 -0
- package/dist/esm/files/scanning/clamav-scanner.backend.service.d.ts.map +1 -0
- package/dist/esm/files/scanning/clamav-scanner.backend.service.js +202 -0
- package/dist/esm/files/scanning/clamav-scanner.backend.service.js.map +1 -0
- package/dist/esm/files/scanning/file-scan.types.d.ts +17 -0
- package/dist/esm/files/scanning/file-scan.types.d.ts.map +1 -0
- package/dist/esm/files/scanning/file-scan.types.js +7 -0
- package/dist/esm/files/scanning/file-scan.types.js.map +1 -0
- package/dist/esm/files/scanning/yara-scanner.backend.service.d.ts +73 -0
- package/dist/esm/files/scanning/yara-scanner.backend.service.d.ts.map +1 -0
- package/dist/esm/files/scanning/yara-scanner.backend.service.js +184 -0
- package/dist/esm/files/scanning/yara-scanner.backend.service.js.map +1 -0
- package/dist/esm/files/services/__tests__/mock-file-field-detection.service.d.ts +12 -0
- package/dist/esm/files/services/__tests__/mock-file-field-detection.service.d.ts.map +1 -0
- package/dist/esm/files/services/__tests__/mock-file-field-detection.service.js +41 -0
- package/dist/esm/files/services/__tests__/mock-file-field-detection.service.js.map +1 -0
- package/dist/esm/files/services/__tests__/mock-file-operation-handler.service.d.ts +33 -0
- package/dist/esm/files/services/__tests__/mock-file-operation-handler.service.d.ts.map +1 -0
- package/dist/esm/files/services/__tests__/mock-file-operation-handler.service.js +71 -0
- package/dist/esm/files/services/__tests__/mock-file-operation-handler.service.js.map +1 -0
- package/dist/esm/files/services/__tests__/mock-file-repository.service.d.ts +16 -0
- package/dist/esm/files/services/__tests__/mock-file-repository.service.d.ts.map +1 -0
- package/dist/esm/files/services/__tests__/mock-file-repository.service.js +95 -0
- package/dist/esm/files/services/__tests__/mock-file-repository.service.js.map +1 -0
- package/dist/esm/files/services/file-field-detection.backend.service.d.ts +57 -0
- package/dist/esm/files/services/file-field-detection.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-field-detection.backend.service.js +145 -0
- package/dist/esm/files/services/file-field-detection.backend.service.js.map +1 -0
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts +103 -0
- package/dist/esm/files/services/file-operation-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-operation-handler.backend.service.js +604 -0
- package/dist/esm/files/services/file-operation-handler.backend.service.js.map +1 -0
- package/dist/esm/files/services/file-population.backend.service.d.ts +73 -0
- package/dist/esm/files/services/file-population.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-population.backend.service.js +367 -0
- package/dist/esm/files/services/file-population.backend.service.js.map +1 -0
- package/dist/esm/files/services/file-rag-indexing.backend.service.d.ts +64 -0
- package/dist/esm/files/services/file-rag-indexing.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-rag-indexing.backend.service.js +188 -0
- package/dist/esm/files/services/file-rag-indexing.backend.service.js.map +1 -0
- package/dist/esm/files/services/file-scanning.backend.service.d.ts +97 -0
- package/dist/esm/files/services/file-scanning.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-scanning.backend.service.js +323 -0
- package/dist/esm/files/services/file-scanning.backend.service.js.map +1 -0
- package/dist/esm/files/services/file-text-extraction.backend.service.d.ts +52 -0
- package/dist/esm/files/services/file-text-extraction.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/file-text-extraction.backend.service.js +168 -0
- package/dist/esm/files/services/file-text-extraction.backend.service.js.map +1 -0
- package/dist/esm/files/services/files.backend.service.d.ts +235 -0
- package/dist/esm/files/services/files.backend.service.d.ts.map +1 -0
- package/dist/esm/files/services/files.backend.service.js +987 -0
- package/dist/esm/files/services/files.backend.service.js.map +1 -0
- package/dist/esm/files/storage/file-storage-path-resolver.backend.service.d.ts +50 -0
- package/dist/esm/files/storage/file-storage-path-resolver.backend.service.d.ts.map +1 -0
- package/dist/esm/files/storage/file-storage-path-resolver.backend.service.js +253 -0
- package/dist/esm/files/storage/file-storage-path-resolver.backend.service.js.map +1 -0
- package/dist/esm/files/storage/file-storage-provider.types.d.ts +156 -0
- package/dist/esm/files/storage/file-storage-provider.types.d.ts.map +1 -0
- package/dist/esm/files/storage/file-storage-provider.types.js +10 -0
- package/dist/esm/files/storage/file-storage-provider.types.js.map +1 -0
- package/dist/esm/files/storage/file-storage-router.backend.service.d.ts +68 -0
- package/dist/esm/files/storage/file-storage-router.backend.service.d.ts.map +1 -0
- package/dist/esm/files/storage/file-storage-router.backend.service.js +168 -0
- package/dist/esm/files/storage/file-storage-router.backend.service.js.map +1 -0
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts +57 -0
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.d.ts.map +1 -0
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js +307 -0
- package/dist/esm/files/storage/local-directory-storage-provider.backend.service.js.map +1 -0
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.d.ts +41 -0
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.d.ts.map +1 -0
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js +397 -0
- package/dist/esm/files/storage/wildo-managed-storage-provider.backend.service.js.map +1 -0
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.d.ts +30 -0
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.d.ts.map +1 -0
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.js +251 -0
- package/dist/esm/files/utils/file-field-schema-path.backend.utils.js.map +1 -0
- package/dist/esm/files/utils/file-upload.utils.d.ts +74 -0
- package/dist/esm/files/utils/file-upload.utils.d.ts.map +1 -0
- package/dist/esm/files/utils/file-upload.utils.js +116 -0
- package/dist/esm/files/utils/file-upload.utils.js.map +1 -0
- package/dist/esm/files/utils/file-uploader.utils.d.ts +15 -0
- package/dist/esm/files/utils/file-uploader.utils.d.ts.map +1 -0
- package/dist/esm/files/utils/file-uploader.utils.js +47 -0
- package/dist/esm/files/utils/file-uploader.utils.js.map +1 -0
- package/dist/esm/files/utils/file-validation.utils.d.ts +111 -0
- package/dist/esm/files/utils/file-validation.utils.d.ts.map +1 -0
- package/dist/esm/files/utils/file-validation.utils.js +516 -0
- package/dist/esm/files/utils/file-validation.utils.js.map +1 -0
- package/dist/esm/flows-actors/agent-catalogs.backend.d.ts +222 -0
- package/dist/esm/flows-actors/agent-catalogs.backend.d.ts.map +1 -0
- package/dist/esm/flows-actors/agent-catalogs.backend.js +320 -0
- package/dist/esm/flows-actors/agent-catalogs.backend.js.map +1 -0
- package/dist/esm/flows-actors/controllers/flows-actors.controller.d.ts +33 -0
- package/dist/esm/flows-actors/controllers/flows-actors.controller.d.ts.map +1 -0
- package/dist/esm/flows-actors/controllers/flows-actors.controller.js +96 -0
- package/dist/esm/flows-actors/controllers/flows-actors.controller.js.map +1 -0
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts +225 -0
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js +323 -0
- package/dist/esm/flows-actors/models/agent-catalogs.backend.definitions.js.map +1 -0
- package/dist/esm/flows-actors/models/agent-facets.backend.definitions.d.ts +77 -0
- package/dist/esm/flows-actors/models/agent-facets.backend.definitions.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/agent-facets.backend.definitions.js +28 -0
- package/dist/esm/flows-actors/models/agent-facets.backend.definitions.js.map +1 -0
- package/dist/esm/flows-actors/models/agents.backend.definitions.d.ts +1 -0
- package/dist/esm/flows-actors/models/agents.backend.definitions.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/agents.backend.definitions.js +1 -0
- package/dist/esm/flows-actors/models/agents.backend.definitions.js.map +1 -0
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts +52 -0
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.js +307 -0
- package/dist/esm/flows-actors/models/core-facets.backend.definitions.js.map +1 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.definitions.d.ts +7 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.definitions.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.definitions.js +8 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.definitions.js.map +1 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts +30 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.d.ts.map +1 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.js +7 -0
- package/dist/esm/flows-actors/models/flows-actors.backend.schemas.js.map +1 -0
- package/dist/esm/flows-actors/services/actors-system.backend.service.d.ts +72 -0
- package/dist/esm/flows-actors/services/actors-system.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/actors-system.backend.service.js +229 -0
- package/dist/esm/flows-actors/services/actors-system.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/services/agent-facets.backend.service.d.ts +95 -0
- package/dist/esm/flows-actors/services/agent-facets.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/agent-facets.backend.service.js +276 -0
- package/dist/esm/flows-actors/services/agent-facets.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts +183 -0
- package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/agents.backend.service.js +2095 -0
- package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/services/context-curation.backend.service.d.ts +64 -0
- package/dist/esm/flows-actors/services/context-curation.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/context-curation.backend.service.js +180 -0
- package/dist/esm/flows-actors/services/context-curation.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +101 -0
- package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js +313 -0
- package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -0
- package/dist/esm/flows-actors/services/flows.backend.services.d.ts +64 -0
- package/dist/esm/flows-actors/services/flows.backend.services.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/flows.backend.services.js +203 -0
- package/dist/esm/flows-actors/services/flows.backend.services.js.map +1 -0
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts +91 -0
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.d.ts.map +1 -0
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js +629 -0
- package/dist/esm/flows-actors/services/prompt-compiler.backend.service.js.map +1 -0
- package/dist/esm/flows-actors/utils/cli-runtime-operation-support.backend.utils.d.ts +15 -0
- package/dist/esm/flows-actors/utils/cli-runtime-operation-support.backend.utils.d.ts.map +1 -0
- package/dist/esm/flows-actors/utils/cli-runtime-operation-support.backend.utils.js +55 -0
- package/dist/esm/flows-actors/utils/cli-runtime-operation-support.backend.utils.js.map +1 -0
- package/dist/esm/flows-actors/utils/cli-runtime-runner.backend.utils.d.ts +22 -0
- package/dist/esm/flows-actors/utils/cli-runtime-runner.backend.utils.d.ts.map +1 -0
- package/dist/esm/flows-actors/utils/cli-runtime-runner.backend.utils.js +131 -0
- package/dist/esm/flows-actors/utils/cli-runtime-runner.backend.utils.js.map +1 -0
- package/dist/esm/flows-actors/utils/flows-actors-frontend-extractor.utils.d.ts +15 -0
- package/dist/esm/flows-actors/utils/flows-actors-frontend-extractor.utils.d.ts.map +1 -0
- package/dist/esm/flows-actors/utils/flows-actors-frontend-extractor.utils.js +43 -0
- package/dist/esm/flows-actors/utils/flows-actors-frontend-extractor.utils.js.map +1 -0
- package/dist/esm/flows-actors/utils/prompt-ir-adapters.backend.utils.d.ts +66 -0
- package/dist/esm/flows-actors/utils/prompt-ir-adapters.backend.utils.d.ts.map +1 -0
- package/dist/esm/flows-actors/utils/prompt-ir-adapters.backend.utils.js +219 -0
- package/dist/esm/flows-actors/utils/prompt-ir-adapters.backend.utils.js.map +1 -0
- package/dist/esm/guidance/batches/dormancy-detection.batch.backend.service.d.ts +17 -0
- package/dist/esm/guidance/batches/dormancy-detection.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/batches/dormancy-detection.batch.backend.service.js +110 -0
- package/dist/esm/guidance/batches/dormancy-detection.batch.backend.service.js.map +1 -0
- package/dist/esm/guidance/services/guidance-trigger-evaluator.backend.service.d.ts +41 -0
- package/dist/esm/guidance/services/guidance-trigger-evaluator.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/services/guidance-trigger-evaluator.backend.service.js +135 -0
- package/dist/esm/guidance/services/guidance-trigger-evaluator.backend.service.js.map +1 -0
- package/dist/esm/guidance/services/lifecycle-custom-implementations.backend.d.ts +33 -0
- package/dist/esm/guidance/services/lifecycle-custom-implementations.backend.d.ts.map +1 -0
- package/dist/esm/guidance/services/lifecycle-custom-implementations.backend.js +105 -0
- package/dist/esm/guidance/services/lifecycle-custom-implementations.backend.js.map +1 -0
- package/dist/esm/guidance/services/lifecycle-evaluator.backend.service.d.ts +103 -0
- package/dist/esm/guidance/services/lifecycle-evaluator.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/services/lifecycle-evaluator.backend.service.js +685 -0
- package/dist/esm/guidance/services/lifecycle-evaluator.backend.service.js.map +1 -0
- package/dist/esm/guidance/services/milestone-condition-registry.backend.service.d.ts +23 -0
- package/dist/esm/guidance/services/milestone-condition-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/services/milestone-condition-registry.backend.service.js +57 -0
- package/dist/esm/guidance/services/milestone-condition-registry.backend.service.js.map +1 -0
- package/dist/esm/guidance/services/milestone-definition-registry.backend.service.d.ts +49 -0
- package/dist/esm/guidance/services/milestone-definition-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/services/milestone-definition-registry.backend.service.js +248 -0
- package/dist/esm/guidance/services/milestone-definition-registry.backend.service.js.map +1 -0
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts +64 -0
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.d.ts.map +1 -0
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.js +487 -0
- package/dist/esm/guidance/services/milestone-evaluator.backend.service.js.map +1 -0
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts +55 -0
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.js +208 -0
- package/dist/esm/i18n/controllers/i18n-controller.backend.service.js.map +1 -0
- package/dist/esm/i18n/services/i18n.backend.service.d.ts +43 -0
- package/dist/esm/i18n/services/i18n.backend.service.d.ts.map +1 -0
- package/dist/esm/i18n/services/i18n.backend.service.js +83 -0
- package/dist/esm/i18n/services/i18n.backend.service.js.map +1 -0
- package/dist/esm/index.d.ts +203 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +239 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/inject/models/container.d.ts +44 -0
- package/dist/esm/inject/models/container.d.ts.map +1 -0
- package/dist/esm/inject/models/container.js +489 -0
- package/dist/esm/inject/models/container.js.map +1 -0
- package/dist/esm/inject/models/service-types.d.ts +198 -0
- package/dist/esm/inject/models/service-types.d.ts.map +1 -0
- package/dist/esm/inject/models/service-types.js +226 -0
- package/dist/esm/inject/models/service-types.js.map +1 -0
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.d.ts +34 -0
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.d.ts.map +1 -0
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js +122 -0
- package/dist/esm/monitoring/analytics/controllers/analytics.backend.controller.js.map +1 -0
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts +41 -0
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.d.ts.map +1 -0
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js +62 -0
- package/dist/esm/monitoring/analytics/services/value-moment-engine.backend.service.js.map +1 -0
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts +18 -0
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.js +43 -0
- package/dist/esm/monitoring/analytics/services/value-moment-handler-registry.backend.service.js.map +1 -0
- package/dist/esm/monitoring/logger/middleware/logging.middleware.d.ts +12 -0
- package/dist/esm/monitoring/logger/middleware/logging.middleware.d.ts.map +1 -0
- package/dist/esm/monitoring/logger/middleware/logging.middleware.js +25 -0
- package/dist/esm/monitoring/logger/middleware/logging.middleware.js.map +1 -0
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts +41 -0
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.d.ts.map +1 -0
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.js +29 -0
- package/dist/esm/monitoring/logger/models/logger.backend.schemas.js.map +1 -0
- package/dist/esm/monitoring/logger/services/__tests__/mock-logger.service.d.ts +22 -0
- package/dist/esm/monitoring/logger/services/__tests__/mock-logger.service.d.ts.map +1 -0
- package/dist/esm/monitoring/logger/services/__tests__/mock-logger.service.js +53 -0
- package/dist/esm/monitoring/logger/services/__tests__/mock-logger.service.js.map +1 -0
- package/dist/esm/monitoring/logger/services/logger.service.d.ts +37 -0
- package/dist/esm/monitoring/logger/services/logger.service.d.ts.map +1 -0
- package/dist/esm/monitoring/logger/services/logger.service.js +189 -0
- package/dist/esm/monitoring/logger/services/logger.service.js.map +1 -0
- package/dist/esm/monitoring/observability/middleware/metrics.middleware.d.ts +38 -0
- package/dist/esm/monitoring/observability/middleware/metrics.middleware.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/middleware/metrics.middleware.js +147 -0
- package/dist/esm/monitoring/observability/middleware/metrics.middleware.js.map +1 -0
- package/dist/esm/monitoring/observability/middleware/telemetry.middleware.d.ts +26 -0
- package/dist/esm/monitoring/observability/middleware/telemetry.middleware.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/middleware/telemetry.middleware.js +117 -0
- package/dist/esm/monitoring/observability/middleware/telemetry.middleware.js.map +1 -0
- package/dist/esm/monitoring/observability/middleware/tracing.middleware.d.ts +28 -0
- package/dist/esm/monitoring/observability/middleware/tracing.middleware.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/middleware/tracing.middleware.js +182 -0
- package/dist/esm/monitoring/observability/middleware/tracing.middleware.js.map +1 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +86 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.js +1 -0
- package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -0
- package/dist/esm/monitoring/observability/services/instrumentations/custom.instrumentations.d.ts +57 -0
- package/dist/esm/monitoring/observability/services/instrumentations/custom.instrumentations.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/services/instrumentations/custom.instrumentations.js +77 -0
- package/dist/esm/monitoring/observability/services/instrumentations/custom.instrumentations.js.map +1 -0
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts +27 -0
- package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/services/metrics.service.js +236 -0
- package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -0
- package/dist/esm/monitoring/observability/services/telemetry.service.d.ts +28 -0
- package/dist/esm/monitoring/observability/services/telemetry.service.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/services/telemetry.service.js +144 -0
- package/dist/esm/monitoring/observability/services/telemetry.service.js.map +1 -0
- package/dist/esm/monitoring/observability/services/tracer.service.d.ts +24 -0
- package/dist/esm/monitoring/observability/services/tracer.service.d.ts.map +1 -0
- package/dist/esm/monitoring/observability/services/tracer.service.js +287 -0
- package/dist/esm/monitoring/observability/services/tracer.service.js.map +1 -0
- package/dist/esm/notifications/email/components/email-components.d.ts +90 -0
- package/dist/esm/notifications/email/components/email-components.d.ts.map +1 -0
- package/dist/esm/notifications/email/components/email-components.js +171 -0
- package/dist/esm/notifications/email/components/email-components.js.map +1 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts +80 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.d.ts.map +1 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.js +25 -0
- package/dist/esm/notifications/email/models/email-context-provider.interface.js.map +1 -0
- package/dist/esm/notifications/email/models/email-template-definition.d.ts +68 -0
- package/dist/esm/notifications/email/models/email-template-definition.d.ts.map +1 -0
- package/dist/esm/notifications/email/models/email-template-definition.js +12 -0
- package/dist/esm/notifications/email/models/email-template-definition.js.map +1 -0
- package/dist/esm/notifications/email/models/email-template.actors-system.backend.definitions.d.ts +19 -0
- package/dist/esm/notifications/email/models/email-template.actors-system.backend.definitions.d.ts.map +1 -0
- package/dist/esm/notifications/email/models/email-template.actors-system.backend.definitions.js +66 -0
- package/dist/esm/notifications/email/models/email-template.actors-system.backend.definitions.js.map +1 -0
- package/dist/esm/notifications/email/models/email.backend.scheamas.d.ts +1 -0
- package/dist/esm/notifications/email/models/email.backend.scheamas.d.ts.map +1 -0
- package/dist/esm/notifications/email/models/email.backend.scheamas.js +1 -0
- package/dist/esm/notifications/email/models/email.backend.scheamas.js.map +1 -0
- package/dist/esm/notifications/email/services/email-batch-send.batch.backend.service.d.ts +74 -0
- package/dist/esm/notifications/email/services/email-batch-send.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-batch-send.batch.backend.service.js +196 -0
- package/dist/esm/notifications/email/services/email-batch-send.batch.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts +49 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js +141 -0
- package/dist/esm/notifications/email/services/email-context-provider-registry.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-renderer.backend.service.d.ts +74 -0
- package/dist/esm/notifications/email/services/email-renderer.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-renderer.backend.service.js +215 -0
- package/dist/esm/notifications/email/services/email-renderer.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts +37 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js +121 -0
- package/dist/esm/notifications/email/services/email-template-compiler.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-template-generation.backend.service.d.ts +115 -0
- package/dist/esm/notifications/email/services/email-template-generation.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-template-generation.backend.service.js +634 -0
- package/dist/esm/notifications/email/services/email-template-generation.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts +48 -0
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.js +146 -0
- package/dist/esm/notifications/email/services/email-template-registry.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts +58 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js +223 -0
- package/dist/esm/notifications/email/services/email-template-sandbox.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.d.ts +49 -0
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.js +204 -0
- package/dist/esm/notifications/email/services/email-template-validator.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/services/email.backend.service.d.ts +76 -0
- package/dist/esm/notifications/email/services/email.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/email/services/email.backend.service.js +294 -0
- package/dist/esm/notifications/email/services/email.backend.service.js.map +1 -0
- package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts +56 -0
- package/dist/esm/notifications/email/utils/color-conversion.utils.d.ts.map +1 -0
- package/dist/esm/notifications/email/utils/color-conversion.utils.js +108 -0
- package/dist/esm/notifications/email/utils/color-conversion.utils.js.map +1 -0
- package/dist/esm/notifications/email/utils/interpolate-email-label.utils.d.ts +8 -0
- package/dist/esm/notifications/email/utils/interpolate-email-label.utils.d.ts.map +1 -0
- package/dist/esm/notifications/email/utils/interpolate-email-label.utils.js +15 -0
- package/dist/esm/notifications/email/utils/interpolate-email-label.utils.js.map +1 -0
- package/dist/esm/notifications/email/utils/zod-to-typescript.utils.d.ts +50 -0
- package/dist/esm/notifications/email/utils/zod-to-typescript.utils.d.ts.map +1 -0
- package/dist/esm/notifications/email/utils/zod-to-typescript.utils.js +281 -0
- package/dist/esm/notifications/email/utils/zod-to-typescript.utils.js.map +1 -0
- package/dist/esm/notifications/services/notification-badge.backend.service.d.ts +94 -0
- package/dist/esm/notifications/services/notification-badge.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/services/notification-badge.backend.service.js +292 -0
- package/dist/esm/notifications/services/notification-badge.backend.service.js.map +1 -0
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts +202 -0
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js +1290 -0
- package/dist/esm/notifications/services/notifications-dispatcher.backend.service.js.map +1 -0
- package/dist/esm/notifications/sms/services/sms.backend.service.d.ts +50 -0
- package/dist/esm/notifications/sms/services/sms.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/sms/services/sms.backend.service.js +209 -0
- package/dist/esm/notifications/sms/services/sms.backend.service.js.map +1 -0
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +58 -0
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +184 -0
- package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -0
- package/dist/esm/notifications/webhooks/services/polymorphic-lookup.backend.service.d.ts +56 -0
- package/dist/esm/notifications/webhooks/services/polymorphic-lookup.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/webhooks/services/polymorphic-lookup.backend.service.js +109 -0
- package/dist/esm/notifications/webhooks/services/polymorphic-lookup.backend.service.js.map +1 -0
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts +96 -0
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js +396 -0
- package/dist/esm/notifications/webhooks/services/webhook-handler.backend.service.js.map +1 -0
- package/dist/esm/organizations/services/org-creation-on-registration.backend.utils.d.ts +39 -0
- package/dist/esm/organizations/services/org-creation-on-registration.backend.utils.d.ts.map +1 -0
- package/dist/esm/organizations/services/org-creation-on-registration.backend.utils.js +73 -0
- package/dist/esm/organizations/services/org-creation-on-registration.backend.utils.js.map +1 -0
- package/dist/esm/organizations/services/org-member-roles-validation.backend.utils.d.ts +22 -0
- package/dist/esm/organizations/services/org-member-roles-validation.backend.utils.d.ts.map +1 -0
- package/dist/esm/organizations/services/org-member-roles-validation.backend.utils.js +35 -0
- package/dist/esm/organizations/services/org-member-roles-validation.backend.utils.js.map +1 -0
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.d.ts +10 -0
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.d.ts.map +1 -0
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js +77 -0
- package/dist/esm/organizations/services/organization-custom-implementation.backend.service.js.map +1 -0
- package/dist/esm/organizations/services/organization-member-custom-implementation.backend.service.d.ts +10 -0
- package/dist/esm/organizations/services/organization-member-custom-implementation.backend.service.d.ts.map +1 -0
- package/dist/esm/organizations/services/organization-member-custom-implementation.backend.service.js +131 -0
- package/dist/esm/organizations/services/organization-member-custom-implementation.backend.service.js.map +1 -0
- package/dist/esm/organizations/services/scim-provisioning-gate.backend.utils.d.ts +22 -0
- package/dist/esm/organizations/services/scim-provisioning-gate.backend.utils.d.ts.map +1 -0
- package/dist/esm/organizations/services/scim-provisioning-gate.backend.utils.js +21 -0
- package/dist/esm/organizations/services/scim-provisioning-gate.backend.utils.js.map +1 -0
- package/dist/esm/organizations/services/user-org-type-grant.backend.utils.d.ts +25 -0
- package/dist/esm/organizations/services/user-org-type-grant.backend.utils.d.ts.map +1 -0
- package/dist/esm/organizations/services/user-org-type-grant.backend.utils.js +34 -0
- package/dist/esm/organizations/services/user-org-type-grant.backend.utils.js.map +1 -0
- package/dist/esm/organizations/services/user-type-revocation-on-org-leave.backend.utils.d.ts +32 -0
- package/dist/esm/organizations/services/user-type-revocation-on-org-leave.backend.utils.d.ts.map +1 -0
- package/dist/esm/organizations/services/user-type-revocation-on-org-leave.backend.utils.js +66 -0
- package/dist/esm/organizations/services/user-type-revocation-on-org-leave.backend.utils.js.map +1 -0
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts +126 -0
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js +370 -0
- package/dist/esm/queue/adapters/rabbitmq-adapter.backend.service.js.map +1 -0
- package/dist/esm/queue/apps-crontabs-manager.backend.service.d.ts +86 -0
- package/dist/esm/queue/apps-crontabs-manager.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/apps-crontabs-manager.backend.service.js +176 -0
- package/dist/esm/queue/apps-crontabs-manager.backend.service.js.map +1 -0
- package/dist/esm/queue/cron-job-sync.backend.service.d.ts +42 -0
- package/dist/esm/queue/cron-job-sync.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/cron-job-sync.backend.service.js +181 -0
- package/dist/esm/queue/cron-job-sync.backend.service.js.map +1 -0
- package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts +84 -0
- package/dist/esm/queue/domain-queue-consumer.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/domain-queue-consumer.backend.service.js +275 -0
- package/dist/esm/queue/domain-queue-consumer.backend.service.js.map +1 -0
- package/dist/esm/queue/job-completion-registry.backend.service.d.ts +111 -0
- package/dist/esm/queue/job-completion-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/job-completion-registry.backend.service.js +237 -0
- package/dist/esm/queue/job-completion-registry.backend.service.js.map +1 -0
- package/dist/esm/queue/job-consumer.backend.service.d.ts +109 -0
- package/dist/esm/queue/job-consumer.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/job-consumer.backend.service.js +515 -0
- package/dist/esm/queue/job-consumer.backend.service.js.map +1 -0
- package/dist/esm/queue/job-executor.backend.service.d.ts +53 -0
- package/dist/esm/queue/job-executor.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/job-executor.backend.service.js +278 -0
- package/dist/esm/queue/job-executor.backend.service.js.map +1 -0
- package/dist/esm/queue/job-payload-storage.backend.service.d.ts +86 -0
- package/dist/esm/queue/job-payload-storage.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/job-payload-storage.backend.service.js +250 -0
- package/dist/esm/queue/job-payload-storage.backend.service.js.map +1 -0
- package/dist/esm/queue/job-status-tracking.backend.service.d.ts +97 -0
- package/dist/esm/queue/job-status-tracking.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/job-status-tracking.backend.service.js +281 -0
- package/dist/esm/queue/job-status-tracking.backend.service.js.map +1 -0
- package/dist/esm/queue/queue-monitoring.backend.service.d.ts +71 -0
- package/dist/esm/queue/queue-monitoring.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/queue-monitoring.backend.service.js +297 -0
- package/dist/esm/queue/queue-monitoring.backend.service.js.map +1 -0
- package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts +63 -0
- package/dist/esm/queue/queue-worker-initializer.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/queue-worker-initializer.backend.service.js +171 -0
- package/dist/esm/queue/queue-worker-initializer.backend.service.js.map +1 -0
- package/dist/esm/queue/queue.backend.service.d.ts +108 -0
- package/dist/esm/queue/queue.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/queue.backend.service.js +419 -0
- package/dist/esm/queue/queue.backend.service.js.map +1 -0
- package/dist/esm/queue/scheduled-message-verifier.backend.service.d.ts +74 -0
- package/dist/esm/queue/scheduled-message-verifier.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/scheduled-message-verifier.backend.service.js +189 -0
- package/dist/esm/queue/scheduled-message-verifier.backend.service.js.map +1 -0
- package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts +124 -0
- package/dist/esm/queue/worker-shutdown-manager.backend.service.d.ts.map +1 -0
- package/dist/esm/queue/worker-shutdown-manager.backend.service.js +250 -0
- package/dist/esm/queue/worker-shutdown-manager.backend.service.js.map +1 -0
- package/dist/esm/requests/models/api-routes.backend.defintions.d.ts +34 -0
- package/dist/esm/requests/models/api-routes.backend.defintions.d.ts.map +1 -0
- package/dist/esm/requests/models/api-routes.backend.defintions.js +42 -0
- package/dist/esm/requests/models/api-routes.backend.defintions.js.map +1 -0
- package/dist/esm/requests/models/requests.backend.schemas.d.ts +48 -0
- package/dist/esm/requests/models/requests.backend.schemas.d.ts.map +1 -0
- package/dist/esm/requests/models/requests.backend.schemas.js +7 -0
- package/dist/esm/requests/models/requests.backend.schemas.js.map +1 -0
- package/dist/esm/requests/service/__tests__/mock-apps-shared-resources-gateway.service.d.ts +6 -0
- package/dist/esm/requests/service/__tests__/mock-apps-shared-resources-gateway.service.d.ts.map +1 -0
- package/dist/esm/requests/service/__tests__/mock-apps-shared-resources-gateway.service.js +20 -0
- package/dist/esm/requests/service/__tests__/mock-apps-shared-resources-gateway.service.js.map +1 -0
- package/dist/esm/requests/service/apps-shared-resources-gateway.backend.service.d.ts +84 -0
- package/dist/esm/requests/service/apps-shared-resources-gateway.backend.service.d.ts.map +1 -0
- package/dist/esm/requests/service/apps-shared-resources-gateway.backend.service.js +462 -0
- package/dist/esm/requests/service/apps-shared-resources-gateway.backend.service.js.map +1 -0
- package/dist/esm/requests/service/platform-mutualized-handler.backend.service.d.ts +9 -0
- package/dist/esm/requests/service/platform-mutualized-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/requests/service/platform-mutualized-handler.backend.service.js +36 -0
- package/dist/esm/requests/service/platform-mutualized-handler.backend.service.js.map +1 -0
- package/dist/esm/requests/service/platform-requests.backend.utils.d.ts +6 -0
- package/dist/esm/requests/service/platform-requests.backend.utils.d.ts.map +1 -0
- package/dist/esm/requests/service/platform-requests.backend.utils.js +47 -0
- package/dist/esm/requests/service/platform-requests.backend.utils.js.map +1 -0
- package/dist/esm/requests/service/remote-client-base.backend.service.d.ts +111 -0
- package/dist/esm/requests/service/remote-client-base.backend.service.d.ts.map +1 -0
- package/dist/esm/requests/service/remote-client-base.backend.service.js +354 -0
- package/dist/esm/requests/service/remote-client-base.backend.service.js.map +1 -0
- package/dist/esm/requests/service/serverless-services-handler.backend.service.d.ts +9 -0
- package/dist/esm/requests/service/serverless-services-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/requests/service/serverless-services-handler.backend.service.js +36 -0
- package/dist/esm/requests/service/serverless-services-handler.backend.service.js.map +1 -0
- package/dist/esm/requests/service/websocket.service.d.ts +507 -0
- package/dist/esm/requests/service/websocket.service.d.ts.map +1 -0
- package/dist/esm/requests/service/websocket.service.js +2222 -0
- package/dist/esm/requests/service/websocket.service.js.map +1 -0
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts +3 -0
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.d.ts.map +1 -0
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js +17 -0
- package/dist/esm/resources/models/custom-service-implementations.backend.definition.js.map +1 -0
- package/dist/esm/resources/models/index.d.ts +7 -0
- package/dist/esm/resources/models/index.d.ts.map +1 -0
- package/dist/esm/resources/models/index.js +7 -0
- package/dist/esm/resources/models/index.js.map +1 -0
- package/dist/esm/resources/models/resources-operations.backend.definitions.d.ts +4 -0
- package/dist/esm/resources/models/resources-operations.backend.definitions.d.ts.map +1 -0
- package/dist/esm/resources/models/resources-operations.backend.definitions.js +7 -0
- package/dist/esm/resources/models/resources-operations.backend.definitions.js.map +1 -0
- package/dist/esm/resources/models/resources-relationships.backend.definitions.d.ts +3 -0
- package/dist/esm/resources/models/resources-relationships.backend.definitions.d.ts.map +1 -0
- package/dist/esm/resources/models/resources-relationships.backend.definitions.js +19 -0
- package/dist/esm/resources/models/resources-relationships.backend.definitions.js.map +1 -0
- package/dist/esm/resources/models/resources-types.backend.schemas.d.ts +13 -0
- package/dist/esm/resources/models/resources-types.backend.schemas.d.ts.map +1 -0
- package/dist/esm/resources/models/resources-types.backend.schemas.js +14 -0
- package/dist/esm/resources/models/resources-types.backend.schemas.js.map +1 -0
- package/dist/esm/resources/models/resources.backend.schemas.d.ts +7 -0
- package/dist/esm/resources/models/resources.backend.schemas.d.ts.map +1 -0
- package/dist/esm/resources/models/resources.backend.schemas.js +8 -0
- package/dist/esm/resources/models/resources.backend.schemas.js.map +1 -0
- package/dist/esm/resources/models/virtual-fields.backend.types.d.ts +121 -0
- package/dist/esm/resources/models/virtual-fields.backend.types.d.ts.map +1 -0
- package/dist/esm/resources/models/virtual-fields.backend.types.js +10 -0
- package/dist/esm/resources/models/virtual-fields.backend.types.js.map +1 -0
- package/dist/esm/resources/services/__tests__/mock-resources-registry.service.d.ts +25 -0
- package/dist/esm/resources/services/__tests__/mock-resources-registry.service.d.ts.map +1 -0
- package/dist/esm/resources/services/__tests__/mock-resources-registry.service.js +59 -0
- package/dist/esm/resources/services/__tests__/mock-resources-registry.service.js.map +1 -0
- package/dist/esm/resources/services/resource-context.backend.service.d.ts +321 -0
- package/dist/esm/resources/services/resource-context.backend.service.d.ts.map +1 -0
- package/dist/esm/resources/services/resource-context.backend.service.js +723 -0
- package/dist/esm/resources/services/resource-context.backend.service.js.map +1 -0
- package/dist/esm/resources/services/resource-id.backend.service.d.ts +110 -0
- package/dist/esm/resources/services/resource-id.backend.service.d.ts.map +1 -0
- package/dist/esm/resources/services/resource-id.backend.service.js +267 -0
- package/dist/esm/resources/services/resource-id.backend.service.js.map +1 -0
- package/dist/esm/resources/services/resource-population.backend.service.d.ts +149 -0
- package/dist/esm/resources/services/resource-population.backend.service.d.ts.map +1 -0
- package/dist/esm/resources/services/resource-population.backend.service.js +543 -0
- package/dist/esm/resources/services/resource-population.backend.service.js.map +1 -0
- package/dist/esm/resources/services/resources-registry.backend.service.d.ts +151 -0
- package/dist/esm/resources/services/resources-registry.backend.service.d.ts.map +1 -0
- package/dist/esm/resources/services/resources-registry.backend.service.js +867 -0
- package/dist/esm/resources/services/resources-registry.backend.service.js.map +1 -0
- package/dist/esm/resources/services/virtual-fields.backend.service.d.ts +72 -0
- package/dist/esm/resources/services/virtual-fields.backend.service.d.ts.map +1 -0
- package/dist/esm/resources/services/virtual-fields.backend.service.js +254 -0
- package/dist/esm/resources/services/virtual-fields.backend.service.js.map +1 -0
- package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts +73 -0
- package/dist/esm/runtime/controllers/health-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/runtime/controllers/health-controller.backend.service.js +275 -0
- package/dist/esm/runtime/controllers/health-controller.backend.service.js.map +1 -0
- package/dist/esm/runtime/domain-module.backend.definitions.d.ts +43 -0
- package/dist/esm/runtime/domain-module.backend.definitions.d.ts.map +1 -0
- package/dist/esm/runtime/domain-module.backend.definitions.js +70 -0
- package/dist/esm/runtime/domain-module.backend.definitions.js.map +1 -0
- package/dist/esm/runtime/models/execution-context.backend.schemas.d.ts +253 -0
- package/dist/esm/runtime/models/execution-context.backend.schemas.d.ts.map +1 -0
- package/dist/esm/runtime/models/execution-context.backend.schemas.js +329 -0
- package/dist/esm/runtime/models/execution-context.backend.schemas.js.map +1 -0
- package/dist/esm/runtime/models/runtime.backend.schemas.d.ts +45 -0
- package/dist/esm/runtime/models/runtime.backend.schemas.d.ts.map +1 -0
- package/dist/esm/runtime/models/runtime.backend.schemas.js +73 -0
- package/dist/esm/runtime/models/runtime.backend.schemas.js.map +1 -0
- package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts +315 -0
- package/dist/esm/runtime/services/execution-context-creator.backend.service.d.ts.map +1 -0
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js +1525 -0
- package/dist/esm/runtime/services/execution-context-creator.backend.service.js.map +1 -0
- package/dist/esm/runtime/services/execution-context-handler.backend.service.d.ts +60 -0
- package/dist/esm/runtime/services/execution-context-handler.backend.service.d.ts.map +1 -0
- package/dist/esm/runtime/services/execution-context-handler.backend.service.js +150 -0
- package/dist/esm/runtime/services/execution-context-handler.backend.service.js.map +1 -0
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts +11 -0
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.d.ts.map +1 -0
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.js +1 -0
- package/dist/esm/runtime/services/health-readiness-contributor.backend.interface.js.map +1 -0
- package/dist/esm/runtime/services/http-server.backend.service.d.ts +188 -0
- package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -0
- package/dist/esm/runtime/services/http-server.backend.service.js +755 -0
- package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -0
- package/dist/esm/runtime/services/start-application.backend.service.d.ts +240 -0
- package/dist/esm/runtime/services/start-application.backend.service.d.ts.map +1 -0
- package/dist/esm/runtime/services/start-application.backend.service.js +977 -0
- package/dist/esm/runtime/services/start-application.backend.service.js.map +1 -0
- package/dist/esm/runtime/testing/execution-context-test-fixtures.d.ts +10 -0
- package/dist/esm/runtime/testing/execution-context-test-fixtures.d.ts.map +1 -0
- package/dist/esm/runtime/testing/execution-context-test-fixtures.js +13 -0
- package/dist/esm/runtime/testing/execution-context-test-fixtures.js.map +1 -0
- package/dist/esm/runtime/testing/mock-execution-context-creator.service.d.ts +15 -0
- package/dist/esm/runtime/testing/mock-execution-context-creator.service.d.ts.map +1 -0
- package/dist/esm/runtime/testing/mock-execution-context-creator.service.js +42 -0
- package/dist/esm/runtime/testing/mock-execution-context-creator.service.js.map +1 -0
- package/dist/esm/runtime/utils/scan-default-exports.backend.utils.d.ts +85 -0
- package/dist/esm/runtime/utils/scan-default-exports.backend.utils.d.ts.map +1 -0
- package/dist/esm/runtime/utils/scan-default-exports.backend.utils.js +171 -0
- package/dist/esm/runtime/utils/scan-default-exports.backend.utils.js.map +1 -0
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts +19 -0
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js +59 -0
- package/dist/esm/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/controllers/auth-method-management-controller.backend.service.d.ts +31 -0
- package/dist/esm/security/authentications/controllers/auth-method-management-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/controllers/auth-method-management-controller.backend.service.js +215 -0
- package/dist/esm/security/authentications/controllers/auth-method-management-controller.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts +493 -0
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js +2371 -0
- package/dist/esm/security/authentications/controllers/authentication-controller.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/models/auth-constants.backend.d.ts +83 -0
- package/dist/esm/security/authentications/models/auth-constants.backend.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/auth-constants.backend.js +113 -0
- package/dist/esm/security/authentications/models/auth-constants.backend.js.map +1 -0
- package/dist/esm/security/authentications/models/authentications.backend.schemas.d.ts +98 -0
- package/dist/esm/security/authentications/models/authentications.backend.schemas.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/authentications.backend.schemas.js +59 -0
- package/dist/esm/security/authentications/models/authentications.backend.schemas.js.map +1 -0
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts +42 -0
- package/dist/esm/security/authentications/models/jwt.backend.schemas.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/jwt.backend.schemas.js +98 -0
- package/dist/esm/security/authentications/models/jwt.backend.schemas.js.map +1 -0
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts +163 -0
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.js +12 -0
- package/dist/esm/security/authentications/models/oauth2-connection.backend.schemas.js.map +1 -0
- package/dist/esm/security/authentications/models/saml-authentication.backend.schemas.d.ts +102 -0
- package/dist/esm/security/authentications/models/saml-authentication.backend.schemas.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/saml-authentication.backend.schemas.js +7 -0
- package/dist/esm/security/authentications/models/saml-authentication.backend.schemas.js.map +1 -0
- package/dist/esm/security/authentications/models/sso-connection.backend.schemas.d.ts +88 -0
- package/dist/esm/security/authentications/models/sso-connection.backend.schemas.d.ts.map +1 -0
- package/dist/esm/security/authentications/models/sso-connection.backend.schemas.js +17 -0
- package/dist/esm/security/authentications/models/sso-connection.backend.schemas.js.map +1 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.d.ts +27 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.js +66 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.js.map +1 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-token-issuer.service.d.ts +30 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-token-issuer.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-token-issuer.service.js +44 -0
- package/dist/esm/security/authentications/services/__tests__/mock-auth-token-issuer.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.d.ts +19 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.js +43 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.d.ts +37 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.js +58 -0
- package/dist/esm/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts +85 -0
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js +379 -0
- package/dist/esm/security/authentications/services/admin-config/auth-organization-configuration.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts +79 -0
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js +205 -0
- package/dist/esm/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts +59 -0
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js +179 -0
- package/dist/esm/security/authentications/services/admin-config/domain-verification.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts +116 -0
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js +436 -0
- package/dist/esm/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.d.ts +67 -0
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.js +222 -0
- package/dist/esm/security/authentications/services/admin-config/oidc-discovery.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts +80 -0
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.js +368 -0
- package/dist/esm/security/authentications/services/anonymous-session.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-credential-verifier.backend.service.d.ts +75 -0
- package/dist/esm/security/authentications/services/auth-credential-verifier.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-credential-verifier.backend.service.js +139 -0
- package/dist/esm/security/authentications/services/auth-credential-verifier.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-execution-context-factory.backend.service.d.ts +72 -0
- package/dist/esm/security/authentications/services/auth-execution-context-factory.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-execution-context-factory.backend.service.js +127 -0
- package/dist/esm/security/authentications/services/auth-execution-context-factory.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts +57 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js +459 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-method-management.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts +44 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js +131 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-mfa.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts +58 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js +209 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-phone-verification.backend.service.d.ts +46 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-phone-verification.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-phone-verification.backend.service.js +124 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-phone-verification.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts +165 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js +816 -0
- package/dist/esm/security/authentications/services/auth-methods/auth-registration.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts +218 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js +1026 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-authentication.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts +150 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js +737 -0
- package/dist/esm/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.d.ts +224 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.js +593 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-authentication.backend.service.d.ts +267 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-authentication.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-authentication.backend.service.js +1376 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-authentication.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-metadata.backend.service.d.ts +93 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-metadata.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-metadata.backend.service.js +396 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-metadata.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-replay-guard.backend.service.d.ts +40 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-replay-guard.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-replay-guard.backend.service.js +92 -0
- package/dist/esm/security/authentications/services/auth-methods/saml-replay-guard.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts +82 -0
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js +325 -0
- package/dist/esm/security/authentications/services/auth-methods/webauthn.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-session-store.backend.service.d.ts +66 -0
- package/dist/esm/security/authentications/services/auth-session-store.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-session-store.backend.service.js +198 -0
- package/dist/esm/security/authentications/services/auth-session-store.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts +108 -0
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js +406 -0
- package/dist/esm/security/authentications/services/auth-token-issuer.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts +366 -0
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js +2631 -0
- package/dist/esm/security/authentications/services/authentication-orchestrator.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.d.ts +13 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js +53 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-custom-implementations.backend.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-policy.custom-impl.backend.service.d.ts +12 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-policy.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-policy.custom-impl.backend.service.js +41 -0
- package/dist/esm/security/authentications/services/custom-impls/auth-policy.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-provisioning-config.custom-impl.backend.service.d.ts +18 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-provisioning-config.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-provisioning-config.custom-impl.backend.service.js +140 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-provisioning-config.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.d.ts +16 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.js +112 -0
- package/dist/esm/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts +16 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js +101 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-export-config.custom-impl.backend.service.d.ts +18 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-export-config.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-export-config.custom-impl.backend.service.js +136 -0
- package/dist/esm/security/authentications/services/custom-impls/siem-export-config.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts +19 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js +154 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.d.ts +26 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.js +657 -0
- package/dist/esm/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.d.ts +27 -0
- package/dist/esm/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.js +60 -0
- package/dist/esm/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.js.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-controller.utils.d.ts +23 -0
- package/dist/esm/security/authentications/services/utils/auth-controller.utils.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-controller.utils.js +44 -0
- package/dist/esm/security/authentications/services/utils/auth-controller.utils.js.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-credential-ops.backend.service.d.ts +89 -0
- package/dist/esm/security/authentications/services/utils/auth-credential-ops.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-credential-ops.backend.service.js +192 -0
- package/dist/esm/security/authentications/services/utils/auth-credential-ops.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-response-helper.backend.service.d.ts +20 -0
- package/dist/esm/security/authentications/services/utils/auth-response-helper.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-response-helper.backend.service.js +55 -0
- package/dist/esm/security/authentications/services/utils/auth-response-helper.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.d.ts +50 -0
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js +135 -0
- package/dist/esm/security/authentications/services/utils/auth-user-lookup.backend.service.js.map +1 -0
- package/dist/esm/security/authentications/services/utils/saml-java-availability.d.ts +26 -0
- package/dist/esm/security/authentications/services/utils/saml-java-availability.d.ts.map +1 -0
- package/dist/esm/security/authentications/services/utils/saml-java-availability.js +59 -0
- package/dist/esm/security/authentications/services/utils/saml-java-availability.js.map +1 -0
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts +137 -0
- package/dist/esm/security/authorizations/services/authorizations.backend.service.d.ts.map +1 -0
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js +723 -0
- package/dist/esm/security/authorizations/services/authorizations.backend.service.js.map +1 -0
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts +28 -0
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js +156 -0
- package/dist/esm/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.js.map +1 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts +4 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js +72 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.js.map +1 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.shared.schemas.d.ts +125 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.shared.schemas.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.shared.schemas.js +69 -0
- package/dist/esm/security/consumable-tokens/models/consumable-tokens.shared.schemas.js.map +1 -0
- package/dist/esm/security/consumable-tokens/models/index.d.ts +3 -0
- package/dist/esm/security/consumable-tokens/models/index.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/models/index.js +3 -0
- package/dist/esm/security/consumable-tokens/models/index.js.map +1 -0
- package/dist/esm/security/consumable-tokens/services/__tests__/mock-consumable-token.service.d.ts +26 -0
- package/dist/esm/security/consumable-tokens/services/__tests__/mock-consumable-token.service.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/services/__tests__/mock-consumable-token.service.js +55 -0
- package/dist/esm/security/consumable-tokens/services/__tests__/mock-consumable-token.service.js.map +1 -0
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts +142 -0
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.d.ts.map +1 -0
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js +446 -0
- package/dist/esm/security/consumable-tokens/services/consumable-token.backend.service.js.map +1 -0
- package/dist/esm/security/jwt/services/auth-jwt-guard.backend.service.d.ts +46 -0
- package/dist/esm/security/jwt/services/auth-jwt-guard.backend.service.d.ts.map +1 -0
- package/dist/esm/security/jwt/services/auth-jwt-guard.backend.service.js +147 -0
- package/dist/esm/security/jwt/services/auth-jwt-guard.backend.service.js.map +1 -0
- package/dist/esm/security/jwt/services/jwt.backend.service.d.ts +75 -0
- package/dist/esm/security/jwt/services/jwt.backend.service.d.ts.map +1 -0
- package/dist/esm/security/jwt/services/jwt.backend.service.js +368 -0
- package/dist/esm/security/jwt/services/jwt.backend.service.js.map +1 -0
- package/dist/esm/security/scim/controllers/scim.backend.controller.d.ts +71 -0
- package/dist/esm/security/scim/controllers/scim.backend.controller.d.ts.map +1 -0
- package/dist/esm/security/scim/controllers/scim.backend.controller.js +863 -0
- package/dist/esm/security/scim/controllers/scim.backend.controller.js.map +1 -0
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts +275 -0
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.d.ts.map +1 -0
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js +139 -0
- package/dist/esm/security/scim/models/scim-protocol.backend.schemas.js.map +1 -0
- package/dist/esm/security/scim/utils/scim-filter-parser.d.ts +35 -0
- package/dist/esm/security/scim/utils/scim-filter-parser.d.ts.map +1 -0
- package/dist/esm/security/scim/utils/scim-filter-parser.js +232 -0
- package/dist/esm/security/scim/utils/scim-filter-parser.js.map +1 -0
- package/dist/esm/security/scim/utils/scim-response-formatter.d.ts +42 -0
- package/dist/esm/security/scim/utils/scim-response-formatter.d.ts.map +1 -0
- package/dist/esm/security/scim/utils/scim-response-formatter.js +89 -0
- package/dist/esm/security/scim/utils/scim-response-formatter.js.map +1 -0
- package/dist/esm/testing.d.ts +31 -0
- package/dist/esm/testing.d.ts.map +1 -0
- package/dist/esm/testing.js +31 -0
- package/dist/esm/testing.js.map +1 -0
- package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts +9 -0
- package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -0
- package/dist/esm/users/services/user-self-custom-implementations.backend.js +48 -0
- package/dist/esm/users/services/user-self-custom-implementations.backend.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +163 -0
- package/src/__tests__/integration/bulk-repository-write-contract.integration.test.ts +373 -0
- package/src/__tests__/integration/custom-batch-job-execution.integration.test.ts +147 -0
- package/src/__tests__/integration/delete-file-rollback-persistence.integration.test.ts +551 -0
- package/src/__tests__/integration/file-management-nested-persistence.integration.test.ts +487 -0
- package/src/__tests__/integration/file-management-postgresql-persistence.integration.test.ts +466 -0
- package/src/__tests__/integration/files-cleanup-persistence.integration.test.ts +335 -0
- package/src/__tests__/integration/generated-bulk-relationship-runtime.integration.test.ts +545 -0
- package/src/__tests__/integration/lifecycle-delete-rollback-persistence.integration.test.ts +537 -0
- package/src/__tests__/integration/postgresql-contextual-filter-enforcement.integration.test.ts +170 -0
- package/src/__tests__/integration/postgresql-delete-best-effort-boundary.integration.test.ts +604 -0
- package/src/__tests__/integration/prompt-compiler.integration.test.ts +723 -0
- package/src/__tests__/integration/relationship-service-semantics.integration.test.ts +2086 -0
- package/src/__tests__/integration/repositories-registry.integration.test.ts +296 -0
- package/src/__tests__/integration/resource-factory-pipeline.integration.test.ts +556 -0
- package/src/__tests__/integration/resource-services.integration.test.ts +265 -0
- package/src/__tests__/integration/resources-registry.integration.test.ts +327 -0
- package/src/__tests__/integration/services-registry.integration.test.ts +231 -0
- package/src/__tests__/integration/update-many-runtime-guards.integration.test.ts +290 -0
- package/src/__tests__/setup.ts +15 -0
- package/src/__tests__/test-container.ts +120 -0
- package/src/applications/models/applications.backend.schemas.ts +18 -0
- package/src/base-classes/__tests__/batches-cronjobs-executor.test.ts +63 -0
- package/src/base-classes/__tests__/bulk-delete-child-file-guard.test.ts +152 -0
- package/src/base-classes/__tests__/bulk-nested-file-update-coordination.test.ts +171 -0
- package/src/base-classes/__tests__/delete-file-coordination.test.ts +185 -0
- package/src/base-classes/__tests__/postgresql-file-transaction-coordination.test.ts +424 -0
- package/src/base-classes/__tests__/postgresql-repository-contextual-filter-enforcement.test.ts +88 -0
- package/src/base-classes/__tests__/repository-contextual-filter-enforcement.test.ts +87 -0
- package/src/base-classes/__tests__/resource-operation-helper-context-enforcement.test.ts +74 -0
- package/src/base-classes/__tests__/transaction-boundaries.test.ts +153 -0
- package/src/base-classes/models/manual-controllers.backend.definition.ts +56 -0
- package/src/base-classes/models/repositories.backend.schemas.ts +105 -0
- package/src/base-classes/services/__tests__/mock-resource-operation-helper.service.ts +61 -0
- package/src/base-classes/services/batches/batches-cronjobs-custom-execution.service.ts +148 -0
- package/src/base-classes/services/batches/batches-cronjobs-executor.backend.service.ts +115 -0
- package/src/base-classes/services/batches/batches-cronjobs-resource-execution.backend.service.ts +58 -0
- package/src/base-classes/services/controllers/__tests__/controller-request-validation.utils.test.ts +292 -0
- package/src/base-classes/services/controllers/__tests__/controller-resource-file-upload-routes.test.ts +1335 -0
- package/src/base-classes/services/controllers/__tests__/controller-resource.version-conflict.test.ts +372 -0
- package/src/base-classes/services/controllers/abstract-controller.backend.service.ts +302 -0
- package/src/base-classes/services/controllers/controller-resource.backend.service.ts +1833 -0
- package/src/base-classes/services/controllers/controllers-registry-handler.backend.service.ts +494 -0
- package/src/base-classes/services/controllers/validate-field-handler.backend.service.ts +613 -0
- package/src/base-classes/services/repositories/__tests__/mock-repositories-registry-handler.service.ts +31 -0
- package/src/base-classes/services/repositories/__tests__/repository-resource.singleton-read.test.ts +50 -0
- package/src/base-classes/services/repositories/postgresql-resource-repository.backend.service.ts +1207 -0
- package/src/base-classes/services/repositories/repositories-registry-handler.backend.service.ts +804 -0
- package/src/base-classes/services/repositories/repository-resource.backend.service.ts +2186 -0
- package/src/base-classes/services/resource-operations-helper.backend.service.ts +468 -0
- package/src/base-classes/services/services/__tests__/mock-services-registry-handler.service.ts +21 -0
- package/src/base-classes/services/services/__tests__/services-registry-handler.notifications.test.ts +65 -0
- package/src/base-classes/services/services/resource-operation-custom-implementation-base.backend.service.ts +305 -0
- package/src/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.ts +224 -0
- package/src/base-classes/services/services/resource-operation-custom-implementation.factory.backend.ts +331 -0
- package/src/base-classes/services/services/services-registry-handler.backend.service.ts +6288 -0
- package/src/base-classes/utils/backend-type-utils.ts +64 -0
- package/src/billing/services/back-office/__tests__/billing-feature-sync.backend.service.test.ts +132 -0
- package/src/billing/services/back-office/__tests__/billing-state.backend.service.test.ts +245 -0
- package/src/billing/services/back-office/__tests__/product-catalog-sync.backend.service.test.ts +238 -0
- package/src/billing/services/back-office/abstract-billing.backend.service.ts +89 -0
- package/src/billing/services/back-office/billing-feature-sync.backend.service.ts +473 -0
- package/src/billing/services/back-office/billing-state.backend.service.ts +348 -0
- package/src/billing/services/back-office/product-catalog-sync.backend.service.ts +415 -0
- package/src/billing/services/back-office/usage-metering.backend.service.ts +326 -0
- package/src/billing/services/billing.utils.ts +26 -0
- package/src/billing/services/custom-impl/billing-account.mutations.custom-impl.backend.service.ts +342 -0
- package/src/billing/services/custom-impl/billing-custom-impl-utils.backend.ts +274 -0
- package/src/billing/services/custom-impl/billing-custom-implementations.backend.ts +236 -0
- package/src/billing/services/custom-impl/credit-pool.custom-ops.custom-impl.backend.service.ts +133 -0
- package/src/billing/services/custom-impl/promotion.custom-ops.custom-impl.backend.service.ts +242 -0
- package/src/billing/services/custom-impl/subscription.mutations.custom-impl.backend.service.ts +434 -0
- package/src/billing/services/webhooks/billing-webhook-adapter.backend.service.ts +70 -0
- package/src/billing/services/webhooks/billing-webhook-capability-handler.backend.service.ts +46 -0
- package/src/billing/services/webhooks/billing-webhook-event-router.backend.service.ts +727 -0
- package/src/billing/testing/billing-test-fixtures.ts +296 -0
- package/src/billing/testing/mock-billing-provider.ts +548 -0
- package/src/charts/controllers/__tests__/chart.backend.controller.test.ts +403 -0
- package/src/charts/controllers/chart.backend.controller.ts +238 -0
- package/src/charts/services/__tests__/chart-registry.backend.service.test.ts +120 -0
- package/src/charts/services/chart-registry.backend.service.ts +109 -0
- package/src/compliance/audit-trails/audit-logs.custom-impl.backend.service.ts +104 -0
- package/src/compliance/audit-trails/services/__tests__/mock-audit-logs.service.ts +48 -0
- package/src/compliance/audit-trails/services/audit-event-dispatcher.backend.service.ts +325 -0
- package/src/compliance/audit-trails/services/audit-logs.backend.service.ts +1313 -0
- package/src/compliance/audit-trails/services/siem-webhook-delivery.backend.service.ts +542 -0
- package/src/compliance/index.ts +1 -0
- package/src/config/custom/application-config-controller.backend.service.ts +119 -0
- package/src/config/models/__tests__/app-config-secrets.boundaries.test.ts +56 -0
- package/src/config/models/__tests__/app-config.backend-authored.definitions.test.ts +286 -0
- package/src/config/models/app-config-secrets.backend.schemas.ts +154 -0
- package/src/config/models/app-config.backend-authored.definitions.ts +165 -0
- package/src/config/models/app-config.backend.schemas.ts +614 -0
- package/src/config/models/app-env-config.backend.schemas.ts +135 -0
- package/src/config/models/config-mutation-boundary.utils.ts +76 -0
- package/src/config/models/postgresql-env-config.backend.schemas.ts +126 -0
- package/src/config/models/runtime-topology.backend.contracts.ts +42 -0
- package/src/config/services/__tests__/app-configuration-loader.backend.service.test.ts +118 -0
- package/src/config/services/__tests__/app-configuration.backend.service.test.ts +40 -0
- package/src/config/services/__tests__/app-configuration.backend.utils.test.ts +72 -0
- package/src/config/services/__tests__/application-startup-config-validator.backend.service.test.ts +404 -0
- package/src/config/services/__tests__/mock-app-configuration.service.ts +131 -0
- package/src/config/services/app-configuration-loader.backend.service.ts +443 -0
- package/src/config/services/app-configuration.backend.service.ts +570 -0
- package/src/config/services/app-configuration.backend.utils.ts +94 -0
- package/src/config/services/application-startup-config-validator.backend.service.ts +611 -0
- package/src/databases/models/aggregation.backend.schemas.ts +174 -0
- package/src/databases/models/databases.backend.schemas.ts +70 -0
- package/src/databases/models/filter.backend.schemas.ts +101 -0
- package/src/databases/models/sql.backend.schemas.ts +111 -0
- package/src/databases/models/transaction.shared.schemas.ts +172 -0
- package/src/databases/services/__tests__/mock-mongo-transaction-registry.service.ts +90 -0
- package/src/databases/services/__tests__/mock-mongodb.service.ts +86 -0
- package/src/databases/services/__tests__/mock-mongoose-model.service.ts +411 -0
- package/src/databases/services/__tests__/mock-redis.service.ts +72 -0
- package/src/databases/services/__tests__/mock-zod-mongoose-schema-convertor.service.ts +41 -0
- package/src/databases/services/__tests__/mongo-aggregation-compiler.test.ts +918 -0
- package/src/databases/services/__tests__/postgresql-filter.backend.service.test.ts +180 -0
- package/src/databases/services/__tests__/sql-hybrid-transform.test.ts +73 -0
- package/src/databases/services/aggregation/__tests__/aggregation-authorization.backend.service.test.ts +444 -0
- package/src/databases/services/aggregation/__tests__/aggregation-query.backend.service.test.ts +150 -0
- package/src/databases/services/aggregation/__tests__/computed-measure-evaluator.test.ts +525 -0
- package/src/databases/services/aggregation/__tests__/field-access-validator.test.ts +458 -0
- package/src/databases/services/aggregation/__tests__/time-series-densifier.test.ts +631 -0
- package/src/databases/services/aggregation/__tests__/window-function-processor.test.ts +598 -0
- package/src/databases/services/aggregation/aggregation-authorization.backend.service.ts +516 -0
- package/src/databases/services/aggregation/aggregation-query.backend.service.ts +514 -0
- package/src/databases/services/aggregation/computed-measure-evaluator.backend.service.ts +196 -0
- package/src/databases/services/aggregation/field-access-validator.backend.service.ts +225 -0
- package/src/databases/services/aggregation/time-series-densifier.backend.service.ts +389 -0
- package/src/databases/services/aggregation/topn-processor.backend.service.ts +221 -0
- package/src/databases/services/aggregation/window-function-processor.backend.service.ts +301 -0
- package/src/databases/services/db-utils.ts +96 -0
- package/src/databases/services/mongo-aggregation.backend.service.ts +762 -0
- package/src/databases/services/mongodb.service.ts +736 -0
- package/src/databases/services/postgresql-aggregation.backend.service.ts +794 -0
- package/src/databases/services/postgresql-database.backend.service.ts +288 -0
- package/src/databases/services/postgresql-filter.backend.service.ts +673 -0
- package/src/databases/services/redis.service.ts +531 -0
- package/src/databases/services/zod-to-mongoose-schema-convertor.backend.service.ts +2486 -0
- package/src/databases/services/zod-to-sql-hybrid-schema.planner.ts +312 -0
- package/src/errors/services/__tests__/error-builder.backend.service.test.ts +31 -0
- package/src/errors/services/__tests__/error-handler.backend.service.test.ts +82 -0
- package/src/errors/services/__tests__/mock-error-builder.service.ts +288 -0
- package/src/errors/services/error-builder.backend.service.ts +403 -0
- package/src/errors/services/error-handler.backend.service.ts +236 -0
- package/src/errors/services/rate-limit.backend.service.ts +45 -0
- package/src/external-providers/models/external-providers.backend.schemas.ts +243 -0
- package/src/external-providers/services/__tests__/external-providers-registry.backend.service.test.ts +136 -0
- package/src/external-providers/services/__tests__/feature-bindings.backend.service.test.ts +40 -0
- package/src/external-providers/services/__tests__/mock-external-providers-registry.service.ts +33 -0
- package/src/external-providers/services/__tests__/mock-lazy-provider-registry.service.ts +45 -0
- package/src/external-providers/services/external-api-handler.backend.service.ts +19 -0
- package/src/external-providers/services/external-providers-registry.backend.service.ts +534 -0
- package/src/external-providers/services/feature-bindings.backend.service.ts +422 -0
- package/src/external-providers/services/lazy-provider-registry.backend.service.ts +486 -0
- package/src/features/__tests__/feature-builders.test.ts +152 -0
- package/src/features/controllers/__tests__/features.backend.controller.test.ts +173 -0
- package/src/features/controllers/features.backend.controller.ts +200 -0
- package/src/features/services/__tests__/feature-definition-registry.backend.service.test.ts +152 -0
- package/src/features/services/__tests__/feature-gate.test.ts +484 -0
- package/src/features/services/__tests__/feature-resolution.backend.service.test.ts +203 -0
- package/src/features/services/__tests__/mock-capability-bindings.service.ts +26 -0
- package/src/features/services/__tests__/mock-feature-definition-registry.service.ts +56 -0
- package/src/features/services/__tests__/mock-feature-resolution.service.ts +36 -0
- package/src/features/services/feature-definition-registry.backend.service.ts +537 -0
- package/src/features/services/feature-gate.backend.service.ts +522 -0
- package/src/features/services/feature-resolution.backend.service.ts +652 -0
- package/src/features/testing/feature-test-utils.ts +200 -0
- package/src/files/batches/__tests__/files-cleanup.batch.backend.service.test.ts +186 -0
- package/src/files/batches/files-cleanup.batch.backend.service.ts +259 -0
- package/src/files/constraints/file-analyzers.types.ts +85 -0
- package/src/files/constraints/file-constraint-resolver-chain.backend.service.ts +99 -0
- package/src/files/constraints/file-constraint.types.ts +104 -0
- package/src/files/constraints/file-validation.backend.service.ts +359 -0
- package/src/files/constraints/resource-field-constraint-resolver.backend.service.ts +138 -0
- package/src/files/controllers/__tests__/file.controller.behavior.test.ts +655 -0
- package/src/files/controllers/file.controller.ts +1030 -0
- package/src/files/handlers/__tests__/resource-file-upload-handler.backend.service.test.ts +392 -0
- package/src/files/handlers/resource-file-upload-handler.backend.service.ts +605 -0
- package/src/files/rag/weaviate-vector-store.backend.service.ts +271 -0
- package/src/files/scanning/clamav-scanner.backend.service.ts +214 -0
- package/src/files/scanning/file-scan.types.ts +17 -0
- package/src/files/scanning/yara-scanner.backend.service.ts +212 -0
- package/src/files/services/__tests__/file-field-detection.backend.service.test.ts +91 -0
- package/src/files/services/__tests__/file-operation-handler.backend.service.test.ts +272 -0
- package/src/files/services/__tests__/file-population.backend.service.test.ts +120 -0
- package/src/files/services/__tests__/file-scanning.backend.service.test.ts +163 -0
- package/src/files/services/__tests__/files.backend.service.test.ts +885 -0
- package/src/files/services/__tests__/mock-file-field-detection.service.ts +43 -0
- package/src/files/services/__tests__/mock-file-operation-handler.service.ts +113 -0
- package/src/files/services/__tests__/mock-file-repository.service.ts +104 -0
- package/src/files/services/file-field-detection.backend.service.ts +156 -0
- package/src/files/services/file-operation-handler.backend.service.ts +861 -0
- package/src/files/services/file-population.backend.service.ts +485 -0
- package/src/files/services/file-rag-indexing.backend.service.ts +229 -0
- package/src/files/services/file-scanning.backend.service.ts +373 -0
- package/src/files/services/file-text-extraction.backend.service.ts +193 -0
- package/src/files/services/files.backend.service.ts +1356 -0
- package/src/files/storage/file-storage-path-resolver.backend.service.ts +289 -0
- package/src/files/storage/file-storage-provider.types.ts +188 -0
- package/src/files/storage/file-storage-router.backend.service.ts +172 -0
- package/src/files/storage/local-directory-storage-provider.backend.service.ts +417 -0
- package/src/files/storage/wildo-managed-storage-provider.backend.service.ts +530 -0
- package/src/files/utils/__tests__/file-field-schema-path.backend.utils.test.ts +44 -0
- package/src/files/utils/__tests__/file-uploader.utils.test.ts +57 -0
- package/src/files/utils/__tests__/file-validation.utils.test.ts +559 -0
- package/src/files/utils/file-field-schema-path.backend.utils.ts +385 -0
- package/src/files/utils/file-upload.utils.ts +146 -0
- package/src/files/utils/file-uploader.utils.ts +65 -0
- package/src/files/utils/file-validation.utils.ts +753 -0
- package/src/flows-actors/agent-catalogs.backend.ts +427 -0
- package/src/flows-actors/controllers/flows-actors.controller.ts +91 -0
- package/src/flows-actors/models/agent-catalogs.backend.definitions.ts +430 -0
- package/src/flows-actors/models/agent-facets.backend.definitions.ts +120 -0
- package/src/flows-actors/models/agents.backend.definitions.ts +4 -0
- package/src/flows-actors/models/core-facets.backend.definitions.ts +348 -0
- package/src/flows-actors/models/flows-actors.backend.definitions.ts +13 -0
- package/src/flows-actors/models/flows-actors.backend.schemas.ts +44 -0
- package/src/flows-actors/services/__tests__/agent-facets-catalogs.test.ts +544 -0
- package/src/flows-actors/services/__tests__/agents.backend.service.cli-runtime.test.ts +234 -0
- package/src/flows-actors/services/actors-system.backend.service.ts +270 -0
- package/src/flows-actors/services/agent-facets.backend.service.ts +350 -0
- package/src/flows-actors/services/agents.backend.service.ts +2730 -0
- package/src/flows-actors/services/context-curation.backend.service.ts +203 -0
- package/src/flows-actors/services/flows-actors-registry.service.ts +374 -0
- package/src/flows-actors/services/flows.backend.services.ts +237 -0
- package/src/flows-actors/services/prompt-compiler.backend.service.ts +734 -0
- package/src/flows-actors/utils/__tests__/cli-runtime-operation-support.backend.utils.test.ts +95 -0
- package/src/flows-actors/utils/cli-runtime-operation-support.backend.utils.ts +87 -0
- package/src/flows-actors/utils/cli-runtime-runner.backend.utils.ts +171 -0
- package/src/flows-actors/utils/flows-actors-frontend-extractor.utils.ts +63 -0
- package/src/flows-actors/utils/prompt-ir-adapters.backend.utils.ts +257 -0
- package/src/guidance/batches/dormancy-detection.batch.backend.service.ts +126 -0
- package/src/guidance/services/__tests__/guidance-trigger-evaluator.backend.service.test.ts +49 -0
- package/src/guidance/services/__tests__/lifecycle-evaluator.backend.service.test.ts +85 -0
- package/src/guidance/services/__tests__/milestone-definition-registry.backend.service.test.ts +211 -0
- package/src/guidance/services/__tests__/milestone-evaluator.backend.service.test.ts +561 -0
- package/src/guidance/services/guidance-trigger-evaluator.backend.service.ts +151 -0
- package/src/guidance/services/lifecycle-custom-implementations.backend.ts +139 -0
- package/src/guidance/services/lifecycle-evaluator.backend.service.ts +908 -0
- package/src/guidance/services/milestone-condition-registry.backend.service.ts +57 -0
- package/src/guidance/services/milestone-definition-registry.backend.service.ts +265 -0
- package/src/guidance/services/milestone-evaluator.backend.service.ts +611 -0
- package/src/i18n/controllers/i18n-controller.backend.service.ts +227 -0
- package/src/i18n/services/i18n.backend.service.ts +88 -0
- package/src/index.ts +286 -0
- package/src/inject/models/container.ts +586 -0
- package/src/inject/models/service-types.ts +488 -0
- package/src/monitoring/analytics/controllers/analytics.backend.controller.ts +114 -0
- package/src/monitoring/analytics/services/value-moment-engine.backend.service.ts +53 -0
- package/src/monitoring/analytics/services/value-moment-handler-registry.backend.service.ts +38 -0
- package/src/monitoring/logger/middleware/logging.middleware.ts +40 -0
- package/src/monitoring/logger/models/logger.backend.schemas.ts +56 -0
- package/src/monitoring/logger/services/__tests__/mock-logger.service.ts +49 -0
- package/src/monitoring/logger/services/logger.service.ts +214 -0
- package/src/monitoring/observability/middleware/metrics.middleware.ts +205 -0
- package/src/monitoring/observability/middleware/telemetry.middleware.ts +188 -0
- package/src/monitoring/observability/middleware/tracing.middleware.ts +265 -0
- package/src/monitoring/observability/models/observability.backend.schemas.ts +96 -0
- package/src/monitoring/observability/services/instrumentations/custom.instrumentations.ts +132 -0
- package/src/monitoring/observability/services/metrics.service.ts +266 -0
- package/src/monitoring/observability/services/telemetry.service.ts +157 -0
- package/src/monitoring/observability/services/tracer.service.ts +334 -0
- package/src/notifications/email/components/email-components.ts +341 -0
- package/src/notifications/email/models/email-context-provider.interface.ts +107 -0
- package/src/notifications/email/models/email-template-definition.ts +74 -0
- package/src/notifications/email/models/email-template.actors-system.backend.definitions.ts +80 -0
- package/src/notifications/email/models/email.backend.scheamas.ts +0 -0
- package/src/notifications/email/services/email-batch-send.batch.backend.service.ts +236 -0
- package/src/notifications/email/services/email-context-provider-registry.backend.service.ts +157 -0
- package/src/notifications/email/services/email-renderer.backend.service.ts +274 -0
- package/src/notifications/email/services/email-template-compiler.backend.service.ts +136 -0
- package/src/notifications/email/services/email-template-generation.backend.service.ts +811 -0
- package/src/notifications/email/services/email-template-registry.backend.service.ts +166 -0
- package/src/notifications/email/services/email-template-sandbox.backend.service.ts +255 -0
- package/src/notifications/email/services/email-template-validator.backend.service.ts +229 -0
- package/src/notifications/email/services/email.backend.service.ts +429 -0
- package/src/notifications/email/utils/color-conversion.utils.ts +142 -0
- package/src/notifications/email/utils/interpolate-email-label.utils.ts +16 -0
- package/src/notifications/email/utils/zod-to-typescript.utils.ts +352 -0
- package/src/notifications/services/__tests__/notifications-dispatcher.operation-semantics.test.ts +773 -0
- package/src/notifications/services/__tests__/notifications-dispatcher.websocket-integration.test.ts +173 -0
- package/src/notifications/services/notification-badge.backend.service.ts +412 -0
- package/src/notifications/services/notifications-dispatcher.backend.service.ts +1696 -0
- package/src/notifications/sms/services/sms.backend.service.ts +283 -0
- package/src/notifications/webhooks/controllers/webhook-auto-controller.backend.service.ts +220 -0
- package/src/notifications/webhooks/services/polymorphic-lookup.backend.service.ts +131 -0
- package/src/notifications/webhooks/services/webhook-handler.backend.service.ts +481 -0
- package/src/organizations/services/__tests__/org-creation-on-registration.backend.utils.test.ts +193 -0
- package/src/organizations/services/__tests__/org-member-roles-validation.backend.utils.test.ts +101 -0
- package/src/organizations/services/__tests__/organization-custom-implementation.backend.service.test.ts +113 -0
- package/src/organizations/services/__tests__/scim-provisioning-gate.backend.utils.test.ts +94 -0
- package/src/organizations/services/__tests__/user-org-type-grant.backend.utils.test.ts +164 -0
- package/src/organizations/services/__tests__/user-type-revocation-on-org-leave.backend.utils.test.ts +161 -0
- package/src/organizations/services/org-creation-on-registration.backend.utils.ts +119 -0
- package/src/organizations/services/org-member-roles-validation.backend.utils.ts +51 -0
- package/src/organizations/services/organization-custom-implementation.backend.service.ts +106 -0
- package/src/organizations/services/organization-member-custom-implementation.backend.service.ts +150 -0
- package/src/organizations/services/scim-provisioning-gate.backend.utils.ts +34 -0
- package/src/organizations/services/user-org-type-grant.backend.utils.ts +49 -0
- package/src/organizations/services/user-type-revocation-on-org-leave.backend.utils.ts +102 -0
- package/src/queue/adapters/rabbitmq-adapter.backend.service.ts +494 -0
- package/src/queue/apps-crontabs-manager.backend.service.ts +258 -0
- package/src/queue/cron-job-sync.backend.service.ts +184 -0
- package/src/queue/domain-queue-consumer.backend.service.ts +333 -0
- package/src/queue/job-completion-registry.backend.service.ts +342 -0
- package/src/queue/job-consumer.backend.service.ts +646 -0
- package/src/queue/job-executor.backend.service.ts +315 -0
- package/src/queue/job-payload-storage.backend.service.ts +297 -0
- package/src/queue/job-status-tracking.backend.service.ts +376 -0
- package/src/queue/queue-monitoring.backend.service.ts +333 -0
- package/src/queue/queue-worker-initializer.backend.service.ts +179 -0
- package/src/queue/queue.backend.service.ts +530 -0
- package/src/queue/scheduled-message-verifier.backend.service.ts +228 -0
- package/src/queue/worker-shutdown-manager.backend.service.ts +298 -0
- package/src/requests/models/api-routes.backend.defintions.ts +45 -0
- package/src/requests/models/requests.backend.schemas.ts +73 -0
- package/src/requests/service/__tests__/websocket.service.auth-refresh.test.ts +361 -0
- package/src/requests/service/__tests__/websocket.service.resource-room-validation.test.ts +234 -0
- package/src/requests/service/__tests__/websocket.service.variant-authorization.test.ts +94 -0
- package/src/requests/service/platform-mutualized-handler.backend.service.ts +19 -0
- package/src/requests/service/platform-requests.backend.utils.ts +54 -0
- package/src/requests/service/remote-client-base.backend.service.ts +485 -0
- package/src/requests/service/serverless-services-handler.backend.service.ts +19 -0
- package/src/requests/service/websocket.service.ts +2844 -0
- package/src/resources/models/custom-service-implementations.backend.definition.ts +22 -0
- package/src/resources/models/index.ts +7 -0
- package/src/resources/models/resources-operations.backend.definitions.ts +9 -0
- package/src/resources/models/resources-relationships.backend.definitions.ts +30 -0
- package/src/resources/models/resources-types.backend.schemas.ts +14 -0
- package/src/resources/models/resources.backend.schemas.ts +6 -0
- package/src/resources/models/virtual-fields.backend.types.ts +132 -0
- package/src/resources/services/__tests__/mock-resources-registry.service.ts +69 -0
- package/src/resources/services/__tests__/resource-id.backend.service.test.ts +69 -0
- package/src/resources/services/resource-context.backend.service.ts +1107 -0
- package/src/resources/services/resource-id.backend.service.ts +280 -0
- package/src/resources/services/resource-population.backend.service.ts +761 -0
- package/src/resources/services/resources-registry.backend.service.ts +1126 -0
- package/src/resources/services/virtual-fields.backend.service.ts +303 -0
- package/src/runtime/__tests__/execution-context-creator.backend.service.test.ts +469 -0
- package/src/runtime/controllers/health-controller.backend.service.ts +297 -0
- package/src/runtime/domain-module.backend.definitions.test.ts +83 -0
- package/src/runtime/domain-module.backend.definitions.ts +161 -0
- package/src/runtime/models/execution-context.backend.schemas.ts +456 -0
- package/src/runtime/models/runtime.backend.schemas.ts +82 -0
- package/src/runtime/services/execution-context-creator.backend.service.ts +2102 -0
- package/src/runtime/services/execution-context-handler.backend.service.ts +224 -0
- package/src/runtime/services/health-readiness-contributor.backend.interface.ts +11 -0
- package/src/runtime/services/http-server.backend.service.ts +870 -0
- package/src/runtime/services/start-application.backend.service.ts +1109 -0
- package/src/runtime/testing/execution-context-test-fixtures.ts +14 -0
- package/src/runtime/testing/mock-execution-context-creator.service.ts +46 -0
- package/src/runtime/utils/scan-default-exports.backend.utils.ts +247 -0
- package/src/security/authentications/__tests__/auth-registration.test.ts +338 -0
- package/src/security/authentications/__tests__/authentication-controller.test.ts +31 -0
- package/src/security/authentications/__tests__/authentication-orchestrator.test.ts +27 -0
- package/src/security/authentications/__tests__/saml-assertion-validator.test.ts +631 -0
- package/src/security/authentications/__tests__/saml-authentication.test.ts +126 -0
- package/src/security/authentications/__tests__/saml-integration-test-helpers.test.ts +234 -0
- package/src/security/authentications/__tests__/saml-metadata.test.ts +185 -0
- package/src/security/authentications/__tests__/saml-replay-guard.test.ts +99 -0
- package/src/security/authentications/__tests__/saml-sso-flow.integration.test.ts +355 -0
- package/src/security/authentications/__tests__/saml-test-fixtures.test.ts +433 -0
- package/src/security/authentications/__tests__/saml-test-parser.test.ts +117 -0
- package/src/security/authentications/__tests__/sso-connection-custom-ops.integration.test.ts +236 -0
- package/src/security/authentications/batches/anonymous-session-cleanup.batch.backend.service.ts +71 -0
- package/src/security/authentications/controllers/auth-method-management-controller.backend.service.ts +205 -0
- package/src/security/authentications/controllers/authentication-controller.backend.service.ts +2712 -0
- package/src/security/authentications/models/auth-constants.backend.ts +141 -0
- package/src/security/authentications/models/authentications.backend.schemas.ts +106 -0
- package/src/security/authentications/models/jwt.backend.schemas.ts +107 -0
- package/src/security/authentications/models/oauth2-connection.backend.schemas.ts +196 -0
- package/src/security/authentications/models/saml-authentication.backend.schemas.ts +124 -0
- package/src/security/authentications/models/sso-connection.backend.schemas.ts +104 -0
- package/src/security/authentications/services/__tests__/mock-auth-execution-context-factory.service.ts +73 -0
- package/src/security/authentications/services/__tests__/mock-auth-token-issuer.service.ts +46 -0
- package/src/security/authentications/services/admin-config/__tests__/mock-domain-to-org-lookup.service.ts +40 -0
- package/src/security/authentications/services/admin-config/__tests__/mock-enterprise-user-provisioning.service.ts +67 -0
- package/src/security/authentications/services/admin-config/auth-organization-configuration.service.ts +424 -0
- package/src/security/authentications/services/admin-config/domain-to-org-lookup.backend.service.ts +244 -0
- package/src/security/authentications/services/admin-config/domain-verification.backend.service.ts +215 -0
- package/src/security/authentications/services/admin-config/enterprise-user-provisioning.backend.service.ts +509 -0
- package/src/security/authentications/services/admin-config/oidc-discovery.backend.service.ts +250 -0
- package/src/security/authentications/services/anonymous-session.backend.service.ts +442 -0
- package/src/security/authentications/services/auth-credential-verifier.backend.service.ts +147 -0
- package/src/security/authentications/services/auth-execution-context-factory.backend.service.ts +132 -0
- package/src/security/authentications/services/auth-methods/auth-method-management.backend.service.ts +532 -0
- package/src/security/authentications/services/auth-methods/auth-mfa.backend.service.ts +141 -0
- package/src/security/authentications/services/auth-methods/auth-password-reset.backend.service.ts +215 -0
- package/src/security/authentications/services/auth-methods/auth-phone-verification.backend.service.ts +136 -0
- package/src/security/authentications/services/auth-methods/auth-registration.backend.service.ts +994 -0
- package/src/security/authentications/services/auth-methods/oauth2-authentication.backend.service.ts +1210 -0
- package/src/security/authentications/services/auth-methods/oauth2-connection-resolver.backend.service.ts +903 -0
- package/src/security/authentications/services/auth-methods/saml-assertion-validator.backend.service.ts +791 -0
- package/src/security/authentications/services/auth-methods/saml-authentication.backend.service.ts +1727 -0
- package/src/security/authentications/services/auth-methods/saml-metadata.backend.service.ts +432 -0
- package/src/security/authentications/services/auth-methods/saml-replay-guard.backend.service.ts +90 -0
- package/src/security/authentications/services/auth-methods/webauthn.backend.service.ts +393 -0
- package/src/security/authentications/services/auth-session-store.backend.service.ts +211 -0
- package/src/security/authentications/services/auth-token-issuer.backend.service.ts +496 -0
- package/src/security/authentications/services/authentication-orchestrator.backend.service.ts +3156 -0
- package/src/security/authentications/services/custom-impls/auth-custom-implementations.backend.ts +88 -0
- package/src/security/authentications/services/custom-impls/auth-policy.custom-impl.backend.service.ts +54 -0
- package/src/security/authentications/services/custom-impls/scim-provisioning-config.custom-impl.backend.service.ts +167 -0
- package/src/security/authentications/services/custom-impls/scim-tokens.custom-impl.backend.service.ts +136 -0
- package/src/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.ts +123 -0
- package/src/security/authentications/services/custom-impls/siem-export-config.custom-impl.backend.service.ts +161 -0
- package/src/security/authentications/services/custom-impls/sso-config.custom-impl.backend.service.ts +185 -0
- package/src/security/authentications/services/custom-impls/sso-connection.custom-impl.backend.service.ts +792 -0
- package/src/security/authentications/services/utils/__tests__/mock-auth-user-lookup.service.ts +62 -0
- package/src/security/authentications/services/utils/auth-controller.utils.ts +51 -0
- package/src/security/authentications/services/utils/auth-credential-ops.backend.service.ts +202 -0
- package/src/security/authentications/services/utils/auth-response-helper.backend.service.ts +38 -0
- package/src/security/authentications/services/utils/auth-user-lookup.backend.service.ts +128 -0
- package/src/security/authentications/services/utils/saml-java-availability.ts +64 -0
- package/src/security/authorizations/__tests__/authorizations.backend.service.test.ts +82 -0
- package/src/security/authorizations/services/authorizations.backend.service.ts +934 -0
- package/src/security/consumable-tokens/batches/consumable-tokens-cleanup.batch.backend.service.ts +168 -0
- package/src/security/consumable-tokens/models/consumable-tokens.backend.resources-config.schemas.ts +92 -0
- package/src/security/consumable-tokens/models/consumable-tokens.shared.schemas.ts +86 -0
- package/src/security/consumable-tokens/models/index.ts +3 -0
- package/src/security/consumable-tokens/services/__tests__/mock-consumable-token.service.ts +63 -0
- package/src/security/consumable-tokens/services/consumable-token.backend.service.ts +568 -0
- package/src/security/jwt/services/auth-jwt-guard.backend.service.ts +137 -0
- package/src/security/jwt/services/jwt.backend.service.ts +397 -0
- package/src/security/scim/__tests__/scim-filter-parser.test.ts +121 -0
- package/src/security/scim/controllers/scim.backend.controller.ts +1066 -0
- package/src/security/scim/models/scim-protocol.backend.schemas.ts +258 -0
- package/src/security/scim/utils/scim-filter-parser.ts +289 -0
- package/src/security/scim/utils/scim-response-formatter.ts +122 -0
- package/src/testing.ts +30 -0
- package/src/types/xmldom.d.ts +9 -0
- package/src/users/services/user-self-custom-implementations.backend.ts +62 -0
|
@@ -0,0 +1,2844 @@
|
|
|
1
|
+
import { injectable, inject, Container } from 'inversify';
|
|
2
|
+
import { Server as HttpServer } from 'http';
|
|
3
|
+
import { Server as SocketIOServer, Socket } from 'socket.io';
|
|
4
|
+
import { createAdapter } from '@socket.io/redis-adapter';
|
|
5
|
+
import { createClient } from 'redis';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { SAAS_SERVICE_TYPES } from '~wildo-backend-lib/inject/models/service-types';
|
|
8
|
+
import { LoggerService } from '~wildo-backend-lib/monitoring/logger/services/logger.service';
|
|
9
|
+
import { AppConfigurationService } from '~wildo-backend-lib/config/services/app-configuration.backend.service';
|
|
10
|
+
import { RedisService } from '~wildo-backend-lib/databases/services/redis.service';
|
|
11
|
+
import { ErrorBuilderBackendService } from '~wildo-backend-lib/errors/services/error-builder.backend.service';
|
|
12
|
+
import {
|
|
13
|
+
ErrorCustomMessageReference,
|
|
14
|
+
ErrorType,
|
|
15
|
+
ExecutionContext_ExecutionType,
|
|
16
|
+
ResourcePrimaryScope,
|
|
17
|
+
CoreResourceOperation,
|
|
18
|
+
ARRAY_RESPONSE_OPERATIONS,
|
|
19
|
+
DataMode,
|
|
20
|
+
ResourceConfiguration_Operation,
|
|
21
|
+
OPERATION_VARIANT_KEY,
|
|
22
|
+
ResourcesConfigOperationsDtosBuilderUtils,
|
|
23
|
+
ResourceOperationsUtils,
|
|
24
|
+
WildoHeaderKeys,
|
|
25
|
+
ResourceOperationVariantType,
|
|
26
|
+
isWildoBackendError,
|
|
27
|
+
} from '@wildo-ai/saas-models';
|
|
28
|
+
import {
|
|
29
|
+
ExecutionContextCreatorBackendService,
|
|
30
|
+
} from '~wildo-backend-lib/runtime/services/execution-context-creator.backend.service';
|
|
31
|
+
import { AuthorizationsBackendService } from '~wildo-backend-lib/security/authorizations/services/authorizations.backend.service';
|
|
32
|
+
import { ResourcesRegistryBackendService } from '~wildo-backend-lib/resources/services/resources-registry.backend.service';
|
|
33
|
+
import { NotificationBadgeBackendService } from '~wildo-backend-lib/notifications/services/notification-badge.backend.service';
|
|
34
|
+
import {
|
|
35
|
+
WS_ResourceSubscribePayload,
|
|
36
|
+
WS_ResourceEditingPayload,
|
|
37
|
+
WS_ResourceCustomEventPayload,
|
|
38
|
+
WS_ResourceUpdatedPayload,
|
|
39
|
+
WS_ResourceDeletedPayload,
|
|
40
|
+
WS_ResourceRoomStatePayload,
|
|
41
|
+
WS_ResourceSyncUpdatedPayload,
|
|
42
|
+
WS_ResourceUpdateNotificationPayload,
|
|
43
|
+
WS_ResourceSubscribePayloadSchema,
|
|
44
|
+
WS_ResourceEditingPayloadSchema,
|
|
45
|
+
WS_ResourceCustomEventPayloadSchema,
|
|
46
|
+
WS_UserNotificationPayload,
|
|
47
|
+
NotificationLevel,
|
|
48
|
+
NotificationDisplayTarget,
|
|
49
|
+
ResourceAction,
|
|
50
|
+
buildResourceRoomName,
|
|
51
|
+
buildScopeRoomName,
|
|
52
|
+
buildUserRoomName,
|
|
53
|
+
buildOrganizationRoomName,
|
|
54
|
+
buildOrganizationRoleRoomName,
|
|
55
|
+
buildAppRoleRoomName,
|
|
56
|
+
parseOrganizationRoomName,
|
|
57
|
+
WebSocketRoomPrefix,
|
|
58
|
+
CoreWebSocketEvent,
|
|
59
|
+
CORE_APP_ROLES,
|
|
60
|
+
WebSocketResourceDeliveryTarget,
|
|
61
|
+
} from '@wildo-ai/saas-models';
|
|
62
|
+
import { SocketAuthResult } from '~wildo-backend-lib/runtime/models/execution-context.backend.schemas';
|
|
63
|
+
|
|
64
|
+
export interface WebSocketConfig {
|
|
65
|
+
cors: {
|
|
66
|
+
origin: string | string[];
|
|
67
|
+
credentials: boolean;
|
|
68
|
+
};
|
|
69
|
+
transports: ('websocket' | 'polling')[];
|
|
70
|
+
pingTimeout: number;
|
|
71
|
+
pingInterval: number;
|
|
72
|
+
maxHttpBufferSize: number;
|
|
73
|
+
allowEIO3: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type WebSocketResourceRoomEmitPayload =
|
|
77
|
+
| WS_ResourceUpdatedPayload
|
|
78
|
+
| WS_ResourceDeletedPayload
|
|
79
|
+
| WS_ResourceRoomStatePayload;
|
|
80
|
+
|
|
81
|
+
function subscriptionMatchesOrganization(
|
|
82
|
+
subscription: SocketTrackedResourceSubscription,
|
|
83
|
+
organizationId: string,
|
|
84
|
+
): boolean {
|
|
85
|
+
if (subscription.scopeId === organizationId) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return Object.values(subscription.contextResourceIdentifiers ?? {}).includes(organizationId);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface WebSocketMessage {
|
|
93
|
+
type: string;
|
|
94
|
+
payload: any;
|
|
95
|
+
timestamp: Date;
|
|
96
|
+
userId?: string;
|
|
97
|
+
organizationId?: string;
|
|
98
|
+
targetUsers?: string[];
|
|
99
|
+
targetRoles?: string[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface RoomInfo {
|
|
103
|
+
name: string;
|
|
104
|
+
organizationId: string;
|
|
105
|
+
type: 'organization' | 'user' | 'role' | 'custom' | 'resource';
|
|
106
|
+
members: Set<string>;
|
|
107
|
+
metadata?: Record<string, any>;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type SocketTrackedResourceSubscription = WS_ResourceSubscribePayload & {
|
|
111
|
+
roomName: string;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Rate limiting configuration (Redis-synchronized)
|
|
116
|
+
*/
|
|
117
|
+
export interface RateLimitConfig {
|
|
118
|
+
/** Maximum events per window */
|
|
119
|
+
maxEvents: number;
|
|
120
|
+
/** Window size in seconds */
|
|
121
|
+
windowSeconds: number;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Default rate limits per event type
|
|
126
|
+
*/
|
|
127
|
+
const DEFAULT_RATE_LIMITS: Record<string, RateLimitConfig> = {
|
|
128
|
+
// Resource subscription: 20 per 10 seconds (allow rapid page navigation)
|
|
129
|
+
[CoreWebSocketEvent.RESOURCE_SUBSCRIBE]: { maxEvents: 20, windowSeconds: 10 },
|
|
130
|
+
[CoreWebSocketEvent.RESOURCE_UNSUBSCRIBE]: { maxEvents: 20, windowSeconds: 10 },
|
|
131
|
+
|
|
132
|
+
// Editing events: 10 per minute (reasonable for form editing)
|
|
133
|
+
[CoreWebSocketEvent.RESOURCE_EDITING_START]: { maxEvents: 10, windowSeconds: 60 },
|
|
134
|
+
[CoreWebSocketEvent.RESOURCE_EDITING_END]: { maxEvents: 10, windowSeconds: 60 },
|
|
135
|
+
|
|
136
|
+
// Custom events: 30 per second (for real-time collaboration like cursor moves)
|
|
137
|
+
[CoreWebSocketEvent.RESOURCE_CUSTOM]: { maxEvents: 30, windowSeconds: 1 },
|
|
138
|
+
|
|
139
|
+
// Badge requests: 10 per second
|
|
140
|
+
[CoreWebSocketEvent.BADGE_GET]: { maxEvents: 10, windowSeconds: 1 },
|
|
141
|
+
[CoreWebSocketEvent.BADGE_GET_ALL]: { maxEvents: 5, windowSeconds: 1 },
|
|
142
|
+
|
|
143
|
+
// Auth/system events: 5 per minute
|
|
144
|
+
[CoreWebSocketEvent.AUTH_REFRESH]: { maxEvents: 5, windowSeconds: 60 },
|
|
145
|
+
[CoreWebSocketEvent.ORGANIZATION_SWITCH]: { maxEvents: 10, windowSeconds: 60 },
|
|
146
|
+
|
|
147
|
+
// Default for unlisted events: 100 per minute
|
|
148
|
+
'default': { maxEvents: 100, windowSeconds: 60 },
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* WebSocket Service
|
|
153
|
+
*
|
|
154
|
+
* Provides real-time communication for SaaS applications:
|
|
155
|
+
* - Multi-tenant socket management with identity-based rooms
|
|
156
|
+
* - Resource-centric rooms for collaboration (editing, locking, custom events)
|
|
157
|
+
* - Role-based message broadcasting
|
|
158
|
+
* - Redis adapter for horizontal scaling
|
|
159
|
+
* - JWT authentication reusing ExecutionContextCreatorBackendService
|
|
160
|
+
* - Authorization reusing AuthorizationsBackendService
|
|
161
|
+
*/
|
|
162
|
+
@injectable()
|
|
163
|
+
export class WebSocketService {
|
|
164
|
+
private io: SocketIOServer | null = null;
|
|
165
|
+
private userSockets: Map<string, Set<string>> = new Map(); // userId -> socketIds
|
|
166
|
+
private rooms: Map<string, RoomInfo> = new Map();
|
|
167
|
+
private organizationSockets: Map<string, Set<string>> = new Map(); // orgId -> socketIds
|
|
168
|
+
|
|
169
|
+
// NEW: Track authenticated sockets and editing state
|
|
170
|
+
private authenticatedSockets: Map<string, SocketAuthResult> = new Map(); // socketId -> auth info
|
|
171
|
+
private resourceEditingState: Map<string, Set<string>> = new Map(); // resource room -> editing userIds
|
|
172
|
+
private resourceSubscriptionsBySocket: Map<string, Map<string, SocketTrackedResourceSubscription>> = new Map();
|
|
173
|
+
|
|
174
|
+
protected logDebug: (message: string, context?: Record<string, unknown>) => void;
|
|
175
|
+
|
|
176
|
+
constructor(
|
|
177
|
+
@inject(SAAS_SERVICE_TYPES.Logger) private logger: LoggerService,
|
|
178
|
+
@inject(SAAS_SERVICE_TYPES.AppConfigService) private configService: AppConfigurationService,
|
|
179
|
+
@inject(SAAS_SERVICE_TYPES.ErrorBuilderService) private errorBuilder: ErrorBuilderBackendService,
|
|
180
|
+
@inject(SAAS_SERVICE_TYPES.RedisService) private redisService: RedisService,
|
|
181
|
+
// Dependencies for factorized authentication/authorization
|
|
182
|
+
@inject(SAAS_SERVICE_TYPES.ExecutionContextCreatorBackendService) private executionContextCreator: ExecutionContextCreatorBackendService,
|
|
183
|
+
@inject(SAAS_SERVICE_TYPES.AuthorizationsService) private authorizationsService: AuthorizationsBackendService,
|
|
184
|
+
@inject(SAAS_SERVICE_TYPES.ResourceRegistryService) private resourcesRegistry: ResourcesRegistryBackendService,
|
|
185
|
+
// Container for lazy resolution of NotificationBadgeService to break circular dependency
|
|
186
|
+
@inject('Container') private container: Container,
|
|
187
|
+
) {
|
|
188
|
+
this.logDebug = this.logger.debugByType('WebSocketService');
|
|
189
|
+
this.logger.setDebugTypeLogging('WebSocketService', false);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Lazy getter for NotificationBadgeService to break circular dependency
|
|
194
|
+
* NotificationBadgeService depends on WebSocketService, so we resolve it lazily
|
|
195
|
+
*/
|
|
196
|
+
private getBadgeService(): NotificationBadgeBackendService {
|
|
197
|
+
return this.container.get<NotificationBadgeBackendService>(SAAS_SERVICE_TYPES.NotificationBadgeService);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private getSocketAuth(socket: Socket): SocketAuthResult {
|
|
201
|
+
return (socket as any).auth as SocketAuthResult;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private hasOrganizationAccess(auth: SocketAuthResult, organizationId: string): boolean {
|
|
205
|
+
if (auth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return auth.initiatorRoles.some((roleInfo) =>
|
|
210
|
+
roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS
|
|
211
|
+
&& roleInfo.relatedResourceId === organizationId,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private trackSocketResourceSubscription(
|
|
216
|
+
socketId: string,
|
|
217
|
+
subscription: SocketTrackedResourceSubscription,
|
|
218
|
+
): void {
|
|
219
|
+
const subscriptions = this.resourceSubscriptionsBySocket.get(socketId) ?? new Map<string, SocketTrackedResourceSubscription>();
|
|
220
|
+
subscriptions.set(subscription.roomName, subscription);
|
|
221
|
+
this.resourceSubscriptionsBySocket.set(socketId, subscriptions);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private untrackSocketResourceSubscription(socketId: string, roomName: string): void {
|
|
225
|
+
const subscriptions = this.resourceSubscriptionsBySocket.get(socketId);
|
|
226
|
+
if (!subscriptions) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
subscriptions.delete(roomName);
|
|
231
|
+
if (subscriptions.size === 0) {
|
|
232
|
+
this.resourceSubscriptionsBySocket.delete(socketId);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private async revokeTrackedResourceSubscription(params: {
|
|
237
|
+
socket: Socket;
|
|
238
|
+
auth: SocketAuthResult;
|
|
239
|
+
subscription: SocketTrackedResourceSubscription;
|
|
240
|
+
reason: 'auth_refresh' | 'organization_switch';
|
|
241
|
+
}): Promise<void> {
|
|
242
|
+
const { socket, auth, subscription, reason } = params;
|
|
243
|
+
|
|
244
|
+
await socket.leave(subscription.roomName);
|
|
245
|
+
|
|
246
|
+
if (subscription.resourceId && auth.initiatorIds?.userId) {
|
|
247
|
+
await this.trackEditingState(
|
|
248
|
+
subscription.resourceType,
|
|
249
|
+
subscription.resourceId,
|
|
250
|
+
auth.initiatorIds.userId,
|
|
251
|
+
'end',
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
this.io?.to(subscription.roomName).emit(CoreWebSocketEvent.RESOURCE_EDITING_END, {
|
|
255
|
+
resourceType: subscription.resourceType,
|
|
256
|
+
resourceId: subscription.resourceId,
|
|
257
|
+
initiatorUserId: auth.initiatorIds.userId,
|
|
258
|
+
reason,
|
|
259
|
+
timestamp: new Date(),
|
|
260
|
+
} satisfies WS_ResourceEditingPayload);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
this.untrackSocketResourceSubscription(socket.id, subscription.roomName);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
private async revalidateTrackedResourceSubscriptions(
|
|
267
|
+
socket: Socket,
|
|
268
|
+
auth: SocketAuthResult,
|
|
269
|
+
): Promise<void> {
|
|
270
|
+
const subscriptions = Array.from(this.resourceSubscriptionsBySocket.get(socket.id)?.values() ?? []);
|
|
271
|
+
for (const subscription of subscriptions) {
|
|
272
|
+
try {
|
|
273
|
+
if (subscription.resourceId) {
|
|
274
|
+
await this.verifyResourceAccess(
|
|
275
|
+
socket,
|
|
276
|
+
auth,
|
|
277
|
+
subscription.resourceType,
|
|
278
|
+
subscription.resourceId,
|
|
279
|
+
subscription.contextResourceIdentifiers,
|
|
280
|
+
);
|
|
281
|
+
} else if (subscription.scopeKey && subscription.scopeId) {
|
|
282
|
+
await this.verifyScopeAccess(
|
|
283
|
+
auth,
|
|
284
|
+
subscription.scopeKey,
|
|
285
|
+
subscription.scopeId,
|
|
286
|
+
subscription.contextResourceIdentifiers,
|
|
287
|
+
);
|
|
288
|
+
} else {
|
|
289
|
+
throw new Error('Tracked resource subscription is missing routing identifiers');
|
|
290
|
+
}
|
|
291
|
+
} catch {
|
|
292
|
+
await this.revokeTrackedResourceSubscription({
|
|
293
|
+
socket,
|
|
294
|
+
auth,
|
|
295
|
+
subscription,
|
|
296
|
+
reason: 'auth_refresh',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Initialize WebSocket server
|
|
304
|
+
*
|
|
305
|
+
* For platform services that don't serve frontends (e.g., crontabs-batches-manager),
|
|
306
|
+
* WebSocket initialization is skipped since they only receive internal backend requests.
|
|
307
|
+
*/
|
|
308
|
+
public async initialize(httpServer: HttpServer): Promise<void> {
|
|
309
|
+
const corsOrigins = this.getCorsOrigins();
|
|
310
|
+
|
|
311
|
+
// If no frontend URLs are configured, skip WebSocket initialization entirely
|
|
312
|
+
// This is expected for platform services that only receive backend-to-backend requests
|
|
313
|
+
// and don't need real-time WebSocket communication with browsers
|
|
314
|
+
if (corsOrigins.length === 0) {
|
|
315
|
+
this.logger.info('📝 No frontend URLs configured - skipping WebSocket initialization (platform/internal service mode)', {
|
|
316
|
+
availableEndpoints: Object.keys(this.configService.config?.runtime?.endPoints || {}),
|
|
317
|
+
note: 'This is expected for platform services that only receive backend-to-backend requests'
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Mark as "initialized" but in disabled mode - all public methods will safely no-op
|
|
321
|
+
this.io = null;
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const config: WebSocketConfig = {
|
|
326
|
+
cors: {
|
|
327
|
+
origin: corsOrigins,
|
|
328
|
+
credentials: true
|
|
329
|
+
},
|
|
330
|
+
transports: ['websocket', 'polling'],
|
|
331
|
+
pingTimeout: 60000,
|
|
332
|
+
pingInterval: 25000,
|
|
333
|
+
maxHttpBufferSize: 1e6,
|
|
334
|
+
allowEIO3: true
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
this.io = new SocketIOServer(httpServer, config);
|
|
338
|
+
|
|
339
|
+
// Setup Redis adapter for horizontal scaling
|
|
340
|
+
await this.setupRedisAdapter();
|
|
341
|
+
|
|
342
|
+
// Setup authentication middleware (FACTORIZED with HTTP)
|
|
343
|
+
this.setupAuthentication();
|
|
344
|
+
|
|
345
|
+
// Setup rate limiting middleware (Redis-synchronized across pods)
|
|
346
|
+
this.setupRateLimiting();
|
|
347
|
+
|
|
348
|
+
// Setup connection handling (identity-based rooms)
|
|
349
|
+
this.setupConnectionHandling();
|
|
350
|
+
|
|
351
|
+
this.logDebug('WebSocket service initialized', {
|
|
352
|
+
cors: config.cors.origin,
|
|
353
|
+
transports: config.transports
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// =====================================================
|
|
358
|
+
// PUBLIC MESSAGING METHODS
|
|
359
|
+
// =====================================================
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Send message to specific user (with cross-pod support via Redis adapter)
|
|
363
|
+
*/
|
|
364
|
+
public async sendToUser(userId: string, message: WebSocketMessage): Promise<boolean> {
|
|
365
|
+
if (!this.io) {
|
|
366
|
+
this.logger.warn('WebSocket not initialized');
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const roomName = buildUserRoomName(userId);
|
|
371
|
+
this.io.to(roomName).emit(message.type, {
|
|
372
|
+
...message,
|
|
373
|
+
timestamp: new Date(),
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
this.logDebug('Message sent to user', {
|
|
377
|
+
userId: userId.substring(0, 8) + '...',
|
|
378
|
+
messageType: message.type,
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Send a direct notification to a specific user.
|
|
386
|
+
*
|
|
387
|
+
* This is a convenience method for sending user notifications that are not
|
|
388
|
+
* tied to resource operations (e.g., "Your export is ready", "Payment received").
|
|
389
|
+
*
|
|
390
|
+
* @param userId - The user ID to notify
|
|
391
|
+
* @param notification - Notification configuration
|
|
392
|
+
* @param notification.type - Notification level (info, success, warning, error)
|
|
393
|
+
* @param notification.identifier - i18n identifier for message lookup
|
|
394
|
+
* @param notification.message - Direct message (fallback if identifier not found)
|
|
395
|
+
* @param notification.title - Optional notification title
|
|
396
|
+
* @param notification.data - Additional context data
|
|
397
|
+
* @param notification.displayTarget - Where to display (toast, center, or both)
|
|
398
|
+
* @param notification.organizationId - Organization context (optional)
|
|
399
|
+
*
|
|
400
|
+
* @example
|
|
401
|
+
* // Notify user about export completion
|
|
402
|
+
* await webSocketService.notifyUser(userId, {
|
|
403
|
+
* type: NotificationLevel.SUCCESS,
|
|
404
|
+
* identifier: 'export.completed',
|
|
405
|
+
* data: { fileName: 'report.pdf', downloadUrl: '/files/123' },
|
|
406
|
+
* });
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* // Notify user with direct message
|
|
410
|
+
* await webSocketService.notifyUser(userId, {
|
|
411
|
+
* type: NotificationLevel.INFO,
|
|
412
|
+
* message: 'Your session will expire in 5 minutes',
|
|
413
|
+
* displayTarget: NotificationDisplayTarget.TOAST,
|
|
414
|
+
* });
|
|
415
|
+
*/
|
|
416
|
+
public async notifyUser(
|
|
417
|
+
userId: string,
|
|
418
|
+
notification: {
|
|
419
|
+
type: NotificationLevel;
|
|
420
|
+
identifier?: string;
|
|
421
|
+
message?: string;
|
|
422
|
+
title?: string;
|
|
423
|
+
data?: Record<string, unknown>;
|
|
424
|
+
displayTarget?: NotificationDisplayTarget;
|
|
425
|
+
organizationId?: string;
|
|
426
|
+
}
|
|
427
|
+
): Promise<boolean> {
|
|
428
|
+
const payload: WS_UserNotificationPayload = {
|
|
429
|
+
notificationLevel: notification.type,
|
|
430
|
+
identifier: notification.identifier,
|
|
431
|
+
message: notification.message,
|
|
432
|
+
title: notification.title,
|
|
433
|
+
data: notification.data,
|
|
434
|
+
displayTarget: notification.displayTarget ?? NotificationDisplayTarget.BOTH,
|
|
435
|
+
organizationId: notification.organizationId,
|
|
436
|
+
timestamp: new Date(),
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const wsMessage: WebSocketMessage = {
|
|
440
|
+
type: CoreWebSocketEvent.USER_NOTIFICATION,
|
|
441
|
+
payload,
|
|
442
|
+
timestamp: new Date(),
|
|
443
|
+
userId,
|
|
444
|
+
organizationId: notification.organizationId,
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
return this.sendToUser(userId, wsMessage);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Send a direct notification to all users in an organization.
|
|
452
|
+
*
|
|
453
|
+
* @param organizationId - The organization ID
|
|
454
|
+
* @param notification - Notification configuration (same as notifyUser)
|
|
455
|
+
* @param excludeUsers - Optional list of user IDs to exclude
|
|
456
|
+
*/
|
|
457
|
+
public async notifyOrganization(
|
|
458
|
+
organizationId: string,
|
|
459
|
+
notification: {
|
|
460
|
+
type: NotificationLevel;
|
|
461
|
+
identifier?: string;
|
|
462
|
+
message?: string;
|
|
463
|
+
title?: string;
|
|
464
|
+
data?: Record<string, unknown>;
|
|
465
|
+
displayTarget?: NotificationDisplayTarget;
|
|
466
|
+
},
|
|
467
|
+
excludeUsers?: string[]
|
|
468
|
+
): Promise<number> {
|
|
469
|
+
const payload: WS_UserNotificationPayload = {
|
|
470
|
+
notificationLevel: notification.type,
|
|
471
|
+
identifier: notification.identifier,
|
|
472
|
+
message: notification.message,
|
|
473
|
+
title: notification.title,
|
|
474
|
+
data: notification.data,
|
|
475
|
+
displayTarget: notification.displayTarget ?? NotificationDisplayTarget.BOTH,
|
|
476
|
+
organizationId,
|
|
477
|
+
timestamp: new Date(),
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
const wsMessage: WebSocketMessage = {
|
|
481
|
+
type: CoreWebSocketEvent.USER_NOTIFICATION,
|
|
482
|
+
payload,
|
|
483
|
+
timestamp: new Date(),
|
|
484
|
+
organizationId,
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
return this.sendToOrganization(organizationId, wsMessage, excludeUsers);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Send message to organization (with cross-pod support via Redis adapter)
|
|
492
|
+
*/
|
|
493
|
+
public async sendToOrganization(
|
|
494
|
+
organizationId: string,
|
|
495
|
+
message: WebSocketMessage,
|
|
496
|
+
excludeUsers?: string[]
|
|
497
|
+
): Promise<number> {
|
|
498
|
+
const roomName = buildOrganizationRoomName(organizationId);
|
|
499
|
+
const messageWithTimestamp = {
|
|
500
|
+
...message,
|
|
501
|
+
timestamp: new Date(),
|
|
502
|
+
organizationId
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
if (!this.io) {
|
|
506
|
+
this.logger.warn('WebSocket not initialized');
|
|
507
|
+
return 0;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (excludeUsers && excludeUsers.length > 0) {
|
|
511
|
+
// For cross-pod compatibility with Redis adapter:
|
|
512
|
+
// 1. Send to the org room (reaches all pods)
|
|
513
|
+
// 2. Exclude users by emitting to their user rooms with a "skip" flag
|
|
514
|
+
//
|
|
515
|
+
// Alternative approach: Use Socket.IO's except() which works with Redis adapter
|
|
516
|
+
const excludeRooms = excludeUsers.map(userId => buildUserRoomName(userId));
|
|
517
|
+
let broadcast = this.io.to(roomName);
|
|
518
|
+
for (const excludeRoom of excludeRooms) {
|
|
519
|
+
broadcast = broadcast.except(excludeRoom);
|
|
520
|
+
}
|
|
521
|
+
broadcast.emit(message.type, messageWithTimestamp);
|
|
522
|
+
|
|
523
|
+
this.logDebug('Message sent to organization with exclusions', {
|
|
524
|
+
organizationId: organizationId.substring(0, 8) + '...',
|
|
525
|
+
messageType: message.type,
|
|
526
|
+
excludedUsers: excludeUsers.length,
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// Return approximate count (exact count not available with except())
|
|
530
|
+
return 1;
|
|
531
|
+
} else {
|
|
532
|
+
this.io.to(roomName).emit(message.type, messageWithTimestamp);
|
|
533
|
+
|
|
534
|
+
this.logDebug('Message sent to organization', {
|
|
535
|
+
organizationId: organizationId.substring(0, 8) + '...',
|
|
536
|
+
messageType: message.type,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
return 1;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Send message to users with specific role within an organization
|
|
545
|
+
*/
|
|
546
|
+
public async sendToRole(
|
|
547
|
+
organizationId: string,
|
|
548
|
+
role: string,
|
|
549
|
+
message: WebSocketMessage
|
|
550
|
+
): Promise<number> {
|
|
551
|
+
const roomName = buildOrganizationRoleRoomName(organizationId, role);
|
|
552
|
+
const messageWithTimestamp = {
|
|
553
|
+
...message,
|
|
554
|
+
timestamp: new Date(),
|
|
555
|
+
organizationId
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
if (!this.io) {
|
|
559
|
+
this.logger.warn('WebSocket not initialized');
|
|
560
|
+
return 0;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const sentCount = (await this.io.in(roomName).fetchSockets()).length;
|
|
564
|
+
this.io.to(roomName).emit(message.type, messageWithTimestamp);
|
|
565
|
+
|
|
566
|
+
this.logDebug('Message sent to role', {
|
|
567
|
+
organizationId: organizationId.substring(0, 8) + '...',
|
|
568
|
+
role,
|
|
569
|
+
messageType: message.type,
|
|
570
|
+
sentCount
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
return sentCount;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Send message to users with application-level role (admin dashboard users).
|
|
578
|
+
*
|
|
579
|
+
* Application-level roles are not scoped to an organization - they are global
|
|
580
|
+
* admin roles like super admins, support staff, billing admins, etc.
|
|
581
|
+
*
|
|
582
|
+
* Users with app-level roles join app role rooms (via buildAppRoleRoomName) on connection.
|
|
583
|
+
*
|
|
584
|
+
* @param role - The application-level role (e.g., 'admin', 'super_admin', 'support')
|
|
585
|
+
* @param message - The WebSocket message to send
|
|
586
|
+
* @returns Number of sockets the message was sent to
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* // Notify all application administrators
|
|
590
|
+
* await webSocketService.sendToAppRole(CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN, {
|
|
591
|
+
* type: CoreWebSocketEvent.USER_NOTIFICATION,
|
|
592
|
+
* payload: { notificationLevel: NotificationLevel.WARNING, message: 'New user signup requires review' },
|
|
593
|
+
* timestamp: new Date(),
|
|
594
|
+
* });
|
|
595
|
+
*/
|
|
596
|
+
public async sendToAppRole(
|
|
597
|
+
role: string,
|
|
598
|
+
message: WebSocketMessage
|
|
599
|
+
): Promise<number> {
|
|
600
|
+
const roomName = buildAppRoleRoomName(role);
|
|
601
|
+
const messageWithTimestamp = {
|
|
602
|
+
...message,
|
|
603
|
+
timestamp: new Date(),
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
if (!this.io) {
|
|
607
|
+
this.logger.warn('WebSocket not initialized');
|
|
608
|
+
return 0;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const sentCount = (await this.io.in(roomName).fetchSockets()).length;
|
|
612
|
+
this.io.to(roomName).emit(message.type, messageWithTimestamp);
|
|
613
|
+
|
|
614
|
+
this.logDebug('Message sent to app role', {
|
|
615
|
+
role,
|
|
616
|
+
messageType: message.type,
|
|
617
|
+
sentCount
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
return sentCount;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Send a direct notification to users with a specific application-level role.
|
|
625
|
+
*
|
|
626
|
+
* Convenience method for sending admin notifications.
|
|
627
|
+
*
|
|
628
|
+
* @param role - The application-level role
|
|
629
|
+
* @param notification - Notification configuration
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* // Notify support staff about a new ticket
|
|
633
|
+
* await webSocketService.notifyAppRole(CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN, {
|
|
634
|
+
* type: NotificationLevel.INFO,
|
|
635
|
+
* identifier: 'support.new_ticket',
|
|
636
|
+
* data: { ticketId: '123', subject: 'Help needed' },
|
|
637
|
+
* });
|
|
638
|
+
*/
|
|
639
|
+
public async notifyAppRole(
|
|
640
|
+
role: string,
|
|
641
|
+
notification: {
|
|
642
|
+
type: NotificationLevel;
|
|
643
|
+
identifier?: string;
|
|
644
|
+
message?: string;
|
|
645
|
+
title?: string;
|
|
646
|
+
data?: Record<string, unknown>;
|
|
647
|
+
displayTarget?: NotificationDisplayTarget;
|
|
648
|
+
}
|
|
649
|
+
): Promise<number> {
|
|
650
|
+
const payload: WS_UserNotificationPayload = {
|
|
651
|
+
notificationLevel: notification.type,
|
|
652
|
+
identifier: notification.identifier,
|
|
653
|
+
message: notification.message,
|
|
654
|
+
title: notification.title,
|
|
655
|
+
data: notification.data,
|
|
656
|
+
displayTarget: notification.displayTarget ?? NotificationDisplayTarget.BOTH,
|
|
657
|
+
timestamp: new Date(),
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
const wsMessage: WebSocketMessage = {
|
|
661
|
+
type: CoreWebSocketEvent.USER_NOTIFICATION,
|
|
662
|
+
payload,
|
|
663
|
+
timestamp: new Date(),
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
return this.sendToAppRole(role, wsMessage);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Broadcast message to all connected users
|
|
671
|
+
*/
|
|
672
|
+
public async broadcast(message: WebSocketMessage): Promise<number> {
|
|
673
|
+
if (!this.io) {
|
|
674
|
+
this.logger.warn('WebSocket not initialized');
|
|
675
|
+
return 0;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
const messageWithTimestamp = {
|
|
679
|
+
...message,
|
|
680
|
+
timestamp: new Date()
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
const sockets = await this.io.fetchSockets();
|
|
684
|
+
this.io.emit(message.type, messageWithTimestamp);
|
|
685
|
+
|
|
686
|
+
this.logDebug('Message broadcasted', {
|
|
687
|
+
messageType: message.type,
|
|
688
|
+
connectedSockets: sockets.length
|
|
689
|
+
});
|
|
690
|
+
|
|
691
|
+
return sockets.length;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// =====================================================
|
|
695
|
+
// RESOURCE ROOM PUBLIC METHODS (for NotificationDispatcher)
|
|
696
|
+
// =====================================================
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Extract DataMode from a websocket payload.
|
|
700
|
+
* Defaults to RAW for websocket messages when no explicit data mode is present.
|
|
701
|
+
*/
|
|
702
|
+
private extractDataMode(payload?: { dataMode?: DataMode | 'raw' | 'summary' | 'context' | string }): DataMode {
|
|
703
|
+
return ResourceOperationsUtils.extractDataMode(payload, undefined, DataMode.RAW);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
/**
|
|
707
|
+
* Select the appropriate response DTO based on DataMode.
|
|
708
|
+
* Similar to controller-resource.backend.service.ts
|
|
709
|
+
*/
|
|
710
|
+
private selectResponseDto(
|
|
711
|
+
operation: ResourceConfiguration_Operation<any, any, any> | null,
|
|
712
|
+
dataMode?: DataMode
|
|
713
|
+
): z.ZodTypeAny | undefined {
|
|
714
|
+
if (!operation) {
|
|
715
|
+
return undefined;
|
|
716
|
+
}
|
|
717
|
+
return ResourcesConfigOperationsDtosBuilderUtils.selectResponseDto(operation, dataMode) || undefined;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Validate and transform websocket resource data before sending it.
|
|
722
|
+
* Similar to controller-resource.backend.service.ts sendResponse() method.
|
|
723
|
+
*
|
|
724
|
+
* This method validates resource data against the appropriate DTO and transforms dates.
|
|
725
|
+
* It is used for sync-grade replay payloads and for custom websocket events that
|
|
726
|
+
* choose to carry resource-shaped data.
|
|
727
|
+
*
|
|
728
|
+
* @param resourceData - The resource data to validate (if present in payload)
|
|
729
|
+
* @param resourceType - Resource type
|
|
730
|
+
* @param operationIdentifier - Operation identifier (optional)
|
|
731
|
+
* @param dataMode - Data mode (defaults to RAW)
|
|
732
|
+
* @returns Validated and transformed resource data, or false when validation cannot proceed
|
|
733
|
+
*/
|
|
734
|
+
private resolveOperationForWebSocketValidation(params: {
|
|
735
|
+
resourceType: string;
|
|
736
|
+
operationIdentifier?: string;
|
|
737
|
+
dataMode: DataMode;
|
|
738
|
+
validationTarget: 'canonical-read' | 'operation-response';
|
|
739
|
+
}) {
|
|
740
|
+
const desiredOperationIdentifier = params.validationTarget === 'canonical-read'
|
|
741
|
+
? CoreResourceOperation.READ
|
|
742
|
+
: params.operationIdentifier ?? CoreResourceOperation.READ;
|
|
743
|
+
|
|
744
|
+
try {
|
|
745
|
+
const operationPath = this.resourcesRegistry.getOperationPathDefault(
|
|
746
|
+
params.resourceType,
|
|
747
|
+
desiredOperationIdentifier as CoreResourceOperation,
|
|
748
|
+
);
|
|
749
|
+
return this.resourcesRegistry.getOperationFromPath(operationPath);
|
|
750
|
+
} catch (error) {
|
|
751
|
+
this.logger.warn('WebSocket resource data validation lookup failed', {
|
|
752
|
+
resourceType: params.resourceType,
|
|
753
|
+
operationIdentifier: params.operationIdentifier,
|
|
754
|
+
desiredOperationIdentifier,
|
|
755
|
+
dataMode: params.dataMode,
|
|
756
|
+
validationTarget: params.validationTarget,
|
|
757
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
758
|
+
});
|
|
759
|
+
return null;
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
private validateAndTransformResourceData(
|
|
764
|
+
resourceData: any,
|
|
765
|
+
resourceType: string,
|
|
766
|
+
operationIdentifier?: string,
|
|
767
|
+
dataMode: DataMode = DataMode.RAW,
|
|
768
|
+
validationTarget: 'canonical-read' | 'operation-response' = 'canonical-read',
|
|
769
|
+
): { success: true; data: unknown } | { success: false } {
|
|
770
|
+
// If no resource data provided, signal the caller to emit metadata only.
|
|
771
|
+
if (!resourceData || typeof resourceData !== 'object') {
|
|
772
|
+
return { success: false };
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const operation = this.resolveOperationForWebSocketValidation({
|
|
776
|
+
resourceType,
|
|
777
|
+
operationIdentifier,
|
|
778
|
+
dataMode,
|
|
779
|
+
validationTarget,
|
|
780
|
+
});
|
|
781
|
+
if (!operation) {
|
|
782
|
+
return { success: false };
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// Select appropriate DTO based on DataMode
|
|
786
|
+
const selectedDto = this.selectResponseDto(operation, dataMode);
|
|
787
|
+
|
|
788
|
+
if (!selectedDto) {
|
|
789
|
+
return { success: false };
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
try {
|
|
793
|
+
// Transform dates from Date objects to ISO strings before validation
|
|
794
|
+
let transformedData = resourceData;
|
|
795
|
+
transformedData = ResourcesConfigOperationsDtosBuilderUtils.transformResponseDates(
|
|
796
|
+
resourceData,
|
|
797
|
+
selectedDto
|
|
798
|
+
);
|
|
799
|
+
|
|
800
|
+
// Validate response against the selected DTO as a runtime safety net
|
|
801
|
+
// Handle array responses (LIST, CREATE_MANY, etc.)
|
|
802
|
+
const effectiveOperation = operation.resourceOperationLike || operation.operationIdentifier;
|
|
803
|
+
const isArrayOperation = ARRAY_RESPONSE_OPERATIONS.includes(effectiveOperation as any);
|
|
804
|
+
|
|
805
|
+
if (isArrayOperation && Array.isArray(transformedData)) {
|
|
806
|
+
// For array operations, validate each item individually
|
|
807
|
+
return {
|
|
808
|
+
success: true,
|
|
809
|
+
data: transformedData.map(item => selectedDto.parse(item)),
|
|
810
|
+
};
|
|
811
|
+
} else {
|
|
812
|
+
// For single-item operations, validate directly
|
|
813
|
+
return {
|
|
814
|
+
success: true,
|
|
815
|
+
data: selectedDto.parse(transformedData),
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
} catch (error) {
|
|
819
|
+
this.logger.warn('WebSocket resource data validation failed', {
|
|
820
|
+
resourceType,
|
|
821
|
+
operationIdentifier,
|
|
822
|
+
dataMode,
|
|
823
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
824
|
+
resourceDataKeys: typeof resourceData === 'object' ? Object.keys(resourceData) : 'not-object'
|
|
825
|
+
});
|
|
826
|
+
return { success: false };
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
private stripScopeNotificationReplayFields(
|
|
831
|
+
payload: WS_ResourceUpdateNotificationPayload,
|
|
832
|
+
): WS_ResourceUpdateNotificationPayload {
|
|
833
|
+
const {
|
|
834
|
+
resourceData: _resourceData,
|
|
835
|
+
fieldMeta: _fieldMeta,
|
|
836
|
+
version: _version,
|
|
837
|
+
dataMode: _dataMode,
|
|
838
|
+
...notificationPayload
|
|
839
|
+
} = payload;
|
|
840
|
+
return notificationPayload;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
private validateAndTransformSyncReplayData(params: {
|
|
844
|
+
resourceData: unknown;
|
|
845
|
+
resourceType: string;
|
|
846
|
+
dataMode?: DataMode;
|
|
847
|
+
}): { success: true; data: unknown } | { success: false } {
|
|
848
|
+
const dataMode = params.dataMode ?? DataMode.RAW;
|
|
849
|
+
|
|
850
|
+
if (!params.resourceData || typeof params.resourceData !== 'object') {
|
|
851
|
+
this.logger.warn('WebSocket sync replay payload is missing resource data', {
|
|
852
|
+
resourceType: params.resourceType,
|
|
853
|
+
dataMode,
|
|
854
|
+
});
|
|
855
|
+
return { success: false };
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
const readOperation = this.resolveOperationForWebSocketValidation({
|
|
859
|
+
resourceType: params.resourceType,
|
|
860
|
+
dataMode,
|
|
861
|
+
validationTarget: 'canonical-read',
|
|
862
|
+
});
|
|
863
|
+
if (!readOperation) {
|
|
864
|
+
return { success: false };
|
|
865
|
+
}
|
|
866
|
+
const selectedDto = this.selectResponseDto(readOperation, dataMode);
|
|
867
|
+
|
|
868
|
+
if (!selectedDto) {
|
|
869
|
+
this.logger.warn('WebSocket sync replay payload missing canonical READ DTO', {
|
|
870
|
+
resourceType: params.resourceType,
|
|
871
|
+
dataMode,
|
|
872
|
+
});
|
|
873
|
+
return { success: false };
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
try {
|
|
877
|
+
const transformedData = ResourcesConfigOperationsDtosBuilderUtils.transformResponseDates(
|
|
878
|
+
params.resourceData,
|
|
879
|
+
selectedDto,
|
|
880
|
+
);
|
|
881
|
+
return {
|
|
882
|
+
success: true,
|
|
883
|
+
data: selectedDto.parse(transformedData),
|
|
884
|
+
};
|
|
885
|
+
} catch (error) {
|
|
886
|
+
this.logger.warn('WebSocket sync replay validation failed', {
|
|
887
|
+
resourceType: params.resourceType,
|
|
888
|
+
dataMode,
|
|
889
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
890
|
+
resourceDataKeys: typeof params.resourceData === 'object' ? Object.keys(params.resourceData as Record<string, unknown>) : 'not-object',
|
|
891
|
+
});
|
|
892
|
+
return { success: false };
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* Emit to a specific resource room (path-independent)
|
|
898
|
+
* Called by NotificationDispatcherService after CRUD operations
|
|
899
|
+
*
|
|
900
|
+
* Resource-room sync payloads now validate replay-grade resource data when it
|
|
901
|
+
* is present in the payload.
|
|
902
|
+
*
|
|
903
|
+
* @param resourceType - Resource type
|
|
904
|
+
* @param resourceId - Resource ID
|
|
905
|
+
* @param event - WebSocket event name
|
|
906
|
+
* @param payload - Resource-room payload. Sync-grade update payloads carry authoritative
|
|
907
|
+
* `version` + `resourceData`; delete/state payloads intentionally do not.
|
|
908
|
+
*
|
|
909
|
+
* @example
|
|
910
|
+
* // Send notification-grade metadata only
|
|
911
|
+
* websocketService.emitToResourceRoom('users', 'userId123', CoreWebSocketEvent.RESOURCE_UPDATED, {
|
|
912
|
+
* resourceType: 'users',
|
|
913
|
+
* resourceId: 'userId123',
|
|
914
|
+
* contextResourceIdentifiers: {},
|
|
915
|
+
* action: ResourceAction.UPDATED,
|
|
916
|
+
* operationIdentifier: CoreResourceOperation.UPDATE
|
|
917
|
+
* });
|
|
918
|
+
*
|
|
919
|
+
* @example
|
|
920
|
+
* // Send synchronization-grade replay data for RESOURCE_ROOM_SYNC
|
|
921
|
+
* websocketService.emitToResourceRoom('users', 'userId123', CoreWebSocketEvent.RESOURCE_UPDATED, {
|
|
922
|
+
* resourceType: 'users',
|
|
923
|
+
* resourceId: 'userId123',
|
|
924
|
+
* contextResourceIdentifiers: {},
|
|
925
|
+
* action: ResourceAction.UPDATED,
|
|
926
|
+
* operationIdentifier: CoreResourceOperation.UPDATE,
|
|
927
|
+
* resourceData: updatedUserObject, // Full resource object
|
|
928
|
+
* dataMode: DataMode.RAW // or DataMode.SUMMARY, DataMode.CONTEXT
|
|
929
|
+
* });
|
|
930
|
+
*/
|
|
931
|
+
public emitToResourceRoom(
|
|
932
|
+
resourceType: string,
|
|
933
|
+
resourceId: string,
|
|
934
|
+
event: string,
|
|
935
|
+
payload: WebSocketResourceRoomEmitPayload
|
|
936
|
+
): boolean {
|
|
937
|
+
if (!this.io) {
|
|
938
|
+
this.logger.warn('WebSocket not initialized, cannot emit to resource room');
|
|
939
|
+
return false;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Only sync-grade resource-room payloads are allowed to act like
|
|
943
|
+
// authoritative replay input for clients. Notification-grade room payloads
|
|
944
|
+
// still emit, but they do not go through the stricter canonical replay gate.
|
|
945
|
+
const shouldValidateSyncReplay = payload.deliveryTarget === WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC
|
|
946
|
+
&& 'resourceData' in payload;
|
|
947
|
+
let payloadToEmit: WebSocketResourceRoomEmitPayload = payload;
|
|
948
|
+
let dataMode: DataMode = DataMode.RAW;
|
|
949
|
+
|
|
950
|
+
if (shouldValidateSyncReplay) {
|
|
951
|
+
dataMode = this.extractDataMode({ dataMode: payload.dataMode });
|
|
952
|
+
const validation = this.validateAndTransformSyncReplayData({
|
|
953
|
+
resourceData: payload.resourceData,
|
|
954
|
+
resourceType,
|
|
955
|
+
dataMode,
|
|
956
|
+
});
|
|
957
|
+
if (!validation.success) {
|
|
958
|
+
this.logDebug('Skipped resource-room emit: sync replay payload failed canonical validation', {
|
|
959
|
+
resourceType,
|
|
960
|
+
resourceId,
|
|
961
|
+
event,
|
|
962
|
+
deliveryTarget: payload.deliveryTarget,
|
|
963
|
+
});
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
payloadToEmit = {
|
|
967
|
+
...payload,
|
|
968
|
+
resourceData: validation.data as Record<string, unknown>,
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
const roomName = buildResourceRoomName(resourceType, resourceId);
|
|
973
|
+
this.io.to(roomName).emit(event, payloadToEmit);
|
|
974
|
+
|
|
975
|
+
this.logDebug('Emitted to resource room', {
|
|
976
|
+
roomName,
|
|
977
|
+
event,
|
|
978
|
+
dataMode: shouldValidateSyncReplay ? dataMode : undefined,
|
|
979
|
+
hasResourceData: shouldValidateSyncReplay,
|
|
980
|
+
deliveryTarget: payload.deliveryTarget,
|
|
981
|
+
});
|
|
982
|
+
return true;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Helper method to send resource data via WebSocket with automatic validation.
|
|
987
|
+
*
|
|
988
|
+
* This is a convenience method that prepares a payload with resource data and sends it
|
|
989
|
+
* to a resource room. Use this when you want to send authoritative resource objects via
|
|
990
|
+
* WebSocket.
|
|
991
|
+
*
|
|
992
|
+
* @param resourceType - Resource type
|
|
993
|
+
* @param resourceId - Resource ID
|
|
994
|
+
* @param event - WebSocket event name (e.g., CoreWebSocketEvent.RESOURCE_UPDATED)
|
|
995
|
+
* @param action - Resource action (ResourceAction.CREATED, UPDATED, DELETED)
|
|
996
|
+
* @param resourceData - The resource data object to send (will be validated and transformed)
|
|
997
|
+
* @param options - Optional configuration
|
|
998
|
+
* @param options.operationIdentifier - Operation identifier (e.g., CoreResourceOperation.UPDATE)
|
|
999
|
+
* @param options.dataMode - Data mode (defaults to RAW)
|
|
1000
|
+
* @param options.contextResourceIdentifiers - Context resource identifiers
|
|
1001
|
+
* @param options.affectedIds - Array of affected resource IDs
|
|
1002
|
+
* @param options.initiatorUserId - User ID of the initiator
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* // Send updated user resource
|
|
1006
|
+
* await websocketService.sendResourceData(
|
|
1007
|
+
* 'users',
|
|
1008
|
+
* 'userId123',
|
|
1009
|
+
* CoreWebSocketEvent.RESOURCE_UPDATED,
|
|
1010
|
+
* ResourceAction.UPDATED,
|
|
1011
|
+
* updatedUserObject,
|
|
1012
|
+
* {
|
|
1013
|
+
* operationIdentifier: CoreResourceOperation.UPDATE,
|
|
1014
|
+
* dataMode: DataMode.RAW,
|
|
1015
|
+
* contextResourceIdentifiers: {},
|
|
1016
|
+
* initiatorUserId: 'currentUserId'
|
|
1017
|
+
* }
|
|
1018
|
+
* );
|
|
1019
|
+
*
|
|
1020
|
+
* @example
|
|
1021
|
+
* // Send created resource with summary data
|
|
1022
|
+
* await websocketService.sendResourceData(
|
|
1023
|
+
* 'todos',
|
|
1024
|
+
* 'todoId456',
|
|
1025
|
+
* CoreWebSocketEvent.RESOURCE_UPDATED,
|
|
1026
|
+
* ResourceAction.CREATED,
|
|
1027
|
+
* newTodoObject,
|
|
1028
|
+
* {
|
|
1029
|
+
* operationIdentifier: CoreResourceOperation.CREATE,
|
|
1030
|
+
* dataMode: DataMode.SUMMARY, // Use summary for list refreshes
|
|
1031
|
+
* contextResourceIdentifiers: { organizationId: 'org123' },
|
|
1032
|
+
* initiatorUserId: 'currentUserId'
|
|
1033
|
+
* }
|
|
1034
|
+
* );
|
|
1035
|
+
*/
|
|
1036
|
+
public sendResourceData(
|
|
1037
|
+
resourceType: string,
|
|
1038
|
+
resourceId: string,
|
|
1039
|
+
event: string,
|
|
1040
|
+
action: ResourceAction,
|
|
1041
|
+
resourceData: any,
|
|
1042
|
+
options: {
|
|
1043
|
+
operationIdentifier?: string;
|
|
1044
|
+
dataMode?: DataMode | string;
|
|
1045
|
+
contextResourceIdentifiers?: Record<string, string>;
|
|
1046
|
+
affectedIds?: string[];
|
|
1047
|
+
initiatorUserId?: string;
|
|
1048
|
+
version?: number;
|
|
1049
|
+
} = {}
|
|
1050
|
+
): void {
|
|
1051
|
+
const {
|
|
1052
|
+
operationIdentifier,
|
|
1053
|
+
dataMode = DataMode.RAW,
|
|
1054
|
+
contextResourceIdentifiers = {},
|
|
1055
|
+
affectedIds,
|
|
1056
|
+
initiatorUserId,
|
|
1057
|
+
version,
|
|
1058
|
+
} = options;
|
|
1059
|
+
|
|
1060
|
+
// Convert DataMode enum to string for schema compatibility
|
|
1061
|
+
const effectiveDataMode = typeof dataMode === 'string'
|
|
1062
|
+
? ResourceOperationsUtils.normalizeDataModeString(dataMode) || DataMode.RAW
|
|
1063
|
+
: dataMode || DataMode.RAW;
|
|
1064
|
+
const dataModeString = ResourceOperationsUtils.dataModeToString(effectiveDataMode);
|
|
1065
|
+
const resolvedVersion = version ?? (
|
|
1066
|
+
resourceData && typeof resourceData === 'object'
|
|
1067
|
+
? (resourceData as Record<string, unknown>)._version as number | undefined
|
|
1068
|
+
: undefined
|
|
1069
|
+
);
|
|
1070
|
+
|
|
1071
|
+
if (action !== ResourceAction.DELETED && resolvedVersion == null) {
|
|
1072
|
+
this.logger.warn('sendResourceData skipped sync payload without authoritative version', {
|
|
1073
|
+
resourceType,
|
|
1074
|
+
resourceId,
|
|
1075
|
+
event,
|
|
1076
|
+
action,
|
|
1077
|
+
});
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
const payload: WS_ResourceSyncUpdatedPayload | WS_ResourceDeletedPayload = action === ResourceAction.DELETED
|
|
1082
|
+
? {
|
|
1083
|
+
deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC,
|
|
1084
|
+
resourceType,
|
|
1085
|
+
resourceId,
|
|
1086
|
+
contextResourceIdentifiers,
|
|
1087
|
+
action: ResourceAction.DELETED,
|
|
1088
|
+
operationIdentifier: operationIdentifier ?? CoreResourceOperation.DELETE,
|
|
1089
|
+
affectedIds,
|
|
1090
|
+
initiatorUserId,
|
|
1091
|
+
timestamp: new Date(),
|
|
1092
|
+
}
|
|
1093
|
+
: {
|
|
1094
|
+
deliveryTarget: WebSocketResourceDeliveryTarget.RESOURCE_ROOM_SYNC,
|
|
1095
|
+
resourceType,
|
|
1096
|
+
resourceId,
|
|
1097
|
+
contextResourceIdentifiers,
|
|
1098
|
+
action,
|
|
1099
|
+
operationIdentifier: operationIdentifier ?? CoreResourceOperation.UPDATE,
|
|
1100
|
+
resourceData,
|
|
1101
|
+
dataMode: dataModeString,
|
|
1102
|
+
affectedIds,
|
|
1103
|
+
initiatorUserId,
|
|
1104
|
+
timestamp: new Date(),
|
|
1105
|
+
version: resolvedVersion,
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
this.emitToResourceRoom(resourceType, resourceId, event, payload);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* Emit to scope rooms (collections) for list refresh
|
|
1113
|
+
* Called by NotificationDispatcherService after CRUD operations
|
|
1114
|
+
*
|
|
1115
|
+
* Scope-room payloads validate resource-shaped data when it is present in the
|
|
1116
|
+
* payload, while still treating these emissions as notification-grade rather
|
|
1117
|
+
* than replay-grade sync.
|
|
1118
|
+
*
|
|
1119
|
+
* @param resourceType - Resource type
|
|
1120
|
+
* @param scopes - Array of scope rooms to emit to
|
|
1121
|
+
* @param event - WebSocket event name
|
|
1122
|
+
* @param payload - Payload with optional resourceData and dataMode
|
|
1123
|
+
*
|
|
1124
|
+
* @example
|
|
1125
|
+
* // Send notification-grade metadata for list refresh
|
|
1126
|
+
* websocketService.emitToScopeRooms('users', [{ scopeKey: 'organization', scopeId: 'org123' }],
|
|
1127
|
+
* CoreWebSocketEvent.RESOURCE_UPDATED, { ... });
|
|
1128
|
+
*
|
|
1129
|
+
* @example
|
|
1130
|
+
* // Send optional summary data for list refresh
|
|
1131
|
+
* websocketService.emitToScopeRooms('users', [{ scopeKey: 'organization', scopeId: 'org123' }],
|
|
1132
|
+
* CoreWebSocketEvent.RESOURCE_UPDATED, {
|
|
1133
|
+
* ...metadata,
|
|
1134
|
+
* resourceData: updatedUserObject,
|
|
1135
|
+
* dataMode: DataMode.SUMMARY // Use SUMMARY for list refreshes
|
|
1136
|
+
* });
|
|
1137
|
+
*/
|
|
1138
|
+
public emitToScopeRooms(
|
|
1139
|
+
resourceType: string,
|
|
1140
|
+
scopes: Array<{ scopeKey: string; scopeId: string }>,
|
|
1141
|
+
event: string,
|
|
1142
|
+
payload: WS_ResourceUpdateNotificationPayload
|
|
1143
|
+
): void {
|
|
1144
|
+
if (!this.io) return;
|
|
1145
|
+
|
|
1146
|
+
// Extract DataMode and validate resource data if present
|
|
1147
|
+
const dataMode = this.extractDataMode({ dataMode: payload.dataMode });
|
|
1148
|
+
let validatedPayload = { ...payload };
|
|
1149
|
+
const resourceData = payload.resourceData;
|
|
1150
|
+
|
|
1151
|
+
// Scope-room payloads stay notification-grade. If DTO shaping fails, strip
|
|
1152
|
+
// replay-like fields rather than emitting non-canonical bodies; list
|
|
1153
|
+
// invalidation is still useful even when authoritative replay truth is not.
|
|
1154
|
+
if (resourceData) {
|
|
1155
|
+
const validation = this.validateAndTransformResourceData(
|
|
1156
|
+
resourceData,
|
|
1157
|
+
resourceType,
|
|
1158
|
+
undefined,
|
|
1159
|
+
dataMode,
|
|
1160
|
+
'canonical-read',
|
|
1161
|
+
);
|
|
1162
|
+
|
|
1163
|
+
if (validation.success) {
|
|
1164
|
+
validatedPayload = {
|
|
1165
|
+
...validatedPayload,
|
|
1166
|
+
resourceData: validation.data,
|
|
1167
|
+
};
|
|
1168
|
+
} else {
|
|
1169
|
+
validatedPayload = this.stripScopeNotificationReplayFields(validatedPayload);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
for (const scope of scopes) {
|
|
1174
|
+
const roomName = buildScopeRoomName(resourceType, scope.scopeKey, scope.scopeId);
|
|
1175
|
+
this.io.to(roomName).emit(event, validatedPayload);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
this.logDebug('Emitted to scope rooms', {
|
|
1179
|
+
resourceType,
|
|
1180
|
+
scopeCount: scopes.length,
|
|
1181
|
+
event,
|
|
1182
|
+
dataMode,
|
|
1183
|
+
hasResourceData: !!resourceData,
|
|
1184
|
+
deliveryTarget: payload.deliveryTarget,
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* Get all users currently editing a resource
|
|
1190
|
+
*/
|
|
1191
|
+
public async getResourceEditingUsers(resourceType: string, resourceId: string): Promise<string[]> {
|
|
1192
|
+
const prefix = this.redisService.getAppPrefix();
|
|
1193
|
+
const key = `${prefix}editing:${resourceType}:${resourceId}`;
|
|
1194
|
+
const redisClient = this.redisService.getClient();
|
|
1195
|
+
|
|
1196
|
+
if (!redisClient) {
|
|
1197
|
+
return Array.from(this.resourceEditingState.get(key) || []);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
try {
|
|
1201
|
+
const editing = await redisClient.hGetAll(key);
|
|
1202
|
+
return Object.keys(editing);
|
|
1203
|
+
} catch {
|
|
1204
|
+
return Array.from(this.resourceEditingState.get(key) || []);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// =====================================================
|
|
1209
|
+
// ROOM MANAGEMENT
|
|
1210
|
+
// =====================================================
|
|
1211
|
+
|
|
1212
|
+
/**
|
|
1213
|
+
* Create custom room
|
|
1214
|
+
*/
|
|
1215
|
+
public async createRoom(
|
|
1216
|
+
roomName: string,
|
|
1217
|
+
organizationId: string,
|
|
1218
|
+
type: RoomInfo['type'] = 'custom',
|
|
1219
|
+
metadata?: Record<string, any>
|
|
1220
|
+
): Promise<void> {
|
|
1221
|
+
const room: RoomInfo = {
|
|
1222
|
+
name: roomName,
|
|
1223
|
+
organizationId,
|
|
1224
|
+
type,
|
|
1225
|
+
members: new Set(),
|
|
1226
|
+
metadata
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
this.rooms.set(roomName, room);
|
|
1230
|
+
|
|
1231
|
+
this.logDebug('Room created', {
|
|
1232
|
+
roomName,
|
|
1233
|
+
organizationId: organizationId.substring(0, 8) + '...',
|
|
1234
|
+
type,
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
/**
|
|
1239
|
+
* Join user to room
|
|
1240
|
+
*/
|
|
1241
|
+
public async joinRoom(userId: string, roomName: string): Promise<boolean> {
|
|
1242
|
+
const socketIds = this.userSockets.get(userId);
|
|
1243
|
+
const room = this.rooms.get(roomName);
|
|
1244
|
+
|
|
1245
|
+
if (!socketIds || !room || !this.io) {
|
|
1246
|
+
return false;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
room.members.add(userId);
|
|
1250
|
+
|
|
1251
|
+
for (const socketId of socketIds) {
|
|
1252
|
+
const socket = this.io.sockets.sockets.get(socketId);
|
|
1253
|
+
if (socket) {
|
|
1254
|
+
await socket.join(roomName);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
this.logDebug('User joined room', { userId: userId.substring(0, 8) + '...', roomName });
|
|
1259
|
+
return true;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
/**
|
|
1263
|
+
* Remove user from room
|
|
1264
|
+
*/
|
|
1265
|
+
public async leaveRoom(userId: string, roomName: string): Promise<boolean> {
|
|
1266
|
+
const socketIds = this.userSockets.get(userId);
|
|
1267
|
+
const room = this.rooms.get(roomName);
|
|
1268
|
+
|
|
1269
|
+
if (!socketIds || !room || !this.io) {
|
|
1270
|
+
return false;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
room.members.delete(userId);
|
|
1274
|
+
|
|
1275
|
+
for (const socketId of socketIds) {
|
|
1276
|
+
const socket = this.io.sockets.sockets.get(socketId);
|
|
1277
|
+
if (socket) {
|
|
1278
|
+
await socket.leave(roomName);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
this.logDebug('User left room', { userId: userId.substring(0, 8) + '...', roomName });
|
|
1283
|
+
return true;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// =====================================================
|
|
1287
|
+
// STATUS METHODS
|
|
1288
|
+
// =====================================================
|
|
1289
|
+
|
|
1290
|
+
public getConnectedUsersCount(): number {
|
|
1291
|
+
return this.authenticatedSockets.size;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
public getOrganizationUsersCount(organizationId: string): number {
|
|
1295
|
+
const socketIds = this.organizationSockets.get(organizationId);
|
|
1296
|
+
return socketIds ? socketIds.size : 0;
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
public isUserConnected(userId: string): boolean {
|
|
1300
|
+
const socketIds = this.userSockets.get(userId);
|
|
1301
|
+
return socketIds ? socketIds.size > 0 : false;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
public getRoomInfo(roomName: string): RoomInfo | undefined {
|
|
1305
|
+
return this.rooms.get(roomName);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// =====================================================
|
|
1309
|
+
// PRIVATE SETUP METHODS
|
|
1310
|
+
// =====================================================
|
|
1311
|
+
|
|
1312
|
+
/**
|
|
1313
|
+
* Get CORS origins from app-config runtime endpoints
|
|
1314
|
+
*/
|
|
1315
|
+
private getCorsOrigins(): string[] {
|
|
1316
|
+
// Config must be initialized - this is ensured by the initialization order:
|
|
1317
|
+
// 1. AppsUpdaterConfigService fetches config from apps-manager
|
|
1318
|
+
// 2. Standard AppConfigurationService is initialized with that config
|
|
1319
|
+
// 3. HTTP server starts, which initializes WebSocket
|
|
1320
|
+
// If config is not initialized here, it's a programming error - fail fast
|
|
1321
|
+
if (!this.configService.isInitialized()) {
|
|
1322
|
+
throw this.errorBuilder.buildError(
|
|
1323
|
+
ErrorType.CONFIGURATION,
|
|
1324
|
+
undefined,
|
|
1325
|
+
{
|
|
1326
|
+
customMessageReference: ErrorCustomMessageReference.APP_CONFIGURATION_NOT_INITIALIZED,
|
|
1327
|
+
context: {
|
|
1328
|
+
message: 'Application configuration not initialized : use config before using the service',
|
|
1329
|
+
service: 'WebSocketService',
|
|
1330
|
+
operation: 'getCorsOrigins'
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
const config = this.configService.config;
|
|
1337
|
+
const frontendServices = Object.keys(config.frontendServices ?? {});
|
|
1338
|
+
|
|
1339
|
+
return frontendServices.map((frontendServiceName) => {
|
|
1340
|
+
const url = config.runtime?.endPoints?.[frontendServiceName]?.publicUrl;
|
|
1341
|
+
if (!url) {
|
|
1342
|
+
throw new Error(
|
|
1343
|
+
`Missing runtime.endPoints.${frontendServiceName}.publicUrl for declared frontend service "${frontendServiceName}". ` +
|
|
1344
|
+
'WebSocket CORS cannot be derived from an incomplete runtime topology.',
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
return url;
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* Setup Redis adapter for horizontal scaling across Kubernetes pods
|
|
1353
|
+
*/
|
|
1354
|
+
private async setupRedisAdapter(): Promise<void> {
|
|
1355
|
+
try {
|
|
1356
|
+
if (!this.io) {
|
|
1357
|
+
throw new Error('Socket.IO server not initialized');
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
// Check if config is initialized before accessing
|
|
1361
|
+
if (!this.configService.isInitialized()) {
|
|
1362
|
+
this.logger.warn('App config not initialized, using memory adapter (single instance only)');
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
const appConfig = this.configService.config;
|
|
1366
|
+
const appSecrets = this.configService.secrets;
|
|
1367
|
+
|
|
1368
|
+
if (!appConfig.database.redis) {
|
|
1369
|
+
this.logger.warn('Redis not configured, using memory adapter (single instance only)');
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
const redisHost = appConfig.database.redis.host;
|
|
1374
|
+
const redisPort = appConfig.database.redis.port || 6379;
|
|
1375
|
+
const redisPassword = appSecrets?.database?.redis?.password;
|
|
1376
|
+
const redisUsername = appSecrets?.database?.redis?.username;
|
|
1377
|
+
|
|
1378
|
+
if (!redisHost || redisHost.includes('localhost')) {
|
|
1379
|
+
this.logger.warn('Redis not properly configured for production, using memory adapter (single instance only)');
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// Build Redis client options (same pattern as RedisService)
|
|
1384
|
+
// Include username for ACL authentication (required when using app-specific credentials)
|
|
1385
|
+
const redisOptions: Parameters<typeof createClient>[0] = {
|
|
1386
|
+
socket: {
|
|
1387
|
+
host: redisHost,
|
|
1388
|
+
port: redisPort,
|
|
1389
|
+
connectTimeout: 10000
|
|
1390
|
+
},
|
|
1391
|
+
username: redisUsername,
|
|
1392
|
+
password: redisPassword,
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1395
|
+
const pubClient = createClient(redisOptions);
|
|
1396
|
+
const subClient = pubClient.duplicate();
|
|
1397
|
+
|
|
1398
|
+
// CRITICAL: Attach error handlers BEFORE connect to prevent "missing 'error' handler" warnings
|
|
1399
|
+
// These handlers prevent unhandled errors from crashing the process during Redis restarts
|
|
1400
|
+
pubClient.on('error', (error) => {
|
|
1401
|
+
this.logger.error('Socket.IO Redis pubClient error', {
|
|
1402
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1403
|
+
});
|
|
1404
|
+
});
|
|
1405
|
+
subClient.on('error', (error) => {
|
|
1406
|
+
this.logger.error('Socket.IO Redis subClient error', {
|
|
1407
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1408
|
+
});
|
|
1409
|
+
});
|
|
1410
|
+
|
|
1411
|
+
// Reconnection handlers for visibility
|
|
1412
|
+
pubClient.on('reconnecting', () => {
|
|
1413
|
+
this.logDebug('Socket.IO Redis pubClient reconnecting...');
|
|
1414
|
+
});
|
|
1415
|
+
subClient.on('reconnecting', () => {
|
|
1416
|
+
this.logDebug('Socket.IO Redis subClient reconnecting...');
|
|
1417
|
+
});
|
|
1418
|
+
|
|
1419
|
+
await Promise.all([
|
|
1420
|
+
pubClient.connect(),
|
|
1421
|
+
subClient.connect()
|
|
1422
|
+
]);
|
|
1423
|
+
|
|
1424
|
+
// SECURITY FIX: Use tenant-specific channel prefix for Socket.IO adapter
|
|
1425
|
+
// This ensures each tenant's Socket.IO messages are isolated to their own channels
|
|
1426
|
+
// ACL pattern &{username}#* will only allow access to channels with this prefix
|
|
1427
|
+
const channelPrefix = redisUsername || 'default';
|
|
1428
|
+
this.io.adapter(createAdapter(pubClient, subClient, { key: channelPrefix }));
|
|
1429
|
+
|
|
1430
|
+
this.logDebug('Socket.IO Redis adapter configured for horizontal scaling', {
|
|
1431
|
+
redisHost,
|
|
1432
|
+
redisPort,
|
|
1433
|
+
channelPrefix,
|
|
1434
|
+
scalingEnabled: true,
|
|
1435
|
+
environment: process.env.APPLICATION_ENV || 'development'
|
|
1436
|
+
});
|
|
1437
|
+
|
|
1438
|
+
} catch (error: unknown) {
|
|
1439
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
1440
|
+
this.logger.error('Failed to setup Redis adapter, falling back to memory adapter', {
|
|
1441
|
+
error: errorMessage,
|
|
1442
|
+
});
|
|
1443
|
+
this.logger.warn('Using memory adapter - horizontal scaling will not work across pods');
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* Setup authentication middleware
|
|
1449
|
+
* FACTORIZED: Uses ExecutionContextCreatorBackendService for JWT validation
|
|
1450
|
+
*/
|
|
1451
|
+
private setupAuthentication(): void {
|
|
1452
|
+
if (!this.io) return;
|
|
1453
|
+
|
|
1454
|
+
this.io.use(async (socket, next) => {
|
|
1455
|
+
try {
|
|
1456
|
+
const token = socket.handshake.auth.token ||
|
|
1457
|
+
socket.handshake.headers.authorization?.replace('Bearer ', '');
|
|
1458
|
+
|
|
1459
|
+
let authResult: SocketAuthResult;
|
|
1460
|
+
|
|
1461
|
+
if (!token) {
|
|
1462
|
+
// No token = public connection (allowed but limited)
|
|
1463
|
+
authResult = this.executionContextCreator.getPublicSocketAuth();
|
|
1464
|
+
this.logDebug('Public socket connection (no token)');
|
|
1465
|
+
} else {
|
|
1466
|
+
authResult = await this.executionContextCreator.authenticateSocketConnection(token);
|
|
1467
|
+
|
|
1468
|
+
// W7.3b: Capture consumable token from handshake auth or headers
|
|
1469
|
+
const consumableToken = socket.handshake.auth?.consumableToken
|
|
1470
|
+
|| socket.handshake.headers?.[WildoHeaderKeys.CONSUMABLE_TOKEN];
|
|
1471
|
+
if (consumableToken && typeof consumableToken === 'string') {
|
|
1472
|
+
authResult.consumableTokenValue = consumableToken;
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
this.logDebug('Authenticated socket connection', {
|
|
1476
|
+
executionType: authResult.executionType,
|
|
1477
|
+
userId: authResult.initiatorIds?.userId?.substring(0, 8) + '...',
|
|
1478
|
+
rolesCount: authResult.initiatorRoles.length,
|
|
1479
|
+
hasConsumableToken: !!authResult.consumableTokenValue,
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
(socket as any).auth = authResult;
|
|
1484
|
+
next();
|
|
1485
|
+
|
|
1486
|
+
} catch (error) {
|
|
1487
|
+
this.logger.warn('WebSocket authentication failed', {
|
|
1488
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
1489
|
+
});
|
|
1490
|
+
next(new Error('Authentication failed'));
|
|
1491
|
+
}
|
|
1492
|
+
});
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
/**
|
|
1496
|
+
* Setup rate limiting middleware
|
|
1497
|
+
* Uses Redis for cross-pod synchronization of rate limit counters
|
|
1498
|
+
*/
|
|
1499
|
+
private setupRateLimiting(): void {
|
|
1500
|
+
if (!this.io) return;
|
|
1501
|
+
|
|
1502
|
+
// Intercept all incoming events with rate limiting
|
|
1503
|
+
this.io.use(async (socket, next) => {
|
|
1504
|
+
// Override socket.on to wrap event handlers with rate limiting
|
|
1505
|
+
const originalOn = socket.on.bind(socket);
|
|
1506
|
+
|
|
1507
|
+
(socket as any).on = (event: string, handler: (...args: any[]) => void) => {
|
|
1508
|
+
// Skip internal Socket.IO events
|
|
1509
|
+
if (event.startsWith('$') || ['connect', 'disconnect', 'error'].includes(event)) {
|
|
1510
|
+
return originalOn(event, handler);
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
// Wrap handler with rate limiting check
|
|
1514
|
+
return originalOn(event, async (...args: any[]) => {
|
|
1515
|
+
const auth = (socket as any).auth as SocketAuthResult;
|
|
1516
|
+
const identifier = auth.initiatorIds?.userId || socket.id;
|
|
1517
|
+
|
|
1518
|
+
const allowed = await this.checkRateLimit(identifier, event);
|
|
1519
|
+
if (!allowed) {
|
|
1520
|
+
// Rate limit exceeded - emit error and skip handler
|
|
1521
|
+
socket.emit(CoreWebSocketEvent.SYSTEM_ERROR, {
|
|
1522
|
+
code: 'RATE_LIMIT_EXCEEDED',
|
|
1523
|
+
message: `Too many ${event} requests. Please slow down.`,
|
|
1524
|
+
details: { event }
|
|
1525
|
+
});
|
|
1526
|
+
this.logDebug('Rate limit exceeded', {
|
|
1527
|
+
identifier: identifier.substring(0, 8),
|
|
1528
|
+
event
|
|
1529
|
+
});
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
// Call original handler
|
|
1534
|
+
handler(...args);
|
|
1535
|
+
});
|
|
1536
|
+
};
|
|
1537
|
+
|
|
1538
|
+
next();
|
|
1539
|
+
});
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* Check rate limit for an event using Redis
|
|
1544
|
+
* Returns true if allowed, false if rate limited
|
|
1545
|
+
*
|
|
1546
|
+
* Uses sliding window algorithm with Redis INCR and EXPIRE
|
|
1547
|
+
*/
|
|
1548
|
+
private async checkRateLimit(identifier: string, event: string): Promise<boolean> {
|
|
1549
|
+
const config = DEFAULT_RATE_LIMITS[event] || DEFAULT_RATE_LIMITS['default'];
|
|
1550
|
+
const redisClient = this.redisService.getClient();
|
|
1551
|
+
|
|
1552
|
+
// Fallback to in-memory if Redis unavailable (less accurate cross-pod)
|
|
1553
|
+
if (!redisClient) {
|
|
1554
|
+
return this.checkRateLimitInMemory(identifier, event, config);
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
try {
|
|
1558
|
+
const prefix = this.redisService.getAppPrefix();
|
|
1559
|
+
const key = `${prefix}ws:ratelimit:${identifier}:${event}`;
|
|
1560
|
+
const windowKey = `${key}:${Math.floor(Date.now() / (config.windowSeconds * 1000))}`;
|
|
1561
|
+
|
|
1562
|
+
// Increment counter for current window
|
|
1563
|
+
const count = await redisClient.incr(windowKey);
|
|
1564
|
+
|
|
1565
|
+
// Set expiry on first request in window
|
|
1566
|
+
if (count === 1) {
|
|
1567
|
+
await redisClient.expire(windowKey, config.windowSeconds + 1);
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
return count <= config.maxEvents;
|
|
1571
|
+
|
|
1572
|
+
} catch (error) {
|
|
1573
|
+
// On Redis error, allow the request (fail open)
|
|
1574
|
+
this.logger.warn('Rate limit check failed, allowing request', {
|
|
1575
|
+
identifier: identifier.substring(0, 8),
|
|
1576
|
+
event,
|
|
1577
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
1578
|
+
});
|
|
1579
|
+
return true;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* In-memory rate limiting fallback (single pod only)
|
|
1585
|
+
*/
|
|
1586
|
+
private inMemoryRateLimits: Map<string, { count: number; resetAt: number }> = new Map();
|
|
1587
|
+
|
|
1588
|
+
private checkRateLimitInMemory(
|
|
1589
|
+
identifier: string,
|
|
1590
|
+
event: string,
|
|
1591
|
+
config: RateLimitConfig
|
|
1592
|
+
): boolean {
|
|
1593
|
+
const key = `${identifier}:${event}`;
|
|
1594
|
+
const now = Date.now();
|
|
1595
|
+
const entry = this.inMemoryRateLimits.get(key);
|
|
1596
|
+
|
|
1597
|
+
if (!entry || now >= entry.resetAt) {
|
|
1598
|
+
// Start new window
|
|
1599
|
+
this.inMemoryRateLimits.set(key, {
|
|
1600
|
+
count: 1,
|
|
1601
|
+
resetAt: now + (config.windowSeconds * 1000),
|
|
1602
|
+
});
|
|
1603
|
+
return true;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
if (entry.count >= config.maxEvents) {
|
|
1607
|
+
return false;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
entry.count++;
|
|
1611
|
+
return true;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
/**
|
|
1615
|
+
* Setup connection handling
|
|
1616
|
+
* Joins user to identity-based rooms based on their roles and IDs
|
|
1617
|
+
* Sets up resource room handlers for collaboration
|
|
1618
|
+
*/
|
|
1619
|
+
private setupConnectionHandling(): void {
|
|
1620
|
+
if (!this.io) return;
|
|
1621
|
+
|
|
1622
|
+
this.io.on('connection', (socket: Socket) => {
|
|
1623
|
+
const auth = (socket as any).auth as SocketAuthResult;
|
|
1624
|
+
|
|
1625
|
+
// Track authenticated socket
|
|
1626
|
+
this.authenticatedSockets.set(socket.id, auth);
|
|
1627
|
+
|
|
1628
|
+
// === IDENTITY-BASED ROOM ASSIGNMENT ===
|
|
1629
|
+
|
|
1630
|
+
if (auth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
1631
|
+
// Public users only join public room
|
|
1632
|
+
socket.join(WebSocketRoomPrefix.PUBLIC);
|
|
1633
|
+
this.logDebug('Public socket connected', { socketId: socket.id });
|
|
1634
|
+
|
|
1635
|
+
// Still setup disconnect handler
|
|
1636
|
+
socket.on('disconnect', () => {
|
|
1637
|
+
this.handleSocketDisconnection(socket.id, this.getSocketAuth(socket));
|
|
1638
|
+
});
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
// User: Join organization-based rooms from their roles
|
|
1643
|
+
for (const roleInfo of auth.initiatorRoles) {
|
|
1644
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS && roleInfo.relatedResourceId) {
|
|
1645
|
+
const orgId = roleInfo.relatedResourceId;
|
|
1646
|
+
|
|
1647
|
+
// Organization room (receives all org-wide notifications)
|
|
1648
|
+
socket.join(buildOrganizationRoomName(orgId));
|
|
1649
|
+
|
|
1650
|
+
// Track organization sockets
|
|
1651
|
+
if (!this.organizationSockets.has(orgId)) {
|
|
1652
|
+
this.organizationSockets.set(orgId, new Set());
|
|
1653
|
+
}
|
|
1654
|
+
this.organizationSockets.get(orgId)!.add(socket.id);
|
|
1655
|
+
|
|
1656
|
+
// Role-specific rooms (for role-targeted notifications)
|
|
1657
|
+
for (const role of roleInfo.roles || []) {
|
|
1658
|
+
socket.join(buildOrganizationRoleRoomName(orgId, role));
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.APPLICATION && roleInfo.relatedResourceId) {
|
|
1663
|
+
// App-level role room (for app admins, super admins)
|
|
1664
|
+
for (const role of roleInfo.roles || []) {
|
|
1665
|
+
socket.join(buildAppRoleRoomName(role));
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
// User-specific room (for direct messages, personal notifications)
|
|
1671
|
+
if (auth.initiatorIds?.userId) {
|
|
1672
|
+
socket.join(buildUserRoomName(auth.initiatorIds.userId));
|
|
1673
|
+
|
|
1674
|
+
// Track user sockets for multi-tab support
|
|
1675
|
+
if (!this.userSockets.has(auth.initiatorIds.userId)) {
|
|
1676
|
+
this.userSockets.set(auth.initiatorIds.userId, new Set());
|
|
1677
|
+
}
|
|
1678
|
+
this.userSockets.get(auth.initiatorIds.userId)!.add(socket.id);
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
this.logDebug('Socket connected with identity rooms', {
|
|
1682
|
+
socketId: socket.id,
|
|
1683
|
+
executionType: auth.executionType,
|
|
1684
|
+
userId: auth.initiatorIds?.userId?.substring(0, 8),
|
|
1685
|
+
organizationRoles: auth.initiatorRoles.filter(r => r.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS).length
|
|
1686
|
+
});
|
|
1687
|
+
|
|
1688
|
+
// === RESOURCE ROOM HANDLERS (for collaboration) ===
|
|
1689
|
+
this.setupResourceRoomHandlers(socket);
|
|
1690
|
+
|
|
1691
|
+
// === BADGE HANDLERS ===
|
|
1692
|
+
this.setupBadgeHandlers(socket);
|
|
1693
|
+
|
|
1694
|
+
// === SYSTEM EVENT HANDLERS ===
|
|
1695
|
+
this.setupSystemEventHandlers(socket);
|
|
1696
|
+
|
|
1697
|
+
// === DISCONNECTION HANDLING ===
|
|
1698
|
+
socket.on('disconnect', () => {
|
|
1699
|
+
this.handleSocketDisconnection(socket.id, this.getSocketAuth(socket));
|
|
1700
|
+
});
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Setup handlers for resource-centric rooms (collaboration, editing locks, custom events)
|
|
1706
|
+
* These rooms are path-independent - same resource = same room regardless of access path
|
|
1707
|
+
*/
|
|
1708
|
+
private setupResourceRoomHandlers(socket: Socket): void {
|
|
1709
|
+
|
|
1710
|
+
// === SUBSCRIBE TO RESOURCE ROOM ===
|
|
1711
|
+
socket.on(CoreWebSocketEvent.RESOURCE_SUBSCRIBE, async (rawPayload: unknown) => {
|
|
1712
|
+
// Runtime validation using Zod schema
|
|
1713
|
+
const parseResult = WS_ResourceSubscribePayloadSchema.safeParse(rawPayload);
|
|
1714
|
+
if (!parseResult.success) {
|
|
1715
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_SUBSCRIBED, {
|
|
1716
|
+
roomName: '',
|
|
1717
|
+
success: false,
|
|
1718
|
+
error: `Invalid payload: ${parseResult.error.issues[0]?.message || 'validation failed'}`
|
|
1719
|
+
});
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
const payload = parseResult.data;
|
|
1724
|
+
const { resourceType, resourceId, scopeKey, scopeId, contextResourceIdentifiers } = payload;
|
|
1725
|
+
|
|
1726
|
+
// Validate contextResourceIdentifiers has at least one entry
|
|
1727
|
+
if (!contextResourceIdentifiers || Object.keys(contextResourceIdentifiers).length === 0) {
|
|
1728
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_SUBSCRIBED, {
|
|
1729
|
+
roomName: '',
|
|
1730
|
+
success: false,
|
|
1731
|
+
error: 'contextResourceIdentifiers is required for authorization'
|
|
1732
|
+
});
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
try {
|
|
1737
|
+
const auth = this.getSocketAuth(socket);
|
|
1738
|
+
// Verify READ access using full context (organization, parent resources, etc.)
|
|
1739
|
+
if (resourceId) {
|
|
1740
|
+
await this.verifyResourceAccess(socket, auth, resourceType, resourceId, contextResourceIdentifiers);
|
|
1741
|
+
} else if (scopeKey && scopeId) {
|
|
1742
|
+
// For collection subscription, verify context access
|
|
1743
|
+
await this.verifyScopeAccess(auth, scopeKey, scopeId, contextResourceIdentifiers);
|
|
1744
|
+
} else {
|
|
1745
|
+
throw this.errorBuilder.buildError(ErrorType.VALIDATION, undefined, {
|
|
1746
|
+
customMessageReference: ErrorCustomMessageReference.SERVICE_RESOURCE_VALIDATION_FAILED,
|
|
1747
|
+
context: { operation: 'resourceSubscribe', message: 'Either resourceId or (scopeKey + scopeId) required' },
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
// Build room name
|
|
1752
|
+
const roomName = resourceId
|
|
1753
|
+
? buildResourceRoomName(resourceType, resourceId)
|
|
1754
|
+
: buildScopeRoomName(resourceType, scopeKey!, scopeId!);
|
|
1755
|
+
|
|
1756
|
+
socket.join(roomName);
|
|
1757
|
+
this.trackSocketResourceSubscription(socket.id, {
|
|
1758
|
+
...payload,
|
|
1759
|
+
roomName,
|
|
1760
|
+
});
|
|
1761
|
+
|
|
1762
|
+
// Get current editing users for this resource (if subscribing to specific resource)
|
|
1763
|
+
let editingUsers: string[] = [];
|
|
1764
|
+
if (resourceId) {
|
|
1765
|
+
editingUsers = await this.getResourceEditingUsers(resourceType, resourceId);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_SUBSCRIBED, {
|
|
1769
|
+
roomName,
|
|
1770
|
+
success: true,
|
|
1771
|
+
editingUsers, // Include current editing users in subscription confirmation
|
|
1772
|
+
});
|
|
1773
|
+
|
|
1774
|
+
this.logDebug('Socket subscribed to resource room', {
|
|
1775
|
+
socketId: socket.id,
|
|
1776
|
+
roomName,
|
|
1777
|
+
userId: auth.initiatorIds?.userId?.substring(0, 8),
|
|
1778
|
+
contextKeys: Object.keys(contextResourceIdentifiers),
|
|
1779
|
+
editingUsersCount: editingUsers.length
|
|
1780
|
+
});
|
|
1781
|
+
|
|
1782
|
+
} catch (error) {
|
|
1783
|
+
const roomName = resourceId
|
|
1784
|
+
? buildResourceRoomName(resourceType, resourceId)
|
|
1785
|
+
: buildScopeRoomName(resourceType, scopeKey || '', scopeId || '');
|
|
1786
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_SUBSCRIBED, {
|
|
1787
|
+
roomName,
|
|
1788
|
+
success: false,
|
|
1789
|
+
error: error instanceof Error ? error.message : 'Access denied'
|
|
1790
|
+
});
|
|
1791
|
+
}
|
|
1792
|
+
});
|
|
1793
|
+
|
|
1794
|
+
// === UNSUBSCRIBE FROM RESOURCE ROOM ===
|
|
1795
|
+
socket.on(CoreWebSocketEvent.RESOURCE_UNSUBSCRIBE, (rawPayload: unknown) => {
|
|
1796
|
+
// Runtime validation using Zod schema
|
|
1797
|
+
const parseResult = WS_ResourceSubscribePayloadSchema.safeParse(rawPayload);
|
|
1798
|
+
if (!parseResult.success) {
|
|
1799
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_UNSUBSCRIBED, {
|
|
1800
|
+
roomName: '',
|
|
1801
|
+
success: false,
|
|
1802
|
+
error: `Invalid payload: ${parseResult.error.issues[0]?.message || 'validation failed'}`
|
|
1803
|
+
});
|
|
1804
|
+
return;
|
|
1805
|
+
}
|
|
1806
|
+
|
|
1807
|
+
const payload = parseResult.data;
|
|
1808
|
+
const { resourceType, resourceId, scopeKey, scopeId } = payload;
|
|
1809
|
+
|
|
1810
|
+
const roomName = resourceId
|
|
1811
|
+
? buildResourceRoomName(resourceType, resourceId)
|
|
1812
|
+
: buildScopeRoomName(resourceType, scopeKey!, scopeId!);
|
|
1813
|
+
|
|
1814
|
+
socket.leave(roomName);
|
|
1815
|
+
this.untrackSocketResourceSubscription(socket.id, roomName);
|
|
1816
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_UNSUBSCRIBED, { roomName, success: true });
|
|
1817
|
+
|
|
1818
|
+
this.logDebug('Socket unsubscribed from resource room', { socketId: socket.id, roomName });
|
|
1819
|
+
});
|
|
1820
|
+
|
|
1821
|
+
// === START EDITING (LOCK) ===
|
|
1822
|
+
socket.on(CoreWebSocketEvent.RESOURCE_EDITING_START, async (rawPayload: unknown) => {
|
|
1823
|
+
// Runtime validation using Zod schema
|
|
1824
|
+
const parseResult = WS_ResourceEditingPayloadSchema.safeParse(rawPayload);
|
|
1825
|
+
if (!parseResult.success) {
|
|
1826
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_EDITING_ERROR, {
|
|
1827
|
+
resourceType: '',
|
|
1828
|
+
resourceId: '',
|
|
1829
|
+
success: false,
|
|
1830
|
+
error: `Invalid payload: ${parseResult.error.issues[0]?.message || 'validation failed'}`
|
|
1831
|
+
});
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
const payload = parseResult.data;
|
|
1836
|
+
const { resourceType, resourceId, contextResourceIdentifiers } = payload;
|
|
1837
|
+
const auth = this.getSocketAuth(socket);
|
|
1838
|
+
const userId = auth.initiatorIds?.userId;
|
|
1839
|
+
|
|
1840
|
+
if (!userId) {
|
|
1841
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_EDITING_ERROR, {
|
|
1842
|
+
resourceType,
|
|
1843
|
+
resourceId,
|
|
1844
|
+
success: false,
|
|
1845
|
+
error: 'Authentication required for editing'
|
|
1846
|
+
});
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
// Validate contextResourceIdentifiers is provided
|
|
1851
|
+
if (!contextResourceIdentifiers || Object.keys(contextResourceIdentifiers).length === 0) {
|
|
1852
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_EDITING_ERROR, {
|
|
1853
|
+
resourceType,
|
|
1854
|
+
resourceId,
|
|
1855
|
+
success: false,
|
|
1856
|
+
error: 'contextResourceIdentifiers is required for authorization'
|
|
1857
|
+
});
|
|
1858
|
+
return;
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
try {
|
|
1862
|
+
// Verify user has WRITE access to edit this resource (using UPDATE operation)
|
|
1863
|
+
await this.verifyResourceAccessForEdit(socket, auth, resourceType, resourceId, contextResourceIdentifiers);
|
|
1864
|
+
|
|
1865
|
+
const roomName = buildResourceRoomName(resourceType, resourceId);
|
|
1866
|
+
|
|
1867
|
+
// Track editing state in memory + Redis for cross-pod sync
|
|
1868
|
+
await this.trackEditingState(resourceType, resourceId, userId, 'start');
|
|
1869
|
+
|
|
1870
|
+
// Broadcast to room (exclude sender) - don't include contextResourceIdentifiers in broadcast
|
|
1871
|
+
const eventPayload: WS_ResourceEditingPayload = {
|
|
1872
|
+
resourceType,
|
|
1873
|
+
resourceId,
|
|
1874
|
+
initiatorUserId: userId,
|
|
1875
|
+
timestamp: new Date(),
|
|
1876
|
+
};
|
|
1877
|
+
socket.to(roomName).emit(CoreWebSocketEvent.RESOURCE_EDITING_START, eventPayload);
|
|
1878
|
+
|
|
1879
|
+
// Confirm to sender
|
|
1880
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_EDITING_STARTED, { resourceType, resourceId, success: true });
|
|
1881
|
+
|
|
1882
|
+
this.logDebug('User started editing resource', {
|
|
1883
|
+
userId: userId.substring(0, 8),
|
|
1884
|
+
resourceType,
|
|
1885
|
+
resourceId: resourceId.substring(0, 8)
|
|
1886
|
+
});
|
|
1887
|
+
|
|
1888
|
+
} catch (error) {
|
|
1889
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_EDITING_ERROR, {
|
|
1890
|
+
resourceType,
|
|
1891
|
+
resourceId,
|
|
1892
|
+
success: false,
|
|
1893
|
+
error: 'Access denied'
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
});
|
|
1897
|
+
|
|
1898
|
+
// === STOP EDITING (UNLOCK) ===
|
|
1899
|
+
socket.on(CoreWebSocketEvent.RESOURCE_EDITING_END, async (rawPayload: unknown) => {
|
|
1900
|
+
// Runtime validation using Zod schema
|
|
1901
|
+
const parseResult = WS_ResourceEditingPayloadSchema.safeParse(rawPayload);
|
|
1902
|
+
if (!parseResult.success) {
|
|
1903
|
+
// Silent fail for editing end (not critical)
|
|
1904
|
+
this.logDebug('Invalid editing end payload', {
|
|
1905
|
+
error: parseResult.error.issues[0]?.message
|
|
1906
|
+
});
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
const payload = parseResult.data;
|
|
1911
|
+
const { resourceType, resourceId } = payload;
|
|
1912
|
+
const auth = this.getSocketAuth(socket);
|
|
1913
|
+
const userId = auth.initiatorIds?.userId;
|
|
1914
|
+
|
|
1915
|
+
if (!userId) return;
|
|
1916
|
+
|
|
1917
|
+
const roomName = buildResourceRoomName(resourceType, resourceId);
|
|
1918
|
+
|
|
1919
|
+
// Clear editing state
|
|
1920
|
+
await this.trackEditingState(resourceType, resourceId, userId, 'end');
|
|
1921
|
+
|
|
1922
|
+
// Broadcast to room (exclude sender)
|
|
1923
|
+
const eventPayload: WS_ResourceEditingPayload = {
|
|
1924
|
+
resourceType,
|
|
1925
|
+
resourceId,
|
|
1926
|
+
initiatorUserId: userId,
|
|
1927
|
+
timestamp: new Date(),
|
|
1928
|
+
};
|
|
1929
|
+
socket.to(roomName).emit(CoreWebSocketEvent.RESOURCE_EDITING_END, eventPayload);
|
|
1930
|
+
|
|
1931
|
+
this.logDebug('User stopped editing resource', {
|
|
1932
|
+
userId: userId.substring(0, 8),
|
|
1933
|
+
resourceType,
|
|
1934
|
+
resourceId: resourceId.substring(0, 8)
|
|
1935
|
+
});
|
|
1936
|
+
});
|
|
1937
|
+
|
|
1938
|
+
// === CUSTOM COLLABORATION EVENT ===
|
|
1939
|
+
socket.on(CoreWebSocketEvent.RESOURCE_CUSTOM, async (rawPayload: unknown) => {
|
|
1940
|
+
// Runtime validation using Zod schema
|
|
1941
|
+
const parseResult = WS_ResourceCustomEventPayloadSchema.safeParse(rawPayload);
|
|
1942
|
+
if (!parseResult.success) {
|
|
1943
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_CUSTOM_ERROR, {
|
|
1944
|
+
eventName: '',
|
|
1945
|
+
error: `Invalid payload: ${parseResult.error.issues[0]?.message || 'validation failed'}`
|
|
1946
|
+
});
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
const payload = parseResult.data;
|
|
1951
|
+
const { resourceType, resourceId, eventName, data, includeSelf, contextResourceIdentifiers } = payload;
|
|
1952
|
+
const auth = this.getSocketAuth(socket);
|
|
1953
|
+
const userId = auth.initiatorIds?.userId;
|
|
1954
|
+
|
|
1955
|
+
// Validate contextResourceIdentifiers is provided
|
|
1956
|
+
if (!contextResourceIdentifiers || Object.keys(contextResourceIdentifiers).length === 0) {
|
|
1957
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_CUSTOM_ERROR, { eventName, error: 'contextResourceIdentifiers is required' });
|
|
1958
|
+
return;
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
try {
|
|
1962
|
+
// Verify READ access (custom events require at least read access)
|
|
1963
|
+
await this.verifyResourceAccess(socket, auth, resourceType, resourceId, contextResourceIdentifiers);
|
|
1964
|
+
|
|
1965
|
+
const roomName = buildResourceRoomName(resourceType, resourceId);
|
|
1966
|
+
|
|
1967
|
+
// Build outgoing event payload (don't include contextResourceIdentifiers in broadcast)
|
|
1968
|
+
const eventPayload: WS_ResourceCustomEventPayload = {
|
|
1969
|
+
resourceType,
|
|
1970
|
+
resourceId,
|
|
1971
|
+
eventName,
|
|
1972
|
+
data,
|
|
1973
|
+
initiatorUserId: userId,
|
|
1974
|
+
timestamp: new Date(),
|
|
1975
|
+
// Include resourceData and dataMode if present in the incoming payload
|
|
1976
|
+
resourceData: payload.resourceData,
|
|
1977
|
+
dataMode: payload.dataMode,
|
|
1978
|
+
};
|
|
1979
|
+
|
|
1980
|
+
// Validate and transform resource data if present
|
|
1981
|
+
if (payload.resourceData) {
|
|
1982
|
+
const dataMode = this.extractDataMode(payload);
|
|
1983
|
+
const validation = this.validateAndTransformResourceData(
|
|
1984
|
+
payload.resourceData,
|
|
1985
|
+
resourceType,
|
|
1986
|
+
undefined, // Custom events don't have operationIdentifier
|
|
1987
|
+
dataMode,
|
|
1988
|
+
'canonical-read',
|
|
1989
|
+
);
|
|
1990
|
+
if (validation.success) {
|
|
1991
|
+
eventPayload.resourceData = validation.data;
|
|
1992
|
+
} else {
|
|
1993
|
+
delete eventPayload.resourceData;
|
|
1994
|
+
delete eventPayload.dataMode;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
// Broadcast to room (include or exclude sender based on flag)
|
|
1999
|
+
if (includeSelf) {
|
|
2000
|
+
this.io!.to(roomName).emit(CoreWebSocketEvent.RESOURCE_CUSTOM, eventPayload);
|
|
2001
|
+
} else {
|
|
2002
|
+
socket.to(roomName).emit(CoreWebSocketEvent.RESOURCE_CUSTOM, eventPayload);
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
} catch (error) {
|
|
2006
|
+
socket.emit(CoreWebSocketEvent.RESOURCE_CUSTOM_ERROR, { eventName, error: 'Access denied' });
|
|
2007
|
+
}
|
|
2008
|
+
});
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
/**
|
|
2012
|
+
* Setup system event handlers (auth refresh, organization switch)
|
|
2013
|
+
*/
|
|
2014
|
+
private setupSystemEventHandlers(socket: Socket): void {
|
|
2015
|
+
// Token refresh handling
|
|
2016
|
+
socket.on(CoreWebSocketEvent.AUTH_REFRESH, async (payload: { token: string }) => {
|
|
2017
|
+
try {
|
|
2018
|
+
const oldAuth = (socket as any).auth as SocketAuthResult;
|
|
2019
|
+
const newAuth = await this.executionContextCreator.authenticateSocketConnection(payload.token);
|
|
2020
|
+
|
|
2021
|
+
// W7.3b: Carry forward consumable token across auth refreshes
|
|
2022
|
+
if (oldAuth.consumableTokenValue) {
|
|
2023
|
+
newAuth.consumableTokenValue = oldAuth.consumableTokenValue;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
(socket as any).auth = newAuth;
|
|
2027
|
+
this.authenticatedSockets.set(socket.id, newAuth);
|
|
2028
|
+
|
|
2029
|
+
// Re-assign identity rooms based on new auth
|
|
2030
|
+
await this.reassignIdentityRooms(socket, oldAuth, newAuth);
|
|
2031
|
+
await this.revalidateTrackedResourceSubscriptions(socket, newAuth);
|
|
2032
|
+
|
|
2033
|
+
socket.emit(CoreWebSocketEvent.SYSTEM_TOKEN_REFRESHED, { success: true });
|
|
2034
|
+
|
|
2035
|
+
this.logDebug('Socket auth refreshed and rooms reassigned', {
|
|
2036
|
+
socketId: socket.id,
|
|
2037
|
+
userId: newAuth.initiatorIds?.userId?.substring(0, 8),
|
|
2038
|
+
newRolesCount: newAuth.initiatorRoles.length
|
|
2039
|
+
});
|
|
2040
|
+
} catch (error) {
|
|
2041
|
+
socket.emit(CoreWebSocketEvent.SYSTEM_ERROR, {
|
|
2042
|
+
code: 'AUTH_REFRESH_FAILED',
|
|
2043
|
+
message: error instanceof Error ? error.message : 'Token refresh failed'
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
});
|
|
2047
|
+
|
|
2048
|
+
// Organization switch handling
|
|
2049
|
+
socket.on(CoreWebSocketEvent.ORGANIZATION_SWITCH, async (payload: { organizationId: string; previousOrganizationId?: string }) => {
|
|
2050
|
+
const auth = this.getSocketAuth(socket);
|
|
2051
|
+
|
|
2052
|
+
if (!this.hasOrganizationAccess(auth, payload.organizationId)) {
|
|
2053
|
+
socket.emit(CoreWebSocketEvent.SYSTEM_ERROR, {
|
|
2054
|
+
code: 'ORGANIZATION_SWITCH_FORBIDDEN',
|
|
2055
|
+
message: 'Access denied to the requested organization',
|
|
2056
|
+
});
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
// Leave old organization rooms if specified
|
|
2061
|
+
if (payload.previousOrganizationId) {
|
|
2062
|
+
socket.leave(buildOrganizationRoomName(payload.previousOrganizationId));
|
|
2063
|
+
this.organizationSockets.get(payload.previousOrganizationId)?.delete(socket.id);
|
|
2064
|
+
if (this.organizationSockets.get(payload.previousOrganizationId)?.size === 0) {
|
|
2065
|
+
this.organizationSockets.delete(payload.previousOrganizationId);
|
|
2066
|
+
}
|
|
2067
|
+
// Leave role rooms too
|
|
2068
|
+
for (const roleInfo of auth.initiatorRoles) {
|
|
2069
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS &&
|
|
2070
|
+
roleInfo.relatedResourceId === payload.previousOrganizationId) {
|
|
2071
|
+
for (const role of roleInfo.roles || []) {
|
|
2072
|
+
socket.leave(buildOrganizationRoleRoomName(payload.previousOrganizationId, role));
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
const trackedSubscriptions = Array.from(this.resourceSubscriptionsBySocket.get(socket.id)?.values() ?? []);
|
|
2078
|
+
for (const subscription of trackedSubscriptions) {
|
|
2079
|
+
if (!subscriptionMatchesOrganization(subscription, payload.previousOrganizationId)) {
|
|
2080
|
+
continue;
|
|
2081
|
+
}
|
|
2082
|
+
await this.revokeTrackedResourceSubscription({
|
|
2083
|
+
socket,
|
|
2084
|
+
auth,
|
|
2085
|
+
subscription,
|
|
2086
|
+
reason: 'organization_switch',
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
// Join new organization rooms
|
|
2092
|
+
socket.join(buildOrganizationRoomName(payload.organizationId));
|
|
2093
|
+
if (!this.organizationSockets.has(payload.organizationId)) {
|
|
2094
|
+
this.organizationSockets.set(payload.organizationId, new Set());
|
|
2095
|
+
}
|
|
2096
|
+
this.organizationSockets.get(payload.organizationId)!.add(socket.id);
|
|
2097
|
+
|
|
2098
|
+
// Find roles for the new organization and join role rooms
|
|
2099
|
+
for (const roleInfo of auth.initiatorRoles) {
|
|
2100
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS &&
|
|
2101
|
+
roleInfo.relatedResourceId === payload.organizationId) {
|
|
2102
|
+
for (const role of roleInfo.roles || []) {
|
|
2103
|
+
socket.join(buildOrganizationRoleRoomName(payload.organizationId, role));
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
this.logDebug('Organization switched', {
|
|
2109
|
+
socketId: socket.id,
|
|
2110
|
+
previousOrganizationId: payload.previousOrganizationId?.substring(0, 8),
|
|
2111
|
+
newOrganizationId: payload.organizationId.substring(0, 8)
|
|
2112
|
+
});
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
/**
|
|
2117
|
+
* Reassign identity-based rooms when auth is refreshed
|
|
2118
|
+
* Handles role changes, organization membership changes, etc.
|
|
2119
|
+
*/
|
|
2120
|
+
private async reassignIdentityRooms(
|
|
2121
|
+
socket: Socket,
|
|
2122
|
+
oldAuth: SocketAuthResult,
|
|
2123
|
+
newAuth: SocketAuthResult
|
|
2124
|
+
): Promise<void> {
|
|
2125
|
+
// === LEAVE OLD ROOMS ===
|
|
2126
|
+
|
|
2127
|
+
// Leave old user room if user ID changed (unlikely but possible)
|
|
2128
|
+
if (oldAuth.initiatorIds?.userId && oldAuth.initiatorIds.userId !== newAuth.initiatorIds?.userId) {
|
|
2129
|
+
socket.leave(buildUserRoomName(oldAuth.initiatorIds.userId));
|
|
2130
|
+
// Update user sockets tracking
|
|
2131
|
+
this.userSockets.get(oldAuth.initiatorIds.userId)?.delete(socket.id);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
// Build sets of old and new organization rooms for comparison
|
|
2135
|
+
const oldOrgRooms = new Set<string>();
|
|
2136
|
+
const oldRoleRooms = new Set<string>();
|
|
2137
|
+
for (const roleInfo of oldAuth.initiatorRoles) {
|
|
2138
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS && roleInfo.relatedResourceId) {
|
|
2139
|
+
oldOrgRooms.add(buildOrganizationRoomName(roleInfo.relatedResourceId));
|
|
2140
|
+
for (const role of roleInfo.roles || []) {
|
|
2141
|
+
oldRoleRooms.add(buildOrganizationRoleRoomName(roleInfo.relatedResourceId, role));
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.APPLICATION) {
|
|
2145
|
+
for (const role of roleInfo.roles || []) {
|
|
2146
|
+
oldRoleRooms.add(buildAppRoleRoomName(role));
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
const newOrgRooms = new Set<string>();
|
|
2152
|
+
const newRoleRooms = new Set<string>();
|
|
2153
|
+
for (const roleInfo of newAuth.initiatorRoles) {
|
|
2154
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS && roleInfo.relatedResourceId) {
|
|
2155
|
+
newOrgRooms.add(buildOrganizationRoomName(roleInfo.relatedResourceId));
|
|
2156
|
+
for (const role of roleInfo.roles || []) {
|
|
2157
|
+
newRoleRooms.add(buildOrganizationRoleRoomName(roleInfo.relatedResourceId, role));
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.APPLICATION) {
|
|
2161
|
+
for (const role of roleInfo.roles || []) {
|
|
2162
|
+
newRoleRooms.add(buildAppRoleRoomName(role));
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
// Leave org rooms that are no longer in new auth
|
|
2168
|
+
for (const room of oldOrgRooms) {
|
|
2169
|
+
if (!newOrgRooms.has(room)) {
|
|
2170
|
+
socket.leave(room);
|
|
2171
|
+
// Update organization sockets tracking
|
|
2172
|
+
const orgId = parseOrganizationRoomName(room);
|
|
2173
|
+
if (orgId) {
|
|
2174
|
+
this.organizationSockets.get(orgId)?.delete(socket.id);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
// Leave role rooms that are no longer in new auth
|
|
2180
|
+
for (const room of oldRoleRooms) {
|
|
2181
|
+
if (!newRoleRooms.has(room)) {
|
|
2182
|
+
socket.leave(room);
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// Leave public room if was public but now authenticated
|
|
2187
|
+
if (oldAuth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION &&
|
|
2188
|
+
newAuth.executionType !== ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
2189
|
+
socket.leave(WebSocketRoomPrefix.PUBLIC);
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
// === JOIN NEW ROOMS ===
|
|
2193
|
+
|
|
2194
|
+
// Join new user room
|
|
2195
|
+
if (newAuth.initiatorIds?.userId) {
|
|
2196
|
+
socket.join(buildUserRoomName(newAuth.initiatorIds.userId));
|
|
2197
|
+
if (!this.userSockets.has(newAuth.initiatorIds.userId)) {
|
|
2198
|
+
this.userSockets.set(newAuth.initiatorIds.userId, new Set());
|
|
2199
|
+
}
|
|
2200
|
+
this.userSockets.get(newAuth.initiatorIds.userId)!.add(socket.id);
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
// Join new org rooms
|
|
2204
|
+
for (const room of newOrgRooms) {
|
|
2205
|
+
if (!oldOrgRooms.has(room)) {
|
|
2206
|
+
socket.join(room);
|
|
2207
|
+
const orgId = parseOrganizationRoomName(room);
|
|
2208
|
+
if (orgId) {
|
|
2209
|
+
if (!this.organizationSockets.has(orgId)) {
|
|
2210
|
+
this.organizationSockets.set(orgId, new Set());
|
|
2211
|
+
}
|
|
2212
|
+
this.organizationSockets.get(orgId)!.add(socket.id);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
|
|
2217
|
+
// Join new role rooms
|
|
2218
|
+
for (const room of newRoleRooms) {
|
|
2219
|
+
if (!oldRoleRooms.has(room)) {
|
|
2220
|
+
socket.join(room);
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
// Join public room if now public
|
|
2225
|
+
if (newAuth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
2226
|
+
socket.join(WebSocketRoomPrefix.PUBLIC);
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
|
|
2230
|
+
/**
|
|
2231
|
+
* Setup badge handlers (badge:get, badge:get-all)
|
|
2232
|
+
* Enables frontend useBadge and useUserBadges hooks
|
|
2233
|
+
*/
|
|
2234
|
+
private setupBadgeHandlers(socket: Socket): void {
|
|
2235
|
+
// badge:get - Get single badge count
|
|
2236
|
+
socket.on(CoreWebSocketEvent.BADGE_GET, async (
|
|
2237
|
+
payload: { identifier: string; scope: string; scopeId: string },
|
|
2238
|
+
callback?: (response: { count: number }) => void
|
|
2239
|
+
) => {
|
|
2240
|
+
if (!callback) return;
|
|
2241
|
+
|
|
2242
|
+
try {
|
|
2243
|
+
const auth = this.getSocketAuth(socket);
|
|
2244
|
+
// Verify user has access to this scope
|
|
2245
|
+
if (!this.verifyBadgeScopeAccess(auth, payload.scope as ResourcePrimaryScope, payload.scopeId)) {
|
|
2246
|
+
callback({ count: 0 });
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
// Build a minimal execution context for the badge service
|
|
2251
|
+
const appReadOp = this.resourcesRegistry.getOperationFromPath(
|
|
2252
|
+
this.resourcesRegistry.getOperationPathDefault('APPLICATION', CoreResourceOperation.READ)
|
|
2253
|
+
);
|
|
2254
|
+
if (!appReadOp) {
|
|
2255
|
+
callback({ count: 0 });
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
const executionContext = await this.executionContextCreator.buildContextFromSocketAuth(
|
|
2260
|
+
auth,
|
|
2261
|
+
appReadOp,
|
|
2262
|
+
{}
|
|
2263
|
+
);
|
|
2264
|
+
|
|
2265
|
+
const count = await this.getBadgeService().getBadgeCount(
|
|
2266
|
+
executionContext,
|
|
2267
|
+
payload.scope as ResourcePrimaryScope,
|
|
2268
|
+
payload.scopeId,
|
|
2269
|
+
payload.identifier as any
|
|
2270
|
+
);
|
|
2271
|
+
|
|
2272
|
+
callback({ count });
|
|
2273
|
+
} catch (error) {
|
|
2274
|
+
this.logger.warn('Failed to get badge count', {
|
|
2275
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
2276
|
+
});
|
|
2277
|
+
callback({ count: 0 });
|
|
2278
|
+
}
|
|
2279
|
+
});
|
|
2280
|
+
|
|
2281
|
+
// badge:get-all - Get all badges for a scope
|
|
2282
|
+
socket.on(CoreWebSocketEvent.BADGE_GET_ALL, async (
|
|
2283
|
+
payload: { scope: string; scopeId: string },
|
|
2284
|
+
callback?: (response: Array<{ identifier: string; count: number }>) => void
|
|
2285
|
+
) => {
|
|
2286
|
+
if (!callback) return;
|
|
2287
|
+
|
|
2288
|
+
try {
|
|
2289
|
+
const auth = this.getSocketAuth(socket);
|
|
2290
|
+
// Verify user has access to this scope
|
|
2291
|
+
if (!this.verifyBadgeScopeAccess(auth, payload.scope as ResourcePrimaryScope, payload.scopeId)) {
|
|
2292
|
+
callback([]);
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
// Build a minimal execution context for the badge service
|
|
2297
|
+
const appReadOp = this.resourcesRegistry.getOperationFromPath(
|
|
2298
|
+
this.resourcesRegistry.getOperationPathDefault('APPLICATION', CoreResourceOperation.READ)
|
|
2299
|
+
);
|
|
2300
|
+
if (!appReadOp) {
|
|
2301
|
+
callback([]);
|
|
2302
|
+
return;
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
const executionContext = await this.executionContextCreator.buildContextFromSocketAuth(
|
|
2306
|
+
auth,
|
|
2307
|
+
appReadOp,
|
|
2308
|
+
{}
|
|
2309
|
+
);
|
|
2310
|
+
|
|
2311
|
+
const badges = await this.getBadgeService().getAllBadges(
|
|
2312
|
+
executionContext,
|
|
2313
|
+
payload.scope as ResourcePrimaryScope,
|
|
2314
|
+
payload.scopeId
|
|
2315
|
+
);
|
|
2316
|
+
|
|
2317
|
+
callback(badges);
|
|
2318
|
+
} catch (error) {
|
|
2319
|
+
this.logger.warn('Failed to get all badges', {
|
|
2320
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
2321
|
+
});
|
|
2322
|
+
callback([]);
|
|
2323
|
+
}
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
/**
|
|
2328
|
+
* Verify user has access to a badge scope
|
|
2329
|
+
*/
|
|
2330
|
+
private verifyBadgeScopeAccess(
|
|
2331
|
+
auth: SocketAuthResult,
|
|
2332
|
+
scope: ResourcePrimaryScope,
|
|
2333
|
+
scopeId: string
|
|
2334
|
+
): boolean {
|
|
2335
|
+
// Public users cannot access badges
|
|
2336
|
+
if (auth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
2337
|
+
return false;
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
switch (scope) {
|
|
2341
|
+
case ResourcePrimaryScope.USER_SELF:
|
|
2342
|
+
// User can only access their own badges
|
|
2343
|
+
return auth.initiatorIds?.userId === scopeId;
|
|
2344
|
+
|
|
2345
|
+
case ResourcePrimaryScope.ORGANIZATIONS:
|
|
2346
|
+
// User must be member of the organization
|
|
2347
|
+
return auth.initiatorRoles.some(
|
|
2348
|
+
r => r.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS &&
|
|
2349
|
+
r.relatedResourceId === scopeId
|
|
2350
|
+
);
|
|
2351
|
+
|
|
2352
|
+
case ResourcePrimaryScope.APPLICATION:
|
|
2353
|
+
// Application-level badges - check if user has any app roles
|
|
2354
|
+
return auth.initiatorRoles.some(
|
|
2355
|
+
r => r.relatedPrimaryScope === ResourcePrimaryScope.APPLICATION
|
|
2356
|
+
);
|
|
2357
|
+
|
|
2358
|
+
default:
|
|
2359
|
+
return false;
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
// =====================================================
|
|
2364
|
+
// AUTHORIZATION HELPERS (FACTORIZED with HTTP)
|
|
2365
|
+
// =====================================================
|
|
2366
|
+
|
|
2367
|
+
/**
|
|
2368
|
+
* Verify user has READ access to a specific resource
|
|
2369
|
+
*
|
|
2370
|
+
* REUSES: AuthorizationsBackendService.authorizeInController()
|
|
2371
|
+
* This is the EXACT same method used by HTTP controllers
|
|
2372
|
+
*/
|
|
2373
|
+
private async verifyResourceAccess(
|
|
2374
|
+
socket: Socket,
|
|
2375
|
+
auth: SocketAuthResult,
|
|
2376
|
+
resourceType: string,
|
|
2377
|
+
resourceId: string,
|
|
2378
|
+
contextResourceIdentifiers: Record<string, string>
|
|
2379
|
+
): Promise<void> {
|
|
2380
|
+
if (auth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
2381
|
+
throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, undefined, {
|
|
2382
|
+
customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
|
|
2383
|
+
context: { resourceType, resourceId, message: 'Public connections cannot access resources' },
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
await this.authorizeSocketResourceAgainstAnyVariant(
|
|
2388
|
+
auth,
|
|
2389
|
+
resourceType,
|
|
2390
|
+
resourceId,
|
|
2391
|
+
contextResourceIdentifiers,
|
|
2392
|
+
CoreResourceOperation.READ,
|
|
2393
|
+
);
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
/**
|
|
2397
|
+
* Verify user has WRITE access to edit a resource (for editing lock)
|
|
2398
|
+
*
|
|
2399
|
+
* REUSES: AuthorizationsBackendService.authorizeInController() with UPDATE operation
|
|
2400
|
+
*/
|
|
2401
|
+
private async verifyResourceAccessForEdit(
|
|
2402
|
+
socket: Socket,
|
|
2403
|
+
auth: SocketAuthResult,
|
|
2404
|
+
resourceType: string,
|
|
2405
|
+
resourceId: string,
|
|
2406
|
+
contextResourceIdentifiers: Record<string, string>
|
|
2407
|
+
): Promise<void> {
|
|
2408
|
+
if (auth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
2409
|
+
throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, undefined, {
|
|
2410
|
+
customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
|
|
2411
|
+
context: { resourceType, resourceId, message: 'Public connections cannot edit resources' },
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
await this.authorizeSocketResourceAgainstAnyVariant(
|
|
2416
|
+
auth,
|
|
2417
|
+
resourceType,
|
|
2418
|
+
resourceId,
|
|
2419
|
+
contextResourceIdentifiers,
|
|
2420
|
+
CoreResourceOperation.UPDATE,
|
|
2421
|
+
);
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
/**
|
|
2425
|
+
* Verify user has access to a scope (for collection subscriptions)
|
|
2426
|
+
*
|
|
2427
|
+
* REUSES: Role-based check for organization scope, or AuthorizationsBackendService for parent resources
|
|
2428
|
+
*/
|
|
2429
|
+
private async verifyScopeAccess(
|
|
2430
|
+
auth: SocketAuthResult,
|
|
2431
|
+
scopeKey: string,
|
|
2432
|
+
scopeId: string,
|
|
2433
|
+
contextResourceIdentifiers: Record<string, string>
|
|
2434
|
+
): Promise<void> {
|
|
2435
|
+
if (auth.executionType === ExecutionContext_ExecutionType.PUBLIC_EXECUTION) {
|
|
2436
|
+
throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, undefined, {
|
|
2437
|
+
customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
|
|
2438
|
+
context: { scopeKey, scopeId, message: 'Public connections cannot access scoped collections' },
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
const normalizedScopeKey = scopeKey.trim().toLowerCase();
|
|
2443
|
+
|
|
2444
|
+
// For organization scope, just check user has role in that org
|
|
2445
|
+
if (normalizedScopeKey === 'org' || normalizedScopeKey === 'organization' || normalizedScopeKey === 'organizationid') {
|
|
2446
|
+
const hasOrgAccess = auth.initiatorRoles.some(
|
|
2447
|
+
r => r.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS &&
|
|
2448
|
+
r.relatedResourceId === scopeId
|
|
2449
|
+
);
|
|
2450
|
+
if (!hasOrgAccess) {
|
|
2451
|
+
throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, undefined, {
|
|
2452
|
+
customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
|
|
2453
|
+
context: { scopeId, scopeKey, message: 'No access to organization' },
|
|
2454
|
+
});
|
|
2455
|
+
}
|
|
2456
|
+
return;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
// For other scopes (e.g., todolist), verify READ access to the parent resource
|
|
2460
|
+
const parentResourceType = this.mapScopeKeyToResourceType(scopeKey);
|
|
2461
|
+
if (!parentResourceType) {
|
|
2462
|
+
throw this.errorBuilder.buildError(ErrorType.AUTHORIZATION, undefined, {
|
|
2463
|
+
customMessageReference: ErrorCustomMessageReference.AUTHORIZATIONS_ACCESS_DENIED,
|
|
2464
|
+
context: { scopeId, scopeKey, message: 'Unknown or unmapped scope key' },
|
|
2465
|
+
});
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
const scopeResourceId = contextResourceIdentifiers[`${scopeKey}Id`]
|
|
2469
|
+
|| contextResourceIdentifiers[`${normalizedScopeKey}Id`]
|
|
2470
|
+
|| contextResourceIdentifiers[scopeKey]
|
|
2471
|
+
|| contextResourceIdentifiers[normalizedScopeKey]
|
|
2472
|
+
|| scopeId;
|
|
2473
|
+
await this.authorizeSocketResourceAgainstAnyVariant(
|
|
2474
|
+
auth,
|
|
2475
|
+
parentResourceType,
|
|
2476
|
+
scopeResourceId,
|
|
2477
|
+
contextResourceIdentifiers,
|
|
2478
|
+
CoreResourceOperation.READ,
|
|
2479
|
+
{ scopeKey },
|
|
2480
|
+
);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
private getSocketAuthorizationCandidateOperations(
|
|
2484
|
+
resourceType: string,
|
|
2485
|
+
coreOperation: CoreResourceOperation.READ | CoreResourceOperation.UPDATE,
|
|
2486
|
+
): ResourceConfiguration_Operation<any, any, any>[] {
|
|
2487
|
+
const registry = this.resourcesRegistry.getResourcesRegistry();
|
|
2488
|
+
const resourceConfiguration = registry.resourceConfigurations[resourceType];
|
|
2489
|
+
|
|
2490
|
+
if (!resourceConfiguration) {
|
|
2491
|
+
throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {
|
|
2492
|
+
customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_OPERATION_PATH_NOT_FOUND,
|
|
2493
|
+
context: { resourceType, operation: coreOperation },
|
|
2494
|
+
});
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
return resourceConfiguration.operations.filter((operation) => (
|
|
2498
|
+
ResourceOperationsUtils.getCoreResourceOperationFromOperation(operation) === coreOperation
|
|
2499
|
+
&& !('isBulkOperation' in operation && operation.isBulkOperation === true)
|
|
2500
|
+
&& (
|
|
2501
|
+
operation.variantType === ResourceOperationVariantType.API_CALL
|
|
2502
|
+
|| operation.variantType === ResourceOperationVariantType.API_CALL_WITH_CALLBACK
|
|
2503
|
+
)
|
|
2504
|
+
&& 'initiatorInfos' in operation
|
|
2505
|
+
&& Array.isArray(operation.initiatorInfos)
|
|
2506
|
+
&& operation.initiatorInfos.length > 0
|
|
2507
|
+
));
|
|
2508
|
+
}
|
|
2509
|
+
|
|
2510
|
+
private async authorizeSocketResourceAgainstAnyVariant(
|
|
2511
|
+
auth: SocketAuthResult,
|
|
2512
|
+
resourceType: string,
|
|
2513
|
+
resourceId: string,
|
|
2514
|
+
contextResourceIdentifiers: Record<string, string>,
|
|
2515
|
+
coreOperation: CoreResourceOperation.READ | CoreResourceOperation.UPDATE,
|
|
2516
|
+
extraContext?: Record<string, unknown>,
|
|
2517
|
+
): Promise<void> {
|
|
2518
|
+
const candidateOperations = this.getSocketAuthorizationCandidateOperations(resourceType, coreOperation);
|
|
2519
|
+
let lastAuthorizationError: unknown;
|
|
2520
|
+
|
|
2521
|
+
for (const operation of candidateOperations) {
|
|
2522
|
+
try {
|
|
2523
|
+
const executionContext = await this.executionContextCreator.buildContextFromSocketAuth(
|
|
2524
|
+
auth,
|
|
2525
|
+
operation,
|
|
2526
|
+
contextResourceIdentifiers,
|
|
2527
|
+
);
|
|
2528
|
+
|
|
2529
|
+
await this.authorizationsService.authorizeInController(resourceId, executionContext);
|
|
2530
|
+
|
|
2531
|
+
this.logDebug('Socket authorization succeeded with operation variant', {
|
|
2532
|
+
resourceType,
|
|
2533
|
+
resourceId,
|
|
2534
|
+
coreOperation,
|
|
2535
|
+
variantKey: operation.variantKey,
|
|
2536
|
+
isOperationDefault: operation.isOperationDefault,
|
|
2537
|
+
...extraContext,
|
|
2538
|
+
});
|
|
2539
|
+
return;
|
|
2540
|
+
} catch (error) {
|
|
2541
|
+
if (isWildoBackendError(error) && error.type === ErrorType.AUTHORIZATION) {
|
|
2542
|
+
lastAuthorizationError = error;
|
|
2543
|
+
continue;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
throw error;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
if (lastAuthorizationError) {
|
|
2551
|
+
throw lastAuthorizationError;
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
throw this.errorBuilder.buildError(ErrorType.NOT_FOUND, undefined, {
|
|
2555
|
+
customMessageReference: ErrorCustomMessageReference.RESOURCES_REGISTRY_OPERATION_PATH_NOT_FOUND,
|
|
2556
|
+
context: { resourceType, operation: coreOperation, ...extraContext },
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
/**
|
|
2561
|
+
* Map scope key to parent resource type using the resources registry
|
|
2562
|
+
*
|
|
2563
|
+
* Scope keys follow the pattern: fieldIdentifier without 'Id' suffix
|
|
2564
|
+
* E.g., 'todolist' → find resource with fieldIdentifier 'todolistId' → TODOLISTS
|
|
2565
|
+
*
|
|
2566
|
+
* Uses the registry's resource configurations to dynamically resolve
|
|
2567
|
+
* without hardcoded mappings.
|
|
2568
|
+
*/
|
|
2569
|
+
private mapScopeKeyToResourceType(scopeKey: string): string | null {
|
|
2570
|
+
// Build the expected field identifier
|
|
2571
|
+
const fieldIdentifierVariants = [
|
|
2572
|
+
`${scopeKey}Id`, // todolist → todolistId
|
|
2573
|
+
`${scopeKey.toLowerCase()}Id`, // TodoList → todolistid (case insensitive)
|
|
2574
|
+
];
|
|
2575
|
+
|
|
2576
|
+
// Search through all resource configurations
|
|
2577
|
+
const registry = this.resourcesRegistry.getResourcesRegistry();
|
|
2578
|
+
const resourceTypes = Object.keys(registry.resourceConfigurations);
|
|
2579
|
+
|
|
2580
|
+
for (const resourceType of resourceTypes) {
|
|
2581
|
+
const config = registry.resourceConfigurations[resourceType];
|
|
2582
|
+
const configFieldId = config.resourceFieldIdentifier?.toLowerCase();
|
|
2583
|
+
|
|
2584
|
+
for (const variant of fieldIdentifierVariants) {
|
|
2585
|
+
if (configFieldId === variant.toLowerCase()) {
|
|
2586
|
+
return resourceType;
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
// Also check if scopeKey is itself a resource type (direct match)
|
|
2592
|
+
if (registry.resourceConfigurations[scopeKey]) {
|
|
2593
|
+
return scopeKey;
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
// Check for case-insensitive resource type match
|
|
2597
|
+
const lowerScopeKey = scopeKey.toLowerCase();
|
|
2598
|
+
for (const resourceType of resourceTypes) {
|
|
2599
|
+
if (resourceType.toLowerCase() === lowerScopeKey) {
|
|
2600
|
+
return resourceType;
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
this.logDebug('Could not map scope key to resource type', { scopeKey });
|
|
2605
|
+
return null;
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
// =====================================================
|
|
2609
|
+
// EDITING STATE TRACKING (Redis-backed for multi-pod)
|
|
2610
|
+
// =====================================================
|
|
2611
|
+
|
|
2612
|
+
/**
|
|
2613
|
+
* Track editing state in Redis for cross-pod synchronization
|
|
2614
|
+
*/
|
|
2615
|
+
private async trackEditingState(
|
|
2616
|
+
resourceType: string,
|
|
2617
|
+
resourceId: string,
|
|
2618
|
+
userId: string,
|
|
2619
|
+
action: 'start' | 'end'
|
|
2620
|
+
): Promise<void> {
|
|
2621
|
+
const prefix = this.redisService.getAppPrefix();
|
|
2622
|
+
const key = `${prefix}editing:${resourceType}:${resourceId}`;
|
|
2623
|
+
const redisClient = this.redisService.getClient();
|
|
2624
|
+
|
|
2625
|
+
if (!redisClient) {
|
|
2626
|
+
// Fallback to in-memory if Redis unavailable
|
|
2627
|
+
if (action === 'start') {
|
|
2628
|
+
if (!this.resourceEditingState.has(key)) {
|
|
2629
|
+
this.resourceEditingState.set(key, new Set());
|
|
2630
|
+
}
|
|
2631
|
+
this.resourceEditingState.get(key)!.add(userId);
|
|
2632
|
+
} else {
|
|
2633
|
+
this.resourceEditingState.get(key)?.delete(userId);
|
|
2634
|
+
}
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
try {
|
|
2639
|
+
if (action === 'start') {
|
|
2640
|
+
await redisClient.hSet(key, userId, new Date().toISOString());
|
|
2641
|
+
await redisClient.expire(key, 3600); // 1 hour TTL (cleanup stale locks)
|
|
2642
|
+
} else {
|
|
2643
|
+
await redisClient.hDel(key, userId);
|
|
2644
|
+
}
|
|
2645
|
+
} catch (error) {
|
|
2646
|
+
this.logger.warn('Failed to track editing state in Redis', {
|
|
2647
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
2648
|
+
resourceType,
|
|
2649
|
+
resourceId: resourceId.substring(0, 8)
|
|
2650
|
+
});
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
/**
|
|
2655
|
+
* Cleanup editing states when user disconnects
|
|
2656
|
+
* Cleans both in-memory state AND Redis for immediate consistency across pods
|
|
2657
|
+
*
|
|
2658
|
+
* CROSS-POD SUPPORT: Uses Redis SCAN to find all editing keys across all pods
|
|
2659
|
+
* where this user is editing, ensuring complete cleanup.
|
|
2660
|
+
*/
|
|
2661
|
+
private async cleanupEditingStatesForUser(userId: string): Promise<void> {
|
|
2662
|
+
if (!userId) return;
|
|
2663
|
+
|
|
2664
|
+
const redisClient = this.redisService.getClient();
|
|
2665
|
+
|
|
2666
|
+
// Cleanup in-memory state on this pod
|
|
2667
|
+
for (const [key, users] of this.resourceEditingState.entries()) {
|
|
2668
|
+
if (users.has(userId)) {
|
|
2669
|
+
users.delete(userId);
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
// Cross-pod cleanup: SCAN Redis for all editing:* keys where this user is editing
|
|
2674
|
+
if (redisClient) {
|
|
2675
|
+
try {
|
|
2676
|
+
await this.cleanupUserEditingStatesFromRedis(redisClient, userId);
|
|
2677
|
+
} catch (error) {
|
|
2678
|
+
this.logger.warn('Failed to cleanup Redis editing states on disconnect', {
|
|
2679
|
+
userId: userId.substring(0, 8),
|
|
2680
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
/**
|
|
2687
|
+
* SCAN Redis for all editing:* keys and remove the user from each
|
|
2688
|
+
* Also broadcasts editing:end to affected resource rooms
|
|
2689
|
+
*
|
|
2690
|
+
* Key format: {appPrefix}editing:{resourceType}:{resourceId}
|
|
2691
|
+
* Example: "wildo-ai-app_local:editing:users:user456"
|
|
2692
|
+
*/
|
|
2693
|
+
private async cleanupUserEditingStatesFromRedis(
|
|
2694
|
+
redisClient: ReturnType<typeof this.redisService.getClient>,
|
|
2695
|
+
userId: string
|
|
2696
|
+
): Promise<void> {
|
|
2697
|
+
if (!redisClient) return;
|
|
2698
|
+
|
|
2699
|
+
let cursor: string = '0';
|
|
2700
|
+
const cleanedResources: Array<{ resourceType: string; resourceId: string }> = [];
|
|
2701
|
+
const prefix = this.redisService.getAppPrefix();
|
|
2702
|
+
|
|
2703
|
+
// SCAN for all editing:* keys scoped to this application
|
|
2704
|
+
do {
|
|
2705
|
+
const result = await redisClient.scan(cursor, {
|
|
2706
|
+
MATCH: `${prefix}editing:*`,
|
|
2707
|
+
COUNT: 100, // Process in batches
|
|
2708
|
+
});
|
|
2709
|
+
|
|
2710
|
+
cursor = result.cursor;
|
|
2711
|
+
const keys = result.keys;
|
|
2712
|
+
|
|
2713
|
+
// Check each key for this user and remove if present
|
|
2714
|
+
for (const key of keys) {
|
|
2715
|
+
try {
|
|
2716
|
+
// Check if user is in this hash
|
|
2717
|
+
const exists = await redisClient.hExists(key, userId);
|
|
2718
|
+
if (exists) {
|
|
2719
|
+
// Remove user from this editing state
|
|
2720
|
+
await redisClient.hDel(key, userId);
|
|
2721
|
+
|
|
2722
|
+
// Parse key to get resource info
|
|
2723
|
+
// Key format: {prefix}editing:{resourceType}:{resourceId}
|
|
2724
|
+
// Remove prefix first, then parse
|
|
2725
|
+
const keyWithoutPrefix = prefix && key.startsWith(prefix)
|
|
2726
|
+
? key.slice(prefix.length)
|
|
2727
|
+
: key;
|
|
2728
|
+
const parts = keyWithoutPrefix.split(':');
|
|
2729
|
+
|
|
2730
|
+
// parts[0] = "editing", parts[1] = resourceType, parts[2] = resourceId
|
|
2731
|
+
if (parts.length >= 3 && parts[0] === 'editing') {
|
|
2732
|
+
cleanedResources.push({
|
|
2733
|
+
resourceType: parts[1],
|
|
2734
|
+
resourceId: parts[2],
|
|
2735
|
+
});
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
} catch (error) {
|
|
2739
|
+
this.logger.warn('Failed to check/delete editing state for key', {
|
|
2740
|
+
key,
|
|
2741
|
+
userId: userId.substring(0, 8),
|
|
2742
|
+
error: error instanceof Error ? error.message : 'Unknown',
|
|
2743
|
+
});
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
} while (cursor !== '0');
|
|
2747
|
+
|
|
2748
|
+
// Broadcast editing:end to all affected resource rooms
|
|
2749
|
+
for (const resource of cleanedResources) {
|
|
2750
|
+
const roomName = buildResourceRoomName(resource.resourceType, resource.resourceId);
|
|
2751
|
+
this.io?.to(roomName).emit(CoreWebSocketEvent.RESOURCE_EDITING_END, {
|
|
2752
|
+
resourceType: resource.resourceType,
|
|
2753
|
+
resourceId: resource.resourceId,
|
|
2754
|
+
initiatorUserId: userId,
|
|
2755
|
+
reason: 'disconnect',
|
|
2756
|
+
timestamp: new Date(),
|
|
2757
|
+
});
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
if (cleanedResources.length > 0) {
|
|
2761
|
+
this.logDebug('Cleaned up editing states for disconnected user', {
|
|
2762
|
+
userId: userId.substring(0, 8),
|
|
2763
|
+
cleanedCount: cleanedResources.length,
|
|
2764
|
+
});
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
// =====================================================
|
|
2769
|
+
// DISCONNECTION HANDLING
|
|
2770
|
+
// =====================================================
|
|
2771
|
+
|
|
2772
|
+
/**
|
|
2773
|
+
* Handle socket disconnection - cleanup state and notify rooms
|
|
2774
|
+
*/
|
|
2775
|
+
private handleSocketDisconnection(socketId: string, auth: SocketAuthResult): void {
|
|
2776
|
+
// Remove from authenticated sockets
|
|
2777
|
+
this.authenticatedSockets.delete(socketId);
|
|
2778
|
+
this.resourceSubscriptionsBySocket.delete(socketId);
|
|
2779
|
+
|
|
2780
|
+
const userId = auth.initiatorIds?.userId;
|
|
2781
|
+
|
|
2782
|
+
if (userId) {
|
|
2783
|
+
// Remove from user sockets tracking
|
|
2784
|
+
const userSocketIds = this.userSockets.get(userId);
|
|
2785
|
+
if (userSocketIds) {
|
|
2786
|
+
userSocketIds.delete(socketId);
|
|
2787
|
+
if (userSocketIds.size === 0) {
|
|
2788
|
+
this.userSockets.delete(userId);
|
|
2789
|
+
|
|
2790
|
+
// User completely disconnected - cleanup editing states
|
|
2791
|
+
this.cleanupEditingStatesForUser(userId);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
// Remove from organization sockets
|
|
2797
|
+
for (const roleInfo of auth.initiatorRoles) {
|
|
2798
|
+
if (roleInfo.relatedPrimaryScope === ResourcePrimaryScope.ORGANIZATIONS && roleInfo.relatedResourceId) {
|
|
2799
|
+
const orgSocketIds = this.organizationSockets.get(roleInfo.relatedResourceId);
|
|
2800
|
+
if (orgSocketIds) {
|
|
2801
|
+
orgSocketIds.delete(socketId);
|
|
2802
|
+
if (orgSocketIds.size === 0) {
|
|
2803
|
+
this.organizationSockets.delete(roleInfo.relatedResourceId);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
this.logDebug('Socket disconnected', {
|
|
2810
|
+
socketId,
|
|
2811
|
+
userId: userId?.substring(0, 8),
|
|
2812
|
+
remainingConnections: this.authenticatedSockets.size
|
|
2813
|
+
});
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
// =====================================================
|
|
2817
|
+
// CLEANUP
|
|
2818
|
+
// =====================================================
|
|
2819
|
+
|
|
2820
|
+
/**
|
|
2821
|
+
* Cleanup resources
|
|
2822
|
+
*/
|
|
2823
|
+
public async cleanup(): Promise<void> {
|
|
2824
|
+
try {
|
|
2825
|
+
if (this.io) {
|
|
2826
|
+
this.io.close();
|
|
2827
|
+
this.io = null;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
this.authenticatedSockets.clear();
|
|
2831
|
+
this.userSockets.clear();
|
|
2832
|
+
this.organizationSockets.clear();
|
|
2833
|
+
this.rooms.clear();
|
|
2834
|
+
this.resourceEditingState.clear();
|
|
2835
|
+
this.resourceSubscriptionsBySocket.clear();
|
|
2836
|
+
|
|
2837
|
+
this.logDebug('WebSocket service cleanup completed');
|
|
2838
|
+
|
|
2839
|
+
} catch (error: unknown) {
|
|
2840
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
2841
|
+
this.logger.error('Error during WebSocket cleanup', { error: errorMessage });
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
}
|