rdapify 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ar.md +572 -0
- package/README.md +74 -77
- package/dist/{application → cjs/application}/client/RDAPClient.js +197 -6
- package/dist/{application → cjs/application}/client/index.js +0 -1
- package/dist/{application → cjs/application}/deduplication/QueryDeduplicator.js +0 -1
- package/dist/{application → cjs/application}/hooks/MiddlewareHooks.js +0 -1
- package/dist/{application → cjs/application}/services/BatchProcessor.js +0 -1
- package/dist/{application → cjs/application}/services/QueryOrchestrator.js +0 -1
- package/dist/{application → cjs/application}/services/QueryPriority.js +0 -1
- package/dist/{application → cjs/application}/services/index.js +0 -1
- package/dist/{cli → cjs/cli}/index.js +0 -1
- package/dist/cjs/core/ports/bootstrap.port.js +2 -0
- package/dist/cjs/core/ports/cache.port.js +2 -0
- package/dist/cjs/core/ports/fetcher.port.js +2 -0
- package/dist/{core → cjs/core}/ports/index.js +0 -1
- package/dist/cjs/core/ports/normalizer.port.js +2 -0
- package/dist/cjs/core/ports/pii-redactor.port.js +2 -0
- package/dist/{index.js → cjs/index.js} +8 -4
- package/dist/{infrastructure → cjs/infrastructure}/cache/CacheManager.js +4 -1
- package/dist/{infrastructure → cjs/infrastructure}/cache/InMemoryCache.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/cache/PersistentCache.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/cache/RedisCache.js +0 -1
- package/dist/cjs/infrastructure/cache/StaleWhileRevalidateCache.js +47 -0
- package/dist/{infrastructure → cjs/infrastructure}/cache/index.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/AuthenticationManager.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/BootstrapDiscovery.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/BrowserFetcher.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/BunFetcher.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/CircuitBreaker.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/CloudflareWorkersFetcher.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/CompressionManager.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/ConnectionPool.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/DenoFetcher.js +0 -1
- package/dist/cjs/infrastructure/http/DistributedRateLimiter.js +26 -0
- package/dist/{infrastructure → cjs/infrastructure}/http/Fetcher.js +5 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/Normalizer.js +23 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/ProxyManager.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/RateLimiter.js +6 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/RetryStrategy.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/http/index.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/logging/AuditLogger.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/logging/Logger.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/monitoring/GrafanaDashboard.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/monitoring/MetricsCollector.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/monitoring/PrometheusExporter.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/monitoring/TelemetryExporter.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/native/NativeBackend.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/security/PIIRedactor.js +0 -1
- package/dist/{infrastructure → cjs/infrastructure}/security/SSRFProtection.js +23 -1
- package/dist/{infrastructure → cjs/infrastructure}/security/index.js +0 -1
- package/dist/cjs/infrastructure/telemetry/UsageTelemetry.js +89 -0
- package/dist/{infrastructure → cjs/infrastructure}/validation/ResponseValidator.js +0 -1
- package/dist/{integrations → cjs/integrations}/express.js +0 -1
- package/dist/{integrations → cjs/integrations}/graphql.js +0 -1
- package/dist/{integrations → cjs/integrations}/nestjs.js +0 -1
- package/dist/{shared → cjs/shared}/constants/http.constants.js +0 -1
- package/dist/{shared → cjs/shared}/constants/index.js +0 -1
- package/dist/{shared → cjs/shared}/constants/rdap.constants.js +0 -1
- package/dist/{shared → cjs/shared}/errors/base.error.js +7 -2
- package/dist/{shared → cjs/shared}/errors/index.js +0 -1
- package/dist/{shared → cjs/shared}/types/entities.js +0 -1
- package/dist/{shared → cjs/shared}/types/enums.js +0 -1
- package/dist/{shared → cjs/shared}/types/errors.js +0 -1
- package/dist/{shared → cjs/shared}/types/generics.js +0 -1
- package/dist/{shared → cjs/shared}/types/index.js +0 -1
- package/dist/{shared → cjs/shared}/types/options.js +5 -1
- package/dist/cjs/shared/types/responses.js +2 -0
- package/dist/{shared → cjs/shared}/utils/deprecation.js +0 -1
- package/dist/{shared → cjs/shared}/utils/enhanced-validators.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/async.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/cache.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/format.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/http.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/index.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/object.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/runtime.js +0 -1
- package/dist/{shared → cjs/shared}/utils/helpers/string.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/asn.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/config-validation.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/domain.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/entity.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/index.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/ip.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/nameserver.js +0 -1
- package/dist/{shared → cjs/shared}/utils/validators/network.js +0 -1
- package/dist/esm/application/client/RDAPClient.js +439 -0
- package/dist/esm/application/client/index.js +1 -0
- package/dist/esm/application/deduplication/QueryDeduplicator.js +41 -0
- package/dist/esm/application/hooks/MiddlewareHooks.js +79 -0
- package/dist/esm/application/services/BatchProcessor.js +145 -0
- package/dist/esm/application/services/QueryOrchestrator.js +615 -0
- package/dist/esm/application/services/QueryPriority.js +109 -0
- package/dist/esm/application/services/index.js +2 -0
- package/dist/esm/cli/index.js +297 -0
- package/dist/esm/core/ports/bootstrap.port.js +1 -0
- package/dist/esm/core/ports/cache.port.js +1 -0
- package/dist/esm/core/ports/fetcher.port.js +1 -0
- package/dist/esm/core/ports/index.js +5 -0
- package/dist/esm/core/ports/normalizer.port.js +1 -0
- package/dist/esm/core/ports/pii-redactor.port.js +1 -0
- package/dist/esm/index.js +40 -0
- package/dist/esm/infrastructure/cache/CacheManager.js +123 -0
- package/dist/esm/infrastructure/cache/InMemoryCache.js +91 -0
- package/dist/esm/infrastructure/cache/PersistentCache.js +188 -0
- package/dist/esm/infrastructure/cache/RedisCache.js +106 -0
- package/dist/esm/infrastructure/cache/StaleWhileRevalidateCache.js +43 -0
- package/dist/esm/infrastructure/cache/index.js +3 -0
- package/dist/esm/infrastructure/http/AuthenticationManager.js +94 -0
- package/dist/esm/infrastructure/http/BootstrapDiscovery.js +189 -0
- package/dist/esm/infrastructure/http/BrowserFetcher.js +42 -0
- package/dist/esm/infrastructure/http/BunFetcher.js +46 -0
- package/dist/esm/infrastructure/http/CircuitBreaker.js +98 -0
- package/dist/esm/infrastructure/http/CloudflareWorkersFetcher.js +39 -0
- package/dist/esm/infrastructure/http/CompressionManager.js +80 -0
- package/dist/esm/infrastructure/http/ConnectionPool.js +101 -0
- package/dist/esm/infrastructure/http/DenoFetcher.js +38 -0
- package/dist/esm/infrastructure/http/DistributedRateLimiter.js +22 -0
- package/dist/esm/infrastructure/http/Fetcher.js +127 -0
- package/dist/esm/infrastructure/http/Normalizer.js +233 -0
- package/dist/esm/infrastructure/http/ProxyManager.js +82 -0
- package/dist/esm/infrastructure/http/RateLimiter.js +102 -0
- package/dist/esm/infrastructure/http/RetryStrategy.js +131 -0
- package/dist/esm/infrastructure/http/index.js +3 -0
- package/dist/esm/infrastructure/logging/AuditLogger.js +187 -0
- package/dist/esm/infrastructure/logging/Logger.js +145 -0
- package/dist/esm/infrastructure/monitoring/GrafanaDashboard.js +115 -0
- package/dist/esm/infrastructure/monitoring/MetricsCollector.js +284 -0
- package/dist/esm/infrastructure/monitoring/PrometheusExporter.js +72 -0
- package/dist/esm/infrastructure/monitoring/TelemetryExporter.js +112 -0
- package/dist/esm/infrastructure/native/NativeBackend.js +86 -0
- package/dist/esm/infrastructure/security/PIIRedactor.js +85 -0
- package/dist/esm/infrastructure/security/SSRFProtection.js +162 -0
- package/dist/esm/infrastructure/security/index.js +2 -0
- package/dist/esm/infrastructure/telemetry/UsageTelemetry.js +84 -0
- package/dist/esm/infrastructure/validation/ResponseValidator.js +194 -0
- package/dist/esm/integrations/express.js +43 -0
- package/dist/esm/integrations/graphql.js +80 -0
- package/dist/esm/integrations/nestjs.js +23 -0
- package/dist/esm/shared/constants/http.constants.js +25 -0
- package/dist/esm/shared/constants/index.js +2 -0
- package/dist/esm/shared/constants/rdap.constants.js +17 -0
- package/dist/esm/shared/errors/base.error.js +140 -0
- package/dist/esm/shared/errors/index.js +1 -0
- package/dist/esm/shared/types/entities.js +1 -0
- package/dist/esm/shared/types/enums.js +1 -0
- package/dist/esm/shared/types/errors.js +82 -0
- package/dist/esm/shared/types/generics.js +1 -0
- package/dist/esm/shared/types/index.js +1 -0
- package/dist/esm/shared/types/options.js +66 -0
- package/dist/esm/shared/types/responses.js +1 -0
- package/dist/esm/shared/utils/deprecation.js +20 -0
- package/dist/esm/shared/utils/enhanced-validators.js +148 -0
- package/dist/esm/shared/utils/helpers/async.js +40 -0
- package/dist/esm/shared/utils/helpers/cache.js +3 -0
- package/dist/esm/shared/utils/helpers/format.js +17 -0
- package/dist/esm/shared/utils/helpers/http.js +13 -0
- package/dist/esm/shared/utils/helpers/index.js +7 -0
- package/dist/esm/shared/utils/helpers/object.js +19 -0
- package/dist/esm/shared/utils/helpers/runtime.js +34 -0
- package/dist/esm/shared/utils/helpers/string.js +23 -0
- package/dist/esm/shared/utils/validators/asn.js +25 -0
- package/dist/esm/shared/utils/validators/config-validation.js +93 -0
- package/dist/esm/shared/utils/validators/domain.js +29 -0
- package/dist/esm/shared/utils/validators/entity.js +22 -0
- package/dist/esm/shared/utils/validators/index.js +7 -0
- package/dist/esm/shared/utils/validators/ip.js +48 -0
- package/dist/esm/shared/utils/validators/nameserver.js +44 -0
- package/dist/esm/shared/utils/validators/network.js +42 -0
- package/dist/{application → types/application}/client/RDAPClient.d.ts +10 -1
- package/dist/types/application/client/RDAPClient.d.ts.map +1 -0
- package/dist/types/application/client/index.d.ts.map +1 -0
- package/dist/types/application/deduplication/QueryDeduplicator.d.ts.map +1 -0
- package/dist/types/application/hooks/MiddlewareHooks.d.ts.map +1 -0
- package/dist/types/application/services/BatchProcessor.d.ts.map +1 -0
- package/dist/types/application/services/QueryOrchestrator.d.ts.map +1 -0
- package/dist/types/application/services/QueryPriority.d.ts.map +1 -0
- package/dist/types/application/services/index.d.ts.map +1 -0
- package/dist/{cli → types/cli}/index.d.ts.map +1 -1
- package/dist/types/core/ports/bootstrap.port.d.ts.map +1 -0
- package/dist/types/core/ports/cache.port.d.ts.map +1 -0
- package/dist/types/core/ports/fetcher.port.d.ts.map +1 -0
- package/dist/types/core/ports/index.d.ts.map +1 -0
- package/dist/types/core/ports/normalizer.port.d.ts.map +1 -0
- package/dist/types/core/ports/pii-redactor.port.d.ts.map +1 -0
- package/dist/{index.d.ts → types/index.d.ts} +6 -3
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/infrastructure/cache/CacheManager.d.ts.map +1 -0
- package/dist/types/infrastructure/cache/InMemoryCache.d.ts.map +1 -0
- package/dist/types/infrastructure/cache/PersistentCache.d.ts.map +1 -0
- package/dist/types/infrastructure/cache/RedisCache.d.ts.map +1 -0
- package/dist/types/infrastructure/cache/StaleWhileRevalidateCache.d.ts +16 -0
- package/dist/types/infrastructure/cache/StaleWhileRevalidateCache.d.ts.map +1 -0
- package/dist/types/infrastructure/cache/index.d.ts.map +1 -0
- package/dist/types/infrastructure/http/AuthenticationManager.d.ts.map +1 -0
- package/dist/types/infrastructure/http/BootstrapDiscovery.d.ts.map +1 -0
- package/dist/types/infrastructure/http/BrowserFetcher.d.ts.map +1 -0
- package/dist/types/infrastructure/http/BunFetcher.d.ts.map +1 -0
- package/dist/types/infrastructure/http/CircuitBreaker.d.ts.map +1 -0
- package/dist/types/infrastructure/http/CloudflareWorkersFetcher.d.ts.map +1 -0
- package/dist/types/infrastructure/http/CompressionManager.d.ts.map +1 -0
- package/dist/types/infrastructure/http/ConnectionPool.d.ts.map +1 -0
- package/dist/types/infrastructure/http/DenoFetcher.d.ts.map +1 -0
- package/dist/types/infrastructure/http/DistributedRateLimiter.d.ts +12 -0
- package/dist/types/infrastructure/http/DistributedRateLimiter.d.ts.map +1 -0
- package/dist/{infrastructure → types/infrastructure}/http/Fetcher.d.ts +2 -0
- package/dist/types/infrastructure/http/Fetcher.d.ts.map +1 -0
- package/dist/types/infrastructure/http/Normalizer.d.ts.map +1 -0
- package/dist/types/infrastructure/http/ProxyManager.d.ts.map +1 -0
- package/dist/{infrastructure → types/infrastructure}/http/RateLimiter.d.ts +5 -0
- package/dist/types/infrastructure/http/RateLimiter.d.ts.map +1 -0
- package/dist/types/infrastructure/http/RetryStrategy.d.ts.map +1 -0
- package/dist/types/infrastructure/http/index.d.ts.map +1 -0
- package/dist/types/infrastructure/logging/AuditLogger.d.ts.map +1 -0
- package/dist/types/infrastructure/logging/Logger.d.ts.map +1 -0
- package/dist/{infrastructure → types/infrastructure}/monitoring/GrafanaDashboard.d.ts.map +1 -1
- package/dist/types/infrastructure/monitoring/MetricsCollector.d.ts.map +1 -0
- package/dist/types/infrastructure/monitoring/PrometheusExporter.d.ts.map +1 -0
- package/dist/types/infrastructure/monitoring/TelemetryExporter.d.ts.map +1 -0
- package/dist/types/infrastructure/native/NativeBackend.d.ts.map +1 -0
- package/dist/types/infrastructure/security/PIIRedactor.d.ts.map +1 -0
- package/dist/{infrastructure → types/infrastructure}/security/SSRFProtection.d.ts +1 -0
- package/dist/types/infrastructure/security/SSRFProtection.d.ts.map +1 -0
- package/dist/types/infrastructure/security/index.d.ts.map +1 -0
- package/dist/types/infrastructure/telemetry/UsageTelemetry.d.ts +13 -0
- package/dist/types/infrastructure/telemetry/UsageTelemetry.d.ts.map +1 -0
- package/dist/types/infrastructure/validation/ResponseValidator.d.ts.map +1 -0
- package/dist/types/integrations/express.d.ts.map +1 -0
- package/dist/types/integrations/graphql.d.ts.map +1 -0
- package/dist/types/integrations/nestjs.d.ts.map +1 -0
- package/dist/types/shared/constants/http.constants.d.ts.map +1 -0
- package/dist/types/shared/constants/index.d.ts.map +1 -0
- package/dist/types/shared/constants/rdap.constants.d.ts.map +1 -0
- package/dist/{shared → types/shared}/errors/base.error.d.ts +3 -0
- package/dist/types/shared/errors/base.error.d.ts.map +1 -0
- package/dist/types/shared/errors/index.d.ts.map +1 -0
- package/dist/types/shared/types/entities.d.ts.map +1 -0
- package/dist/{shared → types/shared}/types/enums.d.ts +1 -1
- package/dist/types/shared/types/enums.d.ts.map +1 -0
- package/dist/types/shared/types/errors.d.ts.map +1 -0
- package/dist/types/shared/types/generics.d.ts.map +1 -0
- package/dist/{shared → types/shared}/types/index.d.ts +1 -1
- package/dist/types/shared/types/index.d.ts.map +1 -0
- package/dist/{shared → types/shared}/types/options.d.ts +9 -0
- package/dist/types/shared/types/options.d.ts.map +1 -0
- package/dist/{shared → types/shared}/types/responses.d.ts +20 -0
- package/dist/types/shared/types/responses.d.ts.map +1 -0
- package/dist/types/shared/utils/deprecation.d.ts.map +1 -0
- package/dist/types/shared/utils/enhanced-validators.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/async.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/cache.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/format.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/http.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/index.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/object.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/runtime.d.ts.map +1 -0
- package/dist/types/shared/utils/helpers/string.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/asn.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/config-validation.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/domain.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/entity.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/index.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/ip.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/nameserver.d.ts.map +1 -0
- package/dist/types/shared/utils/validators/network.d.ts.map +1 -0
- package/package.json +29 -25
- package/dist/application/client/RDAPClient.d.ts.map +0 -1
- package/dist/application/client/RDAPClient.js.map +0 -1
- package/dist/application/client/index.d.ts.map +0 -1
- package/dist/application/client/index.js.map +0 -1
- package/dist/application/deduplication/QueryDeduplicator.d.ts.map +0 -1
- package/dist/application/deduplication/QueryDeduplicator.js.map +0 -1
- package/dist/application/hooks/MiddlewareHooks.d.ts.map +0 -1
- package/dist/application/hooks/MiddlewareHooks.js.map +0 -1
- package/dist/application/services/BatchProcessor.d.ts.map +0 -1
- package/dist/application/services/BatchProcessor.js.map +0 -1
- package/dist/application/services/QueryOrchestrator.d.ts.map +0 -1
- package/dist/application/services/QueryOrchestrator.js.map +0 -1
- package/dist/application/services/QueryPriority.d.ts.map +0 -1
- package/dist/application/services/QueryPriority.js.map +0 -1
- package/dist/application/services/index.d.ts.map +0 -1
- package/dist/application/services/index.js.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/core/ports/bootstrap.port.d.ts.map +0 -1
- package/dist/core/ports/bootstrap.port.js +0 -3
- package/dist/core/ports/bootstrap.port.js.map +0 -1
- package/dist/core/ports/cache.port.d.ts.map +0 -1
- package/dist/core/ports/cache.port.js +0 -3
- package/dist/core/ports/cache.port.js.map +0 -1
- package/dist/core/ports/fetcher.port.d.ts.map +0 -1
- package/dist/core/ports/fetcher.port.js +0 -3
- package/dist/core/ports/fetcher.port.js.map +0 -1
- package/dist/core/ports/index.d.ts.map +0 -1
- package/dist/core/ports/index.js.map +0 -1
- package/dist/core/ports/normalizer.port.d.ts.map +0 -1
- package/dist/core/ports/normalizer.port.js +0 -3
- package/dist/core/ports/normalizer.port.js.map +0 -1
- package/dist/core/ports/pii-redactor.port.d.ts.map +0 -1
- package/dist/core/ports/pii-redactor.port.js +0 -3
- package/dist/core/ports/pii-redactor.port.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/infrastructure/cache/CacheManager.d.ts.map +0 -1
- package/dist/infrastructure/cache/CacheManager.js.map +0 -1
- package/dist/infrastructure/cache/InMemoryCache.d.ts.map +0 -1
- package/dist/infrastructure/cache/InMemoryCache.js.map +0 -1
- package/dist/infrastructure/cache/PersistentCache.d.ts.map +0 -1
- package/dist/infrastructure/cache/PersistentCache.js.map +0 -1
- package/dist/infrastructure/cache/RedisCache.d.ts.map +0 -1
- package/dist/infrastructure/cache/RedisCache.js.map +0 -1
- package/dist/infrastructure/cache/index.d.ts.map +0 -1
- package/dist/infrastructure/cache/index.js.map +0 -1
- package/dist/infrastructure/http/AuthenticationManager.d.ts.map +0 -1
- package/dist/infrastructure/http/AuthenticationManager.js.map +0 -1
- package/dist/infrastructure/http/BootstrapDiscovery.d.ts.map +0 -1
- package/dist/infrastructure/http/BootstrapDiscovery.js.map +0 -1
- package/dist/infrastructure/http/BrowserFetcher.d.ts.map +0 -1
- package/dist/infrastructure/http/BrowserFetcher.js.map +0 -1
- package/dist/infrastructure/http/BunFetcher.d.ts.map +0 -1
- package/dist/infrastructure/http/BunFetcher.js.map +0 -1
- package/dist/infrastructure/http/CircuitBreaker.d.ts.map +0 -1
- package/dist/infrastructure/http/CircuitBreaker.js.map +0 -1
- package/dist/infrastructure/http/CloudflareWorkersFetcher.d.ts.map +0 -1
- package/dist/infrastructure/http/CloudflareWorkersFetcher.js.map +0 -1
- package/dist/infrastructure/http/CompressionManager.d.ts.map +0 -1
- package/dist/infrastructure/http/CompressionManager.js.map +0 -1
- package/dist/infrastructure/http/ConnectionPool.d.ts.map +0 -1
- package/dist/infrastructure/http/ConnectionPool.js.map +0 -1
- package/dist/infrastructure/http/DenoFetcher.d.ts.map +0 -1
- package/dist/infrastructure/http/DenoFetcher.js.map +0 -1
- package/dist/infrastructure/http/Fetcher.d.ts.map +0 -1
- package/dist/infrastructure/http/Fetcher.js.map +0 -1
- package/dist/infrastructure/http/Normalizer.d.ts.map +0 -1
- package/dist/infrastructure/http/Normalizer.js.map +0 -1
- package/dist/infrastructure/http/ProxyManager.d.ts.map +0 -1
- package/dist/infrastructure/http/ProxyManager.js.map +0 -1
- package/dist/infrastructure/http/RateLimiter.d.ts.map +0 -1
- package/dist/infrastructure/http/RateLimiter.js.map +0 -1
- package/dist/infrastructure/http/RetryStrategy.d.ts.map +0 -1
- package/dist/infrastructure/http/RetryStrategy.js.map +0 -1
- package/dist/infrastructure/http/index.d.ts.map +0 -1
- package/dist/infrastructure/http/index.js.map +0 -1
- package/dist/infrastructure/logging/AuditLogger.d.ts.map +0 -1
- package/dist/infrastructure/logging/AuditLogger.js.map +0 -1
- package/dist/infrastructure/logging/Logger.d.ts.map +0 -1
- package/dist/infrastructure/logging/Logger.js.map +0 -1
- package/dist/infrastructure/monitoring/GrafanaDashboard.js.map +0 -1
- package/dist/infrastructure/monitoring/MetricsCollector.d.ts.map +0 -1
- package/dist/infrastructure/monitoring/MetricsCollector.js.map +0 -1
- package/dist/infrastructure/monitoring/PrometheusExporter.d.ts.map +0 -1
- package/dist/infrastructure/monitoring/PrometheusExporter.js.map +0 -1
- package/dist/infrastructure/monitoring/TelemetryExporter.d.ts.map +0 -1
- package/dist/infrastructure/monitoring/TelemetryExporter.js.map +0 -1
- package/dist/infrastructure/native/NativeBackend.d.ts.map +0 -1
- package/dist/infrastructure/native/NativeBackend.js.map +0 -1
- package/dist/infrastructure/security/PIIRedactor.d.ts.map +0 -1
- package/dist/infrastructure/security/PIIRedactor.js.map +0 -1
- package/dist/infrastructure/security/SSRFProtection.d.ts.map +0 -1
- package/dist/infrastructure/security/SSRFProtection.js.map +0 -1
- package/dist/infrastructure/security/index.d.ts.map +0 -1
- package/dist/infrastructure/security/index.js.map +0 -1
- package/dist/infrastructure/validation/ResponseValidator.d.ts.map +0 -1
- package/dist/infrastructure/validation/ResponseValidator.js.map +0 -1
- package/dist/integrations/express.d.ts.map +0 -1
- package/dist/integrations/express.js.map +0 -1
- package/dist/integrations/graphql.d.ts.map +0 -1
- package/dist/integrations/graphql.js.map +0 -1
- package/dist/integrations/nestjs.d.ts.map +0 -1
- package/dist/integrations/nestjs.js.map +0 -1
- package/dist/shared/constants/http.constants.d.ts.map +0 -1
- package/dist/shared/constants/http.constants.js.map +0 -1
- package/dist/shared/constants/index.d.ts.map +0 -1
- package/dist/shared/constants/index.js.map +0 -1
- package/dist/shared/constants/rdap.constants.d.ts.map +0 -1
- package/dist/shared/constants/rdap.constants.js.map +0 -1
- package/dist/shared/errors/base.error.d.ts.map +0 -1
- package/dist/shared/errors/base.error.js.map +0 -1
- package/dist/shared/errors/index.d.ts.map +0 -1
- package/dist/shared/errors/index.js.map +0 -1
- package/dist/shared/types/entities.d.ts.map +0 -1
- package/dist/shared/types/entities.js.map +0 -1
- package/dist/shared/types/enums.d.ts.map +0 -1
- package/dist/shared/types/enums.js.map +0 -1
- package/dist/shared/types/errors.d.ts.map +0 -1
- package/dist/shared/types/errors.js.map +0 -1
- package/dist/shared/types/generics.d.ts.map +0 -1
- package/dist/shared/types/generics.js.map +0 -1
- package/dist/shared/types/index.d.ts.map +0 -1
- package/dist/shared/types/index.js.map +0 -1
- package/dist/shared/types/options.d.ts.map +0 -1
- package/dist/shared/types/options.js.map +0 -1
- package/dist/shared/types/responses.d.ts.map +0 -1
- package/dist/shared/types/responses.js +0 -3
- package/dist/shared/types/responses.js.map +0 -1
- package/dist/shared/utils/deprecation.d.ts.map +0 -1
- package/dist/shared/utils/deprecation.js.map +0 -1
- package/dist/shared/utils/enhanced-validators.d.ts.map +0 -1
- package/dist/shared/utils/enhanced-validators.js.map +0 -1
- package/dist/shared/utils/helpers/async.d.ts.map +0 -1
- package/dist/shared/utils/helpers/async.js.map +0 -1
- package/dist/shared/utils/helpers/cache.d.ts.map +0 -1
- package/dist/shared/utils/helpers/cache.js.map +0 -1
- package/dist/shared/utils/helpers/format.d.ts.map +0 -1
- package/dist/shared/utils/helpers/format.js.map +0 -1
- package/dist/shared/utils/helpers/http.d.ts.map +0 -1
- package/dist/shared/utils/helpers/http.js.map +0 -1
- package/dist/shared/utils/helpers/index.d.ts.map +0 -1
- package/dist/shared/utils/helpers/index.js.map +0 -1
- package/dist/shared/utils/helpers/object.d.ts.map +0 -1
- package/dist/shared/utils/helpers/object.js.map +0 -1
- package/dist/shared/utils/helpers/runtime.d.ts.map +0 -1
- package/dist/shared/utils/helpers/runtime.js.map +0 -1
- package/dist/shared/utils/helpers/string.d.ts.map +0 -1
- package/dist/shared/utils/helpers/string.js.map +0 -1
- package/dist/shared/utils/validators/asn.d.ts.map +0 -1
- package/dist/shared/utils/validators/asn.js.map +0 -1
- package/dist/shared/utils/validators/config-validation.d.ts.map +0 -1
- package/dist/shared/utils/validators/config-validation.js.map +0 -1
- package/dist/shared/utils/validators/domain.d.ts.map +0 -1
- package/dist/shared/utils/validators/domain.js.map +0 -1
- package/dist/shared/utils/validators/entity.d.ts.map +0 -1
- package/dist/shared/utils/validators/entity.js.map +0 -1
- package/dist/shared/utils/validators/index.d.ts.map +0 -1
- package/dist/shared/utils/validators/index.js.map +0 -1
- package/dist/shared/utils/validators/ip.d.ts.map +0 -1
- package/dist/shared/utils/validators/ip.js.map +0 -1
- package/dist/shared/utils/validators/nameserver.d.ts.map +0 -1
- package/dist/shared/utils/validators/nameserver.js.map +0 -1
- package/dist/shared/utils/validators/network.d.ts.map +0 -1
- package/dist/shared/utils/validators/network.js.map +0 -1
- /package/dist/{application → types/application}/client/index.d.ts +0 -0
- /package/dist/{application → types/application}/deduplication/QueryDeduplicator.d.ts +0 -0
- /package/dist/{application → types/application}/hooks/MiddlewareHooks.d.ts +0 -0
- /package/dist/{application → types/application}/services/BatchProcessor.d.ts +0 -0
- /package/dist/{application → types/application}/services/QueryOrchestrator.d.ts +0 -0
- /package/dist/{application → types/application}/services/QueryPriority.d.ts +0 -0
- /package/dist/{application → types/application}/services/index.d.ts +0 -0
- /package/dist/{cli → types/cli}/index.d.ts +0 -0
- /package/dist/{core → types/core}/ports/bootstrap.port.d.ts +0 -0
- /package/dist/{core → types/core}/ports/cache.port.d.ts +0 -0
- /package/dist/{core → types/core}/ports/fetcher.port.d.ts +0 -0
- /package/dist/{core → types/core}/ports/index.d.ts +0 -0
- /package/dist/{core → types/core}/ports/normalizer.port.d.ts +0 -0
- /package/dist/{core → types/core}/ports/pii-redactor.port.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/cache/CacheManager.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/cache/InMemoryCache.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/cache/PersistentCache.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/cache/RedisCache.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/cache/index.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/AuthenticationManager.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/BootstrapDiscovery.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/BrowserFetcher.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/BunFetcher.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/CircuitBreaker.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/CloudflareWorkersFetcher.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/CompressionManager.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/ConnectionPool.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/DenoFetcher.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/Normalizer.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/ProxyManager.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/RetryStrategy.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/http/index.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/logging/AuditLogger.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/logging/Logger.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/monitoring/GrafanaDashboard.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/monitoring/MetricsCollector.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/monitoring/PrometheusExporter.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/monitoring/TelemetryExporter.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/native/NativeBackend.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/security/PIIRedactor.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/security/index.d.ts +0 -0
- /package/dist/{infrastructure → types/infrastructure}/validation/ResponseValidator.d.ts +0 -0
- /package/dist/{integrations → types/integrations}/express.d.ts +0 -0
- /package/dist/{integrations → types/integrations}/graphql.d.ts +0 -0
- /package/dist/{integrations → types/integrations}/nestjs.d.ts +0 -0
- /package/dist/{shared → types/shared}/constants/http.constants.d.ts +0 -0
- /package/dist/{shared → types/shared}/constants/index.d.ts +0 -0
- /package/dist/{shared → types/shared}/constants/rdap.constants.d.ts +0 -0
- /package/dist/{shared → types/shared}/errors/index.d.ts +0 -0
- /package/dist/{shared → types/shared}/types/entities.d.ts +0 -0
- /package/dist/{shared → types/shared}/types/errors.d.ts +0 -0
- /package/dist/{shared → types/shared}/types/generics.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/deprecation.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/enhanced-validators.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/async.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/cache.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/format.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/http.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/index.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/object.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/runtime.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/helpers/string.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/asn.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/config-validation.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/domain.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/entity.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/index.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/ip.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/nameserver.d.ts +0 -0
- /package/dist/{shared → types/shared}/utils/validators/network.d.ts +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import * as dns from 'dns';
|
|
2
|
+
import { SSRFProtectionError } from '../../shared/types/errors';
|
|
3
|
+
import { isPrivateIP, isLocalhost, isLinkLocal, validateIP } from '../../shared/utils/validators';
|
|
4
|
+
export class SSRFProtection {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.options = {
|
|
7
|
+
enabled: options.enabled ?? true,
|
|
8
|
+
blockPrivateIPs: options.blockPrivateIPs ?? true,
|
|
9
|
+
blockLocalhost: options.blockLocalhost ?? true,
|
|
10
|
+
blockLinkLocal: options.blockLinkLocal ?? true,
|
|
11
|
+
blockedDomains: options.blockedDomains || [],
|
|
12
|
+
allowedDomains: options.allowedDomains || [],
|
|
13
|
+
dnsRebinding: options.dnsRebinding ?? false,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
async validateUrl(url) {
|
|
17
|
+
if (!this.options.enabled) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let parsedUrl;
|
|
21
|
+
try {
|
|
22
|
+
parsedUrl = new URL(url);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
throw new SSRFProtectionError(`Invalid URL: ${url}`);
|
|
26
|
+
}
|
|
27
|
+
if (parsedUrl.protocol !== 'https:') {
|
|
28
|
+
throw new SSRFProtectionError(`Only HTTPS protocol is allowed, got: ${parsedUrl.protocol}`, {
|
|
29
|
+
url,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
33
|
+
if (this.options.allowedDomains.length > 0) {
|
|
34
|
+
const isAllowed = this.options.allowedDomains.some((domain) => hostname === domain.toLowerCase() || hostname.endsWith(`.${domain.toLowerCase()}`));
|
|
35
|
+
if (!isAllowed) {
|
|
36
|
+
throw new SSRFProtectionError(`Domain not in allowed list: ${hostname}`, { url, hostname });
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (this.options.blockedDomains.length > 0) {
|
|
41
|
+
const isBlocked = this.options.blockedDomains.some((domain) => hostname === domain.toLowerCase() || hostname.endsWith(`.${domain.toLowerCase()}`));
|
|
42
|
+
if (isBlocked) {
|
|
43
|
+
throw new SSRFProtectionError(`Domain is blocked: ${hostname}`, { url, hostname });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (this.isIPAddress(hostname)) {
|
|
47
|
+
await this.validateIPAddress(hostname, url);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
await this.validateDomain(hostname, url);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async validateIPAddress(ip, url) {
|
|
54
|
+
const zoneIndex = ip.indexOf('%');
|
|
55
|
+
const ipWithoutZone = zoneIndex > 0 ? ip.substring(0, zoneIndex) : ip;
|
|
56
|
+
const ipClean = ipWithoutZone.replace(/^\[|\]$/g, '');
|
|
57
|
+
try {
|
|
58
|
+
validateIP(ipClean);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new SSRFProtectionError(`Invalid IP address: ${ip}`, { url, ip });
|
|
62
|
+
}
|
|
63
|
+
if (this.options.blockLocalhost && isLocalhost(ipClean)) {
|
|
64
|
+
throw new SSRFProtectionError(`Localhost IP addresses are blocked: ${ip}`, {
|
|
65
|
+
url,
|
|
66
|
+
ip,
|
|
67
|
+
reason: 'localhost',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (this.options.blockPrivateIPs && isPrivateIP(ipClean)) {
|
|
71
|
+
throw new SSRFProtectionError(`Private IP addresses are blocked: ${ip}`, {
|
|
72
|
+
url,
|
|
73
|
+
ip,
|
|
74
|
+
reason: 'private',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
if (this.options.blockLinkLocal && isLinkLocal(ipClean)) {
|
|
78
|
+
throw new SSRFProtectionError(`Link-local IP addresses are blocked: ${ip}`, {
|
|
79
|
+
url,
|
|
80
|
+
ip,
|
|
81
|
+
reason: 'link-local',
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async validateDomain(hostname, url) {
|
|
86
|
+
if (this.options.blockLocalhost) {
|
|
87
|
+
const localhostPatterns = ['localhost', 'localhost.localdomain', '*.localhost'];
|
|
88
|
+
for (const pattern of localhostPatterns) {
|
|
89
|
+
if (this.matchesPattern(hostname, pattern)) {
|
|
90
|
+
throw new SSRFProtectionError(`Localhost domains are blocked: ${hostname}`, {
|
|
91
|
+
url,
|
|
92
|
+
hostname,
|
|
93
|
+
reason: 'localhost',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const internalDomains = [
|
|
99
|
+
'internal',
|
|
100
|
+
'corp',
|
|
101
|
+
'local',
|
|
102
|
+
'lan',
|
|
103
|
+
'intranet',
|
|
104
|
+
'*.internal',
|
|
105
|
+
'*.corp',
|
|
106
|
+
'*.local',
|
|
107
|
+
'*.lan',
|
|
108
|
+
'*.intranet',
|
|
109
|
+
];
|
|
110
|
+
for (const pattern of internalDomains) {
|
|
111
|
+
if (this.matchesPattern(hostname, pattern)) {
|
|
112
|
+
throw new SSRFProtectionError(`Internal domains are blocked: ${hostname}`, {
|
|
113
|
+
url,
|
|
114
|
+
hostname,
|
|
115
|
+
reason: 'internal',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (this.options.dnsRebinding) {
|
|
120
|
+
await this.validateDnsRebinding(hostname, url);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async validateDnsRebinding(hostname, url) {
|
|
124
|
+
let ipv4Addresses = [];
|
|
125
|
+
let ipv6Addresses = [];
|
|
126
|
+
try {
|
|
127
|
+
ipv4Addresses = await dns.promises.resolve4(hostname);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
ipv6Addresses = await dns.promises.resolve6(hostname);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
}
|
|
136
|
+
for (const ip of [...ipv4Addresses, ...ipv6Addresses]) {
|
|
137
|
+
await this.validateIPAddress(ip, url);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
isIPAddress(hostname) {
|
|
141
|
+
if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname)) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (hostname.includes(':')) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
matchesPattern(hostname, pattern) {
|
|
150
|
+
if (pattern.startsWith('*.')) {
|
|
151
|
+
const suffix = pattern.substring(2);
|
|
152
|
+
return hostname === suffix || hostname.endsWith(`.${suffix}`);
|
|
153
|
+
}
|
|
154
|
+
return hostname === pattern;
|
|
155
|
+
}
|
|
156
|
+
getConfig() {
|
|
157
|
+
return { ...this.options };
|
|
158
|
+
}
|
|
159
|
+
isEnabled() {
|
|
160
|
+
return this.options.enabled;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import * as crypto from 'crypto';
|
|
5
|
+
export class UsageTelemetry {
|
|
6
|
+
static getPayload() {
|
|
7
|
+
const cfg = UsageTelemetry.loadConfig();
|
|
8
|
+
return {
|
|
9
|
+
installId: cfg.installId,
|
|
10
|
+
rdapifyVersion: '0.3.1',
|
|
11
|
+
nodeVersion: process.version,
|
|
12
|
+
platform: process.platform,
|
|
13
|
+
queryTypesUsed: cfg.queryTypesUsed,
|
|
14
|
+
sessionCount: cfg.sessionCount,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
static async ping(queryType, endpoint) {
|
|
18
|
+
const cfg = UsageTelemetry.loadConfig();
|
|
19
|
+
if (!cfg.enabled)
|
|
20
|
+
return;
|
|
21
|
+
if (!cfg.queryTypesUsed.includes(queryType)) {
|
|
22
|
+
cfg.queryTypesUsed.push(queryType);
|
|
23
|
+
}
|
|
24
|
+
UsageTelemetry.saveConfig(cfg);
|
|
25
|
+
try {
|
|
26
|
+
const url = endpoint ?? UsageTelemetry.DEFAULT_ENDPOINT;
|
|
27
|
+
const payload = UsageTelemetry.getPayload();
|
|
28
|
+
fetch(url, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: { 'Content-Type': 'application/json' },
|
|
31
|
+
body: JSON.stringify(payload),
|
|
32
|
+
signal: AbortSignal.timeout(5000),
|
|
33
|
+
}).catch(() => { });
|
|
34
|
+
}
|
|
35
|
+
catch { }
|
|
36
|
+
}
|
|
37
|
+
static enable() {
|
|
38
|
+
const cfg = UsageTelemetry.loadConfig();
|
|
39
|
+
cfg.enabled = true;
|
|
40
|
+
UsageTelemetry.saveConfig(cfg);
|
|
41
|
+
}
|
|
42
|
+
static disable() {
|
|
43
|
+
const cfg = UsageTelemetry.loadConfig();
|
|
44
|
+
cfg.enabled = false;
|
|
45
|
+
UsageTelemetry.saveConfig(cfg);
|
|
46
|
+
}
|
|
47
|
+
static reset() {
|
|
48
|
+
try {
|
|
49
|
+
fs.rmSync(UsageTelemetry.CONFIG_PATH, { force: true });
|
|
50
|
+
}
|
|
51
|
+
catch { }
|
|
52
|
+
UsageTelemetry.config = null;
|
|
53
|
+
}
|
|
54
|
+
static loadConfig() {
|
|
55
|
+
if (UsageTelemetry.config)
|
|
56
|
+
return UsageTelemetry.config;
|
|
57
|
+
try {
|
|
58
|
+
const raw = fs.readFileSync(UsageTelemetry.CONFIG_PATH, 'utf-8');
|
|
59
|
+
UsageTelemetry.config = JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
UsageTelemetry.config = {
|
|
63
|
+
installId: crypto.randomUUID(),
|
|
64
|
+
sessionCount: 0,
|
|
65
|
+
queryTypesUsed: [],
|
|
66
|
+
enabled: false,
|
|
67
|
+
};
|
|
68
|
+
UsageTelemetry.saveConfig(UsageTelemetry.config);
|
|
69
|
+
}
|
|
70
|
+
return UsageTelemetry.config;
|
|
71
|
+
}
|
|
72
|
+
static saveConfig(cfg) {
|
|
73
|
+
try {
|
|
74
|
+
const dir = path.dirname(UsageTelemetry.CONFIG_PATH);
|
|
75
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
76
|
+
fs.writeFileSync(UsageTelemetry.CONFIG_PATH, JSON.stringify(cfg, null, 2));
|
|
77
|
+
UsageTelemetry.config = cfg;
|
|
78
|
+
}
|
|
79
|
+
catch { }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
UsageTelemetry.CONFIG_PATH = path.join(os.homedir(), '.rdapify', 'telemetry.json');
|
|
83
|
+
UsageTelemetry.DEFAULT_ENDPOINT = 'https://telemetry.rdapify.com/v1/ping';
|
|
84
|
+
UsageTelemetry.config = null;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { RDAPifyError } from '../../shared/errors/base.error';
|
|
2
|
+
export class ResponseValidationError extends RDAPifyError {
|
|
3
|
+
constructor(validationResult) {
|
|
4
|
+
const errorMessages = validationResult.errors.map((e) => e.message).join('; ');
|
|
5
|
+
super(`RDAP response validation failed: ${errorMessages}`, 'RESPONSE_VALIDATION_ERROR', 422, { errorCount: validationResult.errors.length });
|
|
6
|
+
this.validationResult = validationResult;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class ResponseValidator {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.mode = options?.mode ?? 'lenient';
|
|
12
|
+
this.onViolation = options?.onViolation ?? 'warn';
|
|
13
|
+
}
|
|
14
|
+
validateDomain(response) {
|
|
15
|
+
const result = { valid: true, errors: [], warnings: [] };
|
|
16
|
+
if (this.mode === 'off') {
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
if (response.objectClass !== 'domain') {
|
|
20
|
+
result.errors.push({
|
|
21
|
+
field: 'objectClass',
|
|
22
|
+
message: `Expected objectClass 'domain', got '${response.objectClass}'`,
|
|
23
|
+
severity: 'error',
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (!response.query || typeof response.query !== 'string' || response.query.trim() === '') {
|
|
27
|
+
result.errors.push({
|
|
28
|
+
field: 'query',
|
|
29
|
+
message: 'Field "query" must be a non-empty string',
|
|
30
|
+
severity: 'error',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (response.ldhName === undefined || response.ldhName === null) {
|
|
34
|
+
result.warnings.push({
|
|
35
|
+
field: 'ldhName',
|
|
36
|
+
message: 'Field "ldhName" is recommended for domain responses (RFC 7483 §5.3)',
|
|
37
|
+
severity: 'warning',
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (response.status !== undefined && !Array.isArray(response.status)) {
|
|
41
|
+
result.warnings.push({
|
|
42
|
+
field: 'status',
|
|
43
|
+
message: 'Field "status" should be an array',
|
|
44
|
+
severity: 'warning',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (response.events !== undefined) {
|
|
48
|
+
response.events.forEach((event, index) => {
|
|
49
|
+
if (!event.type) {
|
|
50
|
+
result.errors.push({
|
|
51
|
+
field: `events[${index}].type`,
|
|
52
|
+
message: `Event at index ${index} is missing required field "type" (eventAction)`,
|
|
53
|
+
severity: 'error',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (!event.date) {
|
|
57
|
+
result.errors.push({
|
|
58
|
+
field: `events[${index}].date`,
|
|
59
|
+
message: `Event at index ${index} is missing required field "date" (eventDate)`,
|
|
60
|
+
severity: 'error',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (response.nameservers !== undefined) {
|
|
66
|
+
response.nameservers.forEach((ns, index) => {
|
|
67
|
+
if (!ns || typeof ns !== 'string' || ns.trim() === '') {
|
|
68
|
+
result.errors.push({
|
|
69
|
+
field: `nameservers[${index}]`,
|
|
70
|
+
message: `Nameserver at index ${index} must be a non-empty ldhName string`,
|
|
71
|
+
severity: 'error',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (response.entities !== undefined) {
|
|
77
|
+
response.entities.forEach((entity, index) => {
|
|
78
|
+
if (!entity.roles || !Array.isArray(entity.roles)) {
|
|
79
|
+
result.warnings.push({
|
|
80
|
+
field: `entities[${index}].roles`,
|
|
81
|
+
message: `Entity at index ${index} should have a "roles" array`,
|
|
82
|
+
severity: 'warning',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
result.valid = result.errors.length === 0;
|
|
88
|
+
return this.handleResult(result);
|
|
89
|
+
}
|
|
90
|
+
validateIP(response) {
|
|
91
|
+
const result = { valid: true, errors: [], warnings: [] };
|
|
92
|
+
if (this.mode === 'off') {
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
if (response.objectClass !== 'ip network') {
|
|
96
|
+
result.errors.push({
|
|
97
|
+
field: 'objectClass',
|
|
98
|
+
message: `Expected objectClass 'ip network', got '${response.objectClass}'`,
|
|
99
|
+
severity: 'error',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (response.startAddress === undefined || response.startAddress === null) {
|
|
103
|
+
result.warnings.push({
|
|
104
|
+
field: 'startAddress',
|
|
105
|
+
message: 'Field "startAddress" is recommended for IP network responses (RFC 7483 §5.4)',
|
|
106
|
+
severity: 'warning',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (response.endAddress === undefined || response.endAddress === null) {
|
|
110
|
+
result.warnings.push({
|
|
111
|
+
field: 'endAddress',
|
|
112
|
+
message: 'Field "endAddress" is recommended for IP network responses (RFC 7483 §5.4)',
|
|
113
|
+
severity: 'warning',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (response.ipVersion !== undefined && response.ipVersion !== 'v4' && response.ipVersion !== 'v6') {
|
|
117
|
+
result.errors.push({
|
|
118
|
+
field: 'ipVersion',
|
|
119
|
+
message: `Field "ipVersion" must be 'v4' or 'v6', got '${response.ipVersion}'`,
|
|
120
|
+
severity: 'error',
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
result.valid = result.errors.length === 0;
|
|
124
|
+
return this.handleResult(result);
|
|
125
|
+
}
|
|
126
|
+
validateASN(response) {
|
|
127
|
+
const result = { valid: true, errors: [], warnings: [] };
|
|
128
|
+
if (this.mode === 'off') {
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
if (response.objectClass !== 'autnum') {
|
|
132
|
+
result.errors.push({
|
|
133
|
+
field: 'objectClass',
|
|
134
|
+
message: `Expected objectClass 'autnum', got '${response.objectClass}'`,
|
|
135
|
+
severity: 'error',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
if (response.startAutnum === undefined || response.startAutnum === null) {
|
|
139
|
+
result.warnings.push({
|
|
140
|
+
field: 'startAutnum',
|
|
141
|
+
message: 'Field "startAutnum" is recommended for ASN responses (RFC 7483 §5.5)',
|
|
142
|
+
severity: 'warning',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
result.valid = result.errors.length === 0;
|
|
146
|
+
return this.handleResult(result);
|
|
147
|
+
}
|
|
148
|
+
validate(response) {
|
|
149
|
+
if (this.mode === 'off') {
|
|
150
|
+
return { valid: true, errors: [], warnings: [] };
|
|
151
|
+
}
|
|
152
|
+
switch (response.objectClass) {
|
|
153
|
+
case 'domain':
|
|
154
|
+
return this.validateDomain(response);
|
|
155
|
+
case 'ip network':
|
|
156
|
+
return this.validateIP(response);
|
|
157
|
+
case 'autnum':
|
|
158
|
+
return this.validateASN(response);
|
|
159
|
+
default: {
|
|
160
|
+
const result = {
|
|
161
|
+
valid: false,
|
|
162
|
+
errors: [
|
|
163
|
+
{
|
|
164
|
+
field: 'objectClass',
|
|
165
|
+
message: `Unknown objectClass: '${response.objectClass}'`,
|
|
166
|
+
severity: 'error',
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
warnings: [],
|
|
170
|
+
};
|
|
171
|
+
return this.handleResult(result);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
getMode() {
|
|
176
|
+
return this.mode;
|
|
177
|
+
}
|
|
178
|
+
handleResult(result) {
|
|
179
|
+
if (result.errors.length === 0) {
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
switch (this.onViolation) {
|
|
183
|
+
case 'throw':
|
|
184
|
+
throw new ResponseValidationError(result);
|
|
185
|
+
case 'warn':
|
|
186
|
+
result.errors.forEach((e) => {
|
|
187
|
+
console.warn(`[RDAPify] Validation error on field "${e.field}": ${e.message}`);
|
|
188
|
+
});
|
|
189
|
+
return result;
|
|
190
|
+
case 'ignore':
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class MinimalRouter {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.routes = [];
|
|
4
|
+
}
|
|
5
|
+
get(path, handler) {
|
|
6
|
+
this.routes.push({ path, handler });
|
|
7
|
+
return this;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function rdapifyExpress(client, router) {
|
|
11
|
+
const r = router ?? new MinimalRouter();
|
|
12
|
+
r.get('/domain/:name', async (req, res) => {
|
|
13
|
+
try {
|
|
14
|
+
const result = await client.domain(req.params['name'] ?? '');
|
|
15
|
+
res.json(result);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
19
|
+
res.status(500).json({ error: message });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
r.get('/ip/:address', async (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = await client.ip(req.params['address'] ?? '');
|
|
25
|
+
res.json(result);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
29
|
+
res.status(500).json({ error: message });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
r.get('/asn/:number', async (req, res) => {
|
|
33
|
+
try {
|
|
34
|
+
const result = await client.asn(req.params['number'] ?? '');
|
|
35
|
+
res.json(result);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
39
|
+
res.status(500).json({ error: message });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return r;
|
|
43
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export const RDAPIFY_TYPE_DEFS = `
|
|
2
|
+
type DomainResponse {
|
|
3
|
+
query: String!
|
|
4
|
+
ldhName: String
|
|
5
|
+
registrar: String
|
|
6
|
+
status: [String!]!
|
|
7
|
+
expiresAt: String
|
|
8
|
+
createdAt: String
|
|
9
|
+
updatedAt: String
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type IpResponse {
|
|
13
|
+
query: String!
|
|
14
|
+
country: String
|
|
15
|
+
name: String
|
|
16
|
+
status: [String!]!
|
|
17
|
+
startAddress: String
|
|
18
|
+
endAddress: String
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type AsnResponse {
|
|
22
|
+
query: String!
|
|
23
|
+
name: String
|
|
24
|
+
status: [String!]!
|
|
25
|
+
startAutnum: Int
|
|
26
|
+
endAutnum: Int
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type Query {
|
|
30
|
+
"""Query RDAP information for a domain name."""
|
|
31
|
+
domain(name: String!): DomainResponse
|
|
32
|
+
|
|
33
|
+
"""Query RDAP information for an IP address (IPv4 or IPv6)."""
|
|
34
|
+
ip(address: String!): IpResponse
|
|
35
|
+
|
|
36
|
+
"""Query RDAP information for an Autonomous System Number."""
|
|
37
|
+
asn(number: String!): AsnResponse
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
export function createRdapifySchema(client) {
|
|
41
|
+
const resolvers = {
|
|
42
|
+
Query: {
|
|
43
|
+
domain: async (_, args) => {
|
|
44
|
+
const r = await client.domain(args.name);
|
|
45
|
+
const findEvent = (type) => r.events?.find((e) => e.type === type)?.date ?? null;
|
|
46
|
+
return {
|
|
47
|
+
query: r.query,
|
|
48
|
+
ldhName: r.ldhName ?? null,
|
|
49
|
+
registrar: r.registrar?.name ?? null,
|
|
50
|
+
status: r.status ?? [],
|
|
51
|
+
expiresAt: findEvent('expiration'),
|
|
52
|
+
createdAt: findEvent('registration'),
|
|
53
|
+
updatedAt: findEvent('last changed'),
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
ip: async (_, args) => {
|
|
57
|
+
const r = await client.ip(args.address);
|
|
58
|
+
return {
|
|
59
|
+
query: r.query,
|
|
60
|
+
country: r.country ?? null,
|
|
61
|
+
name: r.name ?? null,
|
|
62
|
+
status: r.status ?? [],
|
|
63
|
+
startAddress: r.startAddress ?? null,
|
|
64
|
+
endAddress: r.endAddress ?? null,
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
asn: async (_, args) => {
|
|
68
|
+
const r = await client.asn(args.number);
|
|
69
|
+
return {
|
|
70
|
+
query: String(r.query),
|
|
71
|
+
name: r.name ?? null,
|
|
72
|
+
status: r.status ?? [],
|
|
73
|
+
startAutnum: r.startAutnum ?? null,
|
|
74
|
+
endAutnum: r.endAutnum ?? null,
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
return { typeDefs: RDAPIFY_TYPE_DEFS, resolvers };
|
|
80
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RDAPClient } from '../application/client';
|
|
2
|
+
export const RDAPIFY_CLIENT_TOKEN = Symbol('RDAPIFY_CLIENT');
|
|
3
|
+
export class RdapifyModule {
|
|
4
|
+
static forRoot(options = {}) {
|
|
5
|
+
const provider = {
|
|
6
|
+
provide: RDAPIFY_CLIENT_TOKEN,
|
|
7
|
+
useFactory: () => new RDAPClient(options),
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
module: RdapifyModule,
|
|
11
|
+
providers: [provider],
|
|
12
|
+
exports: [RDAPIFY_CLIENT_TOKEN],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function InjectRdapClient() {
|
|
17
|
+
return (_target, _propertyKey, _index) => {
|
|
18
|
+
if (typeof Reflect !== 'undefined' && typeof Reflect['defineMetadata'] === 'function') {
|
|
19
|
+
const defineMetadata = Reflect['defineMetadata'];
|
|
20
|
+
defineMetadata('self:paramtypes', RDAPIFY_CLIENT_TOKEN, _target, _propertyKey);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const DEFAULT_TIMEOUTS = {
|
|
2
|
+
connect: 5000,
|
|
3
|
+
request: 10000,
|
|
4
|
+
dns: 3000,
|
|
5
|
+
};
|
|
6
|
+
export const DEFAULT_RETRY_CONFIG = {
|
|
7
|
+
maxAttempts: 3,
|
|
8
|
+
initialDelay: 1000,
|
|
9
|
+
maxDelay: 10000,
|
|
10
|
+
backoff: 'exponential',
|
|
11
|
+
};
|
|
12
|
+
export const DEFAULT_REDIRECT_CONFIG = {
|
|
13
|
+
followRedirects: true,
|
|
14
|
+
maxRedirects: 5,
|
|
15
|
+
};
|
|
16
|
+
export const HTTP_STATUS = {
|
|
17
|
+
OK: 200,
|
|
18
|
+
BAD_REQUEST: 400,
|
|
19
|
+
FORBIDDEN: 403,
|
|
20
|
+
NOT_FOUND: 404,
|
|
21
|
+
TIMEOUT: 408,
|
|
22
|
+
TOO_MANY_REQUESTS: 429,
|
|
23
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
24
|
+
SERVICE_UNAVAILABLE: 503,
|
|
25
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const DEFAULT_BOOTSTRAP_URL = 'https://data.iana.org/rdap';
|
|
2
|
+
export const DEFAULT_CACHE_TTL = 3600;
|
|
3
|
+
export const DEFAULT_CACHE_MAX_SIZE = 1000;
|
|
4
|
+
export const BOOTSTRAP_CACHE_TTL = 86400000;
|
|
5
|
+
export const DEFAULT_USER_AGENT = 'RDAPify/0.1.7 (https://github.com/rdapify/rdapify)';
|
|
6
|
+
export const RDAP_CONTENT_TYPES = [
|
|
7
|
+
'application/rdap+json',
|
|
8
|
+
'application/json',
|
|
9
|
+
];
|
|
10
|
+
export const RDAP_OBJECT_CLASSES = [
|
|
11
|
+
'domain',
|
|
12
|
+
'ip network',
|
|
13
|
+
'autnum',
|
|
14
|
+
'nameserver',
|
|
15
|
+
'entity',
|
|
16
|
+
];
|
|
17
|
+
export const BOOTSTRAP_TYPES = ['dns', 'ipv4', 'ipv6', 'asn'];
|