synapse-mcp 1.0.0 → 1.0.2
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/README.md +1820 -147
- package/dist/constants.d.ts +10 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +18 -8
- package/dist/constants.js.map +1 -1
- package/dist/events/emitter.d.ts +63 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +112 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +3 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +51 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +3 -0
- package/dist/events/types.js.map +1 -0
- package/dist/formatters/compose.d.ts +185 -0
- package/dist/formatters/compose.d.ts.map +1 -0
- package/dist/formatters/compose.js +397 -0
- package/dist/formatters/compose.js.map +1 -0
- package/dist/formatters/container.d.ts +84 -0
- package/dist/formatters/container.d.ts.map +1 -0
- package/dist/formatters/container.js +323 -0
- package/dist/formatters/container.js.map +1 -0
- package/dist/formatters/diagnostics.d.ts +20 -0
- package/dist/formatters/diagnostics.d.ts.map +1 -0
- package/dist/formatters/diagnostics.js +73 -0
- package/dist/formatters/diagnostics.js.map +1 -0
- package/dist/formatters/docker.d.ts +139 -0
- package/dist/formatters/docker.d.ts.map +1 -0
- package/dist/formatters/docker.js +216 -0
- package/dist/formatters/docker.js.map +1 -0
- package/dist/formatters/host.d.ts +137 -0
- package/dist/formatters/host.d.ts.map +1 -0
- package/dist/formatters/host.js +198 -0
- package/dist/formatters/host.js.map +1 -0
- package/dist/formatters/index.d.ts +17 -270
- package/dist/formatters/index.d.ts.map +1 -1
- package/dist/formatters/index.js +21 -456
- package/dist/formatters/index.js.map +1 -1
- package/dist/formatters/scout.d.ts +424 -0
- package/dist/formatters/scout.d.ts.map +1 -0
- package/dist/formatters/scout.js +687 -0
- package/dist/formatters/scout.js.map +1 -0
- package/dist/formatters/strategy.d.ts +105 -0
- package/dist/formatters/strategy.d.ts.map +1 -0
- package/dist/formatters/strategy.js +120 -0
- package/dist/formatters/strategy.js.map +1 -0
- package/dist/formatters/utils.d.ts +84 -0
- package/dist/formatters/utils.d.ts.map +1 -0
- package/dist/formatters/utils.js +129 -0
- package/dist/formatters/utils.js.map +1 -0
- package/dist/health-rate-limiter.d.ts +59 -0
- package/dist/health-rate-limiter.d.ts.map +1 -0
- package/dist/health-rate-limiter.js +159 -0
- package/dist/health-rate-limiter.js.map +1 -0
- package/dist/index.js +61 -100
- package/dist/index.js.map +1 -1
- package/dist/middleware/async-handler.d.ts +62 -0
- package/dist/middleware/async-handler.d.ts.map +1 -0
- package/dist/middleware/async-handler.js +58 -0
- package/dist/middleware/async-handler.js.map +1 -0
- package/dist/middleware/auth.d.ts +32 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +63 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/csrf-protection.d.ts +58 -0
- package/dist/middleware/csrf-protection.d.ts.map +1 -0
- package/dist/middleware/csrf-protection.js +123 -0
- package/dist/middleware/csrf-protection.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +49 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +90 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/error-mapper.d.ts +44 -0
- package/dist/middleware/error-mapper.d.ts.map +1 -0
- package/dist/middleware/error-mapper.js +127 -0
- package/dist/middleware/error-mapper.js.map +1 -0
- package/dist/middleware/index.d.ts +13 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +13 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/request-id.d.ts +22 -0
- package/dist/middleware/request-id.d.ts.map +1 -0
- package/dist/middleware/request-id.js +31 -0
- package/dist/middleware/request-id.js.map +1 -0
- package/dist/middleware/types.d.ts +33 -0
- package/dist/middleware/types.d.ts.map +1 -0
- package/dist/middleware/types.js +2 -0
- package/dist/middleware/types.js.map +1 -0
- package/dist/schemas/common.d.ts +205 -8
- package/dist/schemas/common.d.ts.map +1 -1
- package/dist/schemas/common.js +290 -17
- package/dist/schemas/common.js.map +1 -1
- package/dist/schemas/flux/compose.d.ts +307 -44
- package/dist/schemas/flux/compose.d.ts.map +1 -1
- package/dist/schemas/flux/compose.js +74 -48
- package/dist/schemas/flux/compose.js.map +1 -1
- package/dist/schemas/flux/container.d.ts +423 -56
- package/dist/schemas/flux/container.d.ts.map +1 -1
- package/dist/schemas/flux/container.js +83 -61
- package/dist/schemas/flux/container.js.map +1 -1
- package/dist/schemas/flux/docker.d.ts +254 -37
- package/dist/schemas/flux/docker.d.ts.map +1 -1
- package/dist/schemas/flux/docker.js +69 -39
- package/dist/schemas/flux/docker.js.map +1 -1
- package/dist/schemas/flux/host.d.ts +312 -29
- package/dist/schemas/flux/host.d.ts.map +1 -1
- package/dist/schemas/flux/host.js +74 -31
- package/dist/schemas/flux/host.js.map +1 -1
- package/dist/schemas/flux/index.d.ts +503 -11
- package/dist/schemas/flux/index.d.ts.map +1 -1
- package/dist/schemas/flux/index.js +34 -70
- package/dist/schemas/flux/index.js.map +1 -1
- package/dist/schemas/host-config.d.ts +76 -0
- package/dist/schemas/host-config.d.ts.map +1 -0
- package/dist/schemas/host-config.js +105 -0
- package/dist/schemas/host-config.js.map +1 -0
- package/dist/schemas/scout/index.d.ts +80 -23
- package/dist/schemas/scout/index.d.ts.map +1 -1
- package/dist/schemas/scout/index.js +26 -11
- package/dist/schemas/scout/index.js.map +1 -1
- package/dist/schemas/scout/logs.d.ts +17 -5
- package/dist/schemas/scout/logs.d.ts.map +1 -1
- package/dist/schemas/scout/logs.js +41 -31
- package/dist/schemas/scout/logs.js.map +1 -1
- package/dist/schemas/scout/simple.d.ts +126 -11
- package/dist/schemas/scout/simple.d.ts.map +1 -1
- package/dist/schemas/scout/simple.js +112 -57
- package/dist/schemas/scout/simple.js.map +1 -1
- package/dist/schemas/scout/zfs.d.ts +17 -5
- package/dist/schemas/scout/zfs.d.ts.map +1 -1
- package/dist/schemas/scout/zfs.js +34 -25
- package/dist/schemas/scout/zfs.js.map +1 -1
- package/dist/services/cache-layer.d.ts +160 -0
- package/dist/services/cache-layer.d.ts.map +1 -0
- package/dist/services/cache-layer.js +138 -0
- package/dist/services/cache-layer.js.map +1 -0
- package/dist/services/compose-cache.d.ts +75 -0
- package/dist/services/compose-cache.d.ts.map +1 -0
- package/dist/services/compose-cache.js +178 -0
- package/dist/services/compose-cache.js.map +1 -0
- package/dist/services/compose-discovery.d.ts +46 -0
- package/dist/services/compose-discovery.d.ts.map +1 -0
- package/dist/services/compose-discovery.js +219 -0
- package/dist/services/compose-discovery.js.map +1 -0
- package/dist/services/compose-project-lister.d.ts +27 -0
- package/dist/services/compose-project-lister.d.ts.map +1 -0
- package/dist/services/compose-project-lister.js +71 -0
- package/dist/services/compose-project-lister.js.map +1 -0
- package/dist/services/compose-scanner.d.ts +63 -0
- package/dist/services/compose-scanner.d.ts.map +1 -0
- package/dist/services/compose-scanner.js +253 -0
- package/dist/services/compose-scanner.js.map +1 -0
- package/dist/services/compose.d.ts +64 -28
- package/dist/services/compose.d.ts.map +1 -1
- package/dist/services/compose.js +220 -98
- package/dist/services/compose.js.map +1 -1
- package/dist/services/config-loader.d.ts +23 -0
- package/dist/services/config-loader.d.ts.map +1 -0
- package/dist/services/config-loader.js +124 -0
- package/dist/services/config-loader.js.map +1 -0
- package/dist/services/config-service.d.ts +38 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +225 -0
- package/dist/services/config-service.js.map +1 -0
- package/dist/services/container-host-map-cache.d.ts +121 -0
- package/dist/services/container-host-map-cache.d.ts.map +1 -0
- package/dist/services/container-host-map-cache.js +188 -0
- package/dist/services/container-host-map-cache.js.map +1 -0
- package/dist/services/container.d.ts +194 -6
- package/dist/services/container.d.ts.map +1 -1
- package/dist/services/container.js +386 -11
- package/dist/services/container.js.map +1 -1
- package/dist/services/diagnostics.d.ts +57 -0
- package/dist/services/diagnostics.d.ts.map +1 -0
- package/dist/services/diagnostics.js +271 -0
- package/dist/services/diagnostics.js.map +1 -0
- package/dist/services/docker/container-service.d.ts +123 -0
- package/dist/services/docker/container-service.d.ts.map +1 -0
- package/dist/services/docker/container-service.js +347 -0
- package/dist/services/docker/container-service.js.map +1 -0
- package/dist/services/docker/image-service.d.ts +82 -0
- package/dist/services/docker/image-service.d.ts.map +1 -0
- package/dist/services/docker/image-service.js +193 -0
- package/dist/services/docker/image-service.js.map +1 -0
- package/dist/services/docker/index.d.ts +80 -0
- package/dist/services/docker/index.d.ts.map +1 -0
- package/dist/services/docker/index.js +103 -0
- package/dist/services/docker/index.js.map +1 -0
- package/dist/services/docker/network-service.d.ts +22 -0
- package/dist/services/docker/network-service.d.ts.map +1 -0
- package/dist/services/docker/network-service.js +43 -0
- package/dist/services/docker/network-service.js.map +1 -0
- package/dist/services/docker/system-service.d.ts +49 -0
- package/dist/services/docker/system-service.d.ts.map +1 -0
- package/dist/services/docker/system-service.js +215 -0
- package/dist/services/docker/system-service.js.map +1 -0
- package/dist/services/docker/utils/client-factory.d.ts +56 -0
- package/dist/services/docker/utils/client-factory.d.ts.map +1 -0
- package/dist/services/docker/utils/client-factory.js +139 -0
- package/dist/services/docker/utils/client-factory.js.map +1 -0
- package/dist/services/docker/utils/client-manager.d.ts +88 -0
- package/dist/services/docker/utils/client-manager.d.ts.map +1 -0
- package/dist/services/docker/utils/client-manager.js +124 -0
- package/dist/services/docker/utils/client-manager.js.map +1 -0
- package/dist/services/docker/utils/exec-handler.d.ts +94 -0
- package/dist/services/docker/utils/exec-handler.d.ts.map +1 -0
- package/dist/services/docker/utils/exec-handler.js +197 -0
- package/dist/services/docker/utils/exec-handler.js.map +1 -0
- package/dist/services/docker/utils/formatters.d.ts +13 -0
- package/dist/services/docker/utils/formatters.d.ts.map +1 -0
- package/dist/services/docker/utils/formatters.js +33 -0
- package/dist/services/docker/utils/formatters.js.map +1 -0
- package/dist/services/docker/utils/log-parser.d.ts +10 -0
- package/dist/services/docker/utils/log-parser.d.ts.map +1 -0
- package/dist/services/docker/utils/log-parser.js +48 -0
- package/dist/services/docker/utils/log-parser.js.map +1 -0
- package/dist/services/docker/utils/stats-calculator.d.ts +68 -0
- package/dist/services/docker/utils/stats-calculator.d.ts.map +1 -0
- package/dist/services/docker/utils/stats-calculator.js +61 -0
- package/dist/services/docker/utils/stats-calculator.js.map +1 -0
- package/dist/services/docker/volume-service.d.ts +22 -0
- package/dist/services/docker/volume-service.d.ts.map +1 -0
- package/dist/services/docker/volume-service.js +48 -0
- package/dist/services/docker/volume-service.js.map +1 -0
- package/dist/services/docker-interfaces.d.ts +283 -0
- package/dist/services/docker-interfaces.d.ts.map +1 -0
- package/dist/services/docker-interfaces.js +13 -0
- package/dist/services/docker-interfaces.js.map +1 -0
- package/dist/services/docker.d.ts +42 -5
- package/dist/services/docker.d.ts.map +1 -1
- package/dist/services/docker.js +335 -127
- package/dist/services/docker.js.map +1 -1
- package/dist/services/file-service.d.ts +6 -2
- package/dist/services/file-service.d.ts.map +1 -1
- package/dist/services/file-service.js +156 -52
- package/dist/services/file-service.js.map +1 -1
- package/dist/services/host-config-repository.d.ts +133 -0
- package/dist/services/host-config-repository.d.ts.map +1 -0
- package/dist/services/host-config-repository.js +323 -0
- package/dist/services/host-config-repository.js.map +1 -0
- package/dist/services/host-resolver.d.ts +49 -0
- package/dist/services/host-resolver.d.ts.map +1 -0
- package/dist/services/host-resolver.js +176 -0
- package/dist/services/host-resolver.js.map +1 -0
- package/dist/services/interfaces.d.ts +61 -194
- package/dist/services/interfaces.d.ts.map +1 -1
- package/dist/services/local-executor.d.ts +31 -0
- package/dist/services/local-executor.d.ts.map +1 -0
- package/dist/services/local-executor.js +71 -0
- package/dist/services/local-executor.js.map +1 -0
- package/dist/services/ssh-config-loader.d.ts +35 -0
- package/dist/services/ssh-config-loader.d.ts.map +1 -0
- package/dist/services/ssh-config-loader.js +218 -0
- package/dist/services/ssh-config-loader.js.map +1 -0
- package/dist/services/ssh-pool.d.ts +26 -1
- package/dist/services/ssh-pool.d.ts.map +1 -1
- package/dist/services/ssh-pool.js +166 -25
- package/dist/services/ssh-pool.js.map +1 -1
- package/dist/services/ssh-service.d.ts +3 -0
- package/dist/services/ssh-service.d.ts.map +1 -1
- package/dist/services/ssh-service.js +53 -31
- package/dist/services/ssh-service.js.map +1 -1
- package/dist/services/ssh.d.ts +2 -6
- package/dist/services/ssh.d.ts.map +1 -1
- package/dist/services/ssh.js +9 -40
- package/dist/services/ssh.js.map +1 -1
- package/dist/tools/definitions/flux.d.ts +13 -0
- package/dist/tools/definitions/flux.d.ts.map +1 -0
- package/dist/tools/definitions/flux.js +101 -0
- package/dist/tools/definitions/flux.js.map +1 -0
- package/dist/tools/definitions/index.d.ts +8 -0
- package/dist/tools/definitions/index.d.ts.map +1 -0
- package/dist/tools/definitions/index.js +8 -0
- package/dist/tools/definitions/index.js.map +1 -0
- package/dist/tools/definitions/scout.d.ts +13 -0
- package/dist/tools/definitions/scout.d.ts.map +1 -0
- package/dist/tools/definitions/scout.js +78 -0
- package/dist/tools/definitions/scout.js.map +1 -0
- package/dist/tools/flux.d.ts +16 -8
- package/dist/tools/flux.d.ts.map +1 -1
- package/dist/tools/flux.js +27 -66
- package/dist/tools/flux.js.map +1 -1
- package/dist/tools/handlers/base-handler.d.ts +172 -0
- package/dist/tools/handlers/base-handler.d.ts.map +1 -0
- package/dist/tools/handlers/base-handler.js +234 -0
- package/dist/tools/handlers/base-handler.js.map +1 -0
- package/dist/tools/handlers/compose-handlers.d.ts +108 -0
- package/dist/tools/handlers/compose-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/compose-handlers.js +293 -0
- package/dist/tools/handlers/compose-handlers.js.map +1 -0
- package/dist/tools/handlers/compose-utils.d.ts +35 -0
- package/dist/tools/handlers/compose-utils.d.ts.map +1 -0
- package/dist/tools/handlers/compose-utils.js +76 -0
- package/dist/tools/handlers/compose-utils.js.map +1 -0
- package/dist/tools/handlers/compose.d.ts +23 -0
- package/dist/tools/handlers/compose.d.ts.map +1 -0
- package/dist/tools/handlers/compose.js +125 -0
- package/dist/tools/handlers/compose.js.map +1 -0
- package/dist/tools/handlers/container.d.ts +23 -0
- package/dist/tools/handlers/container.d.ts.map +1 -0
- package/dist/tools/handlers/container.js +333 -0
- package/dist/tools/handlers/container.js.map +1 -0
- package/dist/tools/handlers/docker.d.ts +24 -0
- package/dist/tools/handlers/docker.d.ts.map +1 -0
- package/dist/tools/handlers/docker.js +155 -0
- package/dist/tools/handlers/docker.js.map +1 -0
- package/dist/tools/handlers/host.d.ts +23 -0
- package/dist/tools/handlers/host.d.ts.map +1 -0
- package/dist/tools/handlers/host.js +196 -0
- package/dist/tools/handlers/host.js.map +1 -0
- package/dist/tools/handlers/scout-logs.d.ts +24 -0
- package/dist/tools/handlers/scout-logs.d.ts.map +1 -0
- package/dist/tools/handlers/scout-logs.js +119 -0
- package/dist/tools/handlers/scout-logs.js.map +1 -0
- package/dist/tools/handlers/scout-simple.d.ts +23 -0
- package/dist/tools/handlers/scout-simple.d.ts.map +1 -0
- package/dist/tools/handlers/scout-simple.js +286 -0
- package/dist/tools/handlers/scout-simple.js.map +1 -0
- package/dist/tools/handlers/scout-zfs.d.ts +23 -0
- package/dist/tools/handlers/scout-zfs.d.ts.map +1 -0
- package/dist/tools/handlers/scout-zfs.js +82 -0
- package/dist/tools/handlers/scout-zfs.js.map +1 -0
- package/dist/tools/index.d.ts +32 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +41 -35
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/registry.d.ts +135 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +151 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/scout.d.ts +16 -8
- package/dist/tools/scout.d.ts.map +1 -1
- package/dist/tools/scout.js +36 -78
- package/dist/tools/scout.js.map +1 -1
- package/dist/types.d.ts +629 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/command-security.d.ts +82 -0
- package/dist/utils/command-security.d.ts.map +1 -0
- package/dist/utils/command-security.js +122 -0
- package/dist/utils/command-security.js.map +1 -0
- package/dist/utils/error-sanitization.d.ts +77 -0
- package/dist/utils/error-sanitization.d.ts.map +1 -0
- package/dist/utils/error-sanitization.js +107 -0
- package/dist/utils/error-sanitization.js.map +1 -0
- package/dist/utils/errors.d.ts +30 -6
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +91 -12
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/help-handler.d.ts +23 -0
- package/dist/utils/help-handler.d.ts.map +1 -0
- package/dist/utils/help-handler.js +21 -0
- package/dist/utils/help-handler.js.map +1 -0
- package/dist/utils/help.d.ts +1 -1
- package/dist/utils/help.d.ts.map +1 -1
- package/dist/utils/help.js +57 -16
- package/dist/utils/help.js.map +1 -1
- package/dist/utils/host-utils.d.ts +31 -0
- package/dist/utils/host-utils.d.ts.map +1 -0
- package/dist/utils/host-utils.js +80 -0
- package/dist/utils/host-utils.js.map +1 -0
- package/dist/utils/index.d.ts +8 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +8 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/init-detection.d.ts +36 -0
- package/dist/utils/init-detection.d.ts.map +1 -0
- package/dist/utils/init-detection.js +79 -0
- package/dist/utils/init-detection.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +32 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/pagination.d.ts +20 -0
- package/dist/utils/pagination.d.ts.map +1 -0
- package/dist/utils/pagination.js +29 -0
- package/dist/utils/pagination.js.map +1 -0
- package/dist/utils/path-security.d.ts +132 -18
- package/dist/utils/path-security.d.ts.map +1 -1
- package/dist/utils/path-security.js +164 -35
- package/dist/utils/path-security.js.map +1 -1
- package/dist/utils/sorting.d.ts +33 -0
- package/dist/utils/sorting.d.ts.map +1 -0
- package/dist/utils/sorting.js +57 -0
- package/dist/utils/sorting.js.map +1 -0
- package/dist/utils/text-filters.d.ts +13 -0
- package/dist/utils/text-filters.d.ts.map +1 -0
- package/dist/utils/text-filters.js +18 -0
- package/dist/utils/text-filters.js.map +1 -0
- package/dist/utils/time.d.ts +11 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +13 -0
- package/dist/utils/time.js.map +1 -0
- package/dist/utils/validation.d.ts +25 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +56 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +45 -19
- package/dist/schemas/discriminator.d.ts +0 -20
- package/dist/schemas/discriminator.d.ts.map +0 -1
- package/dist/schemas/discriminator.js +0 -25
- package/dist/schemas/discriminator.js.map +0 -1
- package/dist/schemas/unified.d.ts +0 -674
- package/dist/schemas/unified.d.ts.map +0 -1
- package/dist/schemas/unified.js +0 -453
- package/dist/schemas/unified.js.map +0 -1
- package/dist/tools/unified.d.ts +0 -7
- package/dist/tools/unified.d.ts.map +0 -1
- package/dist/tools/unified.js +0 -827
- package/dist/tools/unified.js.map +0 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from "express";
|
|
2
|
+
/**
|
|
3
|
+
* CSRF Protection Middleware
|
|
4
|
+
*
|
|
5
|
+
* Security: Prevents CWE-352 (Cross-Site Request Forgery) by requiring a custom header
|
|
6
|
+
* that browsers cannot send from cross-origin contexts without CORS preflight approval.
|
|
7
|
+
* @see https://cwe.mitre.org/data/definitions/352.html
|
|
8
|
+
*
|
|
9
|
+
* SECURITY (S-M6, CWE-352, CVSS 3.7): Defense-in-Depth CSRF Protection
|
|
10
|
+
* ---------------------------------------------------------------------
|
|
11
|
+
* This middleware implements the OWASP recommended "Custom Request Headers" pattern
|
|
12
|
+
* for CSRF protection in REST APIs.
|
|
13
|
+
* @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#use-of-custom-request-headers
|
|
14
|
+
*
|
|
15
|
+
* **How It Works:**
|
|
16
|
+
* 1. Requires X-Synapse-Client header on all requests
|
|
17
|
+
* 2. Custom headers trigger CORS preflight (OPTIONS request)
|
|
18
|
+
* 3. Server only approves preflight for trusted origins (or none)
|
|
19
|
+
* 4. Browsers won't send custom headers without preflight success
|
|
20
|
+
* 5. Malicious sites cannot forge requests with custom headers
|
|
21
|
+
*
|
|
22
|
+
* **Why This Works:**
|
|
23
|
+
* - Simple cross-origin requests (no custom headers) bypass preflight
|
|
24
|
+
* - But custom headers ALWAYS trigger preflight (browser security model)
|
|
25
|
+
* - Attacker sites cannot complete preflight to untrusted server
|
|
26
|
+
* - Therefore attacker cannot send X-Synapse-Client header
|
|
27
|
+
* - Requests without header are rejected by this middleware
|
|
28
|
+
*
|
|
29
|
+
* **Additional Protection:**
|
|
30
|
+
* - Sets restrictive CORS headers (Access-Control-Allow-Origin: null by default)
|
|
31
|
+
* - Optional SYNAPSE_ALLOWED_ORIGINS for trusted web clients
|
|
32
|
+
* - Only allows POST method
|
|
33
|
+
*
|
|
34
|
+
* **Complements Existing Security:**
|
|
35
|
+
* - X-API-Key authentication (S-C1) prevents unauthorized access
|
|
36
|
+
* - X-Synapse-Client header (S-M6) prevents CSRF from authenticated sessions
|
|
37
|
+
* - Together: Defense-in-depth against both direct attacks and CSRF
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Server setup
|
|
42
|
+
* import { csrfProtectionMiddleware } from "./middleware/csrf-protection.js";
|
|
43
|
+
* app.post("/mcp", csrfProtectionMiddleware, authMiddleware, handler);
|
|
44
|
+
*
|
|
45
|
+
* // Client request (must include custom header)
|
|
46
|
+
* fetch("http://localhost:53000/mcp", {
|
|
47
|
+
* method: "POST",
|
|
48
|
+
* headers: {
|
|
49
|
+
* "Content-Type": "application/json",
|
|
50
|
+
* "X-API-Key": "secret",
|
|
51
|
+
* "X-Synapse-Client": "synapse-mcp-client" // Required for CSRF protection
|
|
52
|
+
* },
|
|
53
|
+
* body: JSON.stringify({ method: "tools/list" })
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function csrfProtectionMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
58
|
+
//# sourceMappingURL=csrf-protection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf-protection.d.ts","sourceRoot":"","sources":["../../src/middleware/csrf-protection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAmC9F"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF Protection Middleware
|
|
3
|
+
*
|
|
4
|
+
* Security: Prevents CWE-352 (Cross-Site Request Forgery) by requiring a custom header
|
|
5
|
+
* that browsers cannot send from cross-origin contexts without CORS preflight approval.
|
|
6
|
+
* @see https://cwe.mitre.org/data/definitions/352.html
|
|
7
|
+
*
|
|
8
|
+
* SECURITY (S-M6, CWE-352, CVSS 3.7): Defense-in-Depth CSRF Protection
|
|
9
|
+
* ---------------------------------------------------------------------
|
|
10
|
+
* This middleware implements the OWASP recommended "Custom Request Headers" pattern
|
|
11
|
+
* for CSRF protection in REST APIs.
|
|
12
|
+
* @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#use-of-custom-request-headers
|
|
13
|
+
*
|
|
14
|
+
* **How It Works:**
|
|
15
|
+
* 1. Requires X-Synapse-Client header on all requests
|
|
16
|
+
* 2. Custom headers trigger CORS preflight (OPTIONS request)
|
|
17
|
+
* 3. Server only approves preflight for trusted origins (or none)
|
|
18
|
+
* 4. Browsers won't send custom headers without preflight success
|
|
19
|
+
* 5. Malicious sites cannot forge requests with custom headers
|
|
20
|
+
*
|
|
21
|
+
* **Why This Works:**
|
|
22
|
+
* - Simple cross-origin requests (no custom headers) bypass preflight
|
|
23
|
+
* - But custom headers ALWAYS trigger preflight (browser security model)
|
|
24
|
+
* - Attacker sites cannot complete preflight to untrusted server
|
|
25
|
+
* - Therefore attacker cannot send X-Synapse-Client header
|
|
26
|
+
* - Requests without header are rejected by this middleware
|
|
27
|
+
*
|
|
28
|
+
* **Additional Protection:**
|
|
29
|
+
* - Sets restrictive CORS headers (Access-Control-Allow-Origin: null by default)
|
|
30
|
+
* - Optional SYNAPSE_ALLOWED_ORIGINS for trusted web clients
|
|
31
|
+
* - Only allows POST method
|
|
32
|
+
*
|
|
33
|
+
* **Complements Existing Security:**
|
|
34
|
+
* - X-API-Key authentication (S-C1) prevents unauthorized access
|
|
35
|
+
* - X-Synapse-Client header (S-M6) prevents CSRF from authenticated sessions
|
|
36
|
+
* - Together: Defense-in-depth against both direct attacks and CSRF
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Server setup
|
|
41
|
+
* import { csrfProtectionMiddleware } from "./middleware/csrf-protection.js";
|
|
42
|
+
* app.post("/mcp", csrfProtectionMiddleware, authMiddleware, handler);
|
|
43
|
+
*
|
|
44
|
+
* // Client request (must include custom header)
|
|
45
|
+
* fetch("http://localhost:53000/mcp", {
|
|
46
|
+
* method: "POST",
|
|
47
|
+
* headers: {
|
|
48
|
+
* "Content-Type": "application/json",
|
|
49
|
+
* "X-API-Key": "secret",
|
|
50
|
+
* "X-Synapse-Client": "synapse-mcp-client" // Required for CSRF protection
|
|
51
|
+
* },
|
|
52
|
+
* body: JSON.stringify({ method: "tools/list" })
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function csrfProtectionMiddleware(req, res, next) {
|
|
57
|
+
// Handle OPTIONS preflight requests
|
|
58
|
+
if (req.method === "OPTIONS") {
|
|
59
|
+
setCORSHeaders(req, res);
|
|
60
|
+
res.status(204).end();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Set CORS headers for all other requests
|
|
64
|
+
setCORSHeaders(req, res);
|
|
65
|
+
// Require X-Synapse-Client custom header (case-insensitive)
|
|
66
|
+
const clientHeader = req.headers["x-synapse-client"];
|
|
67
|
+
if (!clientHeader || clientHeader.trim().length === 0) {
|
|
68
|
+
res.status(403).json({
|
|
69
|
+
error: "Forbidden",
|
|
70
|
+
message: "Missing required X-Synapse-Client header",
|
|
71
|
+
});
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// SECURITY (S-M4): Validate header value format to prevent abuse
|
|
75
|
+
// Only allow alphanumeric characters, hyphens, underscores, dots, and slashes
|
|
76
|
+
// This prevents using the header as a vector for log injection or other attacks
|
|
77
|
+
if (!/^[a-zA-Z0-9._\-/]+$/.test(clientHeader.trim())) {
|
|
78
|
+
res.status(403).json({
|
|
79
|
+
error: "Forbidden",
|
|
80
|
+
message: "Invalid X-Synapse-Client header value",
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Header present, non-empty, and valid format - allow request
|
|
85
|
+
next();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Sets restrictive CORS headers to prevent cross-origin browser access.
|
|
89
|
+
*
|
|
90
|
+
* By default, sets Access-Control-Allow-Origin to "null" which effectively
|
|
91
|
+
* blocks all cross-origin requests from browsers.
|
|
92
|
+
*
|
|
93
|
+
* If SYNAPSE_ALLOWED_ORIGINS is set, checks request origin against allowlist
|
|
94
|
+
* and only sets matching origin if approved.
|
|
95
|
+
*/
|
|
96
|
+
function setCORSHeaders(req, res) {
|
|
97
|
+
const allowedOriginsEnv = process.env.SYNAPSE_ALLOWED_ORIGINS;
|
|
98
|
+
const requestOrigin = req.headers.origin;
|
|
99
|
+
if (allowedOriginsEnv && requestOrigin) {
|
|
100
|
+
// Parse comma-separated allowed origins
|
|
101
|
+
const allowedOrigins = allowedOriginsEnv.split(",").map((o) => o.trim());
|
|
102
|
+
if (allowedOrigins.includes(requestOrigin)) {
|
|
103
|
+
// Request origin is in allowlist - approve it
|
|
104
|
+
res.setHeader("Access-Control-Allow-Origin", requestOrigin);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Request origin not in allowlist - reject with "null"
|
|
108
|
+
res.setHeader("Access-Control-Allow-Origin", "null");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// No allowed origins configured - block all cross-origin
|
|
113
|
+
res.setHeader("Access-Control-Allow-Origin", "null");
|
|
114
|
+
}
|
|
115
|
+
// Only allow POST method
|
|
116
|
+
res.setHeader("Access-Control-Allow-Methods", "POST");
|
|
117
|
+
// Allow required headers
|
|
118
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, X-API-Key, X-Synapse-Client");
|
|
119
|
+
// Tell caches that the response varies by Origin header.
|
|
120
|
+
// Without this, a cached response for one origin could be served to another.
|
|
121
|
+
res.setHeader("Vary", "Origin");
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=csrf-protection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csrf-protection.js","sourceRoot":"","sources":["../../src/middleware/csrf-protection.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IACtF,oCAAoC;IACpC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IAED,0CAA0C;IAC1C,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAEzB,4DAA4D;IAC5D,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAuB,CAAC;IAE3E,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,0CAA0C;SACpD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,iEAAiE;IACjE,8EAA8E;IAC9E,gFAAgF;IAChF,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,uCAAuC;SACjD,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,8DAA8D;IAC9D,IAAI,EAAE,CAAC;AACT,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,cAAc,CAAC,GAAY,EAAE,GAAa;IACjD,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAC9D,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;IAEzC,IAAI,iBAAiB,IAAI,aAAa,EAAE,CAAC;QACvC,wCAAwC;QACxC,MAAM,cAAc,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAEzE,IAAI,cAAc,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC3C,8CAA8C;YAC9C,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,aAAa,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,uDAAuD;YACvD,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,yBAAyB;IACzB,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;IAEtD,yBAAyB;IACzB,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,2CAA2C,CAAC,CAAC;IAE3F,yDAAyD;IACzD,6EAA6E;IAC7E,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler Middleware - Catches and formats all Express errors
|
|
3
|
+
*
|
|
4
|
+
* Primary middleware for catching errors from routes and returning
|
|
5
|
+
* structured JSON responses. Integrates with logError utility for
|
|
6
|
+
* comprehensive error logging with request context.
|
|
7
|
+
*/
|
|
8
|
+
import type { NextFunction, Request, Response } from "express";
|
|
9
|
+
import "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* Primary error handler middleware
|
|
12
|
+
*
|
|
13
|
+
* Catches all errors from routes and:
|
|
14
|
+
* - Logs error with full context (request ID, IP, user agent, etc.)
|
|
15
|
+
* - Maps error to appropriate HTTP status code
|
|
16
|
+
* - Formats error response with consistent structure
|
|
17
|
+
* - Includes stack traces in non-production environments
|
|
18
|
+
* - Handles headers-already-sent scenario gracefully
|
|
19
|
+
*
|
|
20
|
+
* @param error - Error thrown from route or middleware
|
|
21
|
+
* @param req - Express request object (with requestId from Phase 1)
|
|
22
|
+
* @param res - Express response object
|
|
23
|
+
* @param next - Express next function (for headers-already-sent case)
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* app.use(errorHandler);
|
|
27
|
+
* app.use(fallbackErrorHandler); // Safety net
|
|
28
|
+
*/
|
|
29
|
+
export declare function errorHandler(error: unknown, req: Request, res: Response, next: NextFunction): void;
|
|
30
|
+
/**
|
|
31
|
+
* Fallback error handler (last-resort safety net)
|
|
32
|
+
*
|
|
33
|
+
* Handles errors that occur during primary error handling.
|
|
34
|
+
* Prevents server crash if primary handler fails.
|
|
35
|
+
*
|
|
36
|
+
* This should be registered AFTER errorHandler in Express:
|
|
37
|
+
* app.use(errorHandler);
|
|
38
|
+
* app.use(fallbackErrorHandler);
|
|
39
|
+
*
|
|
40
|
+
* @param error - Error thrown during error handling
|
|
41
|
+
* @param req - Express request object
|
|
42
|
+
* @param res - Express response object
|
|
43
|
+
* @param _next - Express next function (unused)
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* app.use(fallbackErrorHandler);
|
|
47
|
+
*/
|
|
48
|
+
export declare function fallbackErrorHandler(error: unknown, req: Request, res: Response, _next: NextFunction): void;
|
|
49
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CA8BN;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,IAAI,CAiBN"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler Middleware - Catches and formats all Express errors
|
|
3
|
+
*
|
|
4
|
+
* Primary middleware for catching errors from routes and returning
|
|
5
|
+
* structured JSON responses. Integrates with logError utility for
|
|
6
|
+
* comprehensive error logging with request context.
|
|
7
|
+
*/
|
|
8
|
+
import { logError } from "../utils/errors.js";
|
|
9
|
+
import { formatErrorResponse, mapErrorToStatus } from "./error-mapper.js";
|
|
10
|
+
import "./types.js"; // Import Request type augmentation
|
|
11
|
+
/**
|
|
12
|
+
* Primary error handler middleware
|
|
13
|
+
*
|
|
14
|
+
* Catches all errors from routes and:
|
|
15
|
+
* - Logs error with full context (request ID, IP, user agent, etc.)
|
|
16
|
+
* - Maps error to appropriate HTTP status code
|
|
17
|
+
* - Formats error response with consistent structure
|
|
18
|
+
* - Includes stack traces in non-production environments
|
|
19
|
+
* - Handles headers-already-sent scenario gracefully
|
|
20
|
+
*
|
|
21
|
+
* @param error - Error thrown from route or middleware
|
|
22
|
+
* @param req - Express request object (with requestId from Phase 1)
|
|
23
|
+
* @param res - Express response object
|
|
24
|
+
* @param next - Express next function (for headers-already-sent case)
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* app.use(errorHandler);
|
|
28
|
+
* app.use(fallbackErrorHandler); // Safety net
|
|
29
|
+
*/
|
|
30
|
+
export function errorHandler(error, req, res, next) {
|
|
31
|
+
// Check if response already sent (can't send error response)
|
|
32
|
+
if (res.headersSent) {
|
|
33
|
+
next(error);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Get request ID from Phase 1 middleware (or fallback to 'unknown')
|
|
37
|
+
const requestId = req.requestId || "unknown";
|
|
38
|
+
// Log error with comprehensive context
|
|
39
|
+
logError(error, {
|
|
40
|
+
requestId,
|
|
41
|
+
operation: `${req.method} ${req.path}`,
|
|
42
|
+
metadata: {
|
|
43
|
+
ip: req.ip,
|
|
44
|
+
userAgent: req.headers["user-agent"],
|
|
45
|
+
forwarded: req.headers["x-forwarded-for"] || req.headers["x-real-ip"],
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
// Determine HTTP status code based on error type
|
|
49
|
+
const statusCode = mapErrorToStatus(error);
|
|
50
|
+
// Format error response (include stack trace in non-production)
|
|
51
|
+
const includeStack = process.env.NODE_ENV !== "production";
|
|
52
|
+
const errorResponse = formatErrorResponse(error, requestId, includeStack);
|
|
53
|
+
// Send JSON response
|
|
54
|
+
res.status(statusCode).json(errorResponse);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Fallback error handler (last-resort safety net)
|
|
58
|
+
*
|
|
59
|
+
* Handles errors that occur during primary error handling.
|
|
60
|
+
* Prevents server crash if primary handler fails.
|
|
61
|
+
*
|
|
62
|
+
* This should be registered AFTER errorHandler in Express:
|
|
63
|
+
* app.use(errorHandler);
|
|
64
|
+
* app.use(fallbackErrorHandler);
|
|
65
|
+
*
|
|
66
|
+
* @param error - Error thrown during error handling
|
|
67
|
+
* @param req - Express request object
|
|
68
|
+
* @param res - Express response object
|
|
69
|
+
* @param _next - Express next function (unused)
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* app.use(fallbackErrorHandler);
|
|
73
|
+
*/
|
|
74
|
+
export function fallbackErrorHandler(error, req, res, _next) {
|
|
75
|
+
// Log critical error with structured context
|
|
76
|
+
logError(error, { operation: "fallbackErrorHandler", requestId: req.requestId });
|
|
77
|
+
// Check if response already sent
|
|
78
|
+
if (res.headersSent) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Send minimal error response
|
|
82
|
+
res.status(500).json({
|
|
83
|
+
error: {
|
|
84
|
+
message: "An unexpected error occurred",
|
|
85
|
+
code: "INTERNAL_ERROR",
|
|
86
|
+
requestId: req.requestId || "unknown",
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,YAAY,CAAC,CAAC,mCAAmC;AAExD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAc,EACd,GAAY,EACZ,GAAa,EACb,IAAkB;IAElB,6DAA6D;IAC7D,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,KAAK,CAAC,CAAC;QACZ,OAAO;IACT,CAAC;IAED,oEAAoE;IACpE,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC;IAE7C,uCAAuC;IACvC,QAAQ,CAAC,KAAK,EAAE;QACd,SAAS;QACT,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE;QACtC,QAAQ,EAAE;YACR,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC;YACpC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC;SACtE;KACF,CAAC,CAAC;IAEH,iDAAiD;IACjD,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAE3C,gEAAgE;IAChE,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;IAC3D,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAE1E,qBAAqB;IACrB,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAc,EACd,GAAY,EACZ,GAAa,EACb,KAAmB;IAEnB,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,sBAAsB,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAEjF,iCAAiC;IACjC,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,8BAA8B;IAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,KAAK,EAAE;YACL,OAAO,EAAE,8BAA8B;YACvC,IAAI,EAAE,gBAAgB;YACtB,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,SAAS;SACtC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Mapper - Translates application errors to HTTP responses
|
|
3
|
+
*
|
|
4
|
+
* Maps custom error classes to appropriate HTTP status codes and formats
|
|
5
|
+
* error responses for consistent API error handling.
|
|
6
|
+
*/
|
|
7
|
+
import type { ErrorCode, ErrorResponse, HTTPStatusCode } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Maps error instances to appropriate HTTP status codes
|
|
10
|
+
*
|
|
11
|
+
* @param error - Error instance to map
|
|
12
|
+
* @returns HTTP status code (400, 502, or 500)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* mapErrorToStatus(new ValidationError(...)) // returns 400
|
|
16
|
+
* mapErrorToStatus(new HostOperationError(...)) // returns 502
|
|
17
|
+
* mapErrorToStatus(new Error(...)) // returns 500
|
|
18
|
+
*/
|
|
19
|
+
export declare function mapErrorToStatus(error: unknown): HTTPStatusCode;
|
|
20
|
+
/**
|
|
21
|
+
* Gets error code string for classification
|
|
22
|
+
*
|
|
23
|
+
* @param error - Error instance to classify
|
|
24
|
+
* @returns Error code string for API response
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* getErrorCode(new ValidationError(...)) // returns "VALIDATION_ERROR"
|
|
28
|
+
* getErrorCode(new HostSecurityError(...)) // returns "SECURITY_ERROR"
|
|
29
|
+
*/
|
|
30
|
+
export declare function getErrorCode(error: unknown): ErrorCode;
|
|
31
|
+
/**
|
|
32
|
+
* Formats error into structured JSON response
|
|
33
|
+
*
|
|
34
|
+
* @param error - Error to format
|
|
35
|
+
* @param requestId - Request ID for tracing
|
|
36
|
+
* @param includeStack - Whether to include stack trace (default: false)
|
|
37
|
+
* @returns Formatted error response object
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* formatErrorResponse(new ValidationError(...), "req-123")
|
|
41
|
+
* // Returns: { error: { message: "...", code: "VALIDATION_ERROR", requestId: "req-123", details: {...} } }
|
|
42
|
+
*/
|
|
43
|
+
export declare function formatErrorResponse(error: unknown, requestId: string, includeStack?: boolean): ErrorResponse;
|
|
44
|
+
//# sourceMappingURL=error-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-mapper.d.ts","sourceRoot":"","sources":["../../src/middleware/error-mapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3E;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAsB/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAsBtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,YAAY,UAAQ,GACnB,aAAa,CAmDf"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Mapper - Translates application errors to HTTP responses
|
|
3
|
+
*
|
|
4
|
+
* Maps custom error classes to appropriate HTTP status codes and formats
|
|
5
|
+
* error responses for consistent API error handling.
|
|
6
|
+
*/
|
|
7
|
+
import { ZodError } from "zod";
|
|
8
|
+
import { ComposeOperationError, HostOperationError, SSHCommandError, ValidationError, } from "../utils/errors.js";
|
|
9
|
+
import { HostSecurityError, SSHArgSecurityError } from "../utils/path-security.js";
|
|
10
|
+
/**
|
|
11
|
+
* Maps error instances to appropriate HTTP status codes
|
|
12
|
+
*
|
|
13
|
+
* @param error - Error instance to map
|
|
14
|
+
* @returns HTTP status code (400, 502, or 500)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* mapErrorToStatus(new ValidationError(...)) // returns 400
|
|
18
|
+
* mapErrorToStatus(new HostOperationError(...)) // returns 502
|
|
19
|
+
* mapErrorToStatus(new Error(...)) // returns 500
|
|
20
|
+
*/
|
|
21
|
+
export function mapErrorToStatus(error) {
|
|
22
|
+
// 400 Bad Request - Client input errors
|
|
23
|
+
if (error instanceof ValidationError ||
|
|
24
|
+
error instanceof HostSecurityError ||
|
|
25
|
+
error instanceof SSHArgSecurityError ||
|
|
26
|
+
error instanceof ZodError) {
|
|
27
|
+
return 400;
|
|
28
|
+
}
|
|
29
|
+
// 502 Bad Gateway - Remote host/service errors
|
|
30
|
+
if (error instanceof HostOperationError ||
|
|
31
|
+
error instanceof SSHCommandError ||
|
|
32
|
+
error instanceof ComposeOperationError) {
|
|
33
|
+
return 502;
|
|
34
|
+
}
|
|
35
|
+
// 500 Internal Server Error - Unknown/unexpected errors
|
|
36
|
+
return 500;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Gets error code string for classification
|
|
40
|
+
*
|
|
41
|
+
* @param error - Error instance to classify
|
|
42
|
+
* @returns Error code string for API response
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* getErrorCode(new ValidationError(...)) // returns "VALIDATION_ERROR"
|
|
46
|
+
* getErrorCode(new HostSecurityError(...)) // returns "SECURITY_ERROR"
|
|
47
|
+
*/
|
|
48
|
+
export function getErrorCode(error) {
|
|
49
|
+
if (error instanceof ValidationError || error instanceof ZodError) {
|
|
50
|
+
return "VALIDATION_ERROR";
|
|
51
|
+
}
|
|
52
|
+
if (error instanceof HostSecurityError || error instanceof SSHArgSecurityError) {
|
|
53
|
+
return "SECURITY_ERROR";
|
|
54
|
+
}
|
|
55
|
+
if (error instanceof HostOperationError) {
|
|
56
|
+
return "HOST_OPERATION_ERROR";
|
|
57
|
+
}
|
|
58
|
+
if (error instanceof SSHCommandError) {
|
|
59
|
+
return "SSH_COMMAND_ERROR";
|
|
60
|
+
}
|
|
61
|
+
if (error instanceof ComposeOperationError) {
|
|
62
|
+
return "COMPOSE_OPERATION_ERROR";
|
|
63
|
+
}
|
|
64
|
+
return "INTERNAL_ERROR";
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Formats error into structured JSON response
|
|
68
|
+
*
|
|
69
|
+
* @param error - Error to format
|
|
70
|
+
* @param requestId - Request ID for tracing
|
|
71
|
+
* @param includeStack - Whether to include stack trace (default: false)
|
|
72
|
+
* @returns Formatted error response object
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* formatErrorResponse(new ValidationError(...), "req-123")
|
|
76
|
+
* // Returns: { error: { message: "...", code: "VALIDATION_ERROR", requestId: "req-123", details: {...} } }
|
|
77
|
+
*/
|
|
78
|
+
export function formatErrorResponse(error, requestId, includeStack = false) {
|
|
79
|
+
const code = getErrorCode(error);
|
|
80
|
+
let message = "Unknown error";
|
|
81
|
+
let details;
|
|
82
|
+
let stack;
|
|
83
|
+
// Extract message and details based on error type
|
|
84
|
+
if (error instanceof ValidationError) {
|
|
85
|
+
message = error.message;
|
|
86
|
+
details = {
|
|
87
|
+
handler: error.handlerName,
|
|
88
|
+
issues: error.issues,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else if (error instanceof ZodError) {
|
|
92
|
+
message = "Validation failed";
|
|
93
|
+
// Transform Zod errors into flat array of strings
|
|
94
|
+
details = {
|
|
95
|
+
issues: error.issues.map((err) => {
|
|
96
|
+
const path = err.path.join(".");
|
|
97
|
+
return path ? `${path}: ${err.message}` : err.message;
|
|
98
|
+
}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
else if (error instanceof Error) {
|
|
102
|
+
message = error.message;
|
|
103
|
+
// Don't include details for security/operational errors (may contain sensitive info)
|
|
104
|
+
}
|
|
105
|
+
else if (typeof error === "string") {
|
|
106
|
+
message = error;
|
|
107
|
+
}
|
|
108
|
+
// Include stack trace if requested and error has one
|
|
109
|
+
if (includeStack && error instanceof Error && error.stack) {
|
|
110
|
+
stack = error.stack;
|
|
111
|
+
}
|
|
112
|
+
const response = {
|
|
113
|
+
error: {
|
|
114
|
+
message,
|
|
115
|
+
code,
|
|
116
|
+
requestId,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
if (details !== undefined) {
|
|
120
|
+
response.error.details = details;
|
|
121
|
+
}
|
|
122
|
+
if (stack !== undefined) {
|
|
123
|
+
response.error.stack = stack;
|
|
124
|
+
}
|
|
125
|
+
return response;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=error-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-mapper.js","sourceRoot":"","sources":["../../src/middleware/error-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Express middleware exports
|
|
3
|
+
*
|
|
4
|
+
* Barrel export for all middleware components.
|
|
5
|
+
*/
|
|
6
|
+
export { type AsyncRouteHandler, asyncHandler } from "./async-handler.js";
|
|
7
|
+
export { authMiddleware } from "./auth.js";
|
|
8
|
+
export { csrfProtectionMiddleware } from "./csrf-protection.js";
|
|
9
|
+
export { errorHandler, fallbackErrorHandler } from "./error-handler.js";
|
|
10
|
+
export * from "./error-mapper.js";
|
|
11
|
+
export { requestIdMiddleware } from "./request-id.js";
|
|
12
|
+
export * from "./types.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,iBAAiB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACxE,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Express middleware exports
|
|
3
|
+
*
|
|
4
|
+
* Barrel export for all middleware components.
|
|
5
|
+
*/
|
|
6
|
+
export { asyncHandler } from "./async-handler.js";
|
|
7
|
+
export { authMiddleware } from "./auth.js";
|
|
8
|
+
export { csrfProtectionMiddleware } from "./csrf-protection.js";
|
|
9
|
+
export { errorHandler, fallbackErrorHandler } from "./error-handler.js";
|
|
10
|
+
export * from "./error-mapper.js";
|
|
11
|
+
export { requestIdMiddleware } from "./request-id.js";
|
|
12
|
+
export * from "./types.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAA0B,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACxE,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from "express";
|
|
2
|
+
import "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Request ID middleware
|
|
5
|
+
*
|
|
6
|
+
* Generates a unique UUID v4 for each request and:
|
|
7
|
+
* - Attaches it to req.requestId for downstream use
|
|
8
|
+
* - Sets X-Request-ID response header for client tracking
|
|
9
|
+
*
|
|
10
|
+
* @param req - Express request object
|
|
11
|
+
* @param res - Express response object
|
|
12
|
+
* @param next - Express next function
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* app.use(requestIdMiddleware);
|
|
16
|
+
* app.get('/api/data', (req, res) => {
|
|
17
|
+
* console.log(`Request ID: ${req.requestId}`);
|
|
18
|
+
* res.json({ data: 'example' });
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
export declare function requestIdMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
22
|
+
//# sourceMappingURL=request-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../../src/middleware/request-id.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAYzF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import "./types.js"; // Import Request type augmentation
|
|
3
|
+
/**
|
|
4
|
+
* Request ID middleware
|
|
5
|
+
*
|
|
6
|
+
* Generates a unique UUID v4 for each request and:
|
|
7
|
+
* - Attaches it to req.requestId for downstream use
|
|
8
|
+
* - Sets X-Request-ID response header for client tracking
|
|
9
|
+
*
|
|
10
|
+
* @param req - Express request object
|
|
11
|
+
* @param res - Express response object
|
|
12
|
+
* @param next - Express next function
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* app.use(requestIdMiddleware);
|
|
16
|
+
* app.get('/api/data', (req, res) => {
|
|
17
|
+
* console.log(`Request ID: ${req.requestId}`);
|
|
18
|
+
* res.json({ data: 'example' });
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
export function requestIdMiddleware(req, res, next) {
|
|
22
|
+
// Generate UUID v4
|
|
23
|
+
const requestId = randomUUID();
|
|
24
|
+
// Attach to request object
|
|
25
|
+
req.requestId = requestId;
|
|
26
|
+
// Set response header
|
|
27
|
+
res.setHeader("X-Request-ID", requestId);
|
|
28
|
+
// Continue middleware chain
|
|
29
|
+
next();
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=request-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-id.js","sourceRoot":"","sources":["../../src/middleware/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,YAAY,CAAC,CAAC,mCAAmC;AAExD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IACjF,mBAAmB;IACnB,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAE/B,2BAA2B;IAC3B,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;IAE1B,sBAAsB;IACtB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAEzC,4BAA4B;IAC5B,IAAI,EAAE,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Express Request type augmentation
|
|
3
|
+
*
|
|
4
|
+
* Adds requestId property to Express Request interface.
|
|
5
|
+
*/
|
|
6
|
+
declare global {
|
|
7
|
+
namespace Express {
|
|
8
|
+
interface Request {
|
|
9
|
+
requestId?: string;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* HTTP status codes used in error responses
|
|
15
|
+
*/
|
|
16
|
+
export type HTTPStatusCode = 400 | 429 | 500 | 502;
|
|
17
|
+
/**
|
|
18
|
+
* Error code strings for classification
|
|
19
|
+
*/
|
|
20
|
+
export type ErrorCode = "VALIDATION_ERROR" | "SECURITY_ERROR" | "HOST_OPERATION_ERROR" | "SSH_COMMAND_ERROR" | "COMPOSE_OPERATION_ERROR" | "INTERNAL_ERROR";
|
|
21
|
+
/**
|
|
22
|
+
* Structured error response format
|
|
23
|
+
*/
|
|
24
|
+
export interface ErrorResponse {
|
|
25
|
+
error: {
|
|
26
|
+
message: string;
|
|
27
|
+
code: ErrorCode;
|
|
28
|
+
requestId: string;
|
|
29
|
+
details?: unknown;
|
|
30
|
+
stack?: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/middleware/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,SAAS,CAAC,EAAE,MAAM,CAAC;SACpB;KACF;CACF;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,sBAAsB,GACtB,mBAAmB,GACnB,yBAAyB,GACzB,gBAAgB,CAAC;AAErB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,SAAS,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH"}
|