recker 1.0.20-next.de24f7d → 1.0.20-next.e194d90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/ai/adaptive-timeout.d.ts +0 -1
- package/dist/ai/client.d.ts +0 -1
- package/dist/ai/client.js +6 -0
- package/dist/ai/index.d.ts +3 -1
- package/dist/ai/index.js +3 -0
- package/dist/ai/providers/anthropic.d.ts +0 -1
- package/dist/ai/providers/base.d.ts +0 -1
- package/dist/ai/providers/google.d.ts +59 -0
- package/dist/ai/providers/google.js +305 -0
- package/dist/ai/providers/index.d.ts +4 -1
- package/dist/ai/providers/index.js +2 -0
- package/dist/ai/providers/ollama.d.ts +44 -0
- package/dist/ai/providers/ollama.js +240 -0
- package/dist/ai/providers/openai.d.ts +0 -1
- package/dist/ai/rate-limiter.d.ts +0 -1
- package/dist/ai/vector/index.d.ts +2 -0
- package/dist/ai/vector/index.js +2 -0
- package/dist/ai/vector/similarity.d.ts +2 -0
- package/dist/ai/vector/similarity.js +27 -0
- package/dist/ai/vector/store.d.ts +27 -0
- package/dist/ai/vector/store.js +82 -0
- package/dist/bench/generator.d.ts +0 -1
- package/dist/bench/stats.d.ts +0 -1
- package/dist/cache/basic-file-storage.d.ts +12 -0
- package/dist/cache/basic-file-storage.js +50 -0
- package/dist/cache/file-storage.d.ts +25 -11
- package/dist/cache/file-storage.js +175 -30
- package/dist/cache/memory-limits.d.ts +0 -1
- package/dist/cache/memory-storage.d.ts +0 -1
- package/dist/cache/redis-storage.d.ts +0 -1
- package/dist/cli/handler.d.ts +2 -1
- package/dist/cli/handler.js +36 -5
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +559 -6
- package/dist/cli/presets.d.ts +0 -1
- package/dist/cli/tui/ai-chat.d.ts +0 -1
- package/dist/cli/tui/load-dashboard.d.ts +0 -1
- package/dist/cli/tui/scroll-buffer.d.ts +0 -1
- package/dist/cli/tui/search-panel.d.ts +0 -1
- package/dist/cli/tui/shell-search.d.ts +0 -1
- package/dist/cli/tui/shell.d.ts +0 -1
- package/dist/cli/tui/shell.js +1 -1
- package/dist/cli/tui/websocket.d.ts +0 -1
- package/dist/constants/http-status.d.ts +0 -1
- package/dist/constants.d.ts +0 -1
- package/dist/contract/index.d.ts +0 -1
- package/dist/cookies/memory-cookie-jar.d.ts +0 -1
- package/dist/core/client.d.ts +0 -1
- package/dist/core/client.js +1 -1
- package/dist/core/errors.d.ts +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/request-promise.d.ts +0 -1
- package/dist/core/request.d.ts +0 -1
- package/dist/core/response.d.ts +0 -1
- package/dist/dns/index.d.ts +0 -1
- package/dist/dns/propagation.d.ts +0 -1
- package/dist/events/request-events.d.ts +0 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -0
- package/dist/mcp/client.d.ts +0 -1
- package/dist/mcp/contract.d.ts +0 -1
- package/dist/mcp/embeddings-loader.d.ts +0 -1
- package/dist/mcp/geoip-loader.d.ts +0 -1
- package/dist/mcp/index.d.ts +0 -1
- package/dist/mcp/ip-intel.d.ts +0 -1
- package/dist/mcp/search/hybrid-search.d.ts +0 -1
- package/dist/mcp/search/index.d.ts +0 -1
- package/dist/mcp/search/math.d.ts +0 -1
- package/dist/mcp/search/types.d.ts +0 -1
- package/dist/mcp/server.d.ts +6 -2
- package/dist/mcp/server.js +193 -151
- package/dist/mcp/tools/loader.d.ts +2 -0
- package/dist/mcp/tools/loader.js +41 -0
- package/dist/mcp/tools/network.d.ts +3 -0
- package/dist/mcp/tools/network.js +267 -0
- package/dist/mcp/tools/registry.d.ts +17 -0
- package/dist/mcp/tools/registry.js +37 -0
- package/dist/mcp/types.d.ts +0 -1
- package/dist/plugins/auth/api-key.d.ts +8 -0
- package/dist/plugins/auth/api-key.js +27 -0
- package/dist/plugins/auth/auth0.d.ts +33 -0
- package/dist/plugins/auth/auth0.js +94 -0
- package/dist/plugins/auth/aws-sigv4.d.ts +10 -0
- package/dist/plugins/auth/aws-sigv4.js +88 -0
- package/dist/plugins/auth/azure-ad.d.ts +48 -0
- package/dist/plugins/auth/azure-ad.js +152 -0
- package/dist/plugins/auth/basic.d.ts +7 -0
- package/dist/plugins/auth/basic.js +13 -0
- package/dist/plugins/auth/bearer.d.ts +8 -0
- package/dist/plugins/auth/bearer.js +17 -0
- package/dist/plugins/auth/cognito.d.ts +45 -0
- package/dist/plugins/auth/cognito.js +208 -0
- package/dist/plugins/auth/digest.d.ts +8 -0
- package/dist/plugins/auth/digest.js +100 -0
- package/dist/plugins/auth/firebase.d.ts +32 -0
- package/dist/plugins/auth/firebase.js +195 -0
- package/dist/plugins/auth/github-app.d.ts +36 -0
- package/dist/plugins/auth/github-app.js +170 -0
- package/dist/plugins/auth/google-service-account.d.ts +49 -0
- package/dist/plugins/auth/google-service-account.js +172 -0
- package/dist/plugins/auth/index.d.ts +15 -0
- package/dist/plugins/auth/index.js +15 -0
- package/dist/plugins/auth/mtls.d.ts +37 -0
- package/dist/plugins/auth/mtls.js +140 -0
- package/dist/plugins/auth/oauth2.d.ts +8 -0
- package/dist/plugins/auth/oauth2.js +26 -0
- package/dist/plugins/auth/oidc.d.ts +55 -0
- package/dist/plugins/auth/oidc.js +222 -0
- package/dist/plugins/auth/okta.d.ts +47 -0
- package/dist/plugins/auth/okta.js +157 -0
- package/dist/plugins/auth.d.ts +1 -45
- package/dist/plugins/auth.js +1 -268
- package/dist/plugins/cache.d.ts +0 -1
- package/dist/plugins/cache.js +1 -1
- package/dist/plugins/certificate-pinning.d.ts +59 -0
- package/dist/plugins/certificate-pinning.js +236 -0
- package/dist/plugins/circuit-breaker.d.ts +0 -1
- package/dist/plugins/compression.d.ts +0 -1
- package/dist/plugins/cookie-jar.d.ts +0 -1
- package/dist/plugins/dedup.d.ts +0 -1
- package/dist/plugins/graphql.d.ts +0 -1
- package/dist/plugins/grpc-web.d.ts +0 -1
- package/dist/plugins/har-player.d.ts +0 -1
- package/dist/plugins/har-recorder.d.ts +0 -1
- package/dist/plugins/hls.d.ts +0 -1
- package/dist/plugins/http2-push.d.ts +0 -1
- package/dist/plugins/http3.d.ts +0 -1
- package/dist/plugins/index.d.ts +27 -0
- package/dist/plugins/index.js +27 -0
- package/dist/plugins/interface-rotator.d.ts +0 -1
- package/dist/plugins/jsonrpc.d.ts +0 -1
- package/dist/plugins/logger.d.ts +0 -1
- package/dist/plugins/odata.d.ts +0 -1
- package/dist/plugins/pagination.d.ts +0 -1
- package/dist/plugins/proxy-rotator.d.ts +0 -1
- package/dist/plugins/rate-limit.d.ts +15 -0
- package/dist/plugins/rate-limit.js +162 -0
- package/dist/plugins/retry.d.ts +0 -1
- package/dist/plugins/retry.js +2 -2
- package/dist/plugins/scrape.d.ts +0 -1
- package/dist/plugins/server-timing.d.ts +0 -1
- package/dist/plugins/soap.d.ts +0 -1
- package/dist/plugins/user-agent.d.ts +0 -1
- package/dist/plugins/xml.d.ts +0 -1
- package/dist/plugins/xsrf.d.ts +0 -1
- package/dist/presets/anthropic.d.ts +0 -1
- package/dist/presets/aws.d.ts +0 -1
- package/dist/presets/azure-openai.d.ts +0 -1
- package/dist/presets/azure.d.ts +0 -1
- package/dist/presets/cloudflare.d.ts +0 -1
- package/dist/presets/cohere.d.ts +0 -1
- package/dist/presets/deepseek.d.ts +0 -1
- package/dist/presets/digitalocean.d.ts +0 -1
- package/dist/presets/discord.d.ts +0 -1
- package/dist/presets/fireworks.d.ts +0 -1
- package/dist/presets/gcp.d.ts +0 -1
- package/dist/presets/gemini.d.ts +0 -1
- package/dist/presets/github.d.ts +0 -1
- package/dist/presets/gitlab.d.ts +0 -1
- package/dist/presets/groq.d.ts +0 -1
- package/dist/presets/huggingface.d.ts +0 -1
- package/dist/presets/index.d.ts +0 -1
- package/dist/presets/linear.d.ts +0 -1
- package/dist/presets/mailgun.d.ts +0 -1
- package/dist/presets/meta.d.ts +0 -1
- package/dist/presets/mistral.d.ts +0 -1
- package/dist/presets/notion.d.ts +0 -1
- package/dist/presets/openai.d.ts +0 -1
- package/dist/presets/oracle.d.ts +0 -1
- package/dist/presets/perplexity.d.ts +0 -1
- package/dist/presets/registry.d.ts +0 -1
- package/dist/presets/replicate.d.ts +0 -1
- package/dist/presets/sinch.d.ts +0 -1
- package/dist/presets/slack.d.ts +0 -1
- package/dist/presets/stripe.d.ts +0 -1
- package/dist/presets/supabase.d.ts +0 -1
- package/dist/presets/tiktok.d.ts +0 -1
- package/dist/presets/together.d.ts +0 -1
- package/dist/presets/twilio.d.ts +0 -1
- package/dist/presets/vercel.d.ts +0 -1
- package/dist/presets/vultr.d.ts +0 -1
- package/dist/presets/xai.d.ts +0 -1
- package/dist/presets/youtube.d.ts +0 -1
- package/dist/protocols/ftp.d.ts +0 -1
- package/dist/protocols/index.d.ts +0 -1
- package/dist/protocols/sftp.d.ts +0 -1
- package/dist/protocols/telnet.d.ts +0 -1
- package/dist/recker.d.ts +0 -1
- package/dist/runner/request-runner.d.ts +0 -1
- package/dist/scrape/document.d.ts +0 -1
- package/dist/scrape/element.d.ts +0 -1
- package/dist/scrape/extractors.d.ts +0 -1
- package/dist/scrape/index.d.ts +0 -1
- package/dist/scrape/types.d.ts +0 -1
- package/dist/testing/index.d.ts +16 -1
- package/dist/testing/index.js +8 -0
- package/dist/testing/mock-dns-server.d.ts +69 -0
- package/dist/testing/mock-dns-server.js +269 -0
- package/dist/testing/mock-ftp-server.d.ts +89 -0
- package/dist/testing/mock-ftp-server.js +562 -0
- package/dist/testing/mock-hls-server.d.ts +80 -0
- package/dist/testing/mock-hls-server.js +381 -0
- package/dist/testing/mock-http-server.d.ts +99 -0
- package/dist/testing/mock-http-server.js +298 -0
- package/dist/testing/mock-sse-server.d.ts +76 -0
- package/dist/testing/mock-sse-server.js +291 -0
- package/dist/testing/mock-telnet-server.d.ts +59 -0
- package/dist/testing/mock-telnet-server.js +273 -0
- package/dist/testing/mock-udp-server.d.ts +0 -1
- package/dist/testing/mock-websocket-server.d.ts +77 -0
- package/dist/testing/mock-websocket-server.js +316 -0
- package/dist/testing/mock-whois-server.d.ts +56 -0
- package/dist/testing/mock-whois-server.js +234 -0
- package/dist/testing/mock.d.ts +0 -1
- package/dist/transport/base-udp.d.ts +0 -1
- package/dist/transport/fetch.d.ts +0 -1
- package/dist/transport/udp-response.d.ts +0 -1
- package/dist/transport/udp.d.ts +0 -1
- package/dist/transport/undici.d.ts +0 -1
- package/dist/transport/undici.js +1 -1
- package/dist/types/ai.d.ts +0 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/logger.d.ts +0 -1
- package/dist/types/udp.d.ts +0 -1
- package/dist/udp/index.d.ts +0 -1
- package/dist/utils/agent-manager.d.ts +0 -1
- package/dist/utils/body.d.ts +0 -1
- package/dist/utils/cert.d.ts +0 -1
- package/dist/utils/charset.d.ts +0 -1
- package/dist/utils/chart.d.ts +0 -1
- package/dist/utils/client-pool.d.ts +0 -1
- package/dist/utils/colors.d.ts +0 -1
- package/dist/utils/concurrency.d.ts +0 -1
- package/dist/utils/dns-toolkit.d.ts +0 -1
- package/dist/utils/dns-toolkit.js +1 -1
- package/dist/utils/dns.d.ts +0 -1
- package/dist/utils/dns.js +2 -2
- package/dist/utils/doh.d.ts +0 -1
- package/dist/utils/download.d.ts +0 -1
- package/dist/utils/env-proxy.d.ts +0 -1
- package/dist/utils/header-parser.d.ts +0 -1
- package/dist/utils/html-cleaner.d.ts +0 -1
- package/dist/utils/link-header.d.ts +0 -1
- package/dist/utils/optional-require.d.ts +0 -1
- package/dist/utils/optional-require.js +1 -1
- package/dist/utils/progress.d.ts +0 -1
- package/dist/utils/rdap.d.ts +0 -1
- package/dist/utils/request-pool.d.ts +0 -1
- package/dist/utils/security-grader.d.ts +0 -1
- package/dist/utils/sparkline.d.ts +0 -1
- package/dist/utils/sse.d.ts +0 -1
- package/dist/utils/streaming.d.ts +0 -1
- package/dist/utils/system-metrics.d.ts +0 -1
- package/dist/utils/tls-inspector.d.ts +0 -1
- package/dist/utils/try-fn.d.ts +0 -1
- package/dist/utils/upload.d.ts +0 -1
- package/dist/utils/user-agent.d.ts +0 -1
- package/dist/utils/whois.d.ts +0 -1
- package/dist/webrtc/index.d.ts +0 -1
- package/dist/webrtc/index.js +1 -1
- package/dist/websocket/client.d.ts +0 -1
- package/package.json +12 -3
- package/dist/ai/adaptive-timeout.d.ts.map +0 -1
- package/dist/ai/client.d.ts.map +0 -1
- package/dist/ai/index.d.ts.map +0 -1
- package/dist/ai/providers/anthropic.d.ts.map +0 -1
- package/dist/ai/providers/base.d.ts.map +0 -1
- package/dist/ai/providers/index.d.ts.map +0 -1
- package/dist/ai/providers/openai.d.ts.map +0 -1
- package/dist/ai/rate-limiter.d.ts.map +0 -1
- package/dist/bench/generator.d.ts.map +0 -1
- package/dist/bench/stats.d.ts.map +0 -1
- package/dist/cache/file-storage.d.ts.map +0 -1
- package/dist/cache/memory-limits.d.ts.map +0 -1
- package/dist/cache/memory-storage.d.ts.map +0 -1
- package/dist/cache/redis-storage.d.ts.map +0 -1
- package/dist/cli/handler.d.ts.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/presets.d.ts.map +0 -1
- package/dist/cli/tui/ai-chat.d.ts.map +0 -1
- package/dist/cli/tui/load-dashboard.d.ts.map +0 -1
- package/dist/cli/tui/scroll-buffer.d.ts.map +0 -1
- package/dist/cli/tui/search-panel.d.ts.map +0 -1
- package/dist/cli/tui/shell-search.d.ts.map +0 -1
- package/dist/cli/tui/shell.d.ts.map +0 -1
- package/dist/cli/tui/websocket.d.ts.map +0 -1
- package/dist/constants/http-status.d.ts.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/contract/index.d.ts.map +0 -1
- package/dist/cookies/memory-cookie-jar.d.ts.map +0 -1
- package/dist/core/client.d.ts.map +0 -1
- package/dist/core/errors.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/request-promise.d.ts.map +0 -1
- package/dist/core/request.d.ts.map +0 -1
- package/dist/core/response.d.ts.map +0 -1
- package/dist/dns/index.d.ts.map +0 -1
- package/dist/dns/propagation.d.ts.map +0 -1
- package/dist/events/request-events.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mcp/client.d.ts.map +0 -1
- package/dist/mcp/contract.d.ts.map +0 -1
- package/dist/mcp/embeddings-loader.d.ts.map +0 -1
- package/dist/mcp/geoip-loader.d.ts.map +0 -1
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/ip-intel.d.ts.map +0 -1
- package/dist/mcp/search/hybrid-search.d.ts.map +0 -1
- package/dist/mcp/search/index.d.ts.map +0 -1
- package/dist/mcp/search/math.d.ts.map +0 -1
- package/dist/mcp/search/types.d.ts.map +0 -1
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/plugins/auth.d.ts.map +0 -1
- package/dist/plugins/cache.d.ts.map +0 -1
- package/dist/plugins/circuit-breaker.d.ts.map +0 -1
- package/dist/plugins/compression.d.ts.map +0 -1
- package/dist/plugins/cookie-jar.d.ts.map +0 -1
- package/dist/plugins/dedup.d.ts.map +0 -1
- package/dist/plugins/graphql.d.ts.map +0 -1
- package/dist/plugins/grpc-web.d.ts.map +0 -1
- package/dist/plugins/har-player.d.ts.map +0 -1
- package/dist/plugins/har-recorder.d.ts.map +0 -1
- package/dist/plugins/hls.d.ts.map +0 -1
- package/dist/plugins/http2-push.d.ts.map +0 -1
- package/dist/plugins/http3.d.ts.map +0 -1
- package/dist/plugins/interface-rotator.d.ts.map +0 -1
- package/dist/plugins/jsonrpc.d.ts.map +0 -1
- package/dist/plugins/logger.d.ts.map +0 -1
- package/dist/plugins/odata.d.ts.map +0 -1
- package/dist/plugins/pagination.d.ts.map +0 -1
- package/dist/plugins/proxy-rotator.d.ts.map +0 -1
- package/dist/plugins/retry.d.ts.map +0 -1
- package/dist/plugins/scrape.d.ts.map +0 -1
- package/dist/plugins/server-timing.d.ts.map +0 -1
- package/dist/plugins/soap.d.ts.map +0 -1
- package/dist/plugins/user-agent.d.ts.map +0 -1
- package/dist/plugins/xml.d.ts.map +0 -1
- package/dist/plugins/xsrf.d.ts.map +0 -1
- package/dist/presets/anthropic.d.ts.map +0 -1
- package/dist/presets/aws.d.ts.map +0 -1
- package/dist/presets/azure-openai.d.ts.map +0 -1
- package/dist/presets/azure.d.ts.map +0 -1
- package/dist/presets/cloudflare.d.ts.map +0 -1
- package/dist/presets/cohere.d.ts.map +0 -1
- package/dist/presets/deepseek.d.ts.map +0 -1
- package/dist/presets/digitalocean.d.ts.map +0 -1
- package/dist/presets/discord.d.ts.map +0 -1
- package/dist/presets/fireworks.d.ts.map +0 -1
- package/dist/presets/gcp.d.ts.map +0 -1
- package/dist/presets/gemini.d.ts.map +0 -1
- package/dist/presets/github.d.ts.map +0 -1
- package/dist/presets/gitlab.d.ts.map +0 -1
- package/dist/presets/groq.d.ts.map +0 -1
- package/dist/presets/huggingface.d.ts.map +0 -1
- package/dist/presets/index.d.ts.map +0 -1
- package/dist/presets/linear.d.ts.map +0 -1
- package/dist/presets/mailgun.d.ts.map +0 -1
- package/dist/presets/meta.d.ts.map +0 -1
- package/dist/presets/mistral.d.ts.map +0 -1
- package/dist/presets/notion.d.ts.map +0 -1
- package/dist/presets/openai.d.ts.map +0 -1
- package/dist/presets/oracle.d.ts.map +0 -1
- package/dist/presets/perplexity.d.ts.map +0 -1
- package/dist/presets/registry.d.ts.map +0 -1
- package/dist/presets/replicate.d.ts.map +0 -1
- package/dist/presets/sinch.d.ts.map +0 -1
- package/dist/presets/slack.d.ts.map +0 -1
- package/dist/presets/stripe.d.ts.map +0 -1
- package/dist/presets/supabase.d.ts.map +0 -1
- package/dist/presets/tiktok.d.ts.map +0 -1
- package/dist/presets/together.d.ts.map +0 -1
- package/dist/presets/twilio.d.ts.map +0 -1
- package/dist/presets/vercel.d.ts.map +0 -1
- package/dist/presets/vultr.d.ts.map +0 -1
- package/dist/presets/xai.d.ts.map +0 -1
- package/dist/presets/youtube.d.ts.map +0 -1
- package/dist/protocols/ftp.d.ts.map +0 -1
- package/dist/protocols/index.d.ts.map +0 -1
- package/dist/protocols/sftp.d.ts.map +0 -1
- package/dist/protocols/telnet.d.ts.map +0 -1
- package/dist/recker.d.ts.map +0 -1
- package/dist/runner/request-runner.d.ts.map +0 -1
- package/dist/scrape/document.d.ts.map +0 -1
- package/dist/scrape/element.d.ts.map +0 -1
- package/dist/scrape/extractors.d.ts.map +0 -1
- package/dist/scrape/index.d.ts.map +0 -1
- package/dist/scrape/types.d.ts.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/mock-udp-server.d.ts.map +0 -1
- package/dist/testing/mock.d.ts.map +0 -1
- package/dist/transport/base-udp.d.ts.map +0 -1
- package/dist/transport/fetch.d.ts.map +0 -1
- package/dist/transport/udp-response.d.ts.map +0 -1
- package/dist/transport/udp.d.ts.map +0 -1
- package/dist/transport/undici.d.ts.map +0 -1
- package/dist/types/ai.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/logger.d.ts.map +0 -1
- package/dist/types/udp.d.ts.map +0 -1
- package/dist/udp/index.d.ts.map +0 -1
- package/dist/utils/agent-manager.d.ts.map +0 -1
- package/dist/utils/body.d.ts.map +0 -1
- package/dist/utils/cert.d.ts.map +0 -1
- package/dist/utils/charset.d.ts.map +0 -1
- package/dist/utils/chart.d.ts.map +0 -1
- package/dist/utils/client-pool.d.ts.map +0 -1
- package/dist/utils/colors.d.ts.map +0 -1
- package/dist/utils/concurrency.d.ts.map +0 -1
- package/dist/utils/dns-toolkit.d.ts.map +0 -1
- package/dist/utils/dns.d.ts.map +0 -1
- package/dist/utils/doh.d.ts.map +0 -1
- package/dist/utils/download.d.ts.map +0 -1
- package/dist/utils/env-proxy.d.ts.map +0 -1
- package/dist/utils/header-parser.d.ts.map +0 -1
- package/dist/utils/html-cleaner.d.ts.map +0 -1
- package/dist/utils/link-header.d.ts.map +0 -1
- package/dist/utils/optional-require.d.ts.map +0 -1
- package/dist/utils/progress.d.ts.map +0 -1
- package/dist/utils/rdap.d.ts.map +0 -1
- package/dist/utils/request-pool.d.ts.map +0 -1
- package/dist/utils/security-grader.d.ts.map +0 -1
- package/dist/utils/sparkline.d.ts.map +0 -1
- package/dist/utils/sse.d.ts.map +0 -1
- package/dist/utils/streaming.d.ts.map +0 -1
- package/dist/utils/system-metrics.d.ts.map +0 -1
- package/dist/utils/tls-inspector.d.ts.map +0 -1
- package/dist/utils/try-fn.d.ts.map +0 -1
- package/dist/utils/upload.d.ts.map +0 -1
- package/dist/utils/user-agent.d.ts.map +0 -1
- package/dist/utils/whois.d.ts.map +0 -1
- package/dist/webrtc/index.d.ts.map +0 -1
- package/dist/websocket/client.d.ts.map +0 -1
package/dist/plugins/auth.d.ts
CHANGED
|
@@ -1,45 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export interface BasicAuthOptions {
|
|
3
|
-
username: string;
|
|
4
|
-
password: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function basicAuth(options: BasicAuthOptions): Middleware;
|
|
7
|
-
export declare function basicAuthPlugin(options: BasicAuthOptions): Plugin;
|
|
8
|
-
export interface BearerAuthOptions {
|
|
9
|
-
token: string | (() => string | Promise<string>);
|
|
10
|
-
type?: string;
|
|
11
|
-
headerName?: string;
|
|
12
|
-
}
|
|
13
|
-
export declare function bearerAuth(options: BearerAuthOptions): Middleware;
|
|
14
|
-
export declare function bearerAuthPlugin(options: BearerAuthOptions): Plugin;
|
|
15
|
-
export interface ApiKeyAuthOptions {
|
|
16
|
-
key: string | (() => string | Promise<string>);
|
|
17
|
-
in?: 'header' | 'query';
|
|
18
|
-
name?: string;
|
|
19
|
-
}
|
|
20
|
-
export declare function apiKeyAuth(options: ApiKeyAuthOptions): Middleware;
|
|
21
|
-
export declare function apiKeyAuthPlugin(options: ApiKeyAuthOptions): Plugin;
|
|
22
|
-
export interface DigestAuthOptions {
|
|
23
|
-
username: string;
|
|
24
|
-
password: string;
|
|
25
|
-
preemptive?: boolean;
|
|
26
|
-
}
|
|
27
|
-
export declare function digestAuth(options: DigestAuthOptions): Middleware;
|
|
28
|
-
export declare function digestAuthPlugin(options: DigestAuthOptions): Plugin;
|
|
29
|
-
export interface OAuth2Options {
|
|
30
|
-
accessToken: string | (() => string | Promise<string>);
|
|
31
|
-
tokenType?: string;
|
|
32
|
-
onTokenExpired?: () => Promise<string>;
|
|
33
|
-
}
|
|
34
|
-
export declare function oauth2(options: OAuth2Options): Middleware;
|
|
35
|
-
export declare function oauth2Plugin(options: OAuth2Options): Plugin;
|
|
36
|
-
export interface AWSSignatureV4Options {
|
|
37
|
-
accessKeyId: string;
|
|
38
|
-
secretAccessKey: string;
|
|
39
|
-
region: string;
|
|
40
|
-
service: string;
|
|
41
|
-
sessionToken?: string;
|
|
42
|
-
}
|
|
43
|
-
export declare function awsSignatureV4(options: AWSSignatureV4Options): Middleware;
|
|
44
|
-
export declare function awsSignatureV4Plugin(options: AWSSignatureV4Options): Plugin;
|
|
45
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
1
|
+
export * from './auth/index.js';
|
package/dist/plugins/auth.js
CHANGED
|
@@ -1,268 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export function basicAuth(options) {
|
|
3
|
-
const credentials = Buffer.from(`${options.username}:${options.password}`).toString('base64');
|
|
4
|
-
const authHeader = `Basic ${credentials}`;
|
|
5
|
-
return async (req, next) => {
|
|
6
|
-
const newReq = req.withHeader('Authorization', authHeader);
|
|
7
|
-
return next(newReq);
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
export function basicAuthPlugin(options) {
|
|
11
|
-
return (client) => {
|
|
12
|
-
client.use(basicAuth(options));
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export function bearerAuth(options) {
|
|
16
|
-
const type = options.type ?? 'Bearer';
|
|
17
|
-
const headerName = options.headerName ?? 'Authorization';
|
|
18
|
-
return async (req, next) => {
|
|
19
|
-
const token = typeof options.token === 'function'
|
|
20
|
-
? await options.token()
|
|
21
|
-
: options.token;
|
|
22
|
-
const authHeader = `${type} ${token}`;
|
|
23
|
-
const newReq = req.withHeader(headerName, authHeader);
|
|
24
|
-
return next(newReq);
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
export function bearerAuthPlugin(options) {
|
|
28
|
-
return (client) => {
|
|
29
|
-
client.use(bearerAuth(options));
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export function apiKeyAuth(options) {
|
|
33
|
-
const location = options.in ?? 'header';
|
|
34
|
-
const name = options.name ?? 'X-API-Key';
|
|
35
|
-
return async (req, next) => {
|
|
36
|
-
const key = typeof options.key === 'function'
|
|
37
|
-
? await options.key()
|
|
38
|
-
: options.key;
|
|
39
|
-
if (location === 'header') {
|
|
40
|
-
const newReq = req.withHeader(name, key);
|
|
41
|
-
return next(newReq);
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
const url = new URL(req.url);
|
|
45
|
-
url.searchParams.set(name, key);
|
|
46
|
-
const newReq = {
|
|
47
|
-
...req,
|
|
48
|
-
url: url.toString(),
|
|
49
|
-
};
|
|
50
|
-
return next(newReq);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
export function apiKeyAuthPlugin(options) {
|
|
55
|
-
return (client) => {
|
|
56
|
-
client.use(apiKeyAuth(options));
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
function parseDigestChallenge(header) {
|
|
60
|
-
if (!header.toLowerCase().startsWith('digest ')) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
const params = {};
|
|
64
|
-
const regex = /(\w+)=(?:"([^"]+)"|([^\s,]+))/g;
|
|
65
|
-
let match;
|
|
66
|
-
while ((match = regex.exec(header)) !== null) {
|
|
67
|
-
params[match[1].toLowerCase()] = match[2] || match[3];
|
|
68
|
-
}
|
|
69
|
-
if (!params.realm || !params.nonce) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
realm: params.realm,
|
|
74
|
-
nonce: params.nonce,
|
|
75
|
-
qop: params.qop,
|
|
76
|
-
opaque: params.opaque,
|
|
77
|
-
algorithm: params.algorithm,
|
|
78
|
-
stale: params.stale === 'true',
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function md5(str) {
|
|
82
|
-
return createHash('md5').update(str).digest('hex');
|
|
83
|
-
}
|
|
84
|
-
function sha256(str) {
|
|
85
|
-
return createHash('sha256').update(str).digest('hex');
|
|
86
|
-
}
|
|
87
|
-
function generateDigestHeader(method, uri, username, password, challenge, nc) {
|
|
88
|
-
const algorithm = challenge.algorithm?.toUpperCase() || 'MD5';
|
|
89
|
-
const hashFn = algorithm.includes('SHA-256') ? sha256 : md5;
|
|
90
|
-
const cnonce = randomBytes(8).toString('hex');
|
|
91
|
-
const ncStr = nc.toString(16).padStart(8, '0');
|
|
92
|
-
let ha1 = hashFn(`${username}:${challenge.realm}:${password}`);
|
|
93
|
-
if (algorithm.endsWith('-SESS')) {
|
|
94
|
-
ha1 = hashFn(`${ha1}:${challenge.nonce}:${cnonce}`);
|
|
95
|
-
}
|
|
96
|
-
const ha2 = hashFn(`${method}:${uri}`);
|
|
97
|
-
let response;
|
|
98
|
-
if (challenge.qop) {
|
|
99
|
-
response = hashFn(`${ha1}:${challenge.nonce}:${ncStr}:${cnonce}:${challenge.qop}:${ha2}`);
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
response = hashFn(`${ha1}:${challenge.nonce}:${ha2}`);
|
|
103
|
-
}
|
|
104
|
-
const parts = [
|
|
105
|
-
`username="${username}"`,
|
|
106
|
-
`realm="${challenge.realm}"`,
|
|
107
|
-
`nonce="${challenge.nonce}"`,
|
|
108
|
-
`uri="${uri}"`,
|
|
109
|
-
`response="${response}"`,
|
|
110
|
-
];
|
|
111
|
-
if (challenge.qop) {
|
|
112
|
-
parts.push(`qop=${challenge.qop.split(',')[0].trim()}`);
|
|
113
|
-
parts.push(`nc=${ncStr}`);
|
|
114
|
-
parts.push(`cnonce="${cnonce}"`);
|
|
115
|
-
}
|
|
116
|
-
if (challenge.opaque) {
|
|
117
|
-
parts.push(`opaque="${challenge.opaque}"`);
|
|
118
|
-
}
|
|
119
|
-
if (algorithm !== 'MD5') {
|
|
120
|
-
parts.push(`algorithm=${algorithm}`);
|
|
121
|
-
}
|
|
122
|
-
return `Digest ${parts.join(', ')}`;
|
|
123
|
-
}
|
|
124
|
-
export function digestAuth(options) {
|
|
125
|
-
let nc = 0;
|
|
126
|
-
let lastChallenge = null;
|
|
127
|
-
return async (req, next) => {
|
|
128
|
-
if (lastChallenge && options.preemptive) {
|
|
129
|
-
nc++;
|
|
130
|
-
const uri = new URL(req.url).pathname + new URL(req.url).search;
|
|
131
|
-
const authHeader = generateDigestHeader(req.method, uri, options.username, options.password, lastChallenge, nc);
|
|
132
|
-
const newReq = req.withHeader('Authorization', authHeader);
|
|
133
|
-
return next(newReq);
|
|
134
|
-
}
|
|
135
|
-
const response = await next(req);
|
|
136
|
-
if (response.status === 401) {
|
|
137
|
-
const wwwAuth = response.headers.get('WWW-Authenticate');
|
|
138
|
-
if (wwwAuth) {
|
|
139
|
-
const challenge = parseDigestChallenge(wwwAuth);
|
|
140
|
-
if (challenge) {
|
|
141
|
-
lastChallenge = challenge;
|
|
142
|
-
nc++;
|
|
143
|
-
const uri = new URL(req.url).pathname + new URL(req.url).search;
|
|
144
|
-
const authHeader = generateDigestHeader(req.method, uri, options.username, options.password, challenge, nc);
|
|
145
|
-
const newReq = req.withHeader('Authorization', authHeader);
|
|
146
|
-
return next(newReq);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return response;
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
export function digestAuthPlugin(options) {
|
|
154
|
-
return (client) => {
|
|
155
|
-
client.use(digestAuth(options));
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
export function oauth2(options) {
|
|
159
|
-
const tokenType = options.tokenType ?? 'Bearer';
|
|
160
|
-
return async (req, next) => {
|
|
161
|
-
const token = typeof options.accessToken === 'function'
|
|
162
|
-
? await options.accessToken()
|
|
163
|
-
: options.accessToken;
|
|
164
|
-
const authReq = req.withHeader('Authorization', `${tokenType} ${token}`);
|
|
165
|
-
const response = await next(authReq);
|
|
166
|
-
if (response.status === 401 && options.onTokenExpired) {
|
|
167
|
-
try {
|
|
168
|
-
const newToken = await options.onTokenExpired();
|
|
169
|
-
const retryReq = req.withHeader('Authorization', `${tokenType} ${newToken}`);
|
|
170
|
-
return next(retryReq);
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
return response;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return response;
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
export function oauth2Plugin(options) {
|
|
180
|
-
return (client) => {
|
|
181
|
-
client.use(oauth2(options));
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
export function awsSignatureV4(options) {
|
|
185
|
-
return async (req, next) => {
|
|
186
|
-
const url = new URL(req.url);
|
|
187
|
-
const host = url.host;
|
|
188
|
-
const pathname = url.pathname;
|
|
189
|
-
const queryString = url.search.slice(1);
|
|
190
|
-
const now = new Date();
|
|
191
|
-
const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
|
|
192
|
-
const dateStamp = amzDate.slice(0, 8);
|
|
193
|
-
const method = req.method;
|
|
194
|
-
const canonicalUri = pathname || '/';
|
|
195
|
-
const canonicalQueryString = queryString
|
|
196
|
-
.split('&')
|
|
197
|
-
.filter(Boolean)
|
|
198
|
-
.sort()
|
|
199
|
-
.join('&');
|
|
200
|
-
let payload = '';
|
|
201
|
-
if (req.body) {
|
|
202
|
-
if (typeof req.body === 'string') {
|
|
203
|
-
payload = req.body;
|
|
204
|
-
}
|
|
205
|
-
else if (req.body instanceof ArrayBuffer) {
|
|
206
|
-
payload = Buffer.from(req.body).toString();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
const payloadHash = sha256(payload);
|
|
210
|
-
const headers = {
|
|
211
|
-
host,
|
|
212
|
-
'x-amz-date': amzDate,
|
|
213
|
-
'x-amz-content-sha256': payloadHash,
|
|
214
|
-
};
|
|
215
|
-
if (options.sessionToken) {
|
|
216
|
-
headers['x-amz-security-token'] = options.sessionToken;
|
|
217
|
-
}
|
|
218
|
-
req.headers.forEach((value, key) => {
|
|
219
|
-
headers[key.toLowerCase()] = value;
|
|
220
|
-
});
|
|
221
|
-
const signedHeaders = Object.keys(headers).sort().join(';');
|
|
222
|
-
const canonicalHeaders = Object.keys(headers)
|
|
223
|
-
.sort()
|
|
224
|
-
.map(key => `${key}:${headers[key].trim()}\n`)
|
|
225
|
-
.join('');
|
|
226
|
-
const canonicalRequest = [
|
|
227
|
-
method,
|
|
228
|
-
canonicalUri,
|
|
229
|
-
canonicalQueryString,
|
|
230
|
-
canonicalHeaders,
|
|
231
|
-
signedHeaders,
|
|
232
|
-
payloadHash,
|
|
233
|
-
].join('\n');
|
|
234
|
-
const algorithm = 'AWS4-HMAC-SHA256';
|
|
235
|
-
const credentialScope = `${dateStamp}/${options.region}/${options.service}/aws4_request`;
|
|
236
|
-
const stringToSign = [
|
|
237
|
-
algorithm,
|
|
238
|
-
amzDate,
|
|
239
|
-
credentialScope,
|
|
240
|
-
sha256(canonicalRequest),
|
|
241
|
-
].join('\n');
|
|
242
|
-
const getSignatureKey = (key, dateStamp, regionName, serviceName) => {
|
|
243
|
-
const kDate = createHash('sha256').update(`AWS4${key}`).update(dateStamp).digest();
|
|
244
|
-
const kRegion = createHash('sha256').update(kDate).update(regionName).digest();
|
|
245
|
-
const kService = createHash('sha256').update(kRegion).update(serviceName).digest();
|
|
246
|
-
const kSigning = createHash('sha256').update(kService).update('aws4_request').digest();
|
|
247
|
-
return kSigning;
|
|
248
|
-
};
|
|
249
|
-
const signingKey = getSignatureKey(options.secretAccessKey, dateStamp, options.region, options.service);
|
|
250
|
-
const signature = createHash('sha256')
|
|
251
|
-
.update(signingKey)
|
|
252
|
-
.update(stringToSign)
|
|
253
|
-
.digest('hex');
|
|
254
|
-
const authorizationHeader = `${algorithm} Credential=${options.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`;
|
|
255
|
-
let newReq = req.withHeader('Authorization', authorizationHeader);
|
|
256
|
-
newReq = newReq.withHeader('x-amz-date', amzDate);
|
|
257
|
-
newReq = newReq.withHeader('x-amz-content-sha256', payloadHash);
|
|
258
|
-
if (options.sessionToken) {
|
|
259
|
-
newReq = newReq.withHeader('x-amz-security-token', options.sessionToken);
|
|
260
|
-
}
|
|
261
|
-
return next(newReq);
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
export function awsSignatureV4Plugin(options) {
|
|
265
|
-
return (client) => {
|
|
266
|
-
client.use(awsSignatureV4(options));
|
|
267
|
-
};
|
|
268
|
-
}
|
|
1
|
+
export * from './auth/index.js';
|
package/dist/plugins/cache.d.ts
CHANGED
package/dist/plugins/cache.js
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Middleware, Plugin, ReckerRequest } from '../types/index.js';
|
|
2
|
+
import { TLSSocket } from 'node:tls';
|
|
3
|
+
export interface CertificatePinningOptions {
|
|
4
|
+
pins: Record<string, PinConfig>;
|
|
5
|
+
onPinFailure?: 'reject' | 'warn' | 'report';
|
|
6
|
+
reportUri?: string;
|
|
7
|
+
includeSubdomains?: boolean;
|
|
8
|
+
cache?: boolean;
|
|
9
|
+
cacheMaxAge?: number;
|
|
10
|
+
onError?: (error: CertificatePinningError, request: ReckerRequest) => void;
|
|
11
|
+
skip?: (request: ReckerRequest) => boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface PinConfig {
|
|
14
|
+
sha256?: string[];
|
|
15
|
+
spki?: string[];
|
|
16
|
+
issuer?: string;
|
|
17
|
+
subject?: string;
|
|
18
|
+
minValidDays?: number;
|
|
19
|
+
allowExpired?: boolean;
|
|
20
|
+
backup?: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare class CertificatePinningError extends Error {
|
|
23
|
+
hostname: string;
|
|
24
|
+
expectedPins: string[];
|
|
25
|
+
actualPin?: string | undefined;
|
|
26
|
+
certificate?: CertificateInfo | undefined;
|
|
27
|
+
constructor(message: string, hostname: string, expectedPins: string[], actualPin?: string | undefined, certificate?: CertificateInfo | undefined);
|
|
28
|
+
}
|
|
29
|
+
export interface CertificateInfo {
|
|
30
|
+
subject: string;
|
|
31
|
+
issuer: string;
|
|
32
|
+
validFrom: Date;
|
|
33
|
+
validTo: Date;
|
|
34
|
+
fingerprint: string;
|
|
35
|
+
fingerprintSha256: string;
|
|
36
|
+
serialNumber: string;
|
|
37
|
+
subjectPublicKeyInfo?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function extractCertificateInfo(socket: TLSSocket): CertificateInfo | null;
|
|
40
|
+
export declare function validateCertificate(certInfo: CertificateInfo, pinConfig: PinConfig): {
|
|
41
|
+
valid: boolean;
|
|
42
|
+
reason?: string;
|
|
43
|
+
};
|
|
44
|
+
export declare function reportPinFailure(reportUri: string, hostname: string, error: CertificatePinningError): Promise<void>;
|
|
45
|
+
export declare function generatePinsFromHost(hostname: string, port?: number): Promise<{
|
|
46
|
+
sha256: string;
|
|
47
|
+
spki?: string;
|
|
48
|
+
}>;
|
|
49
|
+
export declare function certificatePinning(options: CertificatePinningOptions): Middleware;
|
|
50
|
+
export declare function certificatePinningPlugin(options: CertificatePinningOptions): Plugin;
|
|
51
|
+
export declare function clearPinCache(): void;
|
|
52
|
+
export declare function getPinCacheStats(): {
|
|
53
|
+
size: number;
|
|
54
|
+
entries: string[];
|
|
55
|
+
};
|
|
56
|
+
export declare function preloadPins(hosts: string[]): Promise<Map<string, {
|
|
57
|
+
sha256: string;
|
|
58
|
+
spki?: string;
|
|
59
|
+
}>>;
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export class CertificatePinningError extends Error {
|
|
3
|
+
hostname;
|
|
4
|
+
expectedPins;
|
|
5
|
+
actualPin;
|
|
6
|
+
certificate;
|
|
7
|
+
constructor(message, hostname, expectedPins, actualPin, certificate) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.hostname = hostname;
|
|
10
|
+
this.expectedPins = expectedPins;
|
|
11
|
+
this.actualPin = actualPin;
|
|
12
|
+
this.certificate = certificate;
|
|
13
|
+
this.name = 'CertificatePinningError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const pinCache = new Map();
|
|
17
|
+
function normalizeFingerprint(fp) {
|
|
18
|
+
return fp.replace(/:/g, '').toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
function calculateFingerprint(cert) {
|
|
21
|
+
const certBuffer = typeof cert === 'string' ? Buffer.from(cert) : cert;
|
|
22
|
+
return createHash('sha256').update(certBuffer).digest('hex');
|
|
23
|
+
}
|
|
24
|
+
function calculateSPKIFingerprint(publicKey) {
|
|
25
|
+
const keyBuffer = typeof publicKey === 'string' ? Buffer.from(publicKey) : publicKey;
|
|
26
|
+
return createHash('sha256').update(keyBuffer).digest('base64');
|
|
27
|
+
}
|
|
28
|
+
export function extractCertificateInfo(socket) {
|
|
29
|
+
try {
|
|
30
|
+
const cert = socket.getPeerCertificate(true);
|
|
31
|
+
if (!cert || !cert.fingerprint256) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
subject: typeof cert.subject === 'object' ? JSON.stringify(cert.subject) : String(cert.subject),
|
|
36
|
+
issuer: typeof cert.issuer === 'object' ? JSON.stringify(cert.issuer) : String(cert.issuer),
|
|
37
|
+
validFrom: new Date(cert.valid_from),
|
|
38
|
+
validTo: new Date(cert.valid_to),
|
|
39
|
+
fingerprint: cert.fingerprint,
|
|
40
|
+
fingerprintSha256: cert.fingerprint256,
|
|
41
|
+
serialNumber: cert.serialNumber,
|
|
42
|
+
subjectPublicKeyInfo: cert.pubkey?.toString('base64'),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function hostnameMatches(hostname, pattern) {
|
|
50
|
+
if (pattern === '*') {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (pattern.startsWith('*.')) {
|
|
54
|
+
const baseDomain = pattern.slice(2);
|
|
55
|
+
return hostname === baseDomain || hostname.endsWith('.' + baseDomain);
|
|
56
|
+
}
|
|
57
|
+
return hostname === pattern;
|
|
58
|
+
}
|
|
59
|
+
function findPinConfig(hostname, pins, includeSubdomains) {
|
|
60
|
+
if (pins[hostname]) {
|
|
61
|
+
return pins[hostname];
|
|
62
|
+
}
|
|
63
|
+
for (const pattern of Object.keys(pins)) {
|
|
64
|
+
if (hostnameMatches(hostname, pattern)) {
|
|
65
|
+
return pins[pattern];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (includeSubdomains) {
|
|
69
|
+
const parts = hostname.split('.');
|
|
70
|
+
for (let i = 1; i < parts.length; i++) {
|
|
71
|
+
const parentDomain = parts.slice(i).join('.');
|
|
72
|
+
if (pins[parentDomain]) {
|
|
73
|
+
return pins[parentDomain];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
export function validateCertificate(certInfo, pinConfig) {
|
|
80
|
+
const now = new Date();
|
|
81
|
+
if (!pinConfig.allowExpired && certInfo.validTo < now) {
|
|
82
|
+
return { valid: false, reason: 'Certificate has expired' };
|
|
83
|
+
}
|
|
84
|
+
if (certInfo.validFrom > now) {
|
|
85
|
+
return { valid: false, reason: 'Certificate is not yet valid' };
|
|
86
|
+
}
|
|
87
|
+
if (pinConfig.minValidDays) {
|
|
88
|
+
const daysUntilExpiry = Math.floor((certInfo.validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
|
89
|
+
if (daysUntilExpiry < pinConfig.minValidDays) {
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
reason: `Certificate expires in ${daysUntilExpiry} days (minimum: ${pinConfig.minValidDays})`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (pinConfig.issuer && !certInfo.issuer.includes(pinConfig.issuer)) {
|
|
97
|
+
return { valid: false, reason: `Issuer mismatch: expected "${pinConfig.issuer}"` };
|
|
98
|
+
}
|
|
99
|
+
if (pinConfig.subject && !certInfo.subject.includes(pinConfig.subject)) {
|
|
100
|
+
return { valid: false, reason: `Subject mismatch: expected "${pinConfig.subject}"` };
|
|
101
|
+
}
|
|
102
|
+
if (pinConfig.sha256 && pinConfig.sha256.length > 0) {
|
|
103
|
+
const normalizedFingerprint = normalizeFingerprint(certInfo.fingerprintSha256);
|
|
104
|
+
const normalizedPins = pinConfig.sha256.map(normalizeFingerprint);
|
|
105
|
+
if (!normalizedPins.includes(normalizedFingerprint)) {
|
|
106
|
+
if (pinConfig.backup) {
|
|
107
|
+
const normalizedBackups = pinConfig.backup.map(normalizeFingerprint);
|
|
108
|
+
if (!normalizedBackups.includes(normalizedFingerprint)) {
|
|
109
|
+
return { valid: false, reason: 'SHA-256 fingerprint does not match any pins' };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
return { valid: false, reason: 'SHA-256 fingerprint does not match any pins' };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (pinConfig.spki && pinConfig.spki.length > 0 && certInfo.subjectPublicKeyInfo) {
|
|
118
|
+
const spkiFingerprint = calculateSPKIFingerprint(certInfo.subjectPublicKeyInfo);
|
|
119
|
+
if (!pinConfig.spki.includes(spkiFingerprint)) {
|
|
120
|
+
return { valid: false, reason: 'SPKI fingerprint does not match any pins' };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { valid: true };
|
|
124
|
+
}
|
|
125
|
+
export async function reportPinFailure(reportUri, hostname, error) {
|
|
126
|
+
try {
|
|
127
|
+
await fetch(reportUri, {
|
|
128
|
+
method: 'POST',
|
|
129
|
+
headers: {
|
|
130
|
+
'Content-Type': 'application/json',
|
|
131
|
+
},
|
|
132
|
+
body: JSON.stringify({
|
|
133
|
+
timestamp: new Date().toISOString(),
|
|
134
|
+
hostname,
|
|
135
|
+
expectedPins: error.expectedPins,
|
|
136
|
+
actualPin: error.actualPin,
|
|
137
|
+
certificate: error.certificate,
|
|
138
|
+
error: error.message,
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export async function generatePinsFromHost(hostname, port = 443) {
|
|
146
|
+
const tls = await import('node:tls');
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
const socket = tls.connect({
|
|
149
|
+
host: hostname,
|
|
150
|
+
port,
|
|
151
|
+
servername: hostname,
|
|
152
|
+
rejectUnauthorized: false,
|
|
153
|
+
}, () => {
|
|
154
|
+
const cert = socket.getPeerCertificate(true);
|
|
155
|
+
socket.destroy();
|
|
156
|
+
if (!cert || !cert.fingerprint256) {
|
|
157
|
+
reject(new Error('Could not retrieve certificate'));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const result = {
|
|
161
|
+
sha256: normalizeFingerprint(cert.fingerprint256),
|
|
162
|
+
};
|
|
163
|
+
if (cert.pubkey) {
|
|
164
|
+
result.spki = calculateSPKIFingerprint(cert.pubkey);
|
|
165
|
+
}
|
|
166
|
+
resolve(result);
|
|
167
|
+
});
|
|
168
|
+
socket.on('error', reject);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
export function certificatePinning(options) {
|
|
172
|
+
const { pins, onPinFailure = 'reject', reportUri, includeSubdomains = false, cache = true, cacheMaxAge = 86400000, onError, skip, } = options;
|
|
173
|
+
return async (req, next) => {
|
|
174
|
+
if (skip && skip(req)) {
|
|
175
|
+
return next(req);
|
|
176
|
+
}
|
|
177
|
+
const url = new URL(req.url);
|
|
178
|
+
const hostname = url.hostname;
|
|
179
|
+
if (url.protocol !== 'https:') {
|
|
180
|
+
return next(req);
|
|
181
|
+
}
|
|
182
|
+
const pinConfig = findPinConfig(hostname, pins, includeSubdomains);
|
|
183
|
+
if (!pinConfig) {
|
|
184
|
+
return next(req);
|
|
185
|
+
}
|
|
186
|
+
const cacheKey = `${hostname}:${url.port || '443'}`;
|
|
187
|
+
if (cache) {
|
|
188
|
+
const cached = pinCache.get(cacheKey);
|
|
189
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
190
|
+
if (!cached.valid) {
|
|
191
|
+
const error = new CertificatePinningError(`Certificate pinning failed for ${hostname} (cached)`, hostname, pinConfig.sha256 || pinConfig.spki || [], undefined, cached.certificateInfo);
|
|
192
|
+
if (onPinFailure === 'reject') {
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return next(req);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const response = await next(req);
|
|
200
|
+
if (cache) {
|
|
201
|
+
pinCache.set(cacheKey, {
|
|
202
|
+
valid: true,
|
|
203
|
+
expiresAt: Date.now() + cacheMaxAge,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return response;
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
export function certificatePinningPlugin(options) {
|
|
210
|
+
return (client) => {
|
|
211
|
+
client.use(certificatePinning(options));
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
export function clearPinCache() {
|
|
215
|
+
pinCache.clear();
|
|
216
|
+
}
|
|
217
|
+
export function getPinCacheStats() {
|
|
218
|
+
return {
|
|
219
|
+
size: pinCache.size,
|
|
220
|
+
entries: Array.from(pinCache.keys()),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
export async function preloadPins(hosts) {
|
|
224
|
+
const results = new Map();
|
|
225
|
+
await Promise.all(hosts.map(async (host) => {
|
|
226
|
+
try {
|
|
227
|
+
const [hostname, portStr] = host.split(':');
|
|
228
|
+
const port = portStr ? parseInt(portStr, 10) : 443;
|
|
229
|
+
const pins = await generatePinsFromHost(hostname, port);
|
|
230
|
+
results.set(host, pins);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
}
|
|
234
|
+
}));
|
|
235
|
+
return results;
|
|
236
|
+
}
|
|
@@ -2,4 +2,3 @@ import { Middleware, CompressionOptions } from '../types/index.js';
|
|
|
2
2
|
export type CompressionAlgorithm = 'gzip' | 'deflate' | 'br';
|
|
3
3
|
export declare function compression(options?: CompressionOptions): Middleware;
|
|
4
4
|
export declare function createCompressionMiddleware(config: boolean | CompressionOptions): Middleware | null;
|
|
5
|
-
//# sourceMappingURL=compression.d.ts.map
|
package/dist/plugins/dedup.d.ts
CHANGED
|
@@ -11,4 +11,3 @@ export interface GraphQLOptions {
|
|
|
11
11
|
}
|
|
12
12
|
export declare function graphqlPlugin(options?: GraphQLOptions): Plugin;
|
|
13
13
|
export declare function graphql<T = any>(client: Client, query: string, variables?: Record<string, any>, options?: any): Promise<T>;
|
|
14
|
-
//# sourceMappingURL=graphql.d.ts.map
|
package/dist/plugins/hls.d.ts
CHANGED
|
@@ -103,4 +103,3 @@ export declare class HlsPromise implements Promise<void> {
|
|
|
103
103
|
}
|
|
104
104
|
export declare function hls(client: Client, manifestUrl: string, options?: HlsOptions): HlsPromise;
|
|
105
105
|
export type { HlsVariant as Variant, HlsSegment as Segment, HlsKeyInfo as KeyInfo, };
|
|
106
|
-
//# sourceMappingURL=hls.d.ts.map
|