@vorionsys/platform-core 0.1.0
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/LICENSE +190 -0
- package/README.md +88 -0
- package/dist/a2a/attestation.d.ts +145 -0
- package/dist/a2a/attestation.d.ts.map +1 -0
- package/dist/a2a/attestation.js +353 -0
- package/dist/a2a/attestation.js.map +1 -0
- package/dist/a2a/chain-of-trust.d.ts +143 -0
- package/dist/a2a/chain-of-trust.d.ts.map +1 -0
- package/dist/a2a/chain-of-trust.js +422 -0
- package/dist/a2a/chain-of-trust.js.map +1 -0
- package/dist/a2a/index.d.ts +15 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +23 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/a2a/openapi.d.ts +22 -0
- package/dist/a2a/openapi.d.ts.map +1 -0
- package/dist/a2a/openapi.js +1133 -0
- package/dist/a2a/openapi.js.map +1 -0
- package/dist/a2a/router.d.ts +167 -0
- package/dist/a2a/router.d.ts.map +1 -0
- package/dist/a2a/router.js +454 -0
- package/dist/a2a/router.js.map +1 -0
- package/dist/a2a/routes.d.ts +11 -0
- package/dist/a2a/routes.d.ts.map +1 -0
- package/dist/a2a/routes.js +442 -0
- package/dist/a2a/routes.js.map +1 -0
- package/dist/a2a/trust-negotiation.d.ts +119 -0
- package/dist/a2a/trust-negotiation.d.ts.map +1 -0
- package/dist/a2a/trust-negotiation.js +425 -0
- package/dist/a2a/trust-negotiation.js.map +1 -0
- package/dist/a2a/types.d.ts +413 -0
- package/dist/a2a/types.d.ts.map +1 -0
- package/dist/a2a/types.js +38 -0
- package/dist/a2a/types.js.map +1 -0
- package/dist/agent-registry/a3i-cache.d.ts +113 -0
- package/dist/agent-registry/a3i-cache.d.ts.map +1 -0
- package/dist/agent-registry/a3i-cache.js +305 -0
- package/dist/agent-registry/a3i-cache.js.map +1 -0
- package/dist/agent-registry/index.d.ts +14 -0
- package/dist/agent-registry/index.d.ts.map +1 -0
- package/dist/agent-registry/index.js +17 -0
- package/dist/agent-registry/index.js.map +1 -0
- package/dist/agent-registry/openapi.d.ts +23 -0
- package/dist/agent-registry/openapi.d.ts.map +1 -0
- package/dist/agent-registry/openapi.js +1377 -0
- package/dist/agent-registry/openapi.js.map +1 -0
- package/dist/agent-registry/routes.d.ts +10 -0
- package/dist/agent-registry/routes.d.ts.map +1 -0
- package/dist/agent-registry/routes.js +485 -0
- package/dist/agent-registry/routes.js.map +1 -0
- package/dist/agent-registry/service.d.ts +159 -0
- package/dist/agent-registry/service.d.ts.map +1 -0
- package/dist/agent-registry/service.js +652 -0
- package/dist/agent-registry/service.js.map +1 -0
- package/dist/agent-registry/tenant-service.d.ts +104 -0
- package/dist/agent-registry/tenant-service.d.ts.map +1 -0
- package/dist/agent-registry/tenant-service.js +313 -0
- package/dist/agent-registry/tenant-service.js.map +1 -0
- package/dist/api/auth.d.ts +55 -0
- package/dist/api/auth.d.ts.map +1 -0
- package/dist/api/auth.js +322 -0
- package/dist/api/auth.js.map +1 -0
- package/dist/api/errors.d.ts +146 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +464 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +19 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/middleware/api-key-enforcement.d.ts +131 -0
- package/dist/api/middleware/api-key-enforcement.d.ts.map +1 -0
- package/dist/api/middleware/api-key-enforcement.js +674 -0
- package/dist/api/middleware/api-key-enforcement.js.map +1 -0
- package/dist/api/middleware/audit.d.ts +151 -0
- package/dist/api/middleware/audit.d.ts.map +1 -0
- package/dist/api/middleware/audit.js +384 -0
- package/dist/api/middleware/audit.js.map +1 -0
- package/dist/api/middleware/dpop-enforcement.d.ts +176 -0
- package/dist/api/middleware/dpop-enforcement.d.ts.map +1 -0
- package/dist/api/middleware/dpop-enforcement.js +596 -0
- package/dist/api/middleware/dpop-enforcement.js.map +1 -0
- package/dist/api/middleware/index.d.ts +24 -0
- package/dist/api/middleware/index.d.ts.map +1 -0
- package/dist/api/middleware/index.js +43 -0
- package/dist/api/middleware/index.js.map +1 -0
- package/dist/api/middleware/metrics.d.ts +41 -0
- package/dist/api/middleware/metrics.d.ts.map +1 -0
- package/dist/api/middleware/metrics.js +150 -0
- package/dist/api/middleware/metrics.js.map +1 -0
- package/dist/api/middleware/rate-limits.d.ts +224 -0
- package/dist/api/middleware/rate-limits.d.ts.map +1 -0
- package/dist/api/middleware/rate-limits.js +686 -0
- package/dist/api/middleware/rate-limits.js.map +1 -0
- package/dist/api/middleware/rateLimit.d.ts +165 -0
- package/dist/api/middleware/rateLimit.d.ts.map +1 -0
- package/dist/api/middleware/rateLimit.js +477 -0
- package/dist/api/middleware/rateLimit.js.map +1 -0
- package/dist/api/middleware/redis-rate-limiter.d.ts +279 -0
- package/dist/api/middleware/redis-rate-limiter.d.ts.map +1 -0
- package/dist/api/middleware/redis-rate-limiter.js +1074 -0
- package/dist/api/middleware/redis-rate-limiter.js.map +1 -0
- package/dist/api/middleware/security-headers.d.ts +248 -0
- package/dist/api/middleware/security-headers.d.ts.map +1 -0
- package/dist/api/middleware/security-headers.js +410 -0
- package/dist/api/middleware/security-headers.js.map +1 -0
- package/dist/api/middleware/security.d.ts +156 -0
- package/dist/api/middleware/security.d.ts.map +1 -0
- package/dist/api/middleware/security.js +412 -0
- package/dist/api/middleware/security.js.map +1 -0
- package/dist/api/middleware/validation.d.ts +132 -0
- package/dist/api/middleware/validation.d.ts.map +1 -0
- package/dist/api/middleware/validation.js +363 -0
- package/dist/api/middleware/validation.js.map +1 -0
- package/dist/api/middleware/webhook-verify.d.ts +130 -0
- package/dist/api/middleware/webhook-verify.d.ts.map +1 -0
- package/dist/api/middleware/webhook-verify.js +366 -0
- package/dist/api/middleware/webhook-verify.js.map +1 -0
- package/dist/api/rate-limit.d.ts +115 -0
- package/dist/api/rate-limit.d.ts.map +1 -0
- package/dist/api/rate-limit.js +335 -0
- package/dist/api/rate-limit.js.map +1 -0
- package/dist/api/server.d.ts +37 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +2086 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/validation.d.ts +243 -0
- package/dist/api/validation.d.ts.map +1 -0
- package/dist/api/validation.js +247 -0
- package/dist/api/validation.js.map +1 -0
- package/dist/audit/compliance-reporter.d.ts +271 -0
- package/dist/audit/compliance-reporter.d.ts.map +1 -0
- package/dist/audit/compliance-reporter.js +587 -0
- package/dist/audit/compliance-reporter.js.map +1 -0
- package/dist/audit/db-store.d.ts +689 -0
- package/dist/audit/db-store.d.ts.map +1 -0
- package/dist/audit/db-store.js +589 -0
- package/dist/audit/db-store.js.map +1 -0
- package/dist/audit/event-schema.d.ts +605 -0
- package/dist/audit/event-schema.d.ts.map +1 -0
- package/dist/audit/event-schema.js +566 -0
- package/dist/audit/event-schema.js.map +1 -0
- package/dist/audit/index.d.ts +16 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +44 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/security-events.d.ts +1624 -0
- package/dist/audit/security-events.d.ts.map +1 -0
- package/dist/audit/security-events.js +775 -0
- package/dist/audit/security-events.js.map +1 -0
- package/dist/audit/security-logger.d.ts +288 -0
- package/dist/audit/security-logger.d.ts.map +1 -0
- package/dist/audit/security-logger.js +820 -0
- package/dist/audit/security-logger.js.map +1 -0
- package/dist/audit/service.d.ts +206 -0
- package/dist/audit/service.d.ts.map +1 -0
- package/dist/audit/service.js +756 -0
- package/dist/audit/service.js.map +1 -0
- package/dist/audit/siem/elastic.d.ts +94 -0
- package/dist/audit/siem/elastic.d.ts.map +1 -0
- package/dist/audit/siem/elastic.js +412 -0
- package/dist/audit/siem/elastic.js.map +1 -0
- package/dist/audit/siem/index.d.ts +179 -0
- package/dist/audit/siem/index.d.ts.map +1 -0
- package/dist/audit/siem/index.js +368 -0
- package/dist/audit/siem/index.js.map +1 -0
- package/dist/audit/siem/loki.d.ts +100 -0
- package/dist/audit/siem/loki.d.ts.map +1 -0
- package/dist/audit/siem/loki.js +406 -0
- package/dist/audit/siem/loki.js.map +1 -0
- package/dist/audit/siem/splunk.d.ts +91 -0
- package/dist/audit/siem/splunk.d.ts.map +1 -0
- package/dist/audit/siem/splunk.js +375 -0
- package/dist/audit/siem/splunk.js.map +1 -0
- package/dist/audit/siem/types.d.ts +547 -0
- package/dist/audit/siem/types.d.ts.map +1 -0
- package/dist/audit/siem/types.js +270 -0
- package/dist/audit/siem/types.js.map +1 -0
- package/dist/audit/types.d.ts +410 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +130 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/auth/index.d.ts +10 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/mfa/index.d.ts +9 -0
- package/dist/auth/mfa/index.d.ts.map +1 -0
- package/dist/auth/mfa/index.js +9 -0
- package/dist/auth/mfa/index.js.map +1 -0
- package/dist/auth/mfa/totp.d.ts +222 -0
- package/dist/auth/mfa/totp.d.ts.map +1 -0
- package/dist/auth/mfa/totp.js +329 -0
- package/dist/auth/mfa/totp.js.map +1 -0
- package/dist/auth/piv-cac/card-removal-handler.d.ts +197 -0
- package/dist/auth/piv-cac/card-removal-handler.d.ts.map +1 -0
- package/dist/auth/piv-cac/card-removal-handler.js +560 -0
- package/dist/auth/piv-cac/card-removal-handler.js.map +1 -0
- package/dist/auth/piv-cac/certificate-auth.d.ts +117 -0
- package/dist/auth/piv-cac/certificate-auth.d.ts.map +1 -0
- package/dist/auth/piv-cac/certificate-auth.js +727 -0
- package/dist/auth/piv-cac/certificate-auth.js.map +1 -0
- package/dist/auth/piv-cac/certificate-mapper.d.ts +141 -0
- package/dist/auth/piv-cac/certificate-mapper.d.ts.map +1 -0
- package/dist/auth/piv-cac/certificate-mapper.js +569 -0
- package/dist/auth/piv-cac/certificate-mapper.js.map +1 -0
- package/dist/auth/piv-cac/crl-validator.d.ts +195 -0
- package/dist/auth/piv-cac/crl-validator.d.ts.map +1 -0
- package/dist/auth/piv-cac/crl-validator.js +824 -0
- package/dist/auth/piv-cac/crl-validator.js.map +1 -0
- package/dist/auth/piv-cac/index.d.ts +72 -0
- package/dist/auth/piv-cac/index.d.ts.map +1 -0
- package/dist/auth/piv-cac/index.js +172 -0
- package/dist/auth/piv-cac/index.js.map +1 -0
- package/dist/auth/piv-cac/ocsp-validator.d.ts +183 -0
- package/dist/auth/piv-cac/ocsp-validator.d.ts.map +1 -0
- package/dist/auth/piv-cac/ocsp-validator.js +657 -0
- package/dist/auth/piv-cac/ocsp-validator.js.map +1 -0
- package/dist/auth/piv-cac/piv-middleware.d.ts +95 -0
- package/dist/auth/piv-cac/piv-middleware.d.ts.map +1 -0
- package/dist/auth/piv-cac/piv-middleware.js +524 -0
- package/dist/auth/piv-cac/piv-middleware.js.map +1 -0
- package/dist/auth/piv-cac/piv-routes.d.ts +29 -0
- package/dist/auth/piv-cac/piv-routes.d.ts.map +1 -0
- package/dist/auth/piv-cac/piv-routes.js +534 -0
- package/dist/auth/piv-cac/piv-routes.js.map +1 -0
- package/dist/auth/piv-cac/pkcs11-provider.d.ts +280 -0
- package/dist/auth/piv-cac/pkcs11-provider.d.ts.map +1 -0
- package/dist/auth/piv-cac/pkcs11-provider.js +535 -0
- package/dist/auth/piv-cac/pkcs11-provider.js.map +1 -0
- package/dist/auth/piv-cac/types.d.ts +4098 -0
- package/dist/auth/piv-cac/types.d.ts.map +1 -0
- package/dist/auth/piv-cac/types.js +495 -0
- package/dist/auth/piv-cac/types.js.map +1 -0
- package/dist/basis/evaluator.d.ts +72 -0
- package/dist/basis/evaluator.d.ts.map +1 -0
- package/dist/basis/evaluator.js +275 -0
- package/dist/basis/evaluator.js.map +1 -0
- package/dist/basis/expression-evaluator.d.ts +77 -0
- package/dist/basis/expression-evaluator.d.ts.map +1 -0
- package/dist/basis/expression-evaluator.js +826 -0
- package/dist/basis/expression-evaluator.js.map +1 -0
- package/dist/basis/index.d.ts +13 -0
- package/dist/basis/index.d.ts.map +1 -0
- package/dist/basis/index.js +13 -0
- package/dist/basis/index.js.map +1 -0
- package/dist/basis/parser.d.ts +376 -0
- package/dist/basis/parser.d.ts.map +1 -0
- package/dist/basis/parser.js +178 -0
- package/dist/basis/parser.js.map +1 -0
- package/dist/basis/types.d.ts +115 -0
- package/dist/basis/types.d.ts.map +1 -0
- package/dist/basis/types.js +5 -0
- package/dist/basis/types.js.map +1 -0
- package/dist/car-extensions/aci-string-extensions.d.ts +10 -0
- package/dist/car-extensions/aci-string-extensions.d.ts.map +1 -0
- package/dist/car-extensions/aci-string-extensions.js +24 -0
- package/dist/car-extensions/aci-string-extensions.js.map +1 -0
- package/dist/car-extensions/builtin-extensions/audit.d.ts +88 -0
- package/dist/car-extensions/builtin-extensions/audit.d.ts.map +1 -0
- package/dist/car-extensions/builtin-extensions/audit.js +445 -0
- package/dist/car-extensions/builtin-extensions/audit.js.map +1 -0
- package/dist/car-extensions/builtin-extensions/governance.d.ts +32 -0
- package/dist/car-extensions/builtin-extensions/governance.d.ts.map +1 -0
- package/dist/car-extensions/builtin-extensions/governance.js +534 -0
- package/dist/car-extensions/builtin-extensions/governance.js.map +1 -0
- package/dist/car-extensions/builtin-extensions/monitoring.d.ts +43 -0
- package/dist/car-extensions/builtin-extensions/monitoring.d.ts.map +1 -0
- package/dist/car-extensions/builtin-extensions/monitoring.js +416 -0
- package/dist/car-extensions/builtin-extensions/monitoring.js.map +1 -0
- package/dist/car-extensions/car-string-extensions.d.ts +355 -0
- package/dist/car-extensions/car-string-extensions.d.ts.map +1 -0
- package/dist/car-extensions/car-string-extensions.js +473 -0
- package/dist/car-extensions/car-string-extensions.js.map +1 -0
- package/dist/car-extensions/executor.d.ts +208 -0
- package/dist/car-extensions/executor.d.ts.map +1 -0
- package/dist/car-extensions/executor.js +789 -0
- package/dist/car-extensions/executor.js.map +1 -0
- package/dist/car-extensions/index.d.ts +94 -0
- package/dist/car-extensions/index.d.ts.map +1 -0
- package/dist/car-extensions/index.js +159 -0
- package/dist/car-extensions/index.js.map +1 -0
- package/dist/car-extensions/registry.d.ts +217 -0
- package/dist/car-extensions/registry.d.ts.map +1 -0
- package/dist/car-extensions/registry.js +450 -0
- package/dist/car-extensions/registry.js.map +1 -0
- package/dist/car-extensions/service.d.ts +220 -0
- package/dist/car-extensions/service.d.ts.map +1 -0
- package/dist/car-extensions/service.js +486 -0
- package/dist/car-extensions/service.js.map +1 -0
- package/dist/car-extensions/types.d.ts +2269 -0
- package/dist/car-extensions/types.d.ts.map +1 -0
- package/dist/car-extensions/types.js +389 -0
- package/dist/car-extensions/types.js.map +1 -0
- package/dist/cognigate/index.d.ts +192 -0
- package/dist/cognigate/index.d.ts.map +1 -0
- package/dist/cognigate/index.js +435 -0
- package/dist/cognigate/index.js.map +1 -0
- package/dist/cognigate/sandbox/capability-broker.d.ts +166 -0
- package/dist/cognigate/sandbox/capability-broker.d.ts.map +1 -0
- package/dist/cognigate/sandbox/capability-broker.js +461 -0
- package/dist/cognigate/sandbox/capability-broker.js.map +1 -0
- package/dist/cognigate/sandbox/filesystem-policy.d.ts +139 -0
- package/dist/cognigate/sandbox/filesystem-policy.d.ts.map +1 -0
- package/dist/cognigate/sandbox/filesystem-policy.js +426 -0
- package/dist/cognigate/sandbox/filesystem-policy.js.map +1 -0
- package/dist/cognigate/sandbox/index.d.ts +17 -0
- package/dist/cognigate/sandbox/index.d.ts.map +1 -0
- package/dist/cognigate/sandbox/index.js +24 -0
- package/dist/cognigate/sandbox/index.js.map +1 -0
- package/dist/cognigate/sandbox/network-policy.d.ts +126 -0
- package/dist/cognigate/sandbox/network-policy.d.ts.map +1 -0
- package/dist/cognigate/sandbox/network-policy.js +382 -0
- package/dist/cognigate/sandbox/network-policy.js.map +1 -0
- package/dist/cognigate/sandbox/sandbox-service.d.ts +70 -0
- package/dist/cognigate/sandbox/sandbox-service.d.ts.map +1 -0
- package/dist/cognigate/sandbox/sandbox-service.js +472 -0
- package/dist/cognigate/sandbox/sandbox-service.js.map +1 -0
- package/dist/cognigate/sandbox/types.d.ts +376 -0
- package/dist/cognigate/sandbox/types.d.ts.map +1 -0
- package/dist/cognigate/sandbox/types.js +179 -0
- package/dist/cognigate/sandbox/types.js.map +1 -0
- package/dist/common/adapters/index.d.ts +34 -0
- package/dist/common/adapters/index.d.ts.map +1 -0
- package/dist/common/adapters/index.js +46 -0
- package/dist/common/adapters/index.js.map +1 -0
- package/dist/common/adapters/memory-cache.d.ts +91 -0
- package/dist/common/adapters/memory-cache.d.ts.map +1 -0
- package/dist/common/adapters/memory-cache.js +201 -0
- package/dist/common/adapters/memory-cache.js.map +1 -0
- package/dist/common/adapters/memory-lock.d.ts +75 -0
- package/dist/common/adapters/memory-lock.d.ts.map +1 -0
- package/dist/common/adapters/memory-lock.js +219 -0
- package/dist/common/adapters/memory-lock.js.map +1 -0
- package/dist/common/adapters/memory-queue.d.ts +64 -0
- package/dist/common/adapters/memory-queue.d.ts.map +1 -0
- package/dist/common/adapters/memory-queue.js +233 -0
- package/dist/common/adapters/memory-queue.js.map +1 -0
- package/dist/common/adapters/memory-ratelimit.d.ts +78 -0
- package/dist/common/adapters/memory-ratelimit.d.ts.map +1 -0
- package/dist/common/adapters/memory-ratelimit.js +196 -0
- package/dist/common/adapters/memory-ratelimit.js.map +1 -0
- package/dist/common/adapters/memory-session.d.ts +105 -0
- package/dist/common/adapters/memory-session.d.ts.map +1 -0
- package/dist/common/adapters/memory-session.js +302 -0
- package/dist/common/adapters/memory-session.js.map +1 -0
- package/dist/common/adapters/provider.d.ts +47 -0
- package/dist/common/adapters/provider.d.ts.map +1 -0
- package/dist/common/adapters/provider.js +347 -0
- package/dist/common/adapters/provider.js.map +1 -0
- package/dist/common/adapters/types.d.ts +247 -0
- package/dist/common/adapters/types.d.ts.map +1 -0
- package/dist/common/adapters/types.js +11 -0
- package/dist/common/adapters/types.js.map +1 -0
- package/dist/common/alerts.d.ts +57 -0
- package/dist/common/alerts.d.ts.map +1 -0
- package/dist/common/alerts.js +216 -0
- package/dist/common/alerts.js.map +1 -0
- package/dist/common/authorization.d.ts +137 -0
- package/dist/common/authorization.d.ts.map +1 -0
- package/dist/common/authorization.js +270 -0
- package/dist/common/authorization.js.map +1 -0
- package/dist/common/canonical-bridge.d.ts +153 -0
- package/dist/common/canonical-bridge.d.ts.map +1 -0
- package/dist/common/canonical-bridge.js +236 -0
- package/dist/common/canonical-bridge.js.map +1 -0
- package/dist/common/canonical-json.d.ts +64 -0
- package/dist/common/canonical-json.d.ts.map +1 -0
- package/dist/common/canonical-json.js +95 -0
- package/dist/common/canonical-json.js.map +1 -0
- package/dist/common/circuit-breaker.d.ts +320 -0
- package/dist/common/circuit-breaker.d.ts.map +1 -0
- package/dist/common/circuit-breaker.js +887 -0
- package/dist/common/circuit-breaker.js.map +1 -0
- package/dist/common/config.d.ts +2053 -0
- package/dist/common/config.d.ts.map +1 -0
- package/dist/common/config.js +1314 -0
- package/dist/common/config.js.map +1 -0
- package/dist/common/contracts/index.d.ts +2 -0
- package/dist/common/contracts/index.d.ts.map +1 -0
- package/dist/common/contracts/index.js +2 -0
- package/dist/common/contracts/index.js.map +1 -0
- package/dist/common/contracts/output.d.ts +81 -0
- package/dist/common/contracts/output.d.ts.map +1 -0
- package/dist/common/contracts/output.js +38 -0
- package/dist/common/contracts/output.js.map +1 -0
- package/dist/common/crypto-utils.d.ts +103 -0
- package/dist/common/crypto-utils.d.ts.map +1 -0
- package/dist/common/crypto-utils.js +275 -0
- package/dist/common/crypto-utils.js.map +1 -0
- package/dist/common/crypto.d.ts +70 -0
- package/dist/common/crypto.d.ts.map +1 -0
- package/dist/common/crypto.js +201 -0
- package/dist/common/crypto.js.map +1 -0
- package/dist/common/database-resilience.d.ts +156 -0
- package/dist/common/database-resilience.d.ts.map +1 -0
- package/dist/common/database-resilience.js +269 -0
- package/dist/common/database-resilience.js.map +1 -0
- package/dist/common/db-metrics.d.ts +90 -0
- package/dist/common/db-metrics.d.ts.map +1 -0
- package/dist/common/db-metrics.js +219 -0
- package/dist/common/db-metrics.js.map +1 -0
- package/dist/common/db-pool.d.ts +307 -0
- package/dist/common/db-pool.d.ts.map +1 -0
- package/dist/common/db-pool.js +879 -0
- package/dist/common/db-pool.js.map +1 -0
- package/dist/common/db.d.ts +105 -0
- package/dist/common/db.d.ts.map +1 -0
- package/dist/common/db.js +216 -0
- package/dist/common/db.js.map +1 -0
- package/dist/common/debug-auth-middleware.d.ts +111 -0
- package/dist/common/debug-auth-middleware.d.ts.map +1 -0
- package/dist/common/debug-auth-middleware.js +285 -0
- package/dist/common/debug-auth-middleware.js.map +1 -0
- package/dist/common/di.d.ts +202 -0
- package/dist/common/di.d.ts.map +1 -0
- package/dist/common/di.js +219 -0
- package/dist/common/di.js.map +1 -0
- package/dist/common/encryption.d.ts +233 -0
- package/dist/common/encryption.d.ts.map +1 -0
- package/dist/common/encryption.js +527 -0
- package/dist/common/encryption.js.map +1 -0
- package/dist/common/error-sanitizer.d.ts +67 -0
- package/dist/common/error-sanitizer.d.ts.map +1 -0
- package/dist/common/error-sanitizer.js +298 -0
- package/dist/common/error-sanitizer.js.map +1 -0
- package/dist/common/errors.d.ts +229 -0
- package/dist/common/errors.d.ts.map +1 -0
- package/dist/common/errors.js +349 -0
- package/dist/common/errors.js.map +1 -0
- package/dist/common/expression/evaluator.d.ts +58 -0
- package/dist/common/expression/evaluator.d.ts.map +1 -0
- package/dist/common/expression/evaluator.js +326 -0
- package/dist/common/expression/evaluator.js.map +1 -0
- package/dist/common/expression/index.d.ts +180 -0
- package/dist/common/expression/index.d.ts.map +1 -0
- package/dist/common/expression/index.js +198 -0
- package/dist/common/expression/index.js.map +1 -0
- package/dist/common/expression/lexer.d.ts +69 -0
- package/dist/common/expression/lexer.d.ts.map +1 -0
- package/dist/common/expression/lexer.js +255 -0
- package/dist/common/expression/lexer.js.map +1 -0
- package/dist/common/expression/parser.d.ts +133 -0
- package/dist/common/expression/parser.d.ts.map +1 -0
- package/dist/common/expression/parser.js +293 -0
- package/dist/common/expression/parser.js.map +1 -0
- package/dist/common/group-membership.d.ts +119 -0
- package/dist/common/group-membership.d.ts.map +1 -0
- package/dist/common/group-membership.js +250 -0
- package/dist/common/group-membership.js.map +1 -0
- package/dist/common/index.d.ts +14 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +15 -0
- package/dist/common/index.js.map +1 -0
- package/dist/common/leader-election.d.ts +40 -0
- package/dist/common/leader-election.d.ts.map +1 -0
- package/dist/common/leader-election.js +232 -0
- package/dist/common/leader-election.js.map +1 -0
- package/dist/common/lock.d.ts +77 -0
- package/dist/common/lock.d.ts.map +1 -0
- package/dist/common/lock.js +167 -0
- package/dist/common/lock.js.map +1 -0
- package/dist/common/logger.d.ts +19 -0
- package/dist/common/logger.d.ts.map +1 -0
- package/dist/common/logger.js +80 -0
- package/dist/common/logger.js.map +1 -0
- package/dist/common/metrics-registry.d.ts +48 -0
- package/dist/common/metrics-registry.d.ts.map +1 -0
- package/dist/common/metrics-registry.js +77 -0
- package/dist/common/metrics-registry.js.map +1 -0
- package/dist/common/metrics.d.ts +204 -0
- package/dist/common/metrics.d.ts.map +1 -0
- package/dist/common/metrics.js +497 -0
- package/dist/common/metrics.js.map +1 -0
- package/dist/common/operation-tracker.d.ts +137 -0
- package/dist/common/operation-tracker.d.ts.map +1 -0
- package/dist/common/operation-tracker.js +366 -0
- package/dist/common/operation-tracker.js.map +1 -0
- package/dist/common/provenance/chain.d.ts +54 -0
- package/dist/common/provenance/chain.d.ts.map +1 -0
- package/dist/common/provenance/chain.js +252 -0
- package/dist/common/provenance/chain.js.map +1 -0
- package/dist/common/provenance/index.d.ts +14 -0
- package/dist/common/provenance/index.d.ts.map +1 -0
- package/dist/common/provenance/index.js +19 -0
- package/dist/common/provenance/index.js.map +1 -0
- package/dist/common/provenance/query.d.ts +111 -0
- package/dist/common/provenance/query.d.ts.map +1 -0
- package/dist/common/provenance/query.js +310 -0
- package/dist/common/provenance/query.js.map +1 -0
- package/dist/common/provenance/storage.d.ts +297 -0
- package/dist/common/provenance/storage.d.ts.map +1 -0
- package/dist/common/provenance/storage.js +436 -0
- package/dist/common/provenance/storage.js.map +1 -0
- package/dist/common/provenance/tracker.d.ts +57 -0
- package/dist/common/provenance/tracker.d.ts.map +1 -0
- package/dist/common/provenance/tracker.js +209 -0
- package/dist/common/provenance/tracker.js.map +1 -0
- package/dist/common/provenance/types.d.ts +146 -0
- package/dist/common/provenance/types.d.ts.map +1 -0
- package/dist/common/provenance/types.js +10 -0
- package/dist/common/provenance/types.js.map +1 -0
- package/dist/common/random.d.ts +84 -0
- package/dist/common/random.d.ts.map +1 -0
- package/dist/common/random.js +130 -0
- package/dist/common/random.js.map +1 -0
- package/dist/common/redaction.d.ts +49 -0
- package/dist/common/redaction.d.ts.map +1 -0
- package/dist/common/redaction.js +217 -0
- package/dist/common/redaction.js.map +1 -0
- package/dist/common/redis-cluster.d.ts +538 -0
- package/dist/common/redis-cluster.d.ts.map +1 -0
- package/dist/common/redis-cluster.js +1539 -0
- package/dist/common/redis-cluster.js.map +1 -0
- package/dist/common/redis-resilience.d.ts +270 -0
- package/dist/common/redis-resilience.d.ts.map +1 -0
- package/dist/common/redis-resilience.js +586 -0
- package/dist/common/redis-resilience.js.map +1 -0
- package/dist/common/redis.d.ts +19 -0
- package/dist/common/redis.d.ts.map +1 -0
- package/dist/common/redis.js +73 -0
- package/dist/common/redis.js.map +1 -0
- package/dist/common/safe-json.d.ts +246 -0
- package/dist/common/safe-json.d.ts.map +1 -0
- package/dist/common/safe-json.js +442 -0
- package/dist/common/safe-json.js.map +1 -0
- package/dist/common/secret-generator.d.ts +142 -0
- package/dist/common/secret-generator.d.ts.map +1 -0
- package/dist/common/secret-generator.js +286 -0
- package/dist/common/secret-generator.js.map +1 -0
- package/dist/common/secure-fetch.d.ts +182 -0
- package/dist/common/secure-fetch.d.ts.map +1 -0
- package/dist/common/secure-fetch.js +657 -0
- package/dist/common/secure-fetch.js.map +1 -0
- package/dist/common/security-mode.d.ts +151 -0
- package/dist/common/security-mode.d.ts.map +1 -0
- package/dist/common/security-mode.js +482 -0
- package/dist/common/security-mode.js.map +1 -0
- package/dist/common/telemetry/index.d.ts +82 -0
- package/dist/common/telemetry/index.d.ts.map +1 -0
- package/dist/common/telemetry/index.js +198 -0
- package/dist/common/telemetry/index.js.map +1 -0
- package/dist/common/telemetry/instrumentation.d.ts +167 -0
- package/dist/common/telemetry/instrumentation.d.ts.map +1 -0
- package/dist/common/telemetry/instrumentation.js +492 -0
- package/dist/common/telemetry/instrumentation.js.map +1 -0
- package/dist/common/telemetry/metrics-bridge.d.ts +227 -0
- package/dist/common/telemetry/metrics-bridge.d.ts.map +1 -0
- package/dist/common/telemetry/metrics-bridge.js +437 -0
- package/dist/common/telemetry/metrics-bridge.js.map +1 -0
- package/dist/common/telemetry/middleware.d.ts +114 -0
- package/dist/common/telemetry/middleware.d.ts.map +1 -0
- package/dist/common/telemetry/middleware.js +353 -0
- package/dist/common/telemetry/middleware.js.map +1 -0
- package/dist/common/telemetry/propagation.d.ts +221 -0
- package/dist/common/telemetry/propagation.d.ts.map +1 -0
- package/dist/common/telemetry/propagation.js +409 -0
- package/dist/common/telemetry/propagation.js.map +1 -0
- package/dist/common/telemetry/spans.d.ts +295 -0
- package/dist/common/telemetry/spans.d.ts.map +1 -0
- package/dist/common/telemetry/spans.js +439 -0
- package/dist/common/telemetry/spans.js.map +1 -0
- package/dist/common/telemetry/tracer.d.ts +155 -0
- package/dist/common/telemetry/tracer.d.ts.map +1 -0
- package/dist/common/telemetry/tracer.js +343 -0
- package/dist/common/telemetry/tracer.js.map +1 -0
- package/dist/common/telemetry.d.ts +15 -0
- package/dist/common/telemetry.d.ts.map +1 -0
- package/dist/common/telemetry.js +61 -0
- package/dist/common/telemetry.js.map +1 -0
- package/dist/common/tenant-context.d.ts +253 -0
- package/dist/common/tenant-context.d.ts.map +1 -0
- package/dist/common/tenant-context.js +259 -0
- package/dist/common/tenant-context.js.map +1 -0
- package/dist/common/tenant-verification.d.ts +86 -0
- package/dist/common/tenant-verification.d.ts.map +1 -0
- package/dist/common/tenant-verification.js +184 -0
- package/dist/common/tenant-verification.js.map +1 -0
- package/dist/common/timeout.d.ts +40 -0
- package/dist/common/timeout.d.ts.map +1 -0
- package/dist/common/timeout.js +82 -0
- package/dist/common/timeout.js.map +1 -0
- package/dist/common/token-revocation.d.ts +44 -0
- package/dist/common/token-revocation.d.ts.map +1 -0
- package/dist/common/token-revocation.js +169 -0
- package/dist/common/token-revocation.js.map +1 -0
- package/dist/common/trace.d.ts +149 -0
- package/dist/common/trace.d.ts.map +1 -0
- package/dist/common/trace.js +328 -0
- package/dist/common/trace.js.map +1 -0
- package/dist/common/trust-cache.d.ts +263 -0
- package/dist/common/trust-cache.d.ts.map +1 -0
- package/dist/common/trust-cache.js +670 -0
- package/dist/common/trust-cache.js.map +1 -0
- package/dist/common/types.d.ts +351 -0
- package/dist/common/types.d.ts.map +1 -0
- package/dist/common/types.js +55 -0
- package/dist/common/types.js.map +1 -0
- package/dist/common/validation.d.ts +113 -0
- package/dist/common/validation.d.ts.map +1 -0
- package/dist/common/validation.js +221 -0
- package/dist/common/validation.js.map +1 -0
- package/dist/db/client.d.ts +72 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +110 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/index.d.ts +9 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +9 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema/merkle.d.ts +475 -0
- package/dist/db/schema/merkle.d.ts.map +1 -0
- package/dist/db/schema/merkle.js +100 -0
- package/dist/db/schema/merkle.js.map +1 -0
- package/dist/db/schema/proofs.d.ts +412 -0
- package/dist/db/schema/proofs.d.ts.map +1 -0
- package/dist/db/schema/proofs.js +63 -0
- package/dist/db/schema/proofs.js.map +1 -0
- package/dist/enforce/adapters.d.ts +73 -0
- package/dist/enforce/adapters.d.ts.map +1 -0
- package/dist/enforce/adapters.js +293 -0
- package/dist/enforce/adapters.js.map +1 -0
- package/dist/enforce/index.d.ts +213 -0
- package/dist/enforce/index.d.ts.map +1 -0
- package/dist/enforce/index.js +630 -0
- package/dist/enforce/index.js.map +1 -0
- package/dist/enforce/repository.d.ts +203 -0
- package/dist/enforce/repository.d.ts.map +1 -0
- package/dist/enforce/repository.js +359 -0
- package/dist/enforce/repository.js.map +1 -0
- package/dist/enforce/schema.d.ts +1198 -0
- package/dist/enforce/schema.d.ts.map +1 -0
- package/dist/enforce/schema.js +257 -0
- package/dist/enforce/schema.js.map +1 -0
- package/dist/friction/index.d.ts +235 -0
- package/dist/friction/index.d.ts.map +1 -0
- package/dist/friction/index.js +636 -0
- package/dist/friction/index.js.map +1 -0
- package/dist/friction/openapi.d.ts +23 -0
- package/dist/friction/openapi.d.ts.map +1 -0
- package/dist/friction/openapi.js +883 -0
- package/dist/friction/openapi.js.map +1 -0
- package/dist/friction/routes.d.ts +14 -0
- package/dist/friction/routes.d.ts.map +1 -0
- package/dist/friction/routes.js +206 -0
- package/dist/friction/routes.js.map +1 -0
- package/dist/governance/engine.d.ts +158 -0
- package/dist/governance/engine.d.ts.map +1 -0
- package/dist/governance/engine.js +248 -0
- package/dist/governance/engine.js.map +1 -0
- package/dist/governance/evaluator.d.ts +106 -0
- package/dist/governance/evaluator.d.ts.map +1 -0
- package/dist/governance/evaluator.js +277 -0
- package/dist/governance/evaluator.js.map +1 -0
- package/dist/governance/index.d.ts +11 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +14 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/policy.d.ts +152 -0
- package/dist/governance/policy.d.ts.map +1 -0
- package/dist/governance/policy.js +152 -0
- package/dist/governance/policy.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/intent/adapters.d.ts +101 -0
- package/dist/intent/adapters.d.ts.map +1 -0
- package/dist/intent/adapters.js +250 -0
- package/dist/intent/adapters.js.map +1 -0
- package/dist/intent/audit.d.ts +119 -0
- package/dist/intent/audit.d.ts.map +1 -0
- package/dist/intent/audit.js +463 -0
- package/dist/intent/audit.js.map +1 -0
- package/dist/intent/classifier/index.d.ts +121 -0
- package/dist/intent/classifier/index.d.ts.map +1 -0
- package/dist/intent/classifier/index.js +232 -0
- package/dist/intent/classifier/index.js.map +1 -0
- package/dist/intent/classifier/patterns.d.ts +129 -0
- package/dist/intent/classifier/patterns.d.ts.map +1 -0
- package/dist/intent/classifier/patterns.js +471 -0
- package/dist/intent/classifier/patterns.js.map +1 -0
- package/dist/intent/classifier/risk.d.ts +177 -0
- package/dist/intent/classifier/risk.d.ts.map +1 -0
- package/dist/intent/classifier/risk.js +335 -0
- package/dist/intent/classifier/risk.js.map +1 -0
- package/dist/intent/cleanup.d.ts +24 -0
- package/dist/intent/cleanup.d.ts.map +1 -0
- package/dist/intent/cleanup.js +104 -0
- package/dist/intent/cleanup.js.map +1 -0
- package/dist/intent/consent.d.ts +238 -0
- package/dist/intent/consent.d.ts.map +1 -0
- package/dist/intent/consent.js +427 -0
- package/dist/intent/consent.js.map +1 -0
- package/dist/intent/escalation.d.ts +284 -0
- package/dist/intent/escalation.d.ts.map +1 -0
- package/dist/intent/escalation.js +618 -0
- package/dist/intent/escalation.js.map +1 -0
- package/dist/intent/gdpr-rate-limiter.d.ts +170 -0
- package/dist/intent/gdpr-rate-limiter.d.ts.map +1 -0
- package/dist/intent/gdpr-rate-limiter.js +385 -0
- package/dist/intent/gdpr-rate-limiter.js.map +1 -0
- package/dist/intent/gdpr.d.ts +323 -0
- package/dist/intent/gdpr.d.ts.map +1 -0
- package/dist/intent/gdpr.js +1013 -0
- package/dist/intent/gdpr.js.map +1 -0
- package/dist/intent/health.d.ts +214 -0
- package/dist/intent/health.d.ts.map +1 -0
- package/dist/intent/health.js +526 -0
- package/dist/intent/health.js.map +1 -0
- package/dist/intent/index.d.ts +565 -0
- package/dist/intent/index.d.ts.map +1 -0
- package/dist/intent/index.js +756 -0
- package/dist/intent/index.js.map +1 -0
- package/dist/intent/metrics.d.ts +399 -0
- package/dist/intent/metrics.d.ts.map +1 -0
- package/dist/intent/metrics.js +886 -0
- package/dist/intent/metrics.js.map +1 -0
- package/dist/intent/openapi.d.ts +22 -0
- package/dist/intent/openapi.d.ts.map +1 -0
- package/dist/intent/openapi.js +1674 -0
- package/dist/intent/openapi.js.map +1 -0
- package/dist/intent/planner/dependency.d.ts +78 -0
- package/dist/intent/planner/dependency.d.ts.map +1 -0
- package/dist/intent/planner/dependency.js +334 -0
- package/dist/intent/planner/dependency.js.map +1 -0
- package/dist/intent/planner/index.d.ts +130 -0
- package/dist/intent/planner/index.d.ts.map +1 -0
- package/dist/intent/planner/index.js +372 -0
- package/dist/intent/planner/index.js.map +1 -0
- package/dist/intent/planner/rollback.d.ts +92 -0
- package/dist/intent/planner/rollback.d.ts.map +1 -0
- package/dist/intent/planner/rollback.js +326 -0
- package/dist/intent/planner/rollback.js.map +1 -0
- package/dist/intent/planner/templates.d.ts +81 -0
- package/dist/intent/planner/templates.d.ts.map +1 -0
- package/dist/intent/planner/templates.js +560 -0
- package/dist/intent/planner/templates.js.map +1 -0
- package/dist/intent/planner/types.d.ts +38 -0
- package/dist/intent/planner/types.d.ts.map +1 -0
- package/dist/intent/planner/types.js +10 -0
- package/dist/intent/planner/types.js.map +1 -0
- package/dist/intent/queue.d.ts +150 -0
- package/dist/intent/queue.d.ts.map +1 -0
- package/dist/intent/queue.js +339 -0
- package/dist/intent/queue.js.map +1 -0
- package/dist/intent/queues.d.ts +176 -0
- package/dist/intent/queues.d.ts.map +1 -0
- package/dist/intent/queues.js +1393 -0
- package/dist/intent/queues.js.map +1 -0
- package/dist/intent/ratelimit.d.ts +147 -0
- package/dist/intent/ratelimit.d.ts.map +1 -0
- package/dist/intent/ratelimit.js +301 -0
- package/dist/intent/ratelimit.js.map +1 -0
- package/dist/intent/replay/comparator.d.ts +73 -0
- package/dist/intent/replay/comparator.d.ts.map +1 -0
- package/dist/intent/replay/comparator.js +320 -0
- package/dist/intent/replay/comparator.js.map +1 -0
- package/dist/intent/replay/index.d.ts +104 -0
- package/dist/intent/replay/index.d.ts.map +1 -0
- package/dist/intent/replay/index.js +487 -0
- package/dist/intent/replay/index.js.map +1 -0
- package/dist/intent/replay/simulator.d.ts +184 -0
- package/dist/intent/replay/simulator.d.ts.map +1 -0
- package/dist/intent/replay/simulator.js +512 -0
- package/dist/intent/replay/simulator.js.map +1 -0
- package/dist/intent/replay/snapshot.d.ts +149 -0
- package/dist/intent/replay/snapshot.d.ts.map +1 -0
- package/dist/intent/replay/snapshot.js +245 -0
- package/dist/intent/replay/snapshot.js.map +1 -0
- package/dist/intent/replay/types.d.ts +143 -0
- package/dist/intent/replay/types.d.ts.map +1 -0
- package/dist/intent/replay/types.js +10 -0
- package/dist/intent/replay/types.js.map +1 -0
- package/dist/intent/repository.d.ts +198 -0
- package/dist/intent/repository.d.ts.map +1 -0
- package/dist/intent/repository.js +538 -0
- package/dist/intent/repository.js.map +1 -0
- package/dist/intent/response-middleware.d.ts +156 -0
- package/dist/intent/response-middleware.d.ts.map +1 -0
- package/dist/intent/response-middleware.js +346 -0
- package/dist/intent/response-middleware.js.map +1 -0
- package/dist/intent/response.d.ts +267 -0
- package/dist/intent/response.d.ts.map +1 -0
- package/dist/intent/response.js +402 -0
- package/dist/intent/response.js.map +1 -0
- package/dist/intent/routes.d.ts +35 -0
- package/dist/intent/routes.d.ts.map +1 -0
- package/dist/intent/routes.js +1023 -0
- package/dist/intent/routes.js.map +1 -0
- package/dist/intent/scheduler.d.ts +45 -0
- package/dist/intent/scheduler.d.ts.map +1 -0
- package/dist/intent/scheduler.js +221 -0
- package/dist/intent/scheduler.js.map +1 -0
- package/dist/intent/schema.d.ts +3817 -0
- package/dist/intent/schema.d.ts.map +1 -0
- package/dist/intent/schema.js +631 -0
- package/dist/intent/schema.js.map +1 -0
- package/dist/intent/shutdown.d.ts +145 -0
- package/dist/intent/shutdown.d.ts.map +1 -0
- package/dist/intent/shutdown.js +468 -0
- package/dist/intent/shutdown.js.map +1 -0
- package/dist/intent/state-machine.d.ts +111 -0
- package/dist/intent/state-machine.d.ts.map +1 -0
- package/dist/intent/state-machine.js +242 -0
- package/dist/intent/state-machine.js.map +1 -0
- package/dist/intent/tracing.d.ts +152 -0
- package/dist/intent/tracing.d.ts.map +1 -0
- package/dist/intent/tracing.js +658 -0
- package/dist/intent/tracing.js.map +1 -0
- package/dist/intent/types.d.ts +188 -0
- package/dist/intent/types.d.ts.map +1 -0
- package/dist/intent/types.js +25 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/intent/webhooks/delivery-repository.d.ts +80 -0
- package/dist/intent/webhooks/delivery-repository.d.ts.map +1 -0
- package/dist/intent/webhooks/delivery-repository.js +251 -0
- package/dist/intent/webhooks/delivery-repository.js.map +1 -0
- package/dist/intent/webhooks/dns-pinning.d.ts +30 -0
- package/dist/intent/webhooks/dns-pinning.d.ts.map +1 -0
- package/dist/intent/webhooks/dns-pinning.js +69 -0
- package/dist/intent/webhooks/dns-pinning.js.map +1 -0
- package/dist/intent/webhooks/index.d.ts +14 -0
- package/dist/intent/webhooks/index.d.ts.map +1 -0
- package/dist/intent/webhooks/index.js +17 -0
- package/dist/intent/webhooks/index.js.map +1 -0
- package/dist/intent/webhooks/signature.d.ts +47 -0
- package/dist/intent/webhooks/signature.d.ts.map +1 -0
- package/dist/intent/webhooks/signature.js +80 -0
- package/dist/intent/webhooks/signature.js.map +1 -0
- package/dist/intent/webhooks/ssrf-protection.d.ts +29 -0
- package/dist/intent/webhooks/ssrf-protection.d.ts.map +1 -0
- package/dist/intent/webhooks/ssrf-protection.js +161 -0
- package/dist/intent/webhooks/ssrf-protection.js.map +1 -0
- package/dist/intent/webhooks/types.d.ts +132 -0
- package/dist/intent/webhooks/types.d.ts.map +1 -0
- package/dist/intent/webhooks/types.js +14 -0
- package/dist/intent/webhooks/types.js.map +1 -0
- package/dist/intent/webhooks.d.ts +618 -0
- package/dist/intent/webhooks.d.ts.map +1 -0
- package/dist/intent/webhooks.js +1836 -0
- package/dist/intent/webhooks.js.map +1 -0
- package/dist/intent-gateway/ai-act-classifier.d.ts +18 -0
- package/dist/intent-gateway/ai-act-classifier.d.ts.map +1 -0
- package/dist/intent-gateway/ai-act-classifier.js +296 -0
- package/dist/intent-gateway/ai-act-classifier.js.map +1 -0
- package/dist/intent-gateway/index.d.ts +43 -0
- package/dist/intent-gateway/index.d.ts.map +1 -0
- package/dist/intent-gateway/index.js +236 -0
- package/dist/intent-gateway/index.js.map +1 -0
- package/dist/intent-gateway/jurisdiction-resolver.d.ts +19 -0
- package/dist/intent-gateway/jurisdiction-resolver.d.ts.map +1 -0
- package/dist/intent-gateway/jurisdiction-resolver.js +236 -0
- package/dist/intent-gateway/jurisdiction-resolver.js.map +1 -0
- package/dist/intent-gateway/policy-composer.d.ts +27 -0
- package/dist/intent-gateway/policy-composer.d.ts.map +1 -0
- package/dist/intent-gateway/policy-composer.js +418 -0
- package/dist/intent-gateway/policy-composer.js.map +1 -0
- package/dist/intent-gateway/regime-selector.d.ts +26 -0
- package/dist/intent-gateway/regime-selector.d.ts.map +1 -0
- package/dist/intent-gateway/regime-selector.js +185 -0
- package/dist/intent-gateway/regime-selector.js.map +1 -0
- package/dist/intent-gateway/types.d.ts +103 -0
- package/dist/intent-gateway/types.d.ts.map +1 -0
- package/dist/intent-gateway/types.js +85 -0
- package/dist/intent-gateway/types.js.map +1 -0
- package/dist/observability/alerts.d.ts +136 -0
- package/dist/observability/alerts.d.ts.map +1 -0
- package/dist/observability/alerts.js +485 -0
- package/dist/observability/alerts.js.map +1 -0
- package/dist/observability/health.d.ts +102 -0
- package/dist/observability/health.d.ts.map +1 -0
- package/dist/observability/health.js +415 -0
- package/dist/observability/health.js.map +1 -0
- package/dist/observability/index.d.ts +29 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +72 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/logging.d.ts +90 -0
- package/dist/observability/logging.d.ts.map +1 -0
- package/dist/observability/logging.js +260 -0
- package/dist/observability/logging.js.map +1 -0
- package/dist/observability/metrics.d.ts +226 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +527 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/tracing.d.ts +120 -0
- package/dist/observability/tracing.d.ts.map +1 -0
- package/dist/observability/tracing.js +285 -0
- package/dist/observability/tracing.js.map +1 -0
- package/dist/persistence/audit.d.ts +169 -0
- package/dist/persistence/audit.d.ts.map +1 -0
- package/dist/persistence/audit.js +342 -0
- package/dist/persistence/audit.js.map +1 -0
- package/dist/persistence/index.d.ts +13 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +15 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/repository.d.ts +192 -0
- package/dist/persistence/repository.d.ts.map +1 -0
- package/dist/persistence/repository.js +223 -0
- package/dist/persistence/repository.js.map +1 -0
- package/dist/policy/diff.d.ts +88 -0
- package/dist/policy/diff.d.ts.map +1 -0
- package/dist/policy/diff.js +325 -0
- package/dist/policy/diff.js.map +1 -0
- package/dist/policy/distributed-cache.d.ts +205 -0
- package/dist/policy/distributed-cache.d.ts.map +1 -0
- package/dist/policy/distributed-cache.js +683 -0
- package/dist/policy/distributed-cache.js.map +1 -0
- package/dist/policy/evaluator.d.ts +102 -0
- package/dist/policy/evaluator.d.ts.map +1 -0
- package/dist/policy/evaluator.js +648 -0
- package/dist/policy/evaluator.js.map +1 -0
- package/dist/policy/index.d.ts +24 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +27 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/loader.d.ts +63 -0
- package/dist/policy/loader.d.ts.map +1 -0
- package/dist/policy/loader.js +176 -0
- package/dist/policy/loader.js.map +1 -0
- package/dist/policy/service.d.ts +240 -0
- package/dist/policy/service.d.ts.map +1 -0
- package/dist/policy/service.js +1032 -0
- package/dist/policy/service.js.map +1 -0
- package/dist/policy/types.d.ts +220 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +36 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/policy/visual-builder/index.d.ts +201 -0
- package/dist/policy/visual-builder/index.d.ts.map +1 -0
- package/dist/policy/visual-builder/index.js +727 -0
- package/dist/policy/visual-builder/index.js.map +1 -0
- package/dist/policy/visual-builder/inheritance.d.ts +151 -0
- package/dist/policy/visual-builder/inheritance.d.ts.map +1 -0
- package/dist/policy/visual-builder/inheritance.js +314 -0
- package/dist/policy/visual-builder/inheritance.js.map +1 -0
- package/dist/policy/visual-builder/propagation.d.ts +146 -0
- package/dist/policy/visual-builder/propagation.d.ts.map +1 -0
- package/dist/policy/visual-builder/propagation.js +299 -0
- package/dist/policy/visual-builder/propagation.js.map +1 -0
- package/dist/policy/visual-builder/routes.d.ts +14 -0
- package/dist/policy/visual-builder/routes.d.ts.map +1 -0
- package/dist/policy/visual-builder/routes.js +528 -0
- package/dist/policy/visual-builder/routes.js.map +1 -0
- package/dist/policy/visual-builder/simulator.d.ts +161 -0
- package/dist/policy/visual-builder/simulator.d.ts.map +1 -0
- package/dist/policy/visual-builder/simulator.js +413 -0
- package/dist/policy/visual-builder/simulator.js.map +1 -0
- package/dist/policy/visual-builder/templates.d.ts +119 -0
- package/dist/policy/visual-builder/templates.d.ts.map +1 -0
- package/dist/policy/visual-builder/templates.js +627 -0
- package/dist/policy/visual-builder/templates.js.map +1 -0
- package/dist/proof/chain/index.d.ts +271 -0
- package/dist/proof/chain/index.d.ts.map +1 -0
- package/dist/proof/chain/index.js +483 -0
- package/dist/proof/chain/index.js.map +1 -0
- package/dist/proof/index.d.ts +206 -0
- package/dist/proof/index.d.ts.map +1 -0
- package/dist/proof/index.js +597 -0
- package/dist/proof/index.js.map +1 -0
- package/dist/proof/merkle-service.d.ts +194 -0
- package/dist/proof/merkle-service.d.ts.map +1 -0
- package/dist/proof/merkle-service.js +463 -0
- package/dist/proof/merkle-service.js.map +1 -0
- package/dist/proof/merkle.d.ts +118 -0
- package/dist/proof/merkle.d.ts.map +1 -0
- package/dist/proof/merkle.js +265 -0
- package/dist/proof/merkle.js.map +1 -0
- package/dist/security/ai-governance/access-policy.d.ts +197 -0
- package/dist/security/ai-governance/access-policy.d.ts.map +1 -0
- package/dist/security/ai-governance/access-policy.js +522 -0
- package/dist/security/ai-governance/access-policy.js.map +1 -0
- package/dist/security/ai-governance/audit-trail.d.ts +241 -0
- package/dist/security/ai-governance/audit-trail.d.ts.map +1 -0
- package/dist/security/ai-governance/audit-trail.js +645 -0
- package/dist/security/ai-governance/audit-trail.js.map +1 -0
- package/dist/security/ai-governance/bias-detection.d.ts +221 -0
- package/dist/security/ai-governance/bias-detection.d.ts.map +1 -0
- package/dist/security/ai-governance/bias-detection.js +615 -0
- package/dist/security/ai-governance/bias-detection.js.map +1 -0
- package/dist/security/ai-governance/index.d.ts +92 -0
- package/dist/security/ai-governance/index.d.ts.map +1 -0
- package/dist/security/ai-governance/index.js +184 -0
- package/dist/security/ai-governance/index.js.map +1 -0
- package/dist/security/ai-governance/middleware.d.ts +110 -0
- package/dist/security/ai-governance/middleware.d.ts.map +1 -0
- package/dist/security/ai-governance/middleware.js +359 -0
- package/dist/security/ai-governance/middleware.js.map +1 -0
- package/dist/security/ai-governance/model-registry.d.ts +229 -0
- package/dist/security/ai-governance/model-registry.d.ts.map +1 -0
- package/dist/security/ai-governance/model-registry.js +535 -0
- package/dist/security/ai-governance/model-registry.js.map +1 -0
- package/dist/security/ai-governance/output-filter.d.ts +150 -0
- package/dist/security/ai-governance/output-filter.d.ts.map +1 -0
- package/dist/security/ai-governance/output-filter.js +561 -0
- package/dist/security/ai-governance/output-filter.js.map +1 -0
- package/dist/security/ai-governance/prompt-injection.d.ts +153 -0
- package/dist/security/ai-governance/prompt-injection.d.ts.map +1 -0
- package/dist/security/ai-governance/prompt-injection.js +614 -0
- package/dist/security/ai-governance/prompt-injection.js.map +1 -0
- package/dist/security/ai-governance/rate-limiter.d.ts +156 -0
- package/dist/security/ai-governance/rate-limiter.d.ts.map +1 -0
- package/dist/security/ai-governance/rate-limiter.js +541 -0
- package/dist/security/ai-governance/rate-limiter.js.map +1 -0
- package/dist/security/ai-governance/types.d.ts +594 -0
- package/dist/security/ai-governance/types.d.ts.map +1 -0
- package/dist/security/ai-governance/types.js +6 -0
- package/dist/security/ai-governance/types.js.map +1 -0
- package/dist/security/alerting/channels/base.d.ts +91 -0
- package/dist/security/alerting/channels/base.d.ts.map +1 -0
- package/dist/security/alerting/channels/base.js +128 -0
- package/dist/security/alerting/channels/base.js.map +1 -0
- package/dist/security/alerting/channels/email.d.ts +92 -0
- package/dist/security/alerting/channels/email.d.ts.map +1 -0
- package/dist/security/alerting/channels/email.js +418 -0
- package/dist/security/alerting/channels/email.js.map +1 -0
- package/dist/security/alerting/channels/http-base.d.ts +86 -0
- package/dist/security/alerting/channels/http-base.d.ts.map +1 -0
- package/dist/security/alerting/channels/http-base.js +133 -0
- package/dist/security/alerting/channels/http-base.js.map +1 -0
- package/dist/security/alerting/channels/index.d.ts +30 -0
- package/dist/security/alerting/channels/index.d.ts.map +1 -0
- package/dist/security/alerting/channels/index.js +22 -0
- package/dist/security/alerting/channels/index.js.map +1 -0
- package/dist/security/alerting/channels/pagerduty.d.ts +70 -0
- package/dist/security/alerting/channels/pagerduty.d.ts.map +1 -0
- package/dist/security/alerting/channels/pagerduty.js +248 -0
- package/dist/security/alerting/channels/pagerduty.js.map +1 -0
- package/dist/security/alerting/channels/slack.d.ts +55 -0
- package/dist/security/alerting/channels/slack.d.ts.map +1 -0
- package/dist/security/alerting/channels/slack.js +215 -0
- package/dist/security/alerting/channels/slack.js.map +1 -0
- package/dist/security/alerting/channels/sns.d.ts +87 -0
- package/dist/security/alerting/channels/sns.d.ts.map +1 -0
- package/dist/security/alerting/channels/sns.js +251 -0
- package/dist/security/alerting/channels/sns.js.map +1 -0
- package/dist/security/alerting/channels/webhook.d.ts +92 -0
- package/dist/security/alerting/channels/webhook.d.ts.map +1 -0
- package/dist/security/alerting/channels/webhook.js +203 -0
- package/dist/security/alerting/channels/webhook.js.map +1 -0
- package/dist/security/alerting/detector.d.ts +217 -0
- package/dist/security/alerting/detector.d.ts.map +1 -0
- package/dist/security/alerting/detector.js +725 -0
- package/dist/security/alerting/detector.js.map +1 -0
- package/dist/security/alerting/index.d.ts +57 -0
- package/dist/security/alerting/index.d.ts.map +1 -0
- package/dist/security/alerting/index.js +214 -0
- package/dist/security/alerting/index.js.map +1 -0
- package/dist/security/alerting/service.d.ts +190 -0
- package/dist/security/alerting/service.d.ts.map +1 -0
- package/dist/security/alerting/service.js +815 -0
- package/dist/security/alerting/service.js.map +1 -0
- package/dist/security/alerting/types.d.ts +2165 -0
- package/dist/security/alerting/types.d.ts.map +1 -0
- package/dist/security/alerting/types.js +278 -0
- package/dist/security/alerting/types.js.map +1 -0
- package/dist/security/anomaly/detectors/account-compromise.d.ts +198 -0
- package/dist/security/anomaly/detectors/account-compromise.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/account-compromise.js +815 -0
- package/dist/security/anomaly/detectors/account-compromise.js.map +1 -0
- package/dist/security/anomaly/detectors/data-exfiltration.d.ts +175 -0
- package/dist/security/anomaly/detectors/data-exfiltration.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/data-exfiltration.js +733 -0
- package/dist/security/anomaly/detectors/data-exfiltration.js.map +1 -0
- package/dist/security/anomaly/detectors/geographic.d.ts +100 -0
- package/dist/security/anomaly/detectors/geographic.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/geographic.js +348 -0
- package/dist/security/anomaly/detectors/geographic.js.map +1 -0
- package/dist/security/anomaly/detectors/index.d.ts +86 -0
- package/dist/security/anomaly/detectors/index.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/index.js +118 -0
- package/dist/security/anomaly/detectors/index.js.map +1 -0
- package/dist/security/anomaly/detectors/lateral-movement.d.ts +168 -0
- package/dist/security/anomaly/detectors/lateral-movement.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/lateral-movement.js +795 -0
- package/dist/security/anomaly/detectors/lateral-movement.js.map +1 -0
- package/dist/security/anomaly/detectors/privilege-escalation.d.ts +177 -0
- package/dist/security/anomaly/detectors/privilege-escalation.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/privilege-escalation.js +741 -0
- package/dist/security/anomaly/detectors/privilege-escalation.js.map +1 -0
- package/dist/security/anomaly/detectors/temporal.d.ts +71 -0
- package/dist/security/anomaly/detectors/temporal.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/temporal.js +398 -0
- package/dist/security/anomaly/detectors/temporal.js.map +1 -0
- package/dist/security/anomaly/detectors/volume.d.ts +97 -0
- package/dist/security/anomaly/detectors/volume.d.ts.map +1 -0
- package/dist/security/anomaly/detectors/volume.js +424 -0
- package/dist/security/anomaly/detectors/volume.js.map +1 -0
- package/dist/security/anomaly/index.d.ts +128 -0
- package/dist/security/anomaly/index.d.ts.map +1 -0
- package/dist/security/anomaly/index.js +378 -0
- package/dist/security/anomaly/index.js.map +1 -0
- package/dist/security/anomaly/types.d.ts +1209 -0
- package/dist/security/anomaly/types.d.ts.map +1 -0
- package/dist/security/anomaly/types.js +193 -0
- package/dist/security/anomaly/types.js.map +1 -0
- package/dist/security/api-keys/cache.d.ts +255 -0
- package/dist/security/api-keys/cache.d.ts.map +1 -0
- package/dist/security/api-keys/cache.js +595 -0
- package/dist/security/api-keys/cache.js.map +1 -0
- package/dist/security/api-keys/db-store.d.ts +150 -0
- package/dist/security/api-keys/db-store.d.ts.map +1 -0
- package/dist/security/api-keys/db-store.js +694 -0
- package/dist/security/api-keys/db-store.js.map +1 -0
- package/dist/security/api-keys/index.d.ts +29 -0
- package/dist/security/api-keys/index.d.ts.map +1 -0
- package/dist/security/api-keys/index.js +81 -0
- package/dist/security/api-keys/index.js.map +1 -0
- package/dist/security/api-keys/middleware.d.ts +164 -0
- package/dist/security/api-keys/middleware.d.ts.map +1 -0
- package/dist/security/api-keys/middleware.js +392 -0
- package/dist/security/api-keys/middleware.js.map +1 -0
- package/dist/security/api-keys/service.d.ts +226 -0
- package/dist/security/api-keys/service.d.ts.map +1 -0
- package/dist/security/api-keys/service.js +861 -0
- package/dist/security/api-keys/service.js.map +1 -0
- package/dist/security/api-keys/store.d.ts +241 -0
- package/dist/security/api-keys/store.d.ts.map +1 -0
- package/dist/security/api-keys/store.js +360 -0
- package/dist/security/api-keys/store.js.map +1 -0
- package/dist/security/api-keys/types.d.ts +718 -0
- package/dist/security/api-keys/types.d.ts.map +1 -0
- package/dist/security/api-keys/types.js +162 -0
- package/dist/security/api-keys/types.js.map +1 -0
- package/dist/security/brute-force.d.ts +390 -0
- package/dist/security/brute-force.d.ts.map +1 -0
- package/dist/security/brute-force.js +677 -0
- package/dist/security/brute-force.js.map +1 -0
- package/dist/security/config-validator.d.ts +152 -0
- package/dist/security/config-validator.d.ts.map +1 -0
- package/dist/security/config-validator.js +667 -0
- package/dist/security/config-validator.js.map +1 -0
- package/dist/security/crypto/fips-mode.d.ts +726 -0
- package/dist/security/crypto/fips-mode.d.ts.map +1 -0
- package/dist/security/crypto/fips-mode.js +1297 -0
- package/dist/security/crypto/fips-mode.js.map +1 -0
- package/dist/security/crypto/index.d.ts +203 -0
- package/dist/security/crypto/index.d.ts.map +1 -0
- package/dist/security/crypto/index.js +293 -0
- package/dist/security/crypto/index.js.map +1 -0
- package/dist/security/crypto/post-quantum/benchmark.d.ts +125 -0
- package/dist/security/crypto/post-quantum/benchmark.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/benchmark.js +530 -0
- package/dist/security/crypto/post-quantum/benchmark.js.map +1 -0
- package/dist/security/crypto/post-quantum/dilithium.d.ts +146 -0
- package/dist/security/crypto/post-quantum/dilithium.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/dilithium.js +662 -0
- package/dist/security/crypto/post-quantum/dilithium.js.map +1 -0
- package/dist/security/crypto/post-quantum/hybrid.d.ts +267 -0
- package/dist/security/crypto/post-quantum/hybrid.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/hybrid.js +457 -0
- package/dist/security/crypto/post-quantum/hybrid.js.map +1 -0
- package/dist/security/crypto/post-quantum/index.d.ts +166 -0
- package/dist/security/crypto/post-quantum/index.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/index.js +236 -0
- package/dist/security/crypto/post-quantum/index.js.map +1 -0
- package/dist/security/crypto/post-quantum/kyber.d.ts +131 -0
- package/dist/security/crypto/post-quantum/kyber.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/kyber.js +640 -0
- package/dist/security/crypto/post-quantum/kyber.js.map +1 -0
- package/dist/security/crypto/post-quantum/migration.d.ts +230 -0
- package/dist/security/crypto/post-quantum/migration.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/migration.js +563 -0
- package/dist/security/crypto/post-quantum/migration.js.map +1 -0
- package/dist/security/crypto/post-quantum/types.d.ts +1056 -0
- package/dist/security/crypto/post-quantum/types.d.ts.map +1 -0
- package/dist/security/crypto/post-quantum/types.js +350 -0
- package/dist/security/crypto/post-quantum/types.js.map +1 -0
- package/dist/security/crypto/shamir/comparison.d.ts +128 -0
- package/dist/security/crypto/shamir/comparison.d.ts.map +1 -0
- package/dist/security/crypto/shamir/comparison.js +423 -0
- package/dist/security/crypto/shamir/comparison.js.map +1 -0
- package/dist/security/crypto/shamir/index.d.ts +76 -0
- package/dist/security/crypto/shamir/index.d.ts.map +1 -0
- package/dist/security/crypto/shamir/index.js +155 -0
- package/dist/security/crypto/shamir/index.js.map +1 -0
- package/dist/security/crypto/shamir/proofs.d.ts +259 -0
- package/dist/security/crypto/shamir/proofs.d.ts.map +1 -0
- package/dist/security/crypto/shamir/proofs.js +605 -0
- package/dist/security/crypto/shamir/proofs.js.map +1 -0
- package/dist/security/crypto/shamir/property-tests.d.ts +104 -0
- package/dist/security/crypto/shamir/property-tests.d.ts.map +1 -0
- package/dist/security/crypto/shamir/property-tests.js +480 -0
- package/dist/security/crypto/shamir/property-tests.js.map +1 -0
- package/dist/security/crypto/shamir/security-analysis.d.ts +97 -0
- package/dist/security/crypto/shamir/security-analysis.d.ts.map +1 -0
- package/dist/security/crypto/shamir/security-analysis.js +503 -0
- package/dist/security/crypto/shamir/security-analysis.js.map +1 -0
- package/dist/security/crypto/shamir/test-vectors.d.ts +116 -0
- package/dist/security/crypto/shamir/test-vectors.d.ts.map +1 -0
- package/dist/security/crypto/shamir/test-vectors.js +377 -0
- package/dist/security/crypto/shamir/test-vectors.js.map +1 -0
- package/dist/security/crypto/shamir/types.d.ts +281 -0
- package/dist/security/crypto/shamir/types.d.ts.map +1 -0
- package/dist/security/crypto/shamir/types.js +82 -0
- package/dist/security/crypto/shamir/types.js.map +1 -0
- package/dist/security/crypto/shamir/verified-shamir.d.ts +170 -0
- package/dist/security/crypto/shamir/verified-shamir.d.ts.map +1 -0
- package/dist/security/crypto/shamir/verified-shamir.js +624 -0
- package/dist/security/crypto/shamir/verified-shamir.js.map +1 -0
- package/dist/security/csrf.d.ts +215 -0
- package/dist/security/csrf.d.ts.map +1 -0
- package/dist/security/csrf.js +467 -0
- package/dist/security/csrf.js.map +1 -0
- package/dist/security/distributed-state.d.ts +331 -0
- package/dist/security/distributed-state.d.ts.map +1 -0
- package/dist/security/distributed-state.js +768 -0
- package/dist/security/distributed-state.js.map +1 -0
- package/dist/security/dlp/index.d.ts +27 -0
- package/dist/security/dlp/index.d.ts.map +1 -0
- package/dist/security/dlp/index.js +54 -0
- package/dist/security/dlp/index.js.map +1 -0
- package/dist/security/dlp/scanner.d.ts +451 -0
- package/dist/security/dlp/scanner.d.ts.map +1 -0
- package/dist/security/dlp/scanner.js +1241 -0
- package/dist/security/dlp/scanner.js.map +1 -0
- package/dist/security/dpop.d.ts +260 -0
- package/dist/security/dpop.d.ts.map +1 -0
- package/dist/security/dpop.js +1058 -0
- package/dist/security/dpop.js.map +1 -0
- package/dist/security/encryption/decorators.d.ts +263 -0
- package/dist/security/encryption/decorators.d.ts.map +1 -0
- package/dist/security/encryption/decorators.js +359 -0
- package/dist/security/encryption/decorators.js.map +1 -0
- package/dist/security/encryption/index.d.ts +83 -0
- package/dist/security/encryption/index.d.ts.map +1 -0
- package/dist/security/encryption/index.js +140 -0
- package/dist/security/encryption/index.js.map +1 -0
- package/dist/security/encryption/key-provider.d.ts +335 -0
- package/dist/security/encryption/key-provider.d.ts.map +1 -0
- package/dist/security/encryption/key-provider.js +853 -0
- package/dist/security/encryption/key-provider.js.map +1 -0
- package/dist/security/encryption/middleware.d.ts +279 -0
- package/dist/security/encryption/middleware.d.ts.map +1 -0
- package/dist/security/encryption/middleware.js +493 -0
- package/dist/security/encryption/middleware.js.map +1 -0
- package/dist/security/encryption/service.d.ts +164 -0
- package/dist/security/encryption/service.d.ts.map +1 -0
- package/dist/security/encryption/service.js +623 -0
- package/dist/security/encryption/service.js.map +1 -0
- package/dist/security/encryption/types.d.ts +745 -0
- package/dist/security/encryption/types.d.ts.map +1 -0
- package/dist/security/encryption/types.js +229 -0
- package/dist/security/encryption/types.js.map +1 -0
- package/dist/security/error-sanitizer.d.ts +329 -0
- package/dist/security/error-sanitizer.d.ts.map +1 -0
- package/dist/security/error-sanitizer.js +700 -0
- package/dist/security/error-sanitizer.js.map +1 -0
- package/dist/security/fingerprint-service.d.ts +139 -0
- package/dist/security/fingerprint-service.d.ts.map +1 -0
- package/dist/security/fingerprint-service.js +240 -0
- package/dist/security/fingerprint-service.js.map +1 -0
- package/dist/security/headers/csp.d.ts +270 -0
- package/dist/security/headers/csp.d.ts.map +1 -0
- package/dist/security/headers/csp.js +655 -0
- package/dist/security/headers/csp.js.map +1 -0
- package/dist/security/headers/hsts.d.ts +161 -0
- package/dist/security/headers/hsts.d.ts.map +1 -0
- package/dist/security/headers/hsts.js +346 -0
- package/dist/security/headers/hsts.js.map +1 -0
- package/dist/security/headers/index.d.ts +47 -0
- package/dist/security/headers/index.d.ts.map +1 -0
- package/dist/security/headers/index.js +110 -0
- package/dist/security/headers/index.js.map +1 -0
- package/dist/security/headers/middleware.d.ts +70 -0
- package/dist/security/headers/middleware.d.ts.map +1 -0
- package/dist/security/headers/middleware.js +549 -0
- package/dist/security/headers/middleware.js.map +1 -0
- package/dist/security/headers/permissions-policy.d.ts +189 -0
- package/dist/security/headers/permissions-policy.d.ts.map +1 -0
- package/dist/security/headers/permissions-policy.js +508 -0
- package/dist/security/headers/permissions-policy.js.map +1 -0
- package/dist/security/headers/types.d.ts +1570 -0
- package/dist/security/headers/types.d.ts.map +1 -0
- package/dist/security/headers/types.js +281 -0
- package/dist/security/headers/types.js.map +1 -0
- package/dist/security/headers/validator.d.ts +36 -0
- package/dist/security/headers/validator.d.ts.map +1 -0
- package/dist/security/headers/validator.js +616 -0
- package/dist/security/headers/validator.js.map +1 -0
- package/dist/security/hsm/aws-cloudhsm.d.ts +157 -0
- package/dist/security/hsm/aws-cloudhsm.d.ts.map +1 -0
- package/dist/security/hsm/aws-cloudhsm.js +712 -0
- package/dist/security/hsm/aws-cloudhsm.js.map +1 -0
- package/dist/security/hsm/azure-hsm.d.ts +174 -0
- package/dist/security/hsm/azure-hsm.d.ts.map +1 -0
- package/dist/security/hsm/azure-hsm.js +792 -0
- package/dist/security/hsm/azure-hsm.js.map +1 -0
- package/dist/security/hsm/gcp-hsm.d.ts +184 -0
- package/dist/security/hsm/gcp-hsm.d.ts.map +1 -0
- package/dist/security/hsm/gcp-hsm.js +817 -0
- package/dist/security/hsm/gcp-hsm.js.map +1 -0
- package/dist/security/hsm/hsm-service.d.ts +264 -0
- package/dist/security/hsm/hsm-service.d.ts.map +1 -0
- package/dist/security/hsm/hsm-service.js +772 -0
- package/dist/security/hsm/hsm-service.js.map +1 -0
- package/dist/security/hsm/index.d.ts +248 -0
- package/dist/security/hsm/index.d.ts.map +1 -0
- package/dist/security/hsm/index.js +329 -0
- package/dist/security/hsm/index.js.map +1 -0
- package/dist/security/hsm/key-ceremony.d.ts +214 -0
- package/dist/security/hsm/key-ceremony.d.ts.map +1 -0
- package/dist/security/hsm/key-ceremony.js +636 -0
- package/dist/security/hsm/key-ceremony.js.map +1 -0
- package/dist/security/hsm/key-operations.d.ts +218 -0
- package/dist/security/hsm/key-operations.d.ts.map +1 -0
- package/dist/security/hsm/key-operations.js +625 -0
- package/dist/security/hsm/key-operations.js.map +1 -0
- package/dist/security/hsm/local-softHSM.d.ts +122 -0
- package/dist/security/hsm/local-softHSM.d.ts.map +1 -0
- package/dist/security/hsm/local-softHSM.js +786 -0
- package/dist/security/hsm/local-softHSM.js.map +1 -0
- package/dist/security/hsm/pkcs11-wrapper.d.ts +386 -0
- package/dist/security/hsm/pkcs11-wrapper.d.ts.map +1 -0
- package/dist/security/hsm/pkcs11-wrapper.js +1149 -0
- package/dist/security/hsm/pkcs11-wrapper.js.map +1 -0
- package/dist/security/hsm/provider.d.ts +333 -0
- package/dist/security/hsm/provider.d.ts.map +1 -0
- package/dist/security/hsm/provider.js +264 -0
- package/dist/security/hsm/provider.js.map +1 -0
- package/dist/security/hsm/thales-luna.d.ts +209 -0
- package/dist/security/hsm/thales-luna.d.ts.map +1 -0
- package/dist/security/hsm/thales-luna.js +820 -0
- package/dist/security/hsm/thales-luna.js.map +1 -0
- package/dist/security/incident/actions/block-ip.d.ts +82 -0
- package/dist/security/incident/actions/block-ip.d.ts.map +1 -0
- package/dist/security/incident/actions/block-ip.js +454 -0
- package/dist/security/incident/actions/block-ip.js.map +1 -0
- package/dist/security/incident/actions/collect-evidence.d.ts +93 -0
- package/dist/security/incident/actions/collect-evidence.d.ts.map +1 -0
- package/dist/security/incident/actions/collect-evidence.js +449 -0
- package/dist/security/incident/actions/collect-evidence.js.map +1 -0
- package/dist/security/incident/actions/index.d.ts +39 -0
- package/dist/security/incident/actions/index.d.ts.map +1 -0
- package/dist/security/incident/actions/index.js +52 -0
- package/dist/security/incident/actions/index.js.map +1 -0
- package/dist/security/incident/actions/isolate-system.d.ts +61 -0
- package/dist/security/incident/actions/isolate-system.d.ts.map +1 -0
- package/dist/security/incident/actions/isolate-system.js +369 -0
- package/dist/security/incident/actions/isolate-system.js.map +1 -0
- package/dist/security/incident/actions/notify-stakeholders.d.ts +70 -0
- package/dist/security/incident/actions/notify-stakeholders.d.ts.map +1 -0
- package/dist/security/incident/actions/notify-stakeholders.js +377 -0
- package/dist/security/incident/actions/notify-stakeholders.js.map +1 -0
- package/dist/security/incident/actions/revoke-credentials.d.ts +75 -0
- package/dist/security/incident/actions/revoke-credentials.d.ts.map +1 -0
- package/dist/security/incident/actions/revoke-credentials.js +320 -0
- package/dist/security/incident/actions/revoke-credentials.js.map +1 -0
- package/dist/security/incident/actions/scale-monitoring.d.ts +88 -0
- package/dist/security/incident/actions/scale-monitoring.d.ts.map +1 -0
- package/dist/security/incident/actions/scale-monitoring.js +473 -0
- package/dist/security/incident/actions/scale-monitoring.js.map +1 -0
- package/dist/security/incident/executor.d.ts +128 -0
- package/dist/security/incident/executor.d.ts.map +1 -0
- package/dist/security/incident/executor.js +695 -0
- package/dist/security/incident/executor.js.map +1 -0
- package/dist/security/incident/index.d.ts +220 -0
- package/dist/security/incident/index.d.ts.map +1 -0
- package/dist/security/incident/index.js +1284 -0
- package/dist/security/incident/index.js.map +1 -0
- package/dist/security/incident/notification.d.ts +68 -0
- package/dist/security/incident/notification.d.ts.map +1 -0
- package/dist/security/incident/notification.js +512 -0
- package/dist/security/incident/notification.js.map +1 -0
- package/dist/security/incident/playbooks/account-compromise.d.ts +13 -0
- package/dist/security/incident/playbooks/account-compromise.d.ts.map +1 -0
- package/dist/security/incident/playbooks/account-compromise.js +379 -0
- package/dist/security/incident/playbooks/account-compromise.js.map +1 -0
- package/dist/security/incident/playbooks/configuration-error.d.ts +17 -0
- package/dist/security/incident/playbooks/configuration-error.d.ts.map +1 -0
- package/dist/security/incident/playbooks/configuration-error.js +340 -0
- package/dist/security/incident/playbooks/configuration-error.js.map +1 -0
- package/dist/security/incident/playbooks/data-breach.d.ts +13 -0
- package/dist/security/incident/playbooks/data-breach.d.ts.map +1 -0
- package/dist/security/incident/playbooks/data-breach.js +394 -0
- package/dist/security/incident/playbooks/data-breach.js.map +1 -0
- package/dist/security/incident/playbooks/denial-of-service.d.ts +13 -0
- package/dist/security/incident/playbooks/denial-of-service.d.ts.map +1 -0
- package/dist/security/incident/playbooks/denial-of-service.js +540 -0
- package/dist/security/incident/playbooks/denial-of-service.js.map +1 -0
- package/dist/security/incident/playbooks/index.d.ts +36 -0
- package/dist/security/incident/playbooks/index.d.ts.map +1 -0
- package/dist/security/incident/playbooks/index.js +56 -0
- package/dist/security/incident/playbooks/index.js.map +1 -0
- package/dist/security/incident/playbooks/insider-threat.d.ts +18 -0
- package/dist/security/incident/playbooks/insider-threat.d.ts.map +1 -0
- package/dist/security/incident/playbooks/insider-threat.js +600 -0
- package/dist/security/incident/playbooks/insider-threat.js.map +1 -0
- package/dist/security/incident/playbooks/malware.d.ts +13 -0
- package/dist/security/incident/playbooks/malware.d.ts.map +1 -0
- package/dist/security/incident/playbooks/malware.js +515 -0
- package/dist/security/incident/playbooks/malware.js.map +1 -0
- package/dist/security/incident/playbooks/ransomware.d.ts +14 -0
- package/dist/security/incident/playbooks/ransomware.d.ts.map +1 -0
- package/dist/security/incident/playbooks/ransomware.js +693 -0
- package/dist/security/incident/playbooks/ransomware.js.map +1 -0
- package/dist/security/incident/playbooks/unauthorized-access.d.ts +13 -0
- package/dist/security/incident/playbooks/unauthorized-access.d.ts.map +1 -0
- package/dist/security/incident/playbooks/unauthorized-access.js +412 -0
- package/dist/security/incident/playbooks/unauthorized-access.js.map +1 -0
- package/dist/security/incident/triggers.d.ts +120 -0
- package/dist/security/incident/triggers.d.ts.map +1 -0
- package/dist/security/incident/triggers.js +708 -0
- package/dist/security/incident/triggers.js.map +1 -0
- package/dist/security/incident/types.d.ts +1517 -0
- package/dist/security/incident/types.d.ts.map +1 -0
- package/dist/security/incident/types.js +222 -0
- package/dist/security/incident/types.js.map +1 -0
- package/dist/security/index.d.ts +59 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +295 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/injection-detector.d.ts +510 -0
- package/dist/security/injection-detector.d.ts.map +1 -0
- package/dist/security/injection-detector.js +1325 -0
- package/dist/security/injection-detector.js.map +1 -0
- package/dist/security/introspection.d.ts +137 -0
- package/dist/security/introspection.d.ts.map +1 -0
- package/dist/security/introspection.js +451 -0
- package/dist/security/introspection.js.map +1 -0
- package/dist/security/key-rotation.d.ts +213 -0
- package/dist/security/key-rotation.d.ts.map +1 -0
- package/dist/security/key-rotation.js +530 -0
- package/dist/security/key-rotation.js.map +1 -0
- package/dist/security/kms/aws-kms.d.ts +152 -0
- package/dist/security/kms/aws-kms.d.ts.map +1 -0
- package/dist/security/kms/aws-kms.js +808 -0
- package/dist/security/kms/aws-kms.js.map +1 -0
- package/dist/security/kms/index.d.ts +165 -0
- package/dist/security/kms/index.d.ts.map +1 -0
- package/dist/security/kms/index.js +351 -0
- package/dist/security/kms/index.js.map +1 -0
- package/dist/security/kms/local.d.ts +127 -0
- package/dist/security/kms/local.d.ts.map +1 -0
- package/dist/security/kms/local.js +682 -0
- package/dist/security/kms/local.js.map +1 -0
- package/dist/security/kms/types.d.ts +1000 -0
- package/dist/security/kms/types.d.ts.map +1 -0
- package/dist/security/kms/types.js +167 -0
- package/dist/security/kms/types.js.map +1 -0
- package/dist/security/kms/vault.d.ts +165 -0
- package/dist/security/kms/vault.d.ts.map +1 -0
- package/dist/security/kms/vault.js +820 -0
- package/dist/security/kms/vault.js.map +1 -0
- package/dist/security/mfa/index.d.ts +17 -0
- package/dist/security/mfa/index.d.ts.map +1 -0
- package/dist/security/mfa/index.js +37 -0
- package/dist/security/mfa/index.js.map +1 -0
- package/dist/security/mfa/mfa-middleware.d.ts +74 -0
- package/dist/security/mfa/mfa-middleware.d.ts.map +1 -0
- package/dist/security/mfa/mfa-middleware.js +244 -0
- package/dist/security/mfa/mfa-middleware.js.map +1 -0
- package/dist/security/mfa/mfa-service.d.ts +115 -0
- package/dist/security/mfa/mfa-service.d.ts.map +1 -0
- package/dist/security/mfa/mfa-service.js +509 -0
- package/dist/security/mfa/mfa-service.js.map +1 -0
- package/dist/security/mfa/mfa-store.d.ts +615 -0
- package/dist/security/mfa/mfa-store.d.ts.map +1 -0
- package/dist/security/mfa/mfa-store.js +431 -0
- package/dist/security/mfa/mfa-store.js.map +1 -0
- package/dist/security/mfa/types.d.ts +417 -0
- package/dist/security/mfa/types.d.ts.map +1 -0
- package/dist/security/mfa/types.js +123 -0
- package/dist/security/mfa/types.js.map +1 -0
- package/dist/security/middleware.d.ts +179 -0
- package/dist/security/middleware.d.ts.map +1 -0
- package/dist/security/middleware.js +534 -0
- package/dist/security/middleware.js.map +1 -0
- package/dist/security/pairwise-did.d.ts +157 -0
- package/dist/security/pairwise-did.d.ts.map +1 -0
- package/dist/security/pairwise-did.js +450 -0
- package/dist/security/pairwise-did.js.map +1 -0
- package/dist/security/pam/break-glass.d.ts +776 -0
- package/dist/security/pam/break-glass.d.ts.map +1 -0
- package/dist/security/pam/break-glass.js +1137 -0
- package/dist/security/pam/break-glass.js.map +1 -0
- package/dist/security/pam/index.d.ts +120 -0
- package/dist/security/pam/index.d.ts.map +1 -0
- package/dist/security/pam/index.js +179 -0
- package/dist/security/pam/index.js.map +1 -0
- package/dist/security/pam/jit-access.d.ts +482 -0
- package/dist/security/pam/jit-access.d.ts.map +1 -0
- package/dist/security/pam/jit-access.js +1030 -0
- package/dist/security/pam/jit-access.js.map +1 -0
- package/dist/security/pam/session-recording.d.ts +1007 -0
- package/dist/security/pam/session-recording.d.ts.map +1 -0
- package/dist/security/pam/session-recording.js +1047 -0
- package/dist/security/pam/session-recording.js.map +1 -0
- package/dist/security/password-hashing.d.ts +199 -0
- package/dist/security/password-hashing.d.ts.map +1 -0
- package/dist/security/password-hashing.js +366 -0
- package/dist/security/password-hashing.js.map +1 -0
- package/dist/security/password-policy.d.ts +304 -0
- package/dist/security/password-policy.d.ts.map +1 -0
- package/dist/security/password-policy.js +730 -0
- package/dist/security/password-policy.js.map +1 -0
- package/dist/security/pkce.d.ts +269 -0
- package/dist/security/pkce.d.ts.map +1 -0
- package/dist/security/pkce.js +408 -0
- package/dist/security/pkce.js.map +1 -0
- package/dist/security/policy-engine/built-in-policies.d.ts +90 -0
- package/dist/security/policy-engine/built-in-policies.d.ts.map +1 -0
- package/dist/security/policy-engine/built-in-policies.js +627 -0
- package/dist/security/policy-engine/built-in-policies.js.map +1 -0
- package/dist/security/policy-engine/condition-evaluator.d.ts +129 -0
- package/dist/security/policy-engine/condition-evaluator.d.ts.map +1 -0
- package/dist/security/policy-engine/condition-evaluator.js +647 -0
- package/dist/security/policy-engine/condition-evaluator.js.map +1 -0
- package/dist/security/policy-engine/engine.d.ts +200 -0
- package/dist/security/policy-engine/engine.d.ts.map +1 -0
- package/dist/security/policy-engine/engine.js +752 -0
- package/dist/security/policy-engine/engine.js.map +1 -0
- package/dist/security/policy-engine/index.d.ts +58 -0
- package/dist/security/policy-engine/index.d.ts.map +1 -0
- package/dist/security/policy-engine/index.js +80 -0
- package/dist/security/policy-engine/index.js.map +1 -0
- package/dist/security/policy-engine/middleware.d.ts +77 -0
- package/dist/security/policy-engine/middleware.d.ts.map +1 -0
- package/dist/security/policy-engine/middleware.js +375 -0
- package/dist/security/policy-engine/middleware.js.map +1 -0
- package/dist/security/policy-engine/rule-evaluator.d.ts +140 -0
- package/dist/security/policy-engine/rule-evaluator.d.ts.map +1 -0
- package/dist/security/policy-engine/rule-evaluator.js +593 -0
- package/dist/security/policy-engine/rule-evaluator.js.map +1 -0
- package/dist/security/policy-engine/types.d.ts +2855 -0
- package/dist/security/policy-engine/types.d.ts.map +1 -0
- package/dist/security/policy-engine/types.js +443 -0
- package/dist/security/policy-engine/types.js.map +1 -0
- package/dist/security/rbac/index.d.ts +317 -0
- package/dist/security/rbac/index.d.ts.map +1 -0
- package/dist/security/rbac/index.js +618 -0
- package/dist/security/rbac/index.js.map +1 -0
- package/dist/security/rbac/permissions.d.ts +305 -0
- package/dist/security/rbac/permissions.d.ts.map +1 -0
- package/dist/security/rbac/permissions.js +947 -0
- package/dist/security/rbac/permissions.js.map +1 -0
- package/dist/security/rbac/policy-engine.d.ts +542 -0
- package/dist/security/rbac/policy-engine.d.ts.map +1 -0
- package/dist/security/rbac/policy-engine.js +1244 -0
- package/dist/security/rbac/policy-engine.js.map +1 -0
- package/dist/security/rbac/roles.d.ts +478 -0
- package/dist/security/rbac/roles.d.ts.map +1 -0
- package/dist/security/rbac/roles.js +363 -0
- package/dist/security/rbac/roles.js.map +1 -0
- package/dist/security/refresh-token.d.ts +305 -0
- package/dist/security/refresh-token.d.ts.map +1 -0
- package/dist/security/refresh-token.js +674 -0
- package/dist/security/refresh-token.js.map +1 -0
- package/dist/security/request-integrity.d.ts +289 -0
- package/dist/security/request-integrity.d.ts.map +1 -0
- package/dist/security/request-integrity.js +663 -0
- package/dist/security/request-integrity.js.map +1 -0
- package/dist/security/revocation-check.d.ts +188 -0
- package/dist/security/revocation-check.d.ts.map +1 -0
- package/dist/security/revocation-check.js +606 -0
- package/dist/security/revocation-check.js.map +1 -0
- package/dist/security/revocation.d.ts +191 -0
- package/dist/security/revocation.d.ts.map +1 -0
- package/dist/security/revocation.js +522 -0
- package/dist/security/revocation.js.map +1 -0
- package/dist/security/secrets-rotation.d.ts +501 -0
- package/dist/security/secrets-rotation.d.ts.map +1 -0
- package/dist/security/secrets-rotation.js +934 -0
- package/dist/security/secrets-rotation.js.map +1 -0
- package/dist/security/secure-memory.d.ts +325 -0
- package/dist/security/secure-memory.d.ts.map +1 -0
- package/dist/security/secure-memory.js +595 -0
- package/dist/security/secure-memory.js.map +1 -0
- package/dist/security/security-service.d.ts +186 -0
- package/dist/security/security-service.d.ts.map +1 -0
- package/dist/security/security-service.js +531 -0
- package/dist/security/security-service.js.map +1 -0
- package/dist/security/service-auth/index.d.ts +20 -0
- package/dist/security/service-auth/index.d.ts.map +1 -0
- package/dist/security/service-auth/index.js +61 -0
- package/dist/security/service-auth/index.js.map +1 -0
- package/dist/security/service-auth/service-account.d.ts +357 -0
- package/dist/security/service-auth/service-account.d.ts.map +1 -0
- package/dist/security/service-auth/service-account.js +475 -0
- package/dist/security/service-auth/service-account.js.map +1 -0
- package/dist/security/service-auth/service-auth-middleware.d.ts +174 -0
- package/dist/security/service-auth/service-auth-middleware.d.ts.map +1 -0
- package/dist/security/service-auth/service-auth-middleware.js +461 -0
- package/dist/security/service-auth/service-auth-middleware.js.map +1 -0
- package/dist/security/service-auth/service-token.d.ts +391 -0
- package/dist/security/service-auth/service-token.d.ts.map +1 -0
- package/dist/security/service-auth/service-token.js +472 -0
- package/dist/security/service-auth/service-token.js.map +1 -0
- package/dist/security/session-manager.d.ts +177 -0
- package/dist/security/session-manager.d.ts.map +1 -0
- package/dist/security/session-manager.js +353 -0
- package/dist/security/session-manager.js.map +1 -0
- package/dist/security/session-store.d.ts +205 -0
- package/dist/security/session-store.d.ts.map +1 -0
- package/dist/security/session-store.js +581 -0
- package/dist/security/session-store.js.map +1 -0
- package/dist/security/siem/connector.d.ts +147 -0
- package/dist/security/siem/connector.d.ts.map +1 -0
- package/dist/security/siem/connector.js +254 -0
- package/dist/security/siem/connector.js.map +1 -0
- package/dist/security/siem/datadog.d.ts +81 -0
- package/dist/security/siem/datadog.d.ts.map +1 -0
- package/dist/security/siem/datadog.js +362 -0
- package/dist/security/siem/datadog.js.map +1 -0
- package/dist/security/siem/elastic.d.ts +83 -0
- package/dist/security/siem/elastic.d.ts.map +1 -0
- package/dist/security/siem/elastic.js +514 -0
- package/dist/security/siem/elastic.js.map +1 -0
- package/dist/security/siem/enrichment.d.ts +133 -0
- package/dist/security/siem/enrichment.d.ts.map +1 -0
- package/dist/security/siem/enrichment.js +434 -0
- package/dist/security/siem/enrichment.js.map +1 -0
- package/dist/security/siem/formatter.d.ts +118 -0
- package/dist/security/siem/formatter.d.ts.map +1 -0
- package/dist/security/siem/formatter.js +381 -0
- package/dist/security/siem/formatter.js.map +1 -0
- package/dist/security/siem/hooks.d.ts +107 -0
- package/dist/security/siem/hooks.d.ts.map +1 -0
- package/dist/security/siem/hooks.js +459 -0
- package/dist/security/siem/hooks.js.map +1 -0
- package/dist/security/siem/index.d.ts +83 -0
- package/dist/security/siem/index.d.ts.map +1 -0
- package/dist/security/siem/index.js +95 -0
- package/dist/security/siem/index.js.map +1 -0
- package/dist/security/siem/service.d.ts +153 -0
- package/dist/security/siem/service.d.ts.map +1 -0
- package/dist/security/siem/service.js +615 -0
- package/dist/security/siem/service.js.map +1 -0
- package/dist/security/siem/splunk.d.ts +76 -0
- package/dist/security/siem/splunk.d.ts.map +1 -0
- package/dist/security/siem/splunk.js +283 -0
- package/dist/security/siem/splunk.js.map +1 -0
- package/dist/security/siem/types.d.ts +1980 -0
- package/dist/security/siem/types.d.ts.map +1 -0
- package/dist/security/siem/types.js +268 -0
- package/dist/security/siem/types.js.map +1 -0
- package/dist/security/tee-production.d.ts +157 -0
- package/dist/security/tee-production.d.ts.map +1 -0
- package/dist/security/tee-production.js +792 -0
- package/dist/security/tee-production.js.map +1 -0
- package/dist/security/tee.d.ts +182 -0
- package/dist/security/tee.d.ts.map +1 -0
- package/dist/security/tee.js +1031 -0
- package/dist/security/tee.js.map +1 -0
- package/dist/security/threat-intel/bot-detection.d.ts +275 -0
- package/dist/security/threat-intel/bot-detection.d.ts.map +1 -0
- package/dist/security/threat-intel/bot-detection.js +890 -0
- package/dist/security/threat-intel/bot-detection.js.map +1 -0
- package/dist/security/threat-intel/credential-stuffing.d.ts +368 -0
- package/dist/security/threat-intel/credential-stuffing.d.ts.map +1 -0
- package/dist/security/threat-intel/credential-stuffing.js +957 -0
- package/dist/security/threat-intel/credential-stuffing.js.map +1 -0
- package/dist/security/threat-intel/index.d.ts +10 -0
- package/dist/security/threat-intel/index.d.ts.map +1 -0
- package/dist/security/threat-intel/index.js +18 -0
- package/dist/security/threat-intel/index.js.map +1 -0
- package/dist/security/threat-intel/ip-reputation.d.ts +323 -0
- package/dist/security/threat-intel/ip-reputation.d.ts.map +1 -0
- package/dist/security/threat-intel/ip-reputation.js +923 -0
- package/dist/security/threat-intel/ip-reputation.js.map +1 -0
- package/dist/security/token-lifecycle.d.ts +272 -0
- package/dist/security/token-lifecycle.d.ts.map +1 -0
- package/dist/security/token-lifecycle.js +732 -0
- package/dist/security/token-lifecycle.js.map +1 -0
- package/dist/security/token-lifetime.d.ts +206 -0
- package/dist/security/token-lifetime.d.ts.map +1 -0
- package/dist/security/token-lifetime.js +388 -0
- package/dist/security/token-lifetime.js.map +1 -0
- package/dist/security/trust-oracle/alerts.d.ts +202 -0
- package/dist/security/trust-oracle/alerts.d.ts.map +1 -0
- package/dist/security/trust-oracle/alerts.js +763 -0
- package/dist/security/trust-oracle/alerts.js.map +1 -0
- package/dist/security/trust-oracle/api.d.ts +116 -0
- package/dist/security/trust-oracle/api.d.ts.map +1 -0
- package/dist/security/trust-oracle/api.js +721 -0
- package/dist/security/trust-oracle/api.js.map +1 -0
- package/dist/security/trust-oracle/continuous-monitoring.d.ts +105 -0
- package/dist/security/trust-oracle/continuous-monitoring.d.ts.map +1 -0
- package/dist/security/trust-oracle/continuous-monitoring.js +696 -0
- package/dist/security/trust-oracle/continuous-monitoring.js.map +1 -0
- package/dist/security/trust-oracle/data-sources.d.ts +126 -0
- package/dist/security/trust-oracle/data-sources.d.ts.map +1 -0
- package/dist/security/trust-oracle/data-sources.js +867 -0
- package/dist/security/trust-oracle/data-sources.js.map +1 -0
- package/dist/security/trust-oracle/index.d.ts +79 -0
- package/dist/security/trust-oracle/index.d.ts.map +1 -0
- package/dist/security/trust-oracle/index.js +206 -0
- package/dist/security/trust-oracle/index.js.map +1 -0
- package/dist/security/trust-oracle/oracle.d.ts +125 -0
- package/dist/security/trust-oracle/oracle.d.ts.map +1 -0
- package/dist/security/trust-oracle/oracle.js +489 -0
- package/dist/security/trust-oracle/oracle.js.map +1 -0
- package/dist/security/trust-oracle/reporting.d.ts +145 -0
- package/dist/security/trust-oracle/reporting.d.ts.map +1 -0
- package/dist/security/trust-oracle/reporting.js +1098 -0
- package/dist/security/trust-oracle/reporting.js.map +1 -0
- package/dist/security/trust-oracle/risk-scorer.d.ts +207 -0
- package/dist/security/trust-oracle/risk-scorer.d.ts.map +1 -0
- package/dist/security/trust-oracle/risk-scorer.js +1033 -0
- package/dist/security/trust-oracle/risk-scorer.js.map +1 -0
- package/dist/security/trust-oracle/types.d.ts +444 -0
- package/dist/security/trust-oracle/types.d.ts.map +1 -0
- package/dist/security/trust-oracle/types.js +6 -0
- package/dist/security/trust-oracle/types.js.map +1 -0
- package/dist/security/trust-oracle/vendor-registry.d.ts +228 -0
- package/dist/security/trust-oracle/vendor-registry.d.ts.map +1 -0
- package/dist/security/trust-oracle/vendor-registry.js +727 -0
- package/dist/security/trust-oracle/vendor-registry.js.map +1 -0
- package/dist/security/types.d.ts +1777 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +388 -0
- package/dist/security/types.js.map +1 -0
- package/dist/security/webauthn/index.d.ts +47 -0
- package/dist/security/webauthn/index.d.ts.map +1 -0
- package/dist/security/webauthn/index.js +48 -0
- package/dist/security/webauthn/index.js.map +1 -0
- package/dist/security/webauthn/middleware.d.ts +109 -0
- package/dist/security/webauthn/middleware.d.ts.map +1 -0
- package/dist/security/webauthn/middleware.js +629 -0
- package/dist/security/webauthn/middleware.js.map +1 -0
- package/dist/security/webauthn/service.d.ts +179 -0
- package/dist/security/webauthn/service.d.ts.map +1 -0
- package/dist/security/webauthn/service.js +758 -0
- package/dist/security/webauthn/service.js.map +1 -0
- package/dist/security/webauthn/store.d.ts +240 -0
- package/dist/security/webauthn/store.d.ts.map +1 -0
- package/dist/security/webauthn/store.js +505 -0
- package/dist/security/webauthn/store.js.map +1 -0
- package/dist/security/webauthn/types.d.ts +678 -0
- package/dist/security/webauthn/types.d.ts.map +1 -0
- package/dist/security/webauthn/types.js +176 -0
- package/dist/security/webauthn/types.js.map +1 -0
- package/dist/security/zkp/circuits.d.ts +296 -0
- package/dist/security/zkp/circuits.d.ts.map +1 -0
- package/dist/security/zkp/circuits.js +771 -0
- package/dist/security/zkp/circuits.js.map +1 -0
- package/dist/security/zkp/commitment.d.ts +319 -0
- package/dist/security/zkp/commitment.d.ts.map +1 -0
- package/dist/security/zkp/commitment.js +591 -0
- package/dist/security/zkp/commitment.js.map +1 -0
- package/dist/security/zkp/compliance.d.ts +251 -0
- package/dist/security/zkp/compliance.d.ts.map +1 -0
- package/dist/security/zkp/compliance.js +734 -0
- package/dist/security/zkp/compliance.js.map +1 -0
- package/dist/security/zkp/index.d.ts +184 -0
- package/dist/security/zkp/index.d.ts.map +1 -0
- package/dist/security/zkp/index.js +285 -0
- package/dist/security/zkp/index.js.map +1 -0
- package/dist/security/zkp/integration.d.ts +289 -0
- package/dist/security/zkp/integration.d.ts.map +1 -0
- package/dist/security/zkp/integration.js +571 -0
- package/dist/security/zkp/integration.js.map +1 -0
- package/dist/security/zkp/prover.d.ts +158 -0
- package/dist/security/zkp/prover.d.ts.map +1 -0
- package/dist/security/zkp/prover.js +465 -0
- package/dist/security/zkp/prover.js.map +1 -0
- package/dist/security/zkp/snark-utils.d.ts +321 -0
- package/dist/security/zkp/snark-utils.d.ts.map +1 -0
- package/dist/security/zkp/snark-utils.js +640 -0
- package/dist/security/zkp/snark-utils.js.map +1 -0
- package/dist/security/zkp/types.d.ts +1192 -0
- package/dist/security/zkp/types.d.ts.map +1 -0
- package/dist/security/zkp/types.js +264 -0
- package/dist/security/zkp/types.js.map +1 -0
- package/dist/security/zkp/verifier.d.ts +111 -0
- package/dist/security/zkp/verifier.d.ts.map +1 -0
- package/dist/security/zkp/verifier.js +554 -0
- package/dist/security/zkp/verifier.js.map +1 -0
- package/dist/semantic-governance/context-validator.d.ts +158 -0
- package/dist/semantic-governance/context-validator.d.ts.map +1 -0
- package/dist/semantic-governance/context-validator.js +598 -0
- package/dist/semantic-governance/context-validator.js.map +1 -0
- package/dist/semantic-governance/credential-manager.d.ts +156 -0
- package/dist/semantic-governance/credential-manager.d.ts.map +1 -0
- package/dist/semantic-governance/credential-manager.js +438 -0
- package/dist/semantic-governance/credential-manager.js.map +1 -0
- package/dist/semantic-governance/dual-channel.d.ts +138 -0
- package/dist/semantic-governance/dual-channel.d.ts.map +1 -0
- package/dist/semantic-governance/dual-channel.js +333 -0
- package/dist/semantic-governance/dual-channel.js.map +1 -0
- package/dist/semantic-governance/index.d.ts +107 -0
- package/dist/semantic-governance/index.d.ts.map +1 -0
- package/dist/semantic-governance/index.js +141 -0
- package/dist/semantic-governance/index.js.map +1 -0
- package/dist/semantic-governance/inference-validator.d.ts +114 -0
- package/dist/semantic-governance/inference-validator.d.ts.map +1 -0
- package/dist/semantic-governance/inference-validator.js +390 -0
- package/dist/semantic-governance/inference-validator.js.map +1 -0
- package/dist/semantic-governance/instruction-validator.d.ts +146 -0
- package/dist/semantic-governance/instruction-validator.d.ts.map +1 -0
- package/dist/semantic-governance/instruction-validator.js +363 -0
- package/dist/semantic-governance/instruction-validator.js.map +1 -0
- package/dist/semantic-governance/integration.d.ts +253 -0
- package/dist/semantic-governance/integration.d.ts.map +1 -0
- package/dist/semantic-governance/integration.js +658 -0
- package/dist/semantic-governance/integration.js.map +1 -0
- package/dist/semantic-governance/output-validator.d.ts +135 -0
- package/dist/semantic-governance/output-validator.d.ts.map +1 -0
- package/dist/semantic-governance/output-validator.js +448 -0
- package/dist/semantic-governance/output-validator.js.map +1 -0
- package/dist/semantic-governance/service.d.ts +120 -0
- package/dist/semantic-governance/service.d.ts.map +1 -0
- package/dist/semantic-governance/service.js +527 -0
- package/dist/semantic-governance/service.js.map +1 -0
- package/dist/semantic-governance/types.d.ts +3925 -0
- package/dist/semantic-governance/types.d.ts.map +1 -0
- package/dist/semantic-governance/types.js +471 -0
- package/dist/semantic-governance/types.js.map +1 -0
- package/dist/trust-engine/car-integration.d.ts +263 -0
- package/dist/trust-engine/car-integration.d.ts.map +1 -0
- package/dist/trust-engine/car-integration.js +320 -0
- package/dist/trust-engine/car-integration.js.map +1 -0
- package/dist/trust-engine/context.d.ts +198 -0
- package/dist/trust-engine/context.d.ts.map +1 -0
- package/dist/trust-engine/context.js +308 -0
- package/dist/trust-engine/context.js.map +1 -0
- package/dist/trust-engine/diminishing-returns.d.ts +123 -0
- package/dist/trust-engine/diminishing-returns.d.ts.map +1 -0
- package/dist/trust-engine/diminishing-returns.js +197 -0
- package/dist/trust-engine/diminishing-returns.js.map +1 -0
- package/dist/trust-engine/index.d.ts +433 -0
- package/dist/trust-engine/index.d.ts.map +1 -0
- package/dist/trust-engine/index.js +1241 -0
- package/dist/trust-engine/index.js.map +1 -0
- package/dist/trust-engine/observability.d.ts +175 -0
- package/dist/trust-engine/observability.d.ts.map +1 -0
- package/dist/trust-engine/observability.js +246 -0
- package/dist/trust-engine/observability.js.map +1 -0
- package/dist/trust-engine/signal-diversity.d.ts +130 -0
- package/dist/trust-engine/signal-diversity.d.ts.map +1 -0
- package/dist/trust-engine/signal-diversity.js +238 -0
- package/dist/trust-engine/signal-diversity.js.map +1 -0
- package/dist/versioning/deprecation.d.ts +65 -0
- package/dist/versioning/deprecation.d.ts.map +1 -0
- package/dist/versioning/deprecation.js +199 -0
- package/dist/versioning/deprecation.js.map +1 -0
- package/dist/versioning/index.d.ts +46 -0
- package/dist/versioning/index.d.ts.map +1 -0
- package/dist/versioning/index.js +76 -0
- package/dist/versioning/index.js.map +1 -0
- package/dist/versioning/semver.d.ts +116 -0
- package/dist/versioning/semver.d.ts.map +1 -0
- package/dist/versioning/semver.js +321 -0
- package/dist/versioning/semver.js.map +1 -0
- package/package.json +161 -0
|
@@ -0,0 +1,1836 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* INTENT Webhook Notifications
|
|
3
|
+
*
|
|
4
|
+
* Outbound webhook notifications for escalation events.
|
|
5
|
+
* Supports configurable URLs per tenant with retry logic.
|
|
6
|
+
* Includes SSRF protection to prevent internal network access.
|
|
7
|
+
*/
|
|
8
|
+
import { randomUUID, createHmac, timingSafeEqual, randomBytes, createHash } from 'node:crypto';
|
|
9
|
+
import { and, desc, eq, lt, lte } from 'drizzle-orm';
|
|
10
|
+
import { getConfig } from '../common/config.js';
|
|
11
|
+
import { createLogger } from '../common/logger.js';
|
|
12
|
+
import { getRedis } from '../common/redis.js';
|
|
13
|
+
import { getDatabase } from '../common/db.js';
|
|
14
|
+
import { ValidationError, NotFoundError } from '../common/errors.js';
|
|
15
|
+
import { encrypt, decrypt } from '../common/encryption.js';
|
|
16
|
+
import { webhookDeliveries, } from './schema.js';
|
|
17
|
+
import { webhookCircuitBreakerState, webhookCircuitBreakerTripsTotal, webhookDeliveriesSkippedTotal, webhookCircuitBreakerTransitions, recordWebhookDelivery, } from './metrics.js';
|
|
18
|
+
import { traceWebhookDeliver, recordWebhookResult, } from './tracing.js';
|
|
19
|
+
import { secureFetch, SecureFetchError, isPrivateIP as secureFetchIsPrivateIP, } from '../common/secure-fetch.js';
|
|
20
|
+
const logger = createLogger({ component: 'webhooks' });
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// SSRF Protection
|
|
23
|
+
// =============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Check if an IP address is in a private/internal range.
|
|
26
|
+
*
|
|
27
|
+
* Delegates to the comprehensive implementation in secure-fetch.ts which covers:
|
|
28
|
+
* - RFC 1918: Private networks (10.x, 172.16-31.x, 192.168.x)
|
|
29
|
+
* - RFC 5737: Documentation ranges (192.0.2.x, 198.51.100.x, 203.0.113.x)
|
|
30
|
+
* - RFC 6598: Shared address space / CGNAT (100.64-127.x)
|
|
31
|
+
* - Loopback (127.x, ::1)
|
|
32
|
+
* - Link-local (169.254.x, fe80::)
|
|
33
|
+
* - Multicast, broadcast, and other reserved ranges
|
|
34
|
+
* - IPv4-mapped IPv6 addresses
|
|
35
|
+
*/
|
|
36
|
+
function isPrivateIP(ip) {
|
|
37
|
+
return secureFetchIsPrivateIP(ip);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate a webhook URL for SSRF protection
|
|
41
|
+
*/
|
|
42
|
+
export async function validateWebhookUrl(url) {
|
|
43
|
+
try {
|
|
44
|
+
const parsed = new URL(url);
|
|
45
|
+
// Only allow HTTPS (except for localhost in development)
|
|
46
|
+
if (parsed.protocol !== 'https:') {
|
|
47
|
+
// Allow HTTP only for localhost in non-production
|
|
48
|
+
const isDevelopment = process.env['VORION_ENV'] !== 'production';
|
|
49
|
+
const isLocalhost = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';
|
|
50
|
+
if (!(isDevelopment && isLocalhost)) {
|
|
51
|
+
return { valid: false, reason: 'Webhook URL must use HTTPS' };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Block internal hostnames
|
|
55
|
+
const blockedHostnames = [
|
|
56
|
+
'localhost',
|
|
57
|
+
'127.0.0.1',
|
|
58
|
+
'0.0.0.0',
|
|
59
|
+
'::1',
|
|
60
|
+
'metadata.google.internal', // GCP metadata
|
|
61
|
+
'169.254.169.254', // AWS/Azure/GCP metadata
|
|
62
|
+
'metadata.internal',
|
|
63
|
+
'kubernetes.default',
|
|
64
|
+
'kubernetes.default.svc',
|
|
65
|
+
];
|
|
66
|
+
if (blockedHostnames.includes(parsed.hostname.toLowerCase())) {
|
|
67
|
+
// Allow localhost only in development
|
|
68
|
+
const isDevelopment = process.env['VORION_ENV'] !== 'production';
|
|
69
|
+
const isLocalhost = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';
|
|
70
|
+
if (!(isDevelopment && isLocalhost)) {
|
|
71
|
+
return { valid: false, reason: 'Webhook URL hostname is blocked' };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Block internal domains
|
|
75
|
+
const blockedPatterns = [
|
|
76
|
+
/\.internal$/i,
|
|
77
|
+
/\.local$/i,
|
|
78
|
+
/\.localhost$/i,
|
|
79
|
+
/\.svc$/i,
|
|
80
|
+
/\.cluster\.local$/i,
|
|
81
|
+
/\.corp$/i,
|
|
82
|
+
/\.lan$/i,
|
|
83
|
+
/\.home$/i,
|
|
84
|
+
];
|
|
85
|
+
for (const pattern of blockedPatterns) {
|
|
86
|
+
if (pattern.test(parsed.hostname)) {
|
|
87
|
+
return { valid: false, reason: 'Webhook URL domain pattern is blocked' };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Resolve hostname and check for private IPs
|
|
91
|
+
// Note: In production, use dns.lookup to resolve the hostname
|
|
92
|
+
// For now, we'll check if the hostname itself is an IP
|
|
93
|
+
const ipMatch = parsed.hostname.match(/^(\d{1,3}\.){3}\d{1,3}$/);
|
|
94
|
+
if (ipMatch && isPrivateIP(parsed.hostname)) {
|
|
95
|
+
return { valid: false, reason: 'Webhook URL resolves to private IP address' };
|
|
96
|
+
}
|
|
97
|
+
// Block ports commonly used for internal services
|
|
98
|
+
const blockedPorts = ['22', '23', '25', '3306', '5432', '6379', '27017', '9200', '11211'];
|
|
99
|
+
if (parsed.port && blockedPorts.includes(parsed.port)) {
|
|
100
|
+
return { valid: false, reason: `Webhook URL port ${parsed.port} is blocked` };
|
|
101
|
+
}
|
|
102
|
+
return { valid: true };
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return { valid: false, reason: 'Invalid webhook URL format' };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Validate URL at connection time (DNS resolution check)
|
|
110
|
+
* This performs actual DNS resolution to catch DNS rebinding attacks
|
|
111
|
+
*/
|
|
112
|
+
export async function validateWebhookUrlAtRuntime(url) {
|
|
113
|
+
const basicValidation = await validateWebhookUrl(url);
|
|
114
|
+
if (!basicValidation.valid) {
|
|
115
|
+
return basicValidation;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const { hostname } = new URL(url);
|
|
119
|
+
// Skip DNS check for IP addresses (already validated)
|
|
120
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname)) {
|
|
121
|
+
return { valid: true, resolvedIP: hostname };
|
|
122
|
+
}
|
|
123
|
+
// Perform DNS lookup
|
|
124
|
+
const dns = await import('node:dns');
|
|
125
|
+
const { promisify } = await import('node:util');
|
|
126
|
+
const lookup = promisify(dns.lookup);
|
|
127
|
+
const result = await lookup(hostname);
|
|
128
|
+
const resolvedIP = result.address;
|
|
129
|
+
if (isPrivateIP(resolvedIP)) {
|
|
130
|
+
logger.warn({ url, resolvedIP }, 'SSRF attempt detected: webhook URL resolves to private IP');
|
|
131
|
+
return {
|
|
132
|
+
valid: false,
|
|
133
|
+
reason: 'Webhook URL resolves to private IP address',
|
|
134
|
+
resolvedIP,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return { valid: true, resolvedIP };
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
logger.warn({ url, error }, 'Failed to resolve webhook URL');
|
|
141
|
+
return { valid: false, reason: 'Failed to resolve webhook URL hostname' };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// =============================================================================
|
|
145
|
+
// HMAC Signature Generation and Verification
|
|
146
|
+
// =============================================================================
|
|
147
|
+
/**
|
|
148
|
+
* Header name for the HMAC signature
|
|
149
|
+
* Format: v1=<hmac-sha256-hex>
|
|
150
|
+
*/
|
|
151
|
+
export const SIGNATURE_HEADER = 'X-Vorion-Signature';
|
|
152
|
+
/**
|
|
153
|
+
* Header name for the signature timestamp (Unix seconds)
|
|
154
|
+
* Used to prevent replay attacks
|
|
155
|
+
*/
|
|
156
|
+
export const SIGNATURE_TIMESTAMP_HEADER = 'X-Vorion-Timestamp';
|
|
157
|
+
/**
|
|
158
|
+
* Current signature version
|
|
159
|
+
* Allows for future signature algorithm upgrades
|
|
160
|
+
*/
|
|
161
|
+
const SIGNATURE_VERSION = 'v1';
|
|
162
|
+
/**
|
|
163
|
+
* Generate HMAC-SHA256 signature for webhook payload.
|
|
164
|
+
*
|
|
165
|
+
* The signature is computed over a signed payload that combines the timestamp
|
|
166
|
+
* and the JSON payload body to prevent replay attacks. The format is:
|
|
167
|
+
*
|
|
168
|
+
* signedPayload = `${timestamp}.${payload}`
|
|
169
|
+
* signature = HMAC-SHA256(secret, signedPayload)
|
|
170
|
+
*
|
|
171
|
+
* The returned signature string includes a version prefix:
|
|
172
|
+
* `v1=<hex-encoded-hmac>`
|
|
173
|
+
*
|
|
174
|
+
* This versioning allows future algorithm upgrades while maintaining
|
|
175
|
+
* backward compatibility.
|
|
176
|
+
*
|
|
177
|
+
* @param payload - The JSON payload string to sign
|
|
178
|
+
* @param secret - The webhook secret shared with the recipient
|
|
179
|
+
* @param timestamp - Unix timestamp in seconds when the request was generated
|
|
180
|
+
* @returns Versioned signature string in format "v1=<hmac-hex>"
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const payload = JSON.stringify({ event: 'test' });
|
|
185
|
+
* const timestamp = Math.floor(Date.now() / 1000);
|
|
186
|
+
* const signature = generateSignature(payload, 'whsec_xxx', timestamp);
|
|
187
|
+
* // Returns: "v1=abc123..."
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
function generateSignature(payload, secret, timestamp) {
|
|
191
|
+
const signedPayload = `${timestamp}.${payload}`;
|
|
192
|
+
const hmac = createHmac('sha256', secret)
|
|
193
|
+
.update(signedPayload)
|
|
194
|
+
.digest('hex');
|
|
195
|
+
return `${SIGNATURE_VERSION}=${hmac}`;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Verify webhook signature for incoming requests.
|
|
199
|
+
*
|
|
200
|
+
* This function is exported for use in client SDKs to verify that webhook
|
|
201
|
+
* requests originated from Vorion and haven't been tampered with.
|
|
202
|
+
*
|
|
203
|
+
* ## Security Features
|
|
204
|
+
*
|
|
205
|
+
* 1. **Timestamp Validation**: Rejects requests with timestamps older than
|
|
206
|
+
* `toleranceSeconds` (default: 5 minutes) to prevent replay attacks.
|
|
207
|
+
*
|
|
208
|
+
* 2. **Timing-Safe Comparison**: Uses constant-time comparison to prevent
|
|
209
|
+
* timing attacks that could leak information about the expected signature.
|
|
210
|
+
*
|
|
211
|
+
* 3. **Signed Payload**: The signature covers both timestamp and payload,
|
|
212
|
+
* ensuring neither can be modified independently.
|
|
213
|
+
*
|
|
214
|
+
* ## Usage in Client SDKs
|
|
215
|
+
*
|
|
216
|
+
* ```typescript
|
|
217
|
+
* import { verifyWebhookSignature, SIGNATURE_HEADER, SIGNATURE_TIMESTAMP_HEADER } from '@vorion/sdk';
|
|
218
|
+
*
|
|
219
|
+
* app.post('/webhook', (req, res) => {
|
|
220
|
+
* const signature = req.headers[SIGNATURE_HEADER.toLowerCase()];
|
|
221
|
+
* const timestamp = parseInt(req.headers[SIGNATURE_TIMESTAMP_HEADER.toLowerCase()], 10);
|
|
222
|
+
* const payload = JSON.stringify(req.body);
|
|
223
|
+
*
|
|
224
|
+
* if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET, timestamp)) {
|
|
225
|
+
* return res.status(401).send('Invalid signature');
|
|
226
|
+
* }
|
|
227
|
+
*
|
|
228
|
+
* // Process webhook...
|
|
229
|
+
* });
|
|
230
|
+
* ```
|
|
231
|
+
*
|
|
232
|
+
* @param payload - The raw JSON payload string from the request body
|
|
233
|
+
* @param signature - The signature from the X-Vorion-Signature header
|
|
234
|
+
* @param secret - The webhook secret configured for this endpoint
|
|
235
|
+
* @param timestamp - The timestamp from the X-Vorion-Timestamp header (Unix seconds)
|
|
236
|
+
* @param toleranceSeconds - Maximum age of the request in seconds (default: 300 = 5 minutes)
|
|
237
|
+
* @returns true if the signature is valid and timestamp is within tolerance
|
|
238
|
+
*
|
|
239
|
+
* @throws Never throws - returns false for any invalid input
|
|
240
|
+
*/
|
|
241
|
+
export function verifyWebhookSignature(payload, signature, secret, timestamp, toleranceSeconds = 300) {
|
|
242
|
+
// Validate inputs
|
|
243
|
+
if (!payload || !signature || !secret || !timestamp) {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
// Check timestamp is within tolerance (prevent replay attacks)
|
|
247
|
+
const now = Math.floor(Date.now() / 1000);
|
|
248
|
+
if (Math.abs(now - timestamp) > toleranceSeconds) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
// Generate expected signature
|
|
252
|
+
const expectedSignature = generateSignature(payload, secret, timestamp);
|
|
253
|
+
// Convert to buffers for timing-safe comparison
|
|
254
|
+
const signatureBuffer = Buffer.from(signature);
|
|
255
|
+
const expectedBuffer = Buffer.from(expectedSignature);
|
|
256
|
+
// Signatures must be same length for timing-safe comparison
|
|
257
|
+
if (signatureBuffer.length !== expectedBuffer.length) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
// Constant-time comparison to prevent timing attacks
|
|
261
|
+
return timingSafeEqual(signatureBuffer, expectedBuffer);
|
|
262
|
+
}
|
|
263
|
+
// =============================================================================
|
|
264
|
+
// Webhook Secret Management
|
|
265
|
+
// =============================================================================
|
|
266
|
+
/**
|
|
267
|
+
* Prefix for webhook secrets (like Stripe's 'whsec_')
|
|
268
|
+
*/
|
|
269
|
+
const WEBHOOK_SECRET_PREFIX = 'whsec_';
|
|
270
|
+
/**
|
|
271
|
+
* Length of the random portion of the webhook secret (32 bytes = 256 bits)
|
|
272
|
+
*/
|
|
273
|
+
const WEBHOOK_SECRET_LENGTH = 32;
|
|
274
|
+
/**
|
|
275
|
+
* Generate a secure webhook secret.
|
|
276
|
+
*
|
|
277
|
+
* The secret is in the format: whsec_<base64-encoded-random-bytes>
|
|
278
|
+
* This format is similar to Stripe's webhook secrets and provides:
|
|
279
|
+
* - Clear identification as a webhook secret
|
|
280
|
+
* - 256 bits of entropy for cryptographic security
|
|
281
|
+
*
|
|
282
|
+
* @returns A new webhook secret string
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* const secret = generateWebhookSecret();
|
|
287
|
+
* // Returns: "whsec_abc123..."
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
export function generateWebhookSecret() {
|
|
291
|
+
const randomPart = randomBytes(WEBHOOK_SECRET_LENGTH).toString('base64url');
|
|
292
|
+
return `${WEBHOOK_SECRET_PREFIX}${randomPart}`;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Compute a SHA-256 hash of a webhook secret for storage.
|
|
296
|
+
*
|
|
297
|
+
* We store the hash rather than the plaintext secret so that:
|
|
298
|
+
* - Secrets are not exposed in database backups
|
|
299
|
+
* - Secrets are not exposed in logs
|
|
300
|
+
* - A database breach doesn't expose secrets
|
|
301
|
+
*
|
|
302
|
+
* @param secret - The webhook secret to hash
|
|
303
|
+
* @returns The SHA-256 hash of the secret
|
|
304
|
+
*/
|
|
305
|
+
export function hashWebhookSecret(secret) {
|
|
306
|
+
return createHash('sha256').update(secret).digest('hex');
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Get the prefix portion of a webhook secret for display purposes.
|
|
310
|
+
*
|
|
311
|
+
* Returns a truncated version like "whsec_abc...xyz" that allows
|
|
312
|
+
* users to identify which secret is configured without exposing it.
|
|
313
|
+
*
|
|
314
|
+
* @param secret - The full webhook secret
|
|
315
|
+
* @returns A truncated display version of the secret
|
|
316
|
+
*/
|
|
317
|
+
export function getWebhookSecretPrefix(secret) {
|
|
318
|
+
if (!secret || secret.length < 15) {
|
|
319
|
+
return '***';
|
|
320
|
+
}
|
|
321
|
+
// Show first 10 chars and last 4 chars
|
|
322
|
+
return `${secret.substring(0, 10)}...${secret.substring(secret.length - 4)}`;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Verify a webhook secret against a stored hash.
|
|
326
|
+
*
|
|
327
|
+
* Uses timing-safe comparison to prevent timing attacks.
|
|
328
|
+
*
|
|
329
|
+
* @param secret - The secret to verify
|
|
330
|
+
* @param storedHash - The stored SHA-256 hash
|
|
331
|
+
* @returns true if the secret matches the hash
|
|
332
|
+
*/
|
|
333
|
+
export function verifyWebhookSecretHash(secret, storedHash) {
|
|
334
|
+
const computedHash = hashWebhookSecret(secret);
|
|
335
|
+
const computedBuffer = Buffer.from(computedHash);
|
|
336
|
+
const storedBuffer = Buffer.from(storedHash);
|
|
337
|
+
if (computedBuffer.length !== storedBuffer.length) {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
return timingSafeEqual(computedBuffer, storedBuffer);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Numeric values for circuit breaker states (for metrics)
|
|
344
|
+
*/
|
|
345
|
+
const CIRCUIT_STATE_VALUES = {
|
|
346
|
+
closed: 0,
|
|
347
|
+
open: 1,
|
|
348
|
+
half_open: 2,
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Check if a stored secret looks like an encrypted envelope.
|
|
352
|
+
* Used to detect legacy unencrypted secrets for migration.
|
|
353
|
+
*/
|
|
354
|
+
function isEncryptedSecret(value) {
|
|
355
|
+
return (typeof value === 'object' &&
|
|
356
|
+
value !== null &&
|
|
357
|
+
'ciphertext' in value &&
|
|
358
|
+
'iv' in value &&
|
|
359
|
+
'authTag' in value &&
|
|
360
|
+
'version' in value);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Encrypt a webhook secret for storage.
|
|
364
|
+
* Returns undefined if no secret is provided.
|
|
365
|
+
*/
|
|
366
|
+
function encryptSecret(secret) {
|
|
367
|
+
if (!secret) {
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
return encrypt(secret);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Decrypt a webhook secret from storage.
|
|
374
|
+
* Handles both encrypted envelopes and legacy plaintext secrets.
|
|
375
|
+
*
|
|
376
|
+
* @param storedConfig - The config as stored in Redis (may be old or new format)
|
|
377
|
+
* @returns The decrypted secret, or undefined if no secret
|
|
378
|
+
*/
|
|
379
|
+
function decryptStoredSecret(storedConfig) {
|
|
380
|
+
// New format: encrypted secret envelope
|
|
381
|
+
if ('encryptedSecret' in storedConfig && storedConfig.encryptedSecret) {
|
|
382
|
+
if (isEncryptedSecret(storedConfig.encryptedSecret)) {
|
|
383
|
+
return decrypt(storedConfig.encryptedSecret);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
// Legacy format: plaintext secret (for backward compatibility during migration)
|
|
387
|
+
if ('secret' in storedConfig && storedConfig.secret) {
|
|
388
|
+
// Check if it's actually an encrypted envelope stored in 'secret' field
|
|
389
|
+
// (this shouldn't happen, but defensive coding)
|
|
390
|
+
if (typeof storedConfig.secret === 'object' && isEncryptedSecret(storedConfig.secret)) {
|
|
391
|
+
return decrypt(storedConfig.secret);
|
|
392
|
+
}
|
|
393
|
+
// Legacy plaintext secret - log warning and return as-is
|
|
394
|
+
logger.warn({ hasPlaintextSecret: true }, 'Webhook contains legacy plaintext secret. Consider re-registering to encrypt.');
|
|
395
|
+
return storedConfig.secret;
|
|
396
|
+
}
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Convert a WebhookConfig to StoredWebhookConfig for Redis storage.
|
|
401
|
+
* Encrypts the secret field and computes hash/prefix.
|
|
402
|
+
*/
|
|
403
|
+
function toStoredConfig(config) {
|
|
404
|
+
const { secret, secretHash, secretPrefix, lastRotatedAt, ...rest } = config;
|
|
405
|
+
const encryptedSecret = encryptSecret(secret);
|
|
406
|
+
const stored = {
|
|
407
|
+
url: rest.url,
|
|
408
|
+
enabled: rest.enabled,
|
|
409
|
+
events: rest.events,
|
|
410
|
+
};
|
|
411
|
+
if (encryptedSecret) {
|
|
412
|
+
stored.encryptedSecret = encryptedSecret;
|
|
413
|
+
}
|
|
414
|
+
// Store the secret hash for verification
|
|
415
|
+
if (secret) {
|
|
416
|
+
stored.secretHash = hashWebhookSecret(secret);
|
|
417
|
+
stored.secretPrefix = getWebhookSecretPrefix(secret);
|
|
418
|
+
}
|
|
419
|
+
else if (secretHash) {
|
|
420
|
+
// Preserve existing hash if secret not provided but hash exists
|
|
421
|
+
stored.secretHash = secretHash;
|
|
422
|
+
}
|
|
423
|
+
if (secretPrefix && !secret) {
|
|
424
|
+
stored.secretPrefix = secretPrefix;
|
|
425
|
+
}
|
|
426
|
+
if (lastRotatedAt) {
|
|
427
|
+
stored.lastRotatedAt = lastRotatedAt;
|
|
428
|
+
}
|
|
429
|
+
if (rest.retryAttempts !== undefined) {
|
|
430
|
+
stored.retryAttempts = rest.retryAttempts;
|
|
431
|
+
}
|
|
432
|
+
if (rest.retryDelayMs !== undefined) {
|
|
433
|
+
stored.retryDelayMs = rest.retryDelayMs;
|
|
434
|
+
}
|
|
435
|
+
if (rest.resolvedIp !== undefined) {
|
|
436
|
+
stored.resolvedIp = rest.resolvedIp;
|
|
437
|
+
}
|
|
438
|
+
return stored;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Convert a StoredWebhookConfig back to WebhookConfig.
|
|
442
|
+
* Decrypts the secret field.
|
|
443
|
+
*/
|
|
444
|
+
function fromStoredConfig(stored) {
|
|
445
|
+
// Handle both old and new format
|
|
446
|
+
const secret = decryptStoredSecret(stored);
|
|
447
|
+
// Build config without the encryptedSecret field
|
|
448
|
+
const config = {
|
|
449
|
+
url: stored.url,
|
|
450
|
+
enabled: stored.enabled,
|
|
451
|
+
events: stored.events,
|
|
452
|
+
};
|
|
453
|
+
if (secret) {
|
|
454
|
+
config.secret = secret;
|
|
455
|
+
}
|
|
456
|
+
if (stored.retryAttempts !== undefined) {
|
|
457
|
+
config.retryAttempts = stored.retryAttempts;
|
|
458
|
+
}
|
|
459
|
+
if (stored.retryDelayMs !== undefined) {
|
|
460
|
+
config.retryDelayMs = stored.retryDelayMs;
|
|
461
|
+
}
|
|
462
|
+
if (stored.resolvedIp !== undefined) {
|
|
463
|
+
config.resolvedIp = stored.resolvedIp;
|
|
464
|
+
}
|
|
465
|
+
// Include new secret management fields
|
|
466
|
+
if (stored.secretHash) {
|
|
467
|
+
config.secretHash = stored.secretHash;
|
|
468
|
+
}
|
|
469
|
+
if (stored.secretPrefix) {
|
|
470
|
+
config.secretPrefix = stored.secretPrefix;
|
|
471
|
+
}
|
|
472
|
+
if (stored.lastRotatedAt) {
|
|
473
|
+
config.lastRotatedAt = stored.lastRotatedAt;
|
|
474
|
+
}
|
|
475
|
+
return config;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Get webhook configuration from the global config.
|
|
479
|
+
* These values can be overridden per-deployment via environment variables:
|
|
480
|
+
* - VORION_WEBHOOK_TIMEOUT_MS (default: 10000, min: 1000, max: 60000)
|
|
481
|
+
* - VORION_WEBHOOK_RETRY_ATTEMPTS (default: 3)
|
|
482
|
+
* - VORION_WEBHOOK_RETRY_DELAY_MS (default: 1000)
|
|
483
|
+
* - VORION_WEBHOOK_ALLOW_DNS_CHANGE (default: false)
|
|
484
|
+
* - VORION_WEBHOOK_CIRCUIT_FAILURE_THRESHOLD (default: 5)
|
|
485
|
+
* - VORION_WEBHOOK_CIRCUIT_RESET_TIMEOUT_MS (default: 300000 = 5 min)
|
|
486
|
+
* - VORION_WEBHOOK_ALLOWED_DOMAINS (comma-separated list of allowed domains)
|
|
487
|
+
* - VORION_WEBHOOK_BLOCKED_DOMAINS (comma-separated list of blocked domains)
|
|
488
|
+
* - VORION_WEBHOOK_ENFORCE_ALLOWLIST (default: false)
|
|
489
|
+
*/
|
|
490
|
+
function getWebhookConfig() {
|
|
491
|
+
const config = getConfig();
|
|
492
|
+
return {
|
|
493
|
+
timeoutMs: config.webhook.timeoutMs,
|
|
494
|
+
retryAttempts: config.webhook.retryAttempts,
|
|
495
|
+
retryDelayMs: config.webhook.retryDelayMs,
|
|
496
|
+
allowDnsChange: config.webhook.allowDnsChange,
|
|
497
|
+
circuitFailureThreshold: config.webhook.circuitFailureThreshold,
|
|
498
|
+
circuitResetTimeoutMs: config.webhook.circuitResetTimeoutMs,
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Get allowed webhook domains from configuration.
|
|
503
|
+
*
|
|
504
|
+
* SSRF Protection:
|
|
505
|
+
* - Returns the configured allowlist of domains that can receive webhooks
|
|
506
|
+
* - If enforceAllowlist is true, only these domains are allowed
|
|
507
|
+
* - If enforceAllowlist is false, returns undefined to allow any valid external domain
|
|
508
|
+
*
|
|
509
|
+
* Configure via:
|
|
510
|
+
* - VORION_WEBHOOK_ALLOWED_DOMAINS: comma-separated list of allowed domains
|
|
511
|
+
* - VORION_WEBHOOK_ENFORCE_ALLOWLIST: set to "true" to enforce the allowlist
|
|
512
|
+
*/
|
|
513
|
+
function getAllowedWebhookDomains() {
|
|
514
|
+
try {
|
|
515
|
+
const config = getConfig();
|
|
516
|
+
const webhookConfig = config.webhook;
|
|
517
|
+
// If allowlist enforcement is disabled, allow any domain (after SSRF checks)
|
|
518
|
+
if (!webhookConfig.enforceAllowlist) {
|
|
519
|
+
return undefined;
|
|
520
|
+
}
|
|
521
|
+
// Return the configured allowed domains
|
|
522
|
+
return webhookConfig.allowedDomains;
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
// Config not available, don't enforce allowlist
|
|
526
|
+
return undefined;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Get blocked webhook domains from configuration.
|
|
531
|
+
*
|
|
532
|
+
* SSRF Protection:
|
|
533
|
+
* - Returns additional domains to block beyond the default private/internal patterns
|
|
534
|
+
* - Useful for blocking specific external domains that should not receive webhooks
|
|
535
|
+
*
|
|
536
|
+
* Configure via:
|
|
537
|
+
* - VORION_WEBHOOK_BLOCKED_DOMAINS: comma-separated list of blocked domains
|
|
538
|
+
*/
|
|
539
|
+
function getBlockedWebhookDomains() {
|
|
540
|
+
try {
|
|
541
|
+
const config = getConfig();
|
|
542
|
+
return config.webhook.blockedDomains || [];
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
return [];
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Validate webhook IP consistency (DNS pinning).
|
|
550
|
+
* Compares the currently resolved IP with the IP stored at registration time.
|
|
551
|
+
* This prevents DNS rebinding attacks where an attacker:
|
|
552
|
+
* 1. Registers webhook with attacker.com -> resolves to public IP (passes validation)
|
|
553
|
+
* 2. Changes DNS: attacker.com -> 169.254.169.254 (AWS metadata)
|
|
554
|
+
* 3. Webhook delivery resolves new DNS -> blocked because IP changed
|
|
555
|
+
*
|
|
556
|
+
* @param url The webhook URL to validate
|
|
557
|
+
* @param storedIp The IP address stored at registration time
|
|
558
|
+
* @returns Validation result with current and stored IPs for logging
|
|
559
|
+
*/
|
|
560
|
+
export async function validateWebhookIpConsistency(url, storedIp) {
|
|
561
|
+
// If no stored IP (legacy webhook), skip consistency check but log warning
|
|
562
|
+
if (!storedIp) {
|
|
563
|
+
logger.warn({ url }, 'Webhook has no stored IP - DNS pinning cannot be enforced. Re-register webhook to enable DNS rebinding protection.');
|
|
564
|
+
return { valid: true, reason: 'No stored IP (legacy webhook)' };
|
|
565
|
+
}
|
|
566
|
+
try {
|
|
567
|
+
const { hostname } = new URL(url);
|
|
568
|
+
// For IP addresses in the URL, compare directly
|
|
569
|
+
if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname)) {
|
|
570
|
+
if (hostname !== storedIp) {
|
|
571
|
+
return {
|
|
572
|
+
valid: false,
|
|
573
|
+
reason: 'IP address in URL does not match stored IP',
|
|
574
|
+
currentIp: hostname,
|
|
575
|
+
storedIp,
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
return { valid: true, currentIp: hostname, storedIp };
|
|
579
|
+
}
|
|
580
|
+
// Perform DNS lookup
|
|
581
|
+
const dns = await import('node:dns');
|
|
582
|
+
const { promisify } = await import('node:util');
|
|
583
|
+
const lookup = promisify(dns.lookup);
|
|
584
|
+
const result = await lookup(hostname);
|
|
585
|
+
const currentIp = result.address;
|
|
586
|
+
// Check if IP changed since registration
|
|
587
|
+
if (currentIp !== storedIp) {
|
|
588
|
+
logger.warn({ url, currentIp, storedIp }, 'DNS rebinding attack detected: webhook IP changed since registration');
|
|
589
|
+
return {
|
|
590
|
+
valid: false,
|
|
591
|
+
reason: 'DNS resolved IP does not match stored IP from registration',
|
|
592
|
+
currentIp,
|
|
593
|
+
storedIp,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
return { valid: true, currentIp, storedIp };
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
logger.warn({ url, storedIp, error }, 'Failed to resolve webhook URL for IP consistency check');
|
|
600
|
+
return {
|
|
601
|
+
valid: false,
|
|
602
|
+
reason: 'Failed to resolve webhook URL hostname',
|
|
603
|
+
storedIp,
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Webhook Service
|
|
609
|
+
*
|
|
610
|
+
* Manages webhook registration, delivery, and persistence.
|
|
611
|
+
* Includes circuit breaker pattern for failing webhooks and
|
|
612
|
+
* persistent delivery records for auditing and replay.
|
|
613
|
+
*/
|
|
614
|
+
export class WebhookService {
|
|
615
|
+
redis = getRedis();
|
|
616
|
+
keyPrefix = 'webhook:';
|
|
617
|
+
circuitKeyPrefix = 'webhook:circuit:';
|
|
618
|
+
deliveryRepository = null;
|
|
619
|
+
/**
|
|
620
|
+
* Get the delivery repository instance (lazy initialization).
|
|
621
|
+
* This allows the repository to be created only when persistence is needed.
|
|
622
|
+
*/
|
|
623
|
+
getDeliveryRepository() {
|
|
624
|
+
if (!this.deliveryRepository) {
|
|
625
|
+
this.deliveryRepository = new WebhookDeliveryRepository();
|
|
626
|
+
}
|
|
627
|
+
return this.deliveryRepository;
|
|
628
|
+
}
|
|
629
|
+
// =========================================================================
|
|
630
|
+
// Circuit Breaker Methods
|
|
631
|
+
// =========================================================================
|
|
632
|
+
/**
|
|
633
|
+
* Get circuit breaker state for a webhook from Redis
|
|
634
|
+
*/
|
|
635
|
+
async getCircuitState(tenantId, webhookId) {
|
|
636
|
+
const key = `${this.circuitKeyPrefix}${tenantId}:${webhookId}`;
|
|
637
|
+
const data = await this.redis.get(key);
|
|
638
|
+
if (!data) {
|
|
639
|
+
// Default: closed circuit with no failures
|
|
640
|
+
return {
|
|
641
|
+
failures: 0,
|
|
642
|
+
openedAt: null,
|
|
643
|
+
state: 'closed',
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
const parsed = JSON.parse(data);
|
|
647
|
+
// Ensure all required fields have valid values (defensive against corrupt data)
|
|
648
|
+
return {
|
|
649
|
+
failures: typeof parsed.failures === 'number' ? parsed.failures : 0,
|
|
650
|
+
openedAt: typeof parsed.openedAt === 'number' ? parsed.openedAt : null,
|
|
651
|
+
state: (parsed.state === 'closed' || parsed.state === 'open' || parsed.state === 'half_open')
|
|
652
|
+
? parsed.state
|
|
653
|
+
: 'closed',
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Set circuit breaker state for a webhook in Redis
|
|
658
|
+
*/
|
|
659
|
+
async setCircuitState(tenantId, webhookId, circuitData) {
|
|
660
|
+
const key = `${this.circuitKeyPrefix}${tenantId}:${webhookId}`;
|
|
661
|
+
// Store circuit state with a TTL of 24 hours to auto-clean up stale circuits
|
|
662
|
+
const ttlSeconds = 86400;
|
|
663
|
+
await this.redis.set(key, JSON.stringify(circuitData), 'EX', ttlSeconds);
|
|
664
|
+
// Update metrics (with safe default for state)
|
|
665
|
+
const stateValue = CIRCUIT_STATE_VALUES[circuitData.state] ?? 0;
|
|
666
|
+
webhookCircuitBreakerState.set({ tenant_id: tenantId, webhook_id: webhookId }, stateValue);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Transition circuit breaker to a new state with logging and metrics
|
|
670
|
+
*/
|
|
671
|
+
async transitionCircuitState(tenantId, webhookId, fromState, toState, circuitData) {
|
|
672
|
+
if (fromState === toState)
|
|
673
|
+
return;
|
|
674
|
+
logger.info({ tenantId, webhookId, fromState, toState, failures: circuitData.failures }, `Circuit breaker state transition: ${fromState} -> ${toState}`);
|
|
675
|
+
webhookCircuitBreakerTransitions.inc({
|
|
676
|
+
tenant_id: tenantId,
|
|
677
|
+
webhook_id: webhookId,
|
|
678
|
+
from_state: fromState,
|
|
679
|
+
to_state: toState,
|
|
680
|
+
});
|
|
681
|
+
if (toState === 'open') {
|
|
682
|
+
webhookCircuitBreakerTripsTotal.inc({
|
|
683
|
+
tenant_id: tenantId,
|
|
684
|
+
webhook_id: webhookId,
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Check if circuit breaker allows delivery attempt
|
|
690
|
+
* Returns true if delivery should proceed, false if it should be skipped
|
|
691
|
+
*/
|
|
692
|
+
async shouldAttemptDelivery(tenantId, webhookId) {
|
|
693
|
+
const webhookConfig = getWebhookConfig();
|
|
694
|
+
const circuitData = await this.getCircuitState(tenantId, webhookId);
|
|
695
|
+
switch (circuitData.state) {
|
|
696
|
+
case 'closed':
|
|
697
|
+
// Normal operation - allow delivery
|
|
698
|
+
return { allowed: true, circuitData };
|
|
699
|
+
case 'open': {
|
|
700
|
+
// Check if reset timeout has elapsed
|
|
701
|
+
const now = Date.now();
|
|
702
|
+
const resetTimeout = webhookConfig.circuitResetTimeoutMs;
|
|
703
|
+
if (circuitData.openedAt && now - circuitData.openedAt >= resetTimeout) {
|
|
704
|
+
// Transition to half-open state
|
|
705
|
+
const previousState = circuitData.state;
|
|
706
|
+
circuitData.state = 'half_open';
|
|
707
|
+
await this.setCircuitState(tenantId, webhookId, circuitData);
|
|
708
|
+
await this.transitionCircuitState(tenantId, webhookId, previousState, 'half_open', circuitData);
|
|
709
|
+
logger.info({ tenantId, webhookId, elapsedMs: now - circuitData.openedAt }, 'Circuit breaker transitioning to half-open state for test delivery');
|
|
710
|
+
return { allowed: true, circuitData };
|
|
711
|
+
}
|
|
712
|
+
// Circuit is still open - skip delivery
|
|
713
|
+
logger.debug({ tenantId, webhookId, openedAt: circuitData.openedAt, resetTimeout }, 'Skipping webhook delivery: circuit breaker is open');
|
|
714
|
+
webhookDeliveriesSkippedTotal.inc({
|
|
715
|
+
tenant_id: tenantId,
|
|
716
|
+
webhook_id: webhookId,
|
|
717
|
+
});
|
|
718
|
+
return { allowed: false, circuitData };
|
|
719
|
+
}
|
|
720
|
+
case 'half_open':
|
|
721
|
+
// Allow one test delivery
|
|
722
|
+
return { allowed: true, circuitData };
|
|
723
|
+
default:
|
|
724
|
+
return { allowed: true, circuitData };
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Record delivery success and potentially close the circuit
|
|
729
|
+
*/
|
|
730
|
+
async recordDeliverySuccess(tenantId, webhookId, circuitData) {
|
|
731
|
+
const previousState = circuitData.state;
|
|
732
|
+
// Reset failures and close circuit on success
|
|
733
|
+
circuitData.failures = 0;
|
|
734
|
+
circuitData.openedAt = null;
|
|
735
|
+
circuitData.state = 'closed';
|
|
736
|
+
await this.setCircuitState(tenantId, webhookId, circuitData);
|
|
737
|
+
if (previousState !== 'closed') {
|
|
738
|
+
await this.transitionCircuitState(tenantId, webhookId, previousState, 'closed', circuitData);
|
|
739
|
+
logger.info({ tenantId, webhookId, previousState }, 'Circuit breaker closed after successful delivery');
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Record delivery failure and potentially open the circuit
|
|
744
|
+
*/
|
|
745
|
+
async recordDeliveryFailure(tenantId, webhookId, circuitData) {
|
|
746
|
+
const webhookConfig = getWebhookConfig();
|
|
747
|
+
const previousState = circuitData.state;
|
|
748
|
+
// Increment failure count
|
|
749
|
+
circuitData.failures += 1;
|
|
750
|
+
if (circuitData.state === 'half_open') {
|
|
751
|
+
// Failed during half-open test - reopen circuit
|
|
752
|
+
circuitData.state = 'open';
|
|
753
|
+
circuitData.openedAt = Date.now();
|
|
754
|
+
await this.setCircuitState(tenantId, webhookId, circuitData);
|
|
755
|
+
await this.transitionCircuitState(tenantId, webhookId, previousState, 'open', circuitData);
|
|
756
|
+
logger.warn({ tenantId, webhookId, failures: circuitData.failures }, 'Circuit breaker reopened after failed half-open test');
|
|
757
|
+
}
|
|
758
|
+
else if (circuitData.failures >= webhookConfig.circuitFailureThreshold) {
|
|
759
|
+
// Exceeded failure threshold - open circuit
|
|
760
|
+
circuitData.state = 'open';
|
|
761
|
+
circuitData.openedAt = Date.now();
|
|
762
|
+
await this.setCircuitState(tenantId, webhookId, circuitData);
|
|
763
|
+
await this.transitionCircuitState(tenantId, webhookId, previousState, 'open', circuitData);
|
|
764
|
+
logger.warn({ tenantId, webhookId, failures: circuitData.failures, threshold: webhookConfig.circuitFailureThreshold }, 'Circuit breaker opened after exceeding failure threshold');
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
// Just record the failure
|
|
768
|
+
await this.setCircuitState(tenantId, webhookId, circuitData);
|
|
769
|
+
logger.debug({ tenantId, webhookId, failures: circuitData.failures, threshold: webhookConfig.circuitFailureThreshold }, 'Webhook delivery failure recorded');
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Get current circuit breaker status for a webhook (for monitoring/debugging)
|
|
774
|
+
*/
|
|
775
|
+
async getCircuitBreakerStatus(tenantId, webhookId) {
|
|
776
|
+
const webhookConfig = getWebhookConfig();
|
|
777
|
+
const circuitData = await this.getCircuitState(tenantId, webhookId);
|
|
778
|
+
if (circuitData.state === 'open' && circuitData.openedAt) {
|
|
779
|
+
const elapsed = Date.now() - circuitData.openedAt;
|
|
780
|
+
const remaining = Math.max(0, webhookConfig.circuitResetTimeoutMs - elapsed);
|
|
781
|
+
return { ...circuitData, timeUntilResetMs: remaining };
|
|
782
|
+
}
|
|
783
|
+
return circuitData;
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Manually reset circuit breaker for a webhook (for administrative use)
|
|
787
|
+
*/
|
|
788
|
+
async resetCircuitBreaker(tenantId, webhookId) {
|
|
789
|
+
const circuitData = await this.getCircuitState(tenantId, webhookId);
|
|
790
|
+
const previousState = circuitData.state;
|
|
791
|
+
circuitData.failures = 0;
|
|
792
|
+
circuitData.openedAt = null;
|
|
793
|
+
circuitData.state = 'closed';
|
|
794
|
+
await this.setCircuitState(tenantId, webhookId, circuitData);
|
|
795
|
+
if (previousState !== 'closed') {
|
|
796
|
+
await this.transitionCircuitState(tenantId, webhookId, previousState, 'closed', circuitData);
|
|
797
|
+
}
|
|
798
|
+
logger.info({ tenantId, webhookId, previousState }, 'Circuit breaker manually reset');
|
|
799
|
+
}
|
|
800
|
+
async registerWebhook(tenantId, config, options) {
|
|
801
|
+
// SSRF protection: validate webhook URL with DNS resolution
|
|
802
|
+
// This also captures the resolved IP for DNS pinning
|
|
803
|
+
const runtimeValidation = await validateWebhookUrlAtRuntime(config.url);
|
|
804
|
+
if (!runtimeValidation.valid) {
|
|
805
|
+
logger.warn({ tenantId, url: config.url, reason: runtimeValidation.reason }, 'Webhook registration blocked: SSRF protection');
|
|
806
|
+
throw new ValidationError(`Invalid webhook URL: ${runtimeValidation.reason}`, {
|
|
807
|
+
url: config.url,
|
|
808
|
+
reason: runtimeValidation.reason,
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
const webhookId = randomUUID();
|
|
812
|
+
const key = `${this.keyPrefix}config:${tenantId}:${webhookId}`;
|
|
813
|
+
// Auto-generate secret if not provided (security best practice)
|
|
814
|
+
const secret = config.secret || generateWebhookSecret();
|
|
815
|
+
// Store the resolved IP for DNS pinning protection
|
|
816
|
+
// This prevents DNS rebinding attacks where attacker changes DNS after registration
|
|
817
|
+
const configWithSecret = {
|
|
818
|
+
...config,
|
|
819
|
+
secret,
|
|
820
|
+
lastRotatedAt: new Date().toISOString(),
|
|
821
|
+
};
|
|
822
|
+
if (runtimeValidation.resolvedIP) {
|
|
823
|
+
configWithSecret.resolvedIp = runtimeValidation.resolvedIP;
|
|
824
|
+
}
|
|
825
|
+
// Encrypt the secret before storing in Redis
|
|
826
|
+
const storedConfig = toStoredConfig(configWithSecret);
|
|
827
|
+
await this.redis.set(key, JSON.stringify(storedConfig));
|
|
828
|
+
await this.redis.sadd(`${this.keyPrefix}tenants:${tenantId}`, webhookId);
|
|
829
|
+
logger.info({
|
|
830
|
+
tenantId,
|
|
831
|
+
webhookId,
|
|
832
|
+
url: config.url,
|
|
833
|
+
resolvedIp: runtimeValidation.resolvedIP,
|
|
834
|
+
hasSecret: true,
|
|
835
|
+
secretPrefix: getWebhookSecretPrefix(secret),
|
|
836
|
+
}, 'Webhook registered with DNS pinning and signing secret');
|
|
837
|
+
// Return secret only if explicitly requested (for new webhook registration response)
|
|
838
|
+
if (options?.returnSecret) {
|
|
839
|
+
return { webhookId, secret };
|
|
840
|
+
}
|
|
841
|
+
return webhookId;
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Rotate the webhook secret.
|
|
845
|
+
*
|
|
846
|
+
* Generates a new secret and updates the webhook configuration.
|
|
847
|
+
* The new secret is only returned once and should be stored securely by the caller.
|
|
848
|
+
*
|
|
849
|
+
* @param tenantId - Tenant ID
|
|
850
|
+
* @param webhookId - Webhook ID
|
|
851
|
+
* @param rotatedBy - User ID who performed the rotation (for audit)
|
|
852
|
+
* @param reason - Reason for rotation (for audit)
|
|
853
|
+
* @returns The new secret (returned only once, not stored in plaintext)
|
|
854
|
+
* @throws NotFoundError if webhook not found
|
|
855
|
+
*/
|
|
856
|
+
async rotateSecret(tenantId, webhookId, rotatedBy, reason) {
|
|
857
|
+
const key = `${this.keyPrefix}config:${tenantId}:${webhookId}`;
|
|
858
|
+
const data = await this.redis.get(key);
|
|
859
|
+
if (!data) {
|
|
860
|
+
throw new NotFoundError(`Webhook not found: ${webhookId}`, { webhookId, tenantId });
|
|
861
|
+
}
|
|
862
|
+
const storedConfig = JSON.parse(data);
|
|
863
|
+
const previousSecretPrefix = storedConfig.secretPrefix;
|
|
864
|
+
// Generate new secret
|
|
865
|
+
const newSecret = generateWebhookSecret();
|
|
866
|
+
const newSecretHash = hashWebhookSecret(newSecret);
|
|
867
|
+
const newSecretPrefix = getWebhookSecretPrefix(newSecret);
|
|
868
|
+
// Update stored config with new secret
|
|
869
|
+
const updatedConfig = {
|
|
870
|
+
...storedConfig,
|
|
871
|
+
encryptedSecret: encrypt(newSecret),
|
|
872
|
+
secretHash: newSecretHash,
|
|
873
|
+
secretPrefix: newSecretPrefix,
|
|
874
|
+
lastRotatedAt: new Date().toISOString(),
|
|
875
|
+
};
|
|
876
|
+
await this.redis.set(key, JSON.stringify(updatedConfig));
|
|
877
|
+
logger.info({
|
|
878
|
+
tenantId,
|
|
879
|
+
webhookId,
|
|
880
|
+
rotatedBy,
|
|
881
|
+
reason,
|
|
882
|
+
previousSecretPrefix,
|
|
883
|
+
newSecretPrefix,
|
|
884
|
+
}, 'Webhook secret rotated');
|
|
885
|
+
const result = {
|
|
886
|
+
secret: newSecret,
|
|
887
|
+
secretPrefix: newSecretPrefix,
|
|
888
|
+
};
|
|
889
|
+
if (previousSecretPrefix) {
|
|
890
|
+
result.previousSecretPrefix = previousSecretPrefix;
|
|
891
|
+
}
|
|
892
|
+
return result;
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Get a single webhook by ID.
|
|
896
|
+
*
|
|
897
|
+
* @param tenantId - Tenant ID
|
|
898
|
+
* @param webhookId - Webhook ID
|
|
899
|
+
* @returns Webhook config or null if not found
|
|
900
|
+
*/
|
|
901
|
+
async getWebhook(tenantId, webhookId) {
|
|
902
|
+
const key = `${this.keyPrefix}config:${tenantId}:${webhookId}`;
|
|
903
|
+
const data = await this.redis.get(key);
|
|
904
|
+
if (!data) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
const storedConfig = JSON.parse(data);
|
|
908
|
+
return fromStoredConfig(storedConfig);
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Unregister a webhook
|
|
912
|
+
*/
|
|
913
|
+
async unregisterWebhook(tenantId, webhookId) {
|
|
914
|
+
const key = `${this.keyPrefix}config:${tenantId}:${webhookId}`;
|
|
915
|
+
const deleted = await this.redis.del(key);
|
|
916
|
+
await this.redis.srem(`${this.keyPrefix}tenants:${tenantId}`, webhookId);
|
|
917
|
+
if (deleted > 0) {
|
|
918
|
+
logger.info({ tenantId, webhookId }, 'Webhook unregistered');
|
|
919
|
+
return true;
|
|
920
|
+
}
|
|
921
|
+
return false;
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Get all webhooks for a tenant
|
|
925
|
+
*
|
|
926
|
+
* Decrypts stored webhook secrets on retrieval. Handles both new encrypted
|
|
927
|
+
* format and legacy plaintext secrets for backward compatibility.
|
|
928
|
+
*/
|
|
929
|
+
async getWebhooks(tenantId) {
|
|
930
|
+
const webhookIds = await this.redis.smembers(`${this.keyPrefix}tenants:${tenantId}`);
|
|
931
|
+
if (webhookIds.length === 0) {
|
|
932
|
+
return [];
|
|
933
|
+
}
|
|
934
|
+
const webhooks = [];
|
|
935
|
+
// Use pipeline to batch all GET operations if available, otherwise fallback to sequential
|
|
936
|
+
if (typeof this.redis.pipeline === 'function') {
|
|
937
|
+
const pipeline = this.redis.pipeline();
|
|
938
|
+
for (const webhookId of webhookIds) {
|
|
939
|
+
pipeline.get(`${this.keyPrefix}config:${tenantId}:${webhookId}`);
|
|
940
|
+
}
|
|
941
|
+
const results = await pipeline.exec();
|
|
942
|
+
for (let i = 0; i < webhookIds.length; i++) {
|
|
943
|
+
const result = results?.[i];
|
|
944
|
+
const data = result?.[1];
|
|
945
|
+
if (data) {
|
|
946
|
+
const storedConfig = JSON.parse(data);
|
|
947
|
+
const config = fromStoredConfig(storedConfig);
|
|
948
|
+
webhooks.push({ id: webhookIds[i], config });
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
else {
|
|
953
|
+
// Fallback for tests or Redis clients without pipeline support
|
|
954
|
+
for (const webhookId of webhookIds) {
|
|
955
|
+
const data = await this.redis.get(`${this.keyPrefix}config:${tenantId}:${webhookId}`);
|
|
956
|
+
if (data) {
|
|
957
|
+
const storedConfig = JSON.parse(data);
|
|
958
|
+
const config = fromStoredConfig(storedConfig);
|
|
959
|
+
webhooks.push({ id: webhookId, config });
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
return webhooks;
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Send webhook notification for an escalation event
|
|
967
|
+
*/
|
|
968
|
+
async notifyEscalation(eventType, escalation) {
|
|
969
|
+
const payload = {
|
|
970
|
+
id: randomUUID(),
|
|
971
|
+
eventType,
|
|
972
|
+
timestamp: new Date().toISOString(),
|
|
973
|
+
tenantId: escalation.tenantId,
|
|
974
|
+
data: {
|
|
975
|
+
escalationId: escalation.id,
|
|
976
|
+
intentId: escalation.intentId,
|
|
977
|
+
reason: escalation.reason,
|
|
978
|
+
reasonCategory: escalation.reasonCategory,
|
|
979
|
+
escalatedTo: escalation.escalatedTo,
|
|
980
|
+
status: escalation.status,
|
|
981
|
+
resolution: escalation.resolution,
|
|
982
|
+
createdAt: escalation.createdAt,
|
|
983
|
+
updatedAt: escalation.updatedAt,
|
|
984
|
+
},
|
|
985
|
+
};
|
|
986
|
+
return this.deliverToTenant(escalation.tenantId, eventType, payload);
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* Send webhook notification for an intent event
|
|
990
|
+
*/
|
|
991
|
+
async notifyIntent(eventType, intentId, tenantId, additionalData) {
|
|
992
|
+
const payload = {
|
|
993
|
+
id: randomUUID(),
|
|
994
|
+
eventType,
|
|
995
|
+
timestamp: new Date().toISOString(),
|
|
996
|
+
tenantId,
|
|
997
|
+
data: {
|
|
998
|
+
intentId,
|
|
999
|
+
...additionalData,
|
|
1000
|
+
},
|
|
1001
|
+
};
|
|
1002
|
+
return this.deliverToTenant(tenantId, eventType, payload);
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Deliver webhooks to all registered endpoints for a tenant.
|
|
1006
|
+
*
|
|
1007
|
+
* Creates persistent delivery records before attempting delivery,
|
|
1008
|
+
* updating them with success/failure status after each attempt.
|
|
1009
|
+
* Includes circuit breaker check to skip consistently failing webhooks.
|
|
1010
|
+
* Processes webhooks in parallel batches with configurable concurrency.
|
|
1011
|
+
*/
|
|
1012
|
+
async deliverToTenant(tenantId, eventType, payload) {
|
|
1013
|
+
const webhooks = await this.getWebhooks(tenantId);
|
|
1014
|
+
const deliveryRepo = this.getDeliveryRepository();
|
|
1015
|
+
const config = getConfig();
|
|
1016
|
+
const concurrencyLimit = config.webhook?.deliveryConcurrency ?? 10;
|
|
1017
|
+
// Filter eligible webhooks
|
|
1018
|
+
const eligibleWebhooks = webhooks.filter(({ config }) => config.enabled && config.events.includes(eventType));
|
|
1019
|
+
if (eligibleWebhooks.length === 0) {
|
|
1020
|
+
return [];
|
|
1021
|
+
}
|
|
1022
|
+
// Process a single webhook delivery
|
|
1023
|
+
const processWebhook = async (webhook) => {
|
|
1024
|
+
const { id: webhookId, config: webhookConfig } = webhook;
|
|
1025
|
+
// Create persistent delivery record before attempting delivery
|
|
1026
|
+
let deliveryRecord = null;
|
|
1027
|
+
try {
|
|
1028
|
+
deliveryRecord = await deliveryRepo.createDelivery({
|
|
1029
|
+
webhookId,
|
|
1030
|
+
tenantId,
|
|
1031
|
+
eventType,
|
|
1032
|
+
payload: payload,
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
catch (err) {
|
|
1036
|
+
logger.error({ webhookId, tenantId, eventType, error: err }, 'Failed to create webhook delivery record, proceeding with delivery anyway');
|
|
1037
|
+
}
|
|
1038
|
+
// Check circuit breaker before attempting delivery
|
|
1039
|
+
const { allowed, circuitData } = await this.shouldAttemptDelivery(tenantId, webhookId);
|
|
1040
|
+
if (!allowed) {
|
|
1041
|
+
// Circuit is open - skip delivery
|
|
1042
|
+
const skippedResult = {
|
|
1043
|
+
success: false,
|
|
1044
|
+
error: 'Circuit breaker open - webhook delivery skipped',
|
|
1045
|
+
attempts: 0,
|
|
1046
|
+
skippedByCircuitBreaker: true,
|
|
1047
|
+
};
|
|
1048
|
+
// Update delivery record with skipped status
|
|
1049
|
+
if (deliveryRecord) {
|
|
1050
|
+
try {
|
|
1051
|
+
await deliveryRepo.updateDeliveryStatus(deliveryRecord.id, {
|
|
1052
|
+
status: 'failed',
|
|
1053
|
+
attempts: 0,
|
|
1054
|
+
lastError: 'Circuit breaker open - webhook delivery skipped',
|
|
1055
|
+
lastAttemptAt: new Date(),
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
catch (err) {
|
|
1059
|
+
logger.error({ deliveryId: deliveryRecord.id, error: err }, 'Failed to update delivery record');
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
await this.storeDeliveryResult(tenantId, webhookId, payload.id, skippedResult);
|
|
1063
|
+
return skippedResult;
|
|
1064
|
+
}
|
|
1065
|
+
// Attempt delivery with retry logic
|
|
1066
|
+
const result = await this.deliverWithRetry(webhookId, webhookConfig, payload, tenantId, circuitData, deliveryRecord?.id ?? null);
|
|
1067
|
+
// Store delivery result in Redis (legacy - for backwards compatibility)
|
|
1068
|
+
await this.storeDeliveryResult(tenantId, webhookId, payload.id, result);
|
|
1069
|
+
return result;
|
|
1070
|
+
};
|
|
1071
|
+
// Process webhooks in parallel batches with concurrency limit
|
|
1072
|
+
const results = [];
|
|
1073
|
+
for (let i = 0; i < eligibleWebhooks.length; i += concurrencyLimit) {
|
|
1074
|
+
const batch = eligibleWebhooks.slice(i, i + concurrencyLimit);
|
|
1075
|
+
const batchResults = await Promise.all(batch.map(processWebhook));
|
|
1076
|
+
results.push(...batchResults);
|
|
1077
|
+
}
|
|
1078
|
+
return results;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Deliver webhook with retry logic
|
|
1082
|
+
*
|
|
1083
|
+
* Uses per-webhook config if provided, otherwise falls back to global config.
|
|
1084
|
+
* Global defaults are configurable via environment variables.
|
|
1085
|
+
* Updates circuit breaker state and persistent delivery record based on success/failure.
|
|
1086
|
+
*/
|
|
1087
|
+
async deliverWithRetry(webhookId, config, payload, tenantId, circuitData, deliveryRecordId = null) {
|
|
1088
|
+
const deliveryRepo = this.getDeliveryRepository();
|
|
1089
|
+
// Helper to safely update delivery record status
|
|
1090
|
+
const updateDeliveryRecord = async (status, attempts, options = {}) => {
|
|
1091
|
+
if (!deliveryRecordId)
|
|
1092
|
+
return;
|
|
1093
|
+
try {
|
|
1094
|
+
await deliveryRepo.updateDeliveryStatus(deliveryRecordId, {
|
|
1095
|
+
status,
|
|
1096
|
+
attempts,
|
|
1097
|
+
lastAttemptAt: new Date(),
|
|
1098
|
+
lastError: options.lastError ?? null,
|
|
1099
|
+
responseStatus: options.responseStatus ?? null,
|
|
1100
|
+
responseBody: options.responseBody ?? null,
|
|
1101
|
+
deliveredAt: options.deliveredAt ?? null,
|
|
1102
|
+
nextRetryAt: options.nextRetryAt ?? null,
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
catch (err) {
|
|
1106
|
+
logger.error({ deliveryId: deliveryRecordId, error: err }, 'Failed to update delivery record');
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
// Wrap the entire delivery process with tracing
|
|
1110
|
+
return traceWebhookDeliver(webhookId, config.url, payload.eventType, async (span) => {
|
|
1111
|
+
const webhookDefaults = getWebhookConfig();
|
|
1112
|
+
const maxAttempts = config.retryAttempts ?? webhookDefaults.retryAttempts;
|
|
1113
|
+
const retryDelay = config.retryDelayMs ?? webhookDefaults.retryDelayMs;
|
|
1114
|
+
let lastError;
|
|
1115
|
+
let lastStatusCode;
|
|
1116
|
+
let lastResponseBody;
|
|
1117
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1118
|
+
try {
|
|
1119
|
+
const response = await this.sendWebhook(config.url, payload, config.secret, config.resolvedIp);
|
|
1120
|
+
lastStatusCode = response.status;
|
|
1121
|
+
// Try to capture response body for debugging (limited to first 1KB)
|
|
1122
|
+
try {
|
|
1123
|
+
const text = await response.text();
|
|
1124
|
+
lastResponseBody = text.substring(0, 1024);
|
|
1125
|
+
}
|
|
1126
|
+
catch {
|
|
1127
|
+
// Ignore errors reading response body
|
|
1128
|
+
}
|
|
1129
|
+
if (response.ok) {
|
|
1130
|
+
logger.info({ webhookId, eventType: payload.eventType, attempt }, 'Webhook delivered successfully');
|
|
1131
|
+
// Record success in circuit breaker (may close the circuit)
|
|
1132
|
+
await this.recordDeliverySuccess(tenantId, webhookId, circuitData);
|
|
1133
|
+
// Update persistent delivery record with success
|
|
1134
|
+
await updateDeliveryRecord('delivered', attempt, {
|
|
1135
|
+
responseStatus: response.status,
|
|
1136
|
+
responseBody: lastResponseBody ?? null,
|
|
1137
|
+
deliveredAt: new Date(),
|
|
1138
|
+
});
|
|
1139
|
+
// Record span result
|
|
1140
|
+
recordWebhookResult(span, true, response.status);
|
|
1141
|
+
// Record webhook delivery success metric
|
|
1142
|
+
recordWebhookDelivery(tenantId, payload.eventType, true);
|
|
1143
|
+
return {
|
|
1144
|
+
success: true,
|
|
1145
|
+
statusCode: response.status,
|
|
1146
|
+
attempts: attempt,
|
|
1147
|
+
deliveredAt: new Date().toISOString(),
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
lastError = `HTTP ${response.status}: ${response.statusText}`;
|
|
1151
|
+
logger.warn({ webhookId, attempt, statusCode: response.status }, 'Webhook delivery failed, will retry');
|
|
1152
|
+
}
|
|
1153
|
+
catch (error) {
|
|
1154
|
+
lastError = error instanceof Error ? error.message : 'Unknown error';
|
|
1155
|
+
logger.warn({ webhookId, attempt, error: lastError }, 'Webhook delivery error, will retry');
|
|
1156
|
+
}
|
|
1157
|
+
// Update delivery record with retry status (if not last attempt)
|
|
1158
|
+
if (attempt < maxAttempts) {
|
|
1159
|
+
const nextRetryAt = calculateNextRetryTime(attempt, retryDelay);
|
|
1160
|
+
await updateDeliveryRecord('retrying', attempt, {
|
|
1161
|
+
lastError: lastError ?? null,
|
|
1162
|
+
responseStatus: lastStatusCode ?? null,
|
|
1163
|
+
responseBody: lastResponseBody ?? null,
|
|
1164
|
+
nextRetryAt,
|
|
1165
|
+
});
|
|
1166
|
+
// Wait before retry (exponential backoff)
|
|
1167
|
+
const delay = retryDelay * Math.pow(2, attempt - 1);
|
|
1168
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
logger.error({ webhookId, eventType: payload.eventType, attempts: maxAttempts, error: lastError }, 'Webhook delivery failed after all retries');
|
|
1172
|
+
// Record failure in circuit breaker (may open the circuit)
|
|
1173
|
+
await this.recordDeliveryFailure(tenantId, webhookId, circuitData);
|
|
1174
|
+
// Update persistent delivery record with final failure
|
|
1175
|
+
await updateDeliveryRecord('failed', maxAttempts, {
|
|
1176
|
+
lastError: lastError ?? null,
|
|
1177
|
+
responseStatus: lastStatusCode ?? null,
|
|
1178
|
+
responseBody: lastResponseBody ?? null,
|
|
1179
|
+
});
|
|
1180
|
+
// Record span result
|
|
1181
|
+
recordWebhookResult(span, false, lastStatusCode);
|
|
1182
|
+
// Record webhook delivery failure metric
|
|
1183
|
+
recordWebhookDelivery(tenantId, payload.eventType, false);
|
|
1184
|
+
const failureResult = {
|
|
1185
|
+
success: false,
|
|
1186
|
+
attempts: maxAttempts,
|
|
1187
|
+
};
|
|
1188
|
+
if (lastStatusCode !== undefined) {
|
|
1189
|
+
failureResult.statusCode = lastStatusCode;
|
|
1190
|
+
}
|
|
1191
|
+
if (lastError !== undefined) {
|
|
1192
|
+
failureResult.error = lastError;
|
|
1193
|
+
}
|
|
1194
|
+
return failureResult;
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Send HTTP request to webhook URL
|
|
1199
|
+
*
|
|
1200
|
+
* Uses secureFetch for comprehensive SSRF protection:
|
|
1201
|
+
* - URL scheme validation (HTTPS required in production)
|
|
1202
|
+
* - Private IP range blocking (RFC 1918, RFC 5737, RFC 6598)
|
|
1203
|
+
* - Link-local and localhost blocking
|
|
1204
|
+
* - DNS resolution validation to prevent rebinding attacks
|
|
1205
|
+
* - DNS pinning to detect post-registration rebinding
|
|
1206
|
+
* - Request timeout enforcement
|
|
1207
|
+
* - Audit logging of all webhook deliveries
|
|
1208
|
+
*
|
|
1209
|
+
* Timeout is configurable via VORION_WEBHOOK_TIMEOUT_MS environment variable.
|
|
1210
|
+
* Default: 10000ms, Min: 1000ms, Max: 60000ms
|
|
1211
|
+
*/
|
|
1212
|
+
async sendWebhook(url, payload, secret, storedIp) {
|
|
1213
|
+
const webhookConfig = getWebhookConfig();
|
|
1214
|
+
// DNS Pinning: Check IP consistency unless explicitly allowed to change
|
|
1215
|
+
// This is the primary defense against DNS rebinding attacks
|
|
1216
|
+
if (!webhookConfig.allowDnsChange) {
|
|
1217
|
+
const ipConsistency = await validateWebhookIpConsistency(url, storedIp);
|
|
1218
|
+
if (!ipConsistency.valid) {
|
|
1219
|
+
logger.error({
|
|
1220
|
+
url,
|
|
1221
|
+
reason: ipConsistency.reason,
|
|
1222
|
+
currentIp: ipConsistency.currentIp,
|
|
1223
|
+
storedIp: ipConsistency.storedIp,
|
|
1224
|
+
}, 'Webhook blocked: DNS rebinding attack detected. Re-register webhook to update IP.');
|
|
1225
|
+
throw new ValidationError(`Webhook blocked: ${ipConsistency.reason}. Re-register webhook to update pinned IP.`, {
|
|
1226
|
+
url,
|
|
1227
|
+
reason: ipConsistency.reason,
|
|
1228
|
+
currentIp: ipConsistency.currentIp,
|
|
1229
|
+
storedIp: ipConsistency.storedIp,
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
// Runtime SSRF protection: validate URL with DNS resolution
|
|
1234
|
+
// This catches DNS rebinding attacks where URL was valid at registration
|
|
1235
|
+
// but DNS record changed to point to internal IP
|
|
1236
|
+
const runtimeValidation = await validateWebhookUrlAtRuntime(url);
|
|
1237
|
+
if (!runtimeValidation.valid) {
|
|
1238
|
+
logger.error({ url, reason: runtimeValidation.reason, resolvedIP: runtimeValidation.resolvedIP }, 'Webhook blocked at runtime: SSRF protection');
|
|
1239
|
+
throw new ValidationError(`Webhook blocked: ${runtimeValidation.reason}`, {
|
|
1240
|
+
url,
|
|
1241
|
+
reason: runtimeValidation.reason,
|
|
1242
|
+
resolvedIP: runtimeValidation.resolvedIP,
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
const body = JSON.stringify(payload);
|
|
1246
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
1247
|
+
const headers = {
|
|
1248
|
+
'Content-Type': 'application/json',
|
|
1249
|
+
'User-Agent': 'Vorion-Webhook/1.0',
|
|
1250
|
+
'X-Webhook-Event': payload.eventType,
|
|
1251
|
+
'X-Webhook-Delivery': payload.id,
|
|
1252
|
+
};
|
|
1253
|
+
// Add HMAC signature if secret is configured
|
|
1254
|
+
// The signature includes the timestamp to prevent replay attacks
|
|
1255
|
+
if (secret) {
|
|
1256
|
+
const signature = generateSignature(body, secret, timestamp);
|
|
1257
|
+
headers[SIGNATURE_HEADER] = signature;
|
|
1258
|
+
headers[SIGNATURE_TIMESTAMP_HEADER] = String(timestamp);
|
|
1259
|
+
}
|
|
1260
|
+
try {
|
|
1261
|
+
// Use secureFetch for SSRF protection
|
|
1262
|
+
// We skip the DNS check here since we already performed it above
|
|
1263
|
+
// and we want to use the pinned IP for the actual request
|
|
1264
|
+
return await secureFetch(url, {
|
|
1265
|
+
method: 'POST',
|
|
1266
|
+
headers,
|
|
1267
|
+
body,
|
|
1268
|
+
timeoutMs: webhookConfig.timeoutMs,
|
|
1269
|
+
// Skip DNS check since we already validated above
|
|
1270
|
+
skipDnsCheck: true,
|
|
1271
|
+
// Use the pinned IP if available to ensure we connect to the expected server
|
|
1272
|
+
pinnedIp: storedIp,
|
|
1273
|
+
// Allow configured webhook domains from the allowlist
|
|
1274
|
+
allowedDomains: getAllowedWebhookDomains(),
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
1277
|
+
catch (error) {
|
|
1278
|
+
// Handle SecureFetchError specifically for better error reporting
|
|
1279
|
+
if (error instanceof SecureFetchError) {
|
|
1280
|
+
logger.error({
|
|
1281
|
+
url,
|
|
1282
|
+
errorCode: error.code,
|
|
1283
|
+
errorDetails: error.details,
|
|
1284
|
+
}, 'Webhook delivery failed: secure fetch error');
|
|
1285
|
+
throw new ValidationError(`Webhook blocked: ${error.message}`, { url, code: error.code, ...error.details });
|
|
1286
|
+
}
|
|
1287
|
+
throw error;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Store delivery result for auditing
|
|
1292
|
+
*
|
|
1293
|
+
* Uses a Redis SET index to track delivery IDs per webhook, avoiding the need
|
|
1294
|
+
* for expensive KEYS operations when retrieving deliveries.
|
|
1295
|
+
*/
|
|
1296
|
+
async storeDeliveryResult(tenantId, webhookId, deliveryId, result) {
|
|
1297
|
+
const key = `${this.keyPrefix}delivery:${tenantId}:${webhookId}:${deliveryId}`;
|
|
1298
|
+
const indexKey = `${this.keyPrefix}delivery-index:${tenantId}:${webhookId}`;
|
|
1299
|
+
const ttlSeconds = 86400 * 7; // 7 days retention
|
|
1300
|
+
// Store the delivery result with TTL
|
|
1301
|
+
await this.redis.set(key, JSON.stringify(result), 'EX', ttlSeconds);
|
|
1302
|
+
// Add delivery ID to the index SET with timestamp prefix for ordering
|
|
1303
|
+
// Format: "timestamp:deliveryId" allows lexicographic sorting by time
|
|
1304
|
+
const timestamp = Date.now();
|
|
1305
|
+
const indexEntry = `${timestamp}:${deliveryId}`;
|
|
1306
|
+
await this.redis.zadd(indexKey, timestamp, indexEntry);
|
|
1307
|
+
// Set TTL on the index key (refresh on each write)
|
|
1308
|
+
await this.redis.expire(indexKey, ttlSeconds);
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Get recent deliveries for a webhook
|
|
1312
|
+
*
|
|
1313
|
+
* Uses a Redis sorted set index instead of KEYS command.
|
|
1314
|
+
* KEYS is O(n) and blocks Redis during execution, causing latency spikes.
|
|
1315
|
+
* ZREVRANGE on the index is O(log(n) + m) where m is the limit, much more efficient.
|
|
1316
|
+
*/
|
|
1317
|
+
async getDeliveries(tenantId, webhookId, limit = 100) {
|
|
1318
|
+
const indexKey = `${this.keyPrefix}delivery-index:${tenantId}:${webhookId}`;
|
|
1319
|
+
const deliveries = [];
|
|
1320
|
+
// Get most recent delivery IDs from sorted set (sorted by timestamp descending)
|
|
1321
|
+
const indexEntries = await this.redis.zrevrange(indexKey, 0, limit - 1);
|
|
1322
|
+
if (indexEntries.length === 0) {
|
|
1323
|
+
return deliveries;
|
|
1324
|
+
}
|
|
1325
|
+
// Extract delivery IDs and fetch their data
|
|
1326
|
+
// Index entries are in format "timestamp:deliveryId"
|
|
1327
|
+
for (const entry of indexEntries) {
|
|
1328
|
+
const colonIndex = entry.indexOf(':');
|
|
1329
|
+
if (colonIndex === -1)
|
|
1330
|
+
continue;
|
|
1331
|
+
const deliveryId = entry.substring(colonIndex + 1);
|
|
1332
|
+
const key = `${this.keyPrefix}delivery:${tenantId}:${webhookId}:${deliveryId}`;
|
|
1333
|
+
const data = await this.redis.get(key);
|
|
1334
|
+
if (data) {
|
|
1335
|
+
deliveries.push({
|
|
1336
|
+
id: deliveryId,
|
|
1337
|
+
result: JSON.parse(data),
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
else {
|
|
1341
|
+
// Data expired but index entry remains - clean up stale index entry
|
|
1342
|
+
await this.redis.zrem(indexKey, entry);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
return deliveries;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Clean up stale index entries for a webhook
|
|
1349
|
+
*
|
|
1350
|
+
* This removes index entries pointing to expired delivery records.
|
|
1351
|
+
* Called periodically or on-demand to maintain index hygiene.
|
|
1352
|
+
*/
|
|
1353
|
+
async cleanupDeliveryIndex(tenantId, webhookId) {
|
|
1354
|
+
const indexKey = `${this.keyPrefix}delivery-index:${tenantId}:${webhookId}`;
|
|
1355
|
+
let cleanedCount = 0;
|
|
1356
|
+
// Get all index entries
|
|
1357
|
+
const indexEntries = await this.redis.zrange(indexKey, 0, -1);
|
|
1358
|
+
for (const entry of indexEntries) {
|
|
1359
|
+
const colonIndex = entry.indexOf(':');
|
|
1360
|
+
if (colonIndex === -1)
|
|
1361
|
+
continue;
|
|
1362
|
+
const deliveryId = entry.substring(colonIndex + 1);
|
|
1363
|
+
const key = `${this.keyPrefix}delivery:${tenantId}:${webhookId}:${deliveryId}`;
|
|
1364
|
+
const exists = await this.redis.exists(key);
|
|
1365
|
+
if (!exists) {
|
|
1366
|
+
await this.redis.zrem(indexKey, entry);
|
|
1367
|
+
cleanedCount++;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
if (cleanedCount > 0) {
|
|
1371
|
+
logger.info({ tenantId, webhookId, cleanedCount }, 'Cleaned up stale delivery index entries');
|
|
1372
|
+
}
|
|
1373
|
+
return cleanedCount;
|
|
1374
|
+
}
|
|
1375
|
+
// =========================================================================
|
|
1376
|
+
// Persistent Delivery Methods
|
|
1377
|
+
// =========================================================================
|
|
1378
|
+
/**
|
|
1379
|
+
* Get persistent delivery history for a webhook.
|
|
1380
|
+
*
|
|
1381
|
+
* Returns deliveries from the database (not Redis), ordered by creation time.
|
|
1382
|
+
*
|
|
1383
|
+
* @param webhookId - Webhook ID
|
|
1384
|
+
* @param limit - Maximum number of records (default: 50, max: 100)
|
|
1385
|
+
* @returns Array of delivery records
|
|
1386
|
+
*/
|
|
1387
|
+
async getPersistentDeliveryHistory(webhookId, limit = 50) {
|
|
1388
|
+
return this.getDeliveryRepository().getDeliveryHistory(webhookId, limit);
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Get a single persistent delivery record by ID.
|
|
1392
|
+
*
|
|
1393
|
+
* @param deliveryId - Delivery ID
|
|
1394
|
+
* @returns Delivery record or null if not found
|
|
1395
|
+
*/
|
|
1396
|
+
async getPersistentDeliveryById(deliveryId) {
|
|
1397
|
+
return this.getDeliveryRepository().getDeliveryById(deliveryId);
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Replay a failed webhook delivery.
|
|
1401
|
+
*
|
|
1402
|
+
* Marks the delivery for immediate retry and processes it.
|
|
1403
|
+
* Only failed deliveries can be replayed.
|
|
1404
|
+
*
|
|
1405
|
+
* @param deliveryId - Delivery ID to replay
|
|
1406
|
+
* @param tenantId - Tenant ID (for authorization)
|
|
1407
|
+
* @returns Updated delivery record
|
|
1408
|
+
* @throws NotFoundError if delivery not found
|
|
1409
|
+
* @throws ValidationError if delivery is not in failed status
|
|
1410
|
+
*/
|
|
1411
|
+
async replayDelivery(deliveryId, tenantId) {
|
|
1412
|
+
const deliveryRepo = this.getDeliveryRepository();
|
|
1413
|
+
// Get the delivery record
|
|
1414
|
+
const delivery = await deliveryRepo.getDeliveryById(deliveryId);
|
|
1415
|
+
if (!delivery) {
|
|
1416
|
+
throw new NotFoundError(`Webhook delivery not found: ${deliveryId}`);
|
|
1417
|
+
}
|
|
1418
|
+
// Verify tenant authorization
|
|
1419
|
+
if (delivery.tenantId !== tenantId) {
|
|
1420
|
+
throw new NotFoundError(`Webhook delivery not found: ${deliveryId}`);
|
|
1421
|
+
}
|
|
1422
|
+
// Mark for replay (this validates status and sets nextRetryAt)
|
|
1423
|
+
const updatedDelivery = await deliveryRepo.markForReplay(deliveryId);
|
|
1424
|
+
logger.info({
|
|
1425
|
+
deliveryId,
|
|
1426
|
+
webhookId: delivery.webhookId,
|
|
1427
|
+
tenantId,
|
|
1428
|
+
eventType: delivery.eventType,
|
|
1429
|
+
}, 'Webhook delivery queued for replay');
|
|
1430
|
+
return updatedDelivery;
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Process pending retries.
|
|
1434
|
+
*
|
|
1435
|
+
* This method is intended to be called by a background worker/scheduler
|
|
1436
|
+
* to process deliveries that are in 'retrying' status and have passed
|
|
1437
|
+
* their nextRetryAt time.
|
|
1438
|
+
*
|
|
1439
|
+
* @param limit - Maximum number of deliveries to process (default: 100)
|
|
1440
|
+
* @returns Array of processing results
|
|
1441
|
+
*/
|
|
1442
|
+
async processPendingRetries(limit = 100) {
|
|
1443
|
+
const deliveryRepo = this.getDeliveryRepository();
|
|
1444
|
+
const pendingDeliveries = await deliveryRepo.getPendingRetries(limit);
|
|
1445
|
+
const results = [];
|
|
1446
|
+
for (const delivery of pendingDeliveries) {
|
|
1447
|
+
try {
|
|
1448
|
+
// Get webhook config
|
|
1449
|
+
const webhooks = await this.getWebhooks(delivery.tenantId);
|
|
1450
|
+
const webhook = webhooks.find(w => w.id === delivery.webhookId);
|
|
1451
|
+
if (!webhook) {
|
|
1452
|
+
// Webhook no longer exists - mark delivery as failed
|
|
1453
|
+
await deliveryRepo.updateDeliveryStatus(delivery.id, {
|
|
1454
|
+
status: 'failed',
|
|
1455
|
+
lastError: 'Webhook configuration not found',
|
|
1456
|
+
lastAttemptAt: new Date(),
|
|
1457
|
+
});
|
|
1458
|
+
results.push({
|
|
1459
|
+
deliveryId: delivery.id,
|
|
1460
|
+
success: false,
|
|
1461
|
+
error: 'Webhook configuration not found',
|
|
1462
|
+
});
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
if (!webhook.config.enabled) {
|
|
1466
|
+
// Webhook disabled - mark delivery as failed
|
|
1467
|
+
await deliveryRepo.updateDeliveryStatus(delivery.id, {
|
|
1468
|
+
status: 'failed',
|
|
1469
|
+
lastError: 'Webhook is disabled',
|
|
1470
|
+
lastAttemptAt: new Date(),
|
|
1471
|
+
});
|
|
1472
|
+
results.push({
|
|
1473
|
+
deliveryId: delivery.id,
|
|
1474
|
+
success: false,
|
|
1475
|
+
error: 'Webhook is disabled',
|
|
1476
|
+
});
|
|
1477
|
+
continue;
|
|
1478
|
+
}
|
|
1479
|
+
// Check circuit breaker
|
|
1480
|
+
const { allowed, circuitData } = await this.shouldAttemptDelivery(delivery.tenantId, delivery.webhookId);
|
|
1481
|
+
if (!allowed) {
|
|
1482
|
+
// Circuit breaker open - calculate next retry time
|
|
1483
|
+
const nextRetryAt = calculateNextRetryTime(delivery.attempts + 1);
|
|
1484
|
+
await deliveryRepo.updateDeliveryStatus(delivery.id, {
|
|
1485
|
+
status: 'retrying',
|
|
1486
|
+
lastError: 'Circuit breaker open - delivery postponed',
|
|
1487
|
+
lastAttemptAt: new Date(),
|
|
1488
|
+
nextRetryAt,
|
|
1489
|
+
});
|
|
1490
|
+
results.push({
|
|
1491
|
+
deliveryId: delivery.id,
|
|
1492
|
+
success: false,
|
|
1493
|
+
error: 'Circuit breaker open',
|
|
1494
|
+
});
|
|
1495
|
+
continue;
|
|
1496
|
+
}
|
|
1497
|
+
// Attempt delivery
|
|
1498
|
+
const payload = delivery.payload;
|
|
1499
|
+
const result = await this.deliverWithRetry(delivery.webhookId, webhook.config, payload, delivery.tenantId, circuitData, delivery.id);
|
|
1500
|
+
const resultEntry = {
|
|
1501
|
+
deliveryId: delivery.id,
|
|
1502
|
+
success: result.success,
|
|
1503
|
+
};
|
|
1504
|
+
if (result.error) {
|
|
1505
|
+
resultEntry.error = result.error;
|
|
1506
|
+
}
|
|
1507
|
+
results.push(resultEntry);
|
|
1508
|
+
}
|
|
1509
|
+
catch (error) {
|
|
1510
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
1511
|
+
logger.error({ deliveryId: delivery.id, error: errorMessage }, 'Error processing pending retry');
|
|
1512
|
+
results.push({
|
|
1513
|
+
deliveryId: delivery.id,
|
|
1514
|
+
success: false,
|
|
1515
|
+
error: errorMessage,
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
if (results.length > 0) {
|
|
1520
|
+
const successCount = results.filter(r => r.success).length;
|
|
1521
|
+
logger.info({ total: results.length, success: successCount, failed: results.length - successCount }, 'Processed pending webhook retries');
|
|
1522
|
+
}
|
|
1523
|
+
return results;
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Get failed deliveries for a tenant.
|
|
1527
|
+
*
|
|
1528
|
+
* @param tenantId - Tenant ID
|
|
1529
|
+
* @param limit - Maximum number of records (default: 50, max: 100)
|
|
1530
|
+
* @returns Array of failed delivery records
|
|
1531
|
+
*/
|
|
1532
|
+
async getFailedDeliveries(tenantId, limit = 50) {
|
|
1533
|
+
return this.getDeliveryRepository().getFailedDeliveries(tenantId, limit);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* Create webhook service instance
|
|
1538
|
+
*/
|
|
1539
|
+
export function createWebhookService() {
|
|
1540
|
+
return new WebhookService();
|
|
1541
|
+
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Default page size for delivery history queries
|
|
1544
|
+
*/
|
|
1545
|
+
const DEFAULT_DELIVERY_PAGE_SIZE = 50;
|
|
1546
|
+
/**
|
|
1547
|
+
* Maximum page size for delivery history queries
|
|
1548
|
+
*/
|
|
1549
|
+
const MAX_DELIVERY_PAGE_SIZE = 100;
|
|
1550
|
+
/**
|
|
1551
|
+
* Map database row to WebhookDelivery
|
|
1552
|
+
*/
|
|
1553
|
+
function mapDeliveryRow(row) {
|
|
1554
|
+
return {
|
|
1555
|
+
id: row.id,
|
|
1556
|
+
webhookId: row.webhookId,
|
|
1557
|
+
tenantId: row.tenantId,
|
|
1558
|
+
eventType: row.eventType,
|
|
1559
|
+
payload: (row.payload ?? {}),
|
|
1560
|
+
status: row.status,
|
|
1561
|
+
attempts: row.attempts,
|
|
1562
|
+
lastAttemptAt: row.lastAttemptAt?.toISOString() ?? null,
|
|
1563
|
+
lastError: row.lastError ?? null,
|
|
1564
|
+
nextRetryAt: row.nextRetryAt?.toISOString() ?? null,
|
|
1565
|
+
deliveredAt: row.deliveredAt?.toISOString() ?? null,
|
|
1566
|
+
responseStatus: row.responseStatus ?? null,
|
|
1567
|
+
responseBody: row.responseBody ?? null,
|
|
1568
|
+
createdAt: row.createdAt.toISOString(),
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Calculate next retry time with exponential backoff.
|
|
1573
|
+
*
|
|
1574
|
+
* Uses the formula: baseDelay * 2^(attempt - 1)
|
|
1575
|
+
* With a maximum delay cap to prevent extremely long waits.
|
|
1576
|
+
*
|
|
1577
|
+
* @param attempt - Current attempt number (1-based)
|
|
1578
|
+
* @param baseDelayMs - Base delay in milliseconds (default: 1000)
|
|
1579
|
+
* @param maxDelayMs - Maximum delay cap in milliseconds (default: 1 hour)
|
|
1580
|
+
* @returns Date when next retry should occur
|
|
1581
|
+
*/
|
|
1582
|
+
export function calculateNextRetryTime(attempt, baseDelayMs = 1000, maxDelayMs = 3600000 // 1 hour
|
|
1583
|
+
) {
|
|
1584
|
+
const delayMs = Math.min(baseDelayMs * Math.pow(2, attempt - 1), maxDelayMs);
|
|
1585
|
+
return new Date(Date.now() + delayMs);
|
|
1586
|
+
}
|
|
1587
|
+
// =============================================================================
|
|
1588
|
+
// Webhook Delivery Repository
|
|
1589
|
+
// =============================================================================
|
|
1590
|
+
/**
|
|
1591
|
+
* Repository for managing webhook delivery persistence.
|
|
1592
|
+
*
|
|
1593
|
+
* Provides CRUD operations for webhook delivery records, supporting:
|
|
1594
|
+
* - Creation of delivery records before attempting delivery
|
|
1595
|
+
* - Status updates on success/failure
|
|
1596
|
+
* - Retrieval of delivery history for auditing
|
|
1597
|
+
* - Fetching pending retries for background processing
|
|
1598
|
+
* - Fetching failed deliveries for monitoring/debugging
|
|
1599
|
+
*/
|
|
1600
|
+
export class WebhookDeliveryRepository {
|
|
1601
|
+
_db = null;
|
|
1602
|
+
/**
|
|
1603
|
+
* Get database instance (lazy initialization).
|
|
1604
|
+
*/
|
|
1605
|
+
get db() {
|
|
1606
|
+
if (!this._db) {
|
|
1607
|
+
this._db = getDatabase();
|
|
1608
|
+
}
|
|
1609
|
+
return this._db;
|
|
1610
|
+
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Create a new delivery record.
|
|
1613
|
+
*
|
|
1614
|
+
* Call this before attempting webhook delivery to ensure
|
|
1615
|
+
* the delivery is tracked even if the process crashes.
|
|
1616
|
+
*
|
|
1617
|
+
* @param data - Delivery creation options
|
|
1618
|
+
* @returns Created delivery record
|
|
1619
|
+
*/
|
|
1620
|
+
async createDelivery(data) {
|
|
1621
|
+
const insertData = {
|
|
1622
|
+
webhookId: data.webhookId,
|
|
1623
|
+
tenantId: data.tenantId,
|
|
1624
|
+
eventType: data.eventType,
|
|
1625
|
+
payload: data.payload,
|
|
1626
|
+
status: 'pending',
|
|
1627
|
+
attempts: 0,
|
|
1628
|
+
};
|
|
1629
|
+
const [row] = await this.db
|
|
1630
|
+
.insert(webhookDeliveries)
|
|
1631
|
+
.values(insertData)
|
|
1632
|
+
.returning();
|
|
1633
|
+
if (!row) {
|
|
1634
|
+
throw new Error('Failed to create webhook delivery record');
|
|
1635
|
+
}
|
|
1636
|
+
logger.info({ deliveryId: row.id, webhookId: data.webhookId, tenantId: data.tenantId, eventType: data.eventType }, 'Created webhook delivery record');
|
|
1637
|
+
return mapDeliveryRow(row);
|
|
1638
|
+
}
|
|
1639
|
+
/**
|
|
1640
|
+
* Update delivery status with details.
|
|
1641
|
+
*
|
|
1642
|
+
* @param id - Delivery ID
|
|
1643
|
+
* @param options - Status update options
|
|
1644
|
+
* @returns Updated delivery record
|
|
1645
|
+
* @throws NotFoundError if delivery not found
|
|
1646
|
+
*/
|
|
1647
|
+
async updateDeliveryStatus(id, options) {
|
|
1648
|
+
const updateData = {
|
|
1649
|
+
status: options.status,
|
|
1650
|
+
};
|
|
1651
|
+
if (options.attempts !== undefined) {
|
|
1652
|
+
updateData.attempts = options.attempts;
|
|
1653
|
+
}
|
|
1654
|
+
if (options.lastAttemptAt !== undefined) {
|
|
1655
|
+
updateData.lastAttemptAt = options.lastAttemptAt;
|
|
1656
|
+
}
|
|
1657
|
+
if (options.lastError !== undefined) {
|
|
1658
|
+
updateData.lastError = options.lastError;
|
|
1659
|
+
}
|
|
1660
|
+
if (options.nextRetryAt !== undefined) {
|
|
1661
|
+
updateData.nextRetryAt = options.nextRetryAt;
|
|
1662
|
+
}
|
|
1663
|
+
if (options.deliveredAt !== undefined) {
|
|
1664
|
+
updateData.deliveredAt = options.deliveredAt;
|
|
1665
|
+
}
|
|
1666
|
+
if (options.responseStatus !== undefined) {
|
|
1667
|
+
updateData.responseStatus = options.responseStatus;
|
|
1668
|
+
}
|
|
1669
|
+
if (options.responseBody !== undefined) {
|
|
1670
|
+
updateData.responseBody = options.responseBody;
|
|
1671
|
+
}
|
|
1672
|
+
const [row] = await this.db
|
|
1673
|
+
.update(webhookDeliveries)
|
|
1674
|
+
.set(updateData)
|
|
1675
|
+
.where(eq(webhookDeliveries.id, id))
|
|
1676
|
+
.returning();
|
|
1677
|
+
if (!row) {
|
|
1678
|
+
throw new NotFoundError(`Webhook delivery not found: ${id}`);
|
|
1679
|
+
}
|
|
1680
|
+
logger.debug({ deliveryId: id, status: options.status, attempts: options.attempts }, 'Updated webhook delivery status');
|
|
1681
|
+
return mapDeliveryRow(row);
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* Get delivery by ID.
|
|
1685
|
+
*
|
|
1686
|
+
* @param id - Delivery ID
|
|
1687
|
+
* @returns Delivery record or null if not found
|
|
1688
|
+
*/
|
|
1689
|
+
async getDeliveryById(id) {
|
|
1690
|
+
const [row] = await this.db
|
|
1691
|
+
.select()
|
|
1692
|
+
.from(webhookDeliveries)
|
|
1693
|
+
.where(eq(webhookDeliveries.id, id));
|
|
1694
|
+
return row ? mapDeliveryRow(row) : null;
|
|
1695
|
+
}
|
|
1696
|
+
/**
|
|
1697
|
+
* Get delivery history for a webhook.
|
|
1698
|
+
*
|
|
1699
|
+
* Returns deliveries ordered by creation time (most recent first).
|
|
1700
|
+
*
|
|
1701
|
+
* @param webhookId - Webhook ID
|
|
1702
|
+
* @param limit - Maximum number of records to return (default: 50, max: 100)
|
|
1703
|
+
* @returns Array of delivery records
|
|
1704
|
+
*/
|
|
1705
|
+
async getDeliveryHistory(webhookId, limit = DEFAULT_DELIVERY_PAGE_SIZE) {
|
|
1706
|
+
const effectiveLimit = Math.min(limit, MAX_DELIVERY_PAGE_SIZE);
|
|
1707
|
+
const rows = await this.db
|
|
1708
|
+
.select()
|
|
1709
|
+
.from(webhookDeliveries)
|
|
1710
|
+
.where(eq(webhookDeliveries.webhookId, webhookId))
|
|
1711
|
+
.orderBy(desc(webhookDeliveries.createdAt))
|
|
1712
|
+
.limit(effectiveLimit);
|
|
1713
|
+
return rows.map(mapDeliveryRow);
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Get pending retries that are due for processing.
|
|
1717
|
+
*
|
|
1718
|
+
* Returns deliveries with status='retrying' and nextRetryAt <= now.
|
|
1719
|
+
*
|
|
1720
|
+
* @param limit - Maximum number of records to return (default: 100)
|
|
1721
|
+
* @returns Array of delivery records ready for retry
|
|
1722
|
+
*/
|
|
1723
|
+
async getPendingRetries(limit = 100) {
|
|
1724
|
+
const now = new Date();
|
|
1725
|
+
const rows = await this.db
|
|
1726
|
+
.select()
|
|
1727
|
+
.from(webhookDeliveries)
|
|
1728
|
+
.where(and(eq(webhookDeliveries.status, 'retrying'), lte(webhookDeliveries.nextRetryAt, now)))
|
|
1729
|
+
.orderBy(webhookDeliveries.nextRetryAt)
|
|
1730
|
+
.limit(limit);
|
|
1731
|
+
return rows.map(mapDeliveryRow);
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Get failed deliveries for a tenant.
|
|
1735
|
+
*
|
|
1736
|
+
* Returns deliveries with status='failed' for monitoring and debugging.
|
|
1737
|
+
*
|
|
1738
|
+
* @param tenantId - Tenant ID
|
|
1739
|
+
* @param limit - Maximum number of records to return (default: 50, max: 100)
|
|
1740
|
+
* @returns Array of failed delivery records
|
|
1741
|
+
*/
|
|
1742
|
+
async getFailedDeliveries(tenantId, limit = DEFAULT_DELIVERY_PAGE_SIZE) {
|
|
1743
|
+
const effectiveLimit = Math.min(limit, MAX_DELIVERY_PAGE_SIZE);
|
|
1744
|
+
const rows = await this.db
|
|
1745
|
+
.select()
|
|
1746
|
+
.from(webhookDeliveries)
|
|
1747
|
+
.where(and(eq(webhookDeliveries.tenantId, tenantId), eq(webhookDeliveries.status, 'failed')))
|
|
1748
|
+
.orderBy(desc(webhookDeliveries.createdAt))
|
|
1749
|
+
.limit(effectiveLimit);
|
|
1750
|
+
return rows.map(mapDeliveryRow);
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* Get deliveries by tenant with pagination.
|
|
1754
|
+
*
|
|
1755
|
+
* @param tenantId - Tenant ID
|
|
1756
|
+
* @param options - Pagination options
|
|
1757
|
+
* @returns Paginated array of delivery records
|
|
1758
|
+
*/
|
|
1759
|
+
async getDeliveriesByTenant(tenantId, options = {}) {
|
|
1760
|
+
const limit = Math.min(options.limit ?? DEFAULT_DELIVERY_PAGE_SIZE, MAX_DELIVERY_PAGE_SIZE);
|
|
1761
|
+
const offset = options.offset ?? 0;
|
|
1762
|
+
const whereConditions = [eq(webhookDeliveries.tenantId, tenantId)];
|
|
1763
|
+
if (options.status) {
|
|
1764
|
+
whereConditions.push(eq(webhookDeliveries.status, options.status));
|
|
1765
|
+
}
|
|
1766
|
+
const rows = await this.db
|
|
1767
|
+
.select()
|
|
1768
|
+
.from(webhookDeliveries)
|
|
1769
|
+
.where(and(...whereConditions))
|
|
1770
|
+
.orderBy(desc(webhookDeliveries.createdAt))
|
|
1771
|
+
.limit(limit + 1)
|
|
1772
|
+
.offset(offset);
|
|
1773
|
+
const hasMore = rows.length > limit;
|
|
1774
|
+
const items = hasMore ? rows.slice(0, limit) : rows;
|
|
1775
|
+
return {
|
|
1776
|
+
items: items.map(mapDeliveryRow),
|
|
1777
|
+
hasMore,
|
|
1778
|
+
};
|
|
1779
|
+
}
|
|
1780
|
+
/**
|
|
1781
|
+
* Mark a delivery for immediate replay.
|
|
1782
|
+
*
|
|
1783
|
+
* Resets the delivery status to 'retrying' with nextRetryAt set to now.
|
|
1784
|
+
* Does not reset attempt count to preserve audit history.
|
|
1785
|
+
*
|
|
1786
|
+
* @param id - Delivery ID
|
|
1787
|
+
* @returns Updated delivery record
|
|
1788
|
+
* @throws NotFoundError if delivery not found
|
|
1789
|
+
*/
|
|
1790
|
+
async markForReplay(id) {
|
|
1791
|
+
const delivery = await this.getDeliveryById(id);
|
|
1792
|
+
if (!delivery) {
|
|
1793
|
+
throw new NotFoundError(`Webhook delivery not found: ${id}`);
|
|
1794
|
+
}
|
|
1795
|
+
// Only allow replay of failed deliveries
|
|
1796
|
+
if (delivery.status !== 'failed') {
|
|
1797
|
+
throw new ValidationError(`Cannot replay delivery with status '${delivery.status}'. Only failed deliveries can be replayed.`, { deliveryId: id, currentStatus: delivery.status });
|
|
1798
|
+
}
|
|
1799
|
+
const updatedDelivery = await this.updateDeliveryStatus(id, {
|
|
1800
|
+
status: 'retrying',
|
|
1801
|
+
nextRetryAt: new Date(), // Immediate retry
|
|
1802
|
+
lastError: null, // Clear last error for retry
|
|
1803
|
+
});
|
|
1804
|
+
logger.info({ deliveryId: id, webhookId: delivery.webhookId, tenantId: delivery.tenantId }, 'Marked webhook delivery for replay');
|
|
1805
|
+
return updatedDelivery;
|
|
1806
|
+
}
|
|
1807
|
+
/**
|
|
1808
|
+
* Clean up old delivery records.
|
|
1809
|
+
*
|
|
1810
|
+
* Deletes deliveries older than the specified retention period.
|
|
1811
|
+
* Typically called by a scheduled cleanup job.
|
|
1812
|
+
*
|
|
1813
|
+
* @param retentionDays - Number of days to retain records
|
|
1814
|
+
* @returns Number of records deleted
|
|
1815
|
+
*/
|
|
1816
|
+
async cleanupOldDeliveries(retentionDays) {
|
|
1817
|
+
const cutoffDate = new Date();
|
|
1818
|
+
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
|
|
1819
|
+
const result = await this.db
|
|
1820
|
+
.delete(webhookDeliveries)
|
|
1821
|
+
.where(lt(webhookDeliveries.createdAt, cutoffDate))
|
|
1822
|
+
.returning({ id: webhookDeliveries.id });
|
|
1823
|
+
const deletedCount = result.length;
|
|
1824
|
+
if (deletedCount > 0) {
|
|
1825
|
+
logger.info({ deletedCount, retentionDays, cutoffDate: cutoffDate.toISOString() }, 'Cleaned up old webhook delivery records');
|
|
1826
|
+
}
|
|
1827
|
+
return deletedCount;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Create webhook delivery repository instance
|
|
1832
|
+
*/
|
|
1833
|
+
export function createWebhookDeliveryRepository() {
|
|
1834
|
+
return new WebhookDeliveryRepository();
|
|
1835
|
+
}
|
|
1836
|
+
//# sourceMappingURL=webhooks.js.map
|