@humain/terminal 0.1.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/bundle/chunks/{anthropic-messages-XULXUBIG.js → anthropic-messages-QFCEKGI3.js} +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-JEG2XOYC.js → azure-openai-responses-G4ZMHV37.js} +1 -1
- package/dist/bundle/chunks/chunk-7T6XCLJF.js +22 -0
- package/dist/bundle/chunks/{chunk-LYAMSPR2.js → chunk-ADQYVZ6A.js} +483 -506
- package/dist/bundle/chunks/chunk-D6HHRSB5.js +103 -0
- package/dist/bundle/chunks/{chunk-JUPSJTFQ.js → chunk-K4JAZYQH.js} +1 -1
- package/dist/bundle/chunks/{chunk-HPPQHK3J.js → chunk-KKIB2TVR.js} +1 -1
- package/dist/bundle/chunks/chunk-LI2YVPWP.js +2 -0
- package/dist/bundle/chunks/chunk-NMPIM7MN.js +2 -0
- package/dist/bundle/chunks/{chunk-BZQ53VGE.js → chunk-XSR434CO.js} +1 -1
- package/dist/bundle/chunks/compat-CN7WN6DA.js +2 -0
- package/dist/bundle/chunks/dist-PRPIUY3U.js +2 -0
- package/dist/bundle/chunks/esm-E7UVEYTO.js +4 -0
- package/dist/bundle/chunks/{extract-TRW5FBY6.js → extract-CTIFQZDJ.js} +15 -14
- package/dist/bundle/chunks/{google-generative-ai-OX6VSCA6.js → google-generative-ai-RSUU4MWO.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-GW76GSS2.js → google-vertex-CKQPOITO.js} +1 -1
- package/dist/bundle/chunks/host-WP3MVKS2.js +2 -0
- package/dist/bundle/chunks/{node-KOIP55YZ.js → node-NF43OPII.js} +1 -1
- package/dist/bundle/chunks/{node-XY3CBY3C.js → node-UMFM7CDZ.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-NPLWP6ZC.js → openai-codex-responses-S34V5ZSD.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-OT2GTJKC.js → openai-completions-T2IGVUEI.js} +1 -1
- package/dist/bundle/chunks/{openai-responses-5A6CR7GI.js → openai-responses-GYZODCT3.js} +1 -1
- package/dist/bundle/chunks/readability-LAGF34IB.js +3 -0
- package/dist/bundle/chunks/turndown.cjs-HRMZVRUL.js +2 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/model-runtime.d.ts +21 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +34 -4
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +21 -8
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/subagent-env.d.ts +20 -0
- package/dist/core/tools/subagent-env.d.ts.map +1 -0
- package/dist/core/tools/subagent-env.js +47 -0
- package/dist/core/tools/subagent-env.js.map +1 -0
- package/dist/core/tools/subagent-scheduler.d.ts +36 -0
- package/dist/core/tools/subagent-scheduler.d.ts.map +1 -0
- package/dist/core/tools/subagent-scheduler.js +213 -0
- package/dist/core/tools/subagent-scheduler.js.map +1 -0
- package/dist/core/tools/subagent.d.ts +83 -3
- package/dist/core/tools/subagent.d.ts.map +1 -1
- package/dist/core/tools/subagent.js +215 -76
- package/dist/core/tools/subagent.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +78 -0
- package/dist/humain/mcp-adapter/vendor/README.md +125 -19
- package/dist/humain/mcp-adapter/vendor/agent-plugin-loader.ts +69 -30
- package/dist/humain/mcp-adapter/vendor/agent-plugin-provenance.ts +36 -0
- package/dist/humain/mcp-adapter/vendor/claude-plugin-loader.ts +365 -0
- package/dist/humain/mcp-adapter/vendor/commands.ts +13 -15
- package/dist/humain/mcp-adapter/vendor/config.ts +198 -30
- package/dist/humain/mcp-adapter/vendor/consent-manager.ts +40 -9
- package/dist/humain/mcp-adapter/vendor/direct-tool-surface.ts +250 -0
- package/dist/humain/mcp-adapter/vendor/direct-tools.ts +9 -228
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.js +74 -32
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-loader.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-provenance.d.ts +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-provenance.js +31 -0
- package/dist/humain/mcp-adapter/vendor/dist/agent-plugin-provenance.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/claude-plugin-loader.d.ts +9 -0
- package/dist/humain/mcp-adapter/vendor/dist/claude-plugin-loader.js +362 -0
- package/dist/humain/mcp-adapter/vendor/dist/claude-plugin-loader.js.map +1 -0
- package/dist/humain/mcp-adapter/vendor/dist/config.d.ts +3 -1
- package/dist/humain/mcp-adapter/vendor/dist/config.js +189 -27
- package/dist/humain/mcp-adapter/vendor/dist/config.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.js +7 -16
- package/dist/humain/mcp-adapter/vendor/dist/metadata-cache.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.js +5 -17
- package/dist/humain/mcp-adapter/vendor/dist/package-mcp-loader.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/types.d.ts +30 -4
- package/dist/humain/mcp-adapter/vendor/dist/types.js +26 -0
- package/dist/humain/mcp-adapter/vendor/dist/types.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/dist/utils.d.ts +6 -0
- package/dist/humain/mcp-adapter/vendor/dist/utils.js +65 -6
- package/dist/humain/mcp-adapter/vendor/dist/utils.js.map +1 -1
- package/dist/humain/mcp-adapter/vendor/host-html-template.ts +20 -19
- package/dist/humain/mcp-adapter/vendor/http-ca.ts +84 -0
- package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +37102 -15103
- package/dist/humain/mcp-adapter/vendor/index.ts +828 -164
- package/dist/humain/mcp-adapter/vendor/init.ts +48 -10
- package/dist/humain/mcp-adapter/vendor/lazy-loader.ts +7 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth-fetch.ts +113 -0
- package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +256 -77
- package/dist/humain/mcp-adapter/vendor/mcp-auth.ts +316 -54
- package/dist/humain/mcp-adapter/vendor/mcp-code.ts +45 -18
- package/dist/humain/mcp-adapter/vendor/mcp-install.ts +60 -0
- package/dist/humain/mcp-adapter/vendor/mcp-oauth-provider.ts +70 -6
- package/dist/humain/mcp-adapter/vendor/mcp-output-guard.ts +53 -42
- package/dist/humain/mcp-adapter/vendor/mcp-panel-theme.ts +105 -0
- package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +366 -331
- package/dist/humain/mcp-adapter/vendor/mcp-references.ts +9 -14
- package/dist/humain/mcp-adapter/vendor/mcp-script-worker.mjs +3 -1
- package/dist/humain/mcp-adapter/vendor/mcp-setup-panel.ts +383 -341
- package/dist/humain/mcp-adapter/vendor/mcp-status.ts +5 -0
- package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +7 -16
- package/dist/humain/mcp-adapter/vendor/namespace-tools.ts +61 -3
- package/dist/humain/mcp-adapter/vendor/oauth.ts +6 -2
- package/dist/humain/mcp-adapter/vendor/package-mcp-loader.ts +5 -17
- package/dist/humain/mcp-adapter/vendor/package.json +13 -3
- package/dist/humain/mcp-adapter/vendor/prompts.ts +35 -3
- package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +108 -7
- package/dist/humain/mcp-adapter/vendor/runtime-owner.ts +16 -1
- package/dist/humain/mcp-adapter/vendor/sampling-handler.ts +9 -32
- package/dist/humain/mcp-adapter/vendor/sandbox-proxy-template.ts +20 -93
- package/dist/humain/mcp-adapter/vendor/server-manager.ts +227 -40
- package/dist/humain/mcp-adapter/vendor/session-approvals.ts +187 -0
- package/dist/humain/mcp-adapter/vendor/skills/mcp-scripting/SKILL.md +9 -1
- package/dist/humain/mcp-adapter/vendor/state.ts +10 -1
- package/dist/humain/mcp-adapter/vendor/tool-approval.ts +10 -22
- package/dist/humain/mcp-adapter/vendor/tool-metadata.ts +14 -0
- package/dist/humain/mcp-adapter/vendor/types.ts +57 -4
- package/dist/humain/mcp-adapter/vendor/ui-server.ts +36 -28
- package/dist/humain/mcp-adapter/vendor/utils.ts +64 -6
- package/dist/humain/web-access/vendor/abortable.d.ts +3 -0
- package/dist/humain/web-access/vendor/abortable.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/abortable.js +22 -0
- package/dist/humain/web-access/vendor/abortable.js.map +1 -0
- package/dist/humain/web-access/vendor/crawl4ai.d.ts +9 -0
- package/dist/humain/web-access/vendor/crawl4ai.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/crawl4ai.js +187 -0
- package/dist/humain/web-access/vendor/crawl4ai.js.map +1 -0
- package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/credential-source.js +1 -0
- package/dist/humain/web-access/vendor/credential-source.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-page.js +20 -2
- package/dist/humain/web-access/vendor/curator-page.js.map +1 -1
- package/dist/humain/web-access/vendor/curator-run.d.ts +11 -0
- package/dist/humain/web-access/vendor/curator-run.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/curator-run.js +38 -0
- package/dist/humain/web-access/vendor/curator-run.js.map +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts +1 -0
- package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/curator-server.js +2 -0
- package/dist/humain/web-access/vendor/curator-server.js.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.js +1 -1
- package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts +1 -1
- package/dist/humain/web-access/vendor/extract.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/extract.js +58 -11
- package/dist/humain/web-access/vendor/extract.js.map +1 -1
- package/dist/humain/web-access/vendor/fetch-params.js +1 -1
- package/dist/humain/web-access/vendor/fetch-params.js.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.d.ts +2 -2
- package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/gemini-search.js +12 -5
- package/dist/humain/web-access/vendor/gemini-search.js.map +1 -1
- package/dist/humain/web-access/vendor/index.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/index.js +23 -19
- package/dist/humain/web-access/vendor/index.js.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/openai-search.js +40 -14
- package/dist/humain/web-access/vendor/openai-search.js.map +1 -1
- package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/page-query.js +6 -2
- package/dist/humain/web-access/vendor/page-query.js.map +1 -1
- package/dist/humain/web-access/vendor/query-rewrite.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/query-rewrite.js +6 -2
- package/dist/humain/web-access/vendor/query-rewrite.js.map +1 -1
- package/dist/humain/web-access/vendor/serpapi.d.ts +4 -0
- package/dist/humain/web-access/vendor/serpapi.d.ts.map +1 -0
- package/dist/humain/web-access/vendor/serpapi.js +215 -0
- package/dist/humain/web-access/vendor/serpapi.js.map +1 -0
- package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js +5 -1
- package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -1
- package/dist/humain/web-access/vendor/storage.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/storage.js +9 -0
- package/dist/humain/web-access/vendor/storage.js.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts +1 -1
- package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/summary-review.js +35 -24
- package/dist/humain/web-access/vendor/summary-review.js.map +1 -1
- package/dist/humain/web-access/vendor/utils.d.ts.map +1 -1
- package/dist/humain/web-access/vendor/utils.js +5 -3
- package/dist/humain/web-access/vendor/utils.js.map +1 -1
- package/dist/modes/json-event.d.ts +8 -0
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +17 -0
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +3 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/docs/environment-variables.md +9 -0
- package/docs/json.md +16 -0
- package/npm-shrinkwrap.json +6 -6
- package/package.json +2 -2
- package/src/humain/mcp-adapter/UPSTREAM.md +56 -7
- package/src/humain/mcp-adapter/upstream.json +6 -4
- package/src/humain/mcp-adapter/vendor/CHANGELOG.md +78 -0
- package/src/humain/web-access/UPSTREAM.md +18 -8
- package/src/humain/web-access/upstream.json +6 -5
- package/dist/bundle/chunks/chunk-2LC3S3VV.js +0 -105
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { activityMonitor } from "./activity.js";
|
|
3
|
+
import { hasCredentialSource, redactCredential, resolveCredential } from "./credential-source.js";
|
|
4
|
+
import { getWebSearchConfigPath } from "./utils.js";
|
|
5
|
+
const SERPAPI_SEARCH_URL = "https://serpapi.com/search.json";
|
|
6
|
+
const CONFIG_PATH = getWebSearchConfigPath();
|
|
7
|
+
const SEARCH_TIMEOUT_MS = 60_000;
|
|
8
|
+
const RECENCY_TBS = {
|
|
9
|
+
day: "qdr:d",
|
|
10
|
+
week: "qdr:w",
|
|
11
|
+
month: "qdr:m",
|
|
12
|
+
year: "qdr:y",
|
|
13
|
+
};
|
|
14
|
+
let cachedConfig = null;
|
|
15
|
+
function loadConfig() {
|
|
16
|
+
if (cachedConfig)
|
|
17
|
+
return cachedConfig;
|
|
18
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
19
|
+
cachedConfig = {};
|
|
20
|
+
return cachedConfig;
|
|
21
|
+
}
|
|
22
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
23
|
+
let parsed;
|
|
24
|
+
try {
|
|
25
|
+
parsed = JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
29
|
+
throw new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);
|
|
30
|
+
}
|
|
31
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
32
|
+
throw new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);
|
|
33
|
+
}
|
|
34
|
+
cachedConfig = parsed;
|
|
35
|
+
return cachedConfig;
|
|
36
|
+
}
|
|
37
|
+
async function getApiKey(signal) {
|
|
38
|
+
return resolveCredential({
|
|
39
|
+
provider: "SerpApi",
|
|
40
|
+
configuredValue: loadConfig().serpapiApiKey,
|
|
41
|
+
environmentValue: process.env.SERPAPI_KEY,
|
|
42
|
+
signal,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function requireApiKey(signal) {
|
|
46
|
+
const apiKey = await getApiKey(signal);
|
|
47
|
+
if (!apiKey) {
|
|
48
|
+
throw new Error("SerpApi API key not found. Either:\n" +
|
|
49
|
+
` 1. Create ${CONFIG_PATH} with { "serpapiApiKey": "your-key" }\n` +
|
|
50
|
+
" 2. Set SERPAPI_KEY environment variable\n" +
|
|
51
|
+
"Get a key at https://serpapi.com/manage-api-key");
|
|
52
|
+
}
|
|
53
|
+
return apiKey;
|
|
54
|
+
}
|
|
55
|
+
function normalizeCount(value) {
|
|
56
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
57
|
+
return 5;
|
|
58
|
+
return Math.max(1, Math.min(Math.floor(value), 20));
|
|
59
|
+
}
|
|
60
|
+
function normalizeDomain(value) {
|
|
61
|
+
let input = value.trim().toLowerCase();
|
|
62
|
+
if (!input)
|
|
63
|
+
return null;
|
|
64
|
+
if (input.startsWith("-"))
|
|
65
|
+
input = input.slice(1).trim();
|
|
66
|
+
if (!input)
|
|
67
|
+
return null;
|
|
68
|
+
try {
|
|
69
|
+
const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
|
|
70
|
+
input = parsed.hostname;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
input = input.split("/")[0]?.split(":")[0] ?? "";
|
|
74
|
+
}
|
|
75
|
+
input = input.replace(/^\.+|\.+$/g, "");
|
|
76
|
+
return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
|
|
77
|
+
}
|
|
78
|
+
function parseDomainFilter(domainFilter) {
|
|
79
|
+
const filters = { include: [], exclude: [] };
|
|
80
|
+
for (const raw of domainFilter ?? []) {
|
|
81
|
+
const domain = normalizeDomain(raw);
|
|
82
|
+
if (!domain)
|
|
83
|
+
continue;
|
|
84
|
+
const target = raw.trim().startsWith("-") ? filters.exclude : filters.include;
|
|
85
|
+
if (!target.includes(domain))
|
|
86
|
+
target.push(domain);
|
|
87
|
+
}
|
|
88
|
+
return filters;
|
|
89
|
+
}
|
|
90
|
+
function passesDomainFilters(url, filters) {
|
|
91
|
+
if (filters.include.length === 0 && filters.exclude.length === 0)
|
|
92
|
+
return true;
|
|
93
|
+
let hostname;
|
|
94
|
+
try {
|
|
95
|
+
hostname = new URL(url).hostname.toLowerCase();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
const matches = (domain) => hostname === domain || hostname.endsWith(`.${domain}`);
|
|
101
|
+
if (filters.exclude.some(matches))
|
|
102
|
+
return false;
|
|
103
|
+
return filters.include.length === 0 || filters.include.some(matches);
|
|
104
|
+
}
|
|
105
|
+
function buildQuery(query, filters) {
|
|
106
|
+
const parts = [query];
|
|
107
|
+
if (filters.include.length === 1)
|
|
108
|
+
parts.push(`site:${filters.include[0]}`);
|
|
109
|
+
if (filters.include.length > 1)
|
|
110
|
+
parts.push(`(${filters.include.map(domain => `site:${domain}`).join(" OR ")})`);
|
|
111
|
+
for (const domain of filters.exclude)
|
|
112
|
+
parts.push(`-site:${domain}`);
|
|
113
|
+
return parts.join(" ");
|
|
114
|
+
}
|
|
115
|
+
function errorMessage(err) {
|
|
116
|
+
return err instanceof Error ? err.message : String(err);
|
|
117
|
+
}
|
|
118
|
+
function invalidResponse(message) {
|
|
119
|
+
return new Error(`SerpApi returned invalid response: ${message}`);
|
|
120
|
+
}
|
|
121
|
+
function parseResponse(value) {
|
|
122
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
123
|
+
throw invalidResponse("expected an object envelope");
|
|
124
|
+
const envelope = value;
|
|
125
|
+
if (typeof envelope.error === "string" && envelope.error.trim())
|
|
126
|
+
throw invalidResponse(envelope.error.trim());
|
|
127
|
+
if (!Array.isArray(envelope.organic_results))
|
|
128
|
+
throw invalidResponse("expected organic_results array");
|
|
129
|
+
return envelope.organic_results;
|
|
130
|
+
}
|
|
131
|
+
function buildAnswer(results) {
|
|
132
|
+
return results.map((result) => result.snippet
|
|
133
|
+
? `${result.snippet}\nSource: ${result.title} (${result.url})`
|
|
134
|
+
: `Source: ${result.title} (${result.url})`).join("\n\n");
|
|
135
|
+
}
|
|
136
|
+
export function isSerpApiAvailable() {
|
|
137
|
+
return hasCredentialSource({ provider: "SerpApi", configuredValue: loadConfig().serpapiApiKey, environmentValue: process.env.SERPAPI_KEY });
|
|
138
|
+
}
|
|
139
|
+
export async function searchWithSerpApi(query, options = {}) {
|
|
140
|
+
const apiKey = await requireApiKey(options.signal);
|
|
141
|
+
const numResults = normalizeCount(options.numResults);
|
|
142
|
+
const filters = parseDomainFilter(options.domainFilter);
|
|
143
|
+
const requestCount = options.domainFilter?.length ? Math.min(20, numResults + 5) : numResults;
|
|
144
|
+
const url = new URL(SERPAPI_SEARCH_URL);
|
|
145
|
+
url.searchParams.set("engine", "google");
|
|
146
|
+
url.searchParams.set("q", buildQuery(query, filters));
|
|
147
|
+
url.searchParams.set("api_key", apiKey);
|
|
148
|
+
url.searchParams.set("num", String(requestCount));
|
|
149
|
+
if (options.recencyFilter)
|
|
150
|
+
url.searchParams.set("tbs", RECENCY_TBS[options.recencyFilter]);
|
|
151
|
+
const activityId = activityMonitor.logStart({ type: "api", query });
|
|
152
|
+
const timeoutSignal = AbortSignal.timeout(SEARCH_TIMEOUT_MS);
|
|
153
|
+
let response;
|
|
154
|
+
let entries;
|
|
155
|
+
try {
|
|
156
|
+
response = await fetch(url, {
|
|
157
|
+
headers: { Accept: "application/json" },
|
|
158
|
+
signal: options.signal ? AbortSignal.any([timeoutSignal, options.signal]) : timeoutSignal,
|
|
159
|
+
});
|
|
160
|
+
if (!response.ok) {
|
|
161
|
+
const errorText = await response.text();
|
|
162
|
+
throw new Error(`SerpApi error ${response.status}: ${redactCredential(errorText, apiKey).slice(0, 300)}`);
|
|
163
|
+
}
|
|
164
|
+
let rawData;
|
|
165
|
+
try {
|
|
166
|
+
rawData = await response.json();
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
if (err instanceof Error && err.name === "TimeoutError")
|
|
170
|
+
throw err;
|
|
171
|
+
throw new Error(`SerpApi returned invalid JSON: ${errorMessage(err)}`);
|
|
172
|
+
}
|
|
173
|
+
entries = parseResponse(rawData);
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
if (options.signal?.aborted) {
|
|
177
|
+
activityMonitor.logComplete(activityId, 0);
|
|
178
|
+
throw new Error("Aborted");
|
|
179
|
+
}
|
|
180
|
+
const message = errorMessage(err);
|
|
181
|
+
const providerTimeout = timeoutSignal.aborted || (err instanceof Error && err.name === "TimeoutError");
|
|
182
|
+
const outgoing = providerTimeout
|
|
183
|
+
? new Error(`SerpApi request timed out after ${Math.round(SEARCH_TIMEOUT_MS / 1000)}s`)
|
|
184
|
+
: (() => {
|
|
185
|
+
const redactedMessage = redactCredential(message, apiKey);
|
|
186
|
+
if (redactedMessage === message && err instanceof Error)
|
|
187
|
+
return err;
|
|
188
|
+
const redactedError = new Error(redactedMessage);
|
|
189
|
+
if (err instanceof Error)
|
|
190
|
+
redactedError.name = err.name;
|
|
191
|
+
return redactedError;
|
|
192
|
+
})();
|
|
193
|
+
activityMonitor.logError(activityId, redactCredential(errorMessage(outgoing), apiKey));
|
|
194
|
+
throw outgoing;
|
|
195
|
+
}
|
|
196
|
+
activityMonitor.logComplete(activityId, response.status);
|
|
197
|
+
const results = [];
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
if (!entry || typeof entry !== "object")
|
|
200
|
+
continue;
|
|
201
|
+
if (typeof entry.link !== "string" || !entry.link)
|
|
202
|
+
continue;
|
|
203
|
+
if (!passesDomainFilters(entry.link, filters))
|
|
204
|
+
continue;
|
|
205
|
+
results.push({
|
|
206
|
+
title: typeof entry.title === "string" && entry.title.trim() ? entry.title.trim() : `Source ${results.length + 1}`,
|
|
207
|
+
url: entry.link,
|
|
208
|
+
snippet: typeof entry.snippet === "string" ? entry.snippet : "",
|
|
209
|
+
});
|
|
210
|
+
if (results.length >= numResults)
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
return { answer: buildAnswer(results), results };
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=serpapi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serpapi.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/serpapi.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { activityMonitor } from \"./activity.ts\";\nimport type { SearchOptions, SearchResponse } from \"./perplexity.ts\";\nimport { hasCredentialSource, redactCredential, resolveCredential } from \"./credential-source.ts\";\nimport { getWebSearchConfigPath } from \"./utils.ts\";\n\nconst SERPAPI_SEARCH_URL = \"https://serpapi.com/search.json\";\nconst CONFIG_PATH = getWebSearchConfigPath();\nconst SEARCH_TIMEOUT_MS = 60_000;\nconst RECENCY_TBS: Record<NonNullable<SearchOptions[\"recencyFilter\"]>, string> = {\n\tday: \"qdr:d\",\n\tweek: \"qdr:w\",\n\tmonth: \"qdr:m\",\n\tyear: \"qdr:y\",\n};\n\ninterface WebSearchConfig {\n\tserpapiApiKey?: unknown;\n}\n\ninterface SerpApiOrganicResult {\n\ttitle?: unknown;\n\tlink?: unknown;\n\tsnippet?: unknown;\n}\n\nlet cachedConfig: WebSearchConfig | null = null;\n\nfunction loadConfig(): WebSearchConfig {\n\tif (cachedConfig) return cachedConfig;\n\tif (!existsSync(CONFIG_PATH)) {\n\t\tcachedConfig = {};\n\t\treturn cachedConfig;\n\t}\n\tconst raw = readFileSync(CONFIG_PATH, \"utf-8\");\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${CONFIG_PATH}: ${message}`);\n\t}\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`Invalid config in ${CONFIG_PATH}: expected a JSON object`);\n\t}\n\tcachedConfig = parsed as WebSearchConfig;\n\treturn cachedConfig;\n}\n\nasync function getApiKey(signal?: AbortSignal): Promise<string | null> {\n\treturn resolveCredential({\n\t\tprovider: \"SerpApi\",\n\t\tconfiguredValue: loadConfig().serpapiApiKey,\n\t\tenvironmentValue: process.env.SERPAPI_KEY,\n\t\tsignal,\n\t});\n}\n\nasync function requireApiKey(signal?: AbortSignal): Promise<string> {\n\tconst apiKey = await getApiKey(signal);\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t\"SerpApi API key not found. Either:\\n\" +\n\t\t\t` 1. Create ${CONFIG_PATH} with { \"serpapiApiKey\": \"your-key\" }\\n` +\n\t\t\t\" 2. Set SERPAPI_KEY environment variable\\n\" +\n\t\t\t\"Get a key at https://serpapi.com/manage-api-key\",\n\t\t);\n\t}\n\treturn apiKey;\n}\n\nfunction normalizeCount(value: number | undefined): number {\n\tif (typeof value !== \"number\" || !Number.isFinite(value)) return 5;\n\treturn Math.max(1, Math.min(Math.floor(value), 20));\n}\n\ninterface DomainFilters {\n\tinclude: string[];\n\texclude: string[];\n}\n\nfunction normalizeDomain(value: string): string | null {\n\tlet input = value.trim().toLowerCase();\n\tif (!input) return null;\n\tif (input.startsWith(\"-\")) input = input.slice(1).trim();\n\tif (!input) return null;\n\ttry {\n\t\tconst parsed = input.includes(\"://\") ? new URL(input) : new URL(`https://${input}`);\n\t\tinput = parsed.hostname;\n\t} catch {\n\t\tinput = input.split(\"/\")[0]?.split(\":\")[0] ?? \"\";\n\t}\n\tinput = input.replace(/^\\.+|\\.+$/g, \"\");\n\treturn /^[a-z0-9][a-z0-9.-]*\\.[a-z]{2,}$/i.test(input) ? input : null;\n}\n\nfunction parseDomainFilter(domainFilter: string[] | undefined): DomainFilters {\n\tconst filters: DomainFilters = { include: [], exclude: [] };\n\tfor (const raw of domainFilter ?? []) {\n\t\tconst domain = normalizeDomain(raw);\n\t\tif (!domain) continue;\n\t\tconst target = raw.trim().startsWith(\"-\") ? filters.exclude : filters.include;\n\t\tif (!target.includes(domain)) target.push(domain);\n\t}\n\treturn filters;\n}\n\nfunction passesDomainFilters(url: string, filters: DomainFilters): boolean {\n\tif (filters.include.length === 0 && filters.exclude.length === 0) return true;\n\tlet hostname: string;\n\ttry {\n\t\thostname = new URL(url).hostname.toLowerCase();\n\t} catch {\n\t\treturn false;\n\t}\n\tconst matches = (domain: string) => hostname === domain || hostname.endsWith(`.${domain}`);\n\tif (filters.exclude.some(matches)) return false;\n\treturn filters.include.length === 0 || filters.include.some(matches);\n}\n\nfunction buildQuery(query: string, filters: DomainFilters): string {\n\tconst parts = [query];\n\tif (filters.include.length === 1) parts.push(`site:${filters.include[0]}`);\n\tif (filters.include.length > 1) parts.push(`(${filters.include.map(domain => `site:${domain}`).join(\" OR \")})`);\n\tfor (const domain of filters.exclude) parts.push(`-site:${domain}`);\n\treturn parts.join(\" \");\n}\n\nfunction errorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n\nfunction invalidResponse(message: string): Error {\n\treturn new Error(`SerpApi returned invalid response: ${message}`);\n}\n\nfunction parseResponse(value: unknown): SerpApiOrganicResult[] {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) throw invalidResponse(\"expected an object envelope\");\n\tconst envelope = value as Record<string, unknown>;\n\tif (typeof envelope.error === \"string\" && envelope.error.trim()) throw invalidResponse(envelope.error.trim());\n\tif (!Array.isArray(envelope.organic_results)) throw invalidResponse(\"expected organic_results array\");\n\treturn envelope.organic_results as SerpApiOrganicResult[];\n}\n\nfunction buildAnswer(results: SearchResponse[\"results\"]): string {\n\treturn results.map((result) => result.snippet\n\t\t? `${result.snippet}\\nSource: ${result.title} (${result.url})`\n\t\t: `Source: ${result.title} (${result.url})`).join(\"\\n\\n\");\n}\n\nexport function isSerpApiAvailable(): boolean {\n\treturn hasCredentialSource({ provider: \"SerpApi\", configuredValue: loadConfig().serpapiApiKey, environmentValue: process.env.SERPAPI_KEY });\n}\n\nexport async function searchWithSerpApi(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst apiKey = await requireApiKey(options.signal);\n\tconst numResults = normalizeCount(options.numResults);\n\tconst filters = parseDomainFilter(options.domainFilter);\n\tconst requestCount = options.domainFilter?.length ? Math.min(20, numResults + 5) : numResults;\n\tconst url = new URL(SERPAPI_SEARCH_URL);\n\turl.searchParams.set(\"engine\", \"google\");\n\turl.searchParams.set(\"q\", buildQuery(query, filters));\n\turl.searchParams.set(\"api_key\", apiKey);\n\turl.searchParams.set(\"num\", String(requestCount));\n\tif (options.recencyFilter) url.searchParams.set(\"tbs\", RECENCY_TBS[options.recencyFilter]);\n\tconst activityId = activityMonitor.logStart({ type: \"api\", query });\n\tconst timeoutSignal = AbortSignal.timeout(SEARCH_TIMEOUT_MS);\n\tlet response: Response;\n\tlet entries: SerpApiOrganicResult[];\n\ttry {\n\t\tresponse = await fetch(url, {\n\t\t\theaders: { Accept: \"application/json\" },\n\t\t\tsignal: options.signal ? AbortSignal.any([timeoutSignal, options.signal]) : timeoutSignal,\n\t\t});\n\t\tif (!response.ok) {\n\t\t\tconst errorText = await response.text();\n\t\t\tthrow new Error(`SerpApi error ${response.status}: ${redactCredential(errorText, apiKey).slice(0, 300)}`);\n\t\t}\n\t\tlet rawData: unknown;\n\t\ttry {\n\t\t\trawData = await response.json();\n\t\t} catch (err) {\n\t\t\tif (err instanceof Error && err.name === \"TimeoutError\") throw err;\n\t\t\tthrow new Error(`SerpApi returned invalid JSON: ${errorMessage(err)}`);\n\t\t}\n\t\tentries = parseResponse(rawData);\n\t} catch (err) {\n\t\tif (options.signal?.aborted) {\n\t\t\tactivityMonitor.logComplete(activityId, 0);\n\t\t\tthrow new Error(\"Aborted\");\n\t\t}\n\t\tconst message = errorMessage(err);\n\t\tconst providerTimeout = timeoutSignal.aborted || (err instanceof Error && err.name === \"TimeoutError\");\n\t\tconst outgoing = providerTimeout\n\t\t\t? new Error(`SerpApi request timed out after ${Math.round(SEARCH_TIMEOUT_MS / 1000)}s`)\n\t\t\t: (() => {\n\t\t\t\tconst redactedMessage = redactCredential(message, apiKey);\n\t\t\t\tif (redactedMessage === message && err instanceof Error) return err;\n\t\t\t\tconst redactedError = new Error(redactedMessage);\n\t\t\t\tif (err instanceof Error) redactedError.name = err.name;\n\t\t\t\treturn redactedError;\n\t\t\t})();\n\t\tactivityMonitor.logError(activityId, redactCredential(errorMessage(outgoing), apiKey));\n\t\tthrow outgoing;\n\t}\n\tactivityMonitor.logComplete(activityId, response.status);\n\tconst results: SearchResponse[\"results\"] = [];\n\tfor (const entry of entries) {\n\t\tif (!entry || typeof entry !== \"object\") continue;\n\t\tif (typeof entry.link !== \"string\" || !entry.link) continue;\n\t\tif (!passesDomainFilters(entry.link, filters)) continue;\n\t\tresults.push({\n\t\t\ttitle: typeof entry.title === \"string\" && entry.title.trim() ? entry.title.trim() : `Source ${results.length + 1}`,\n\t\t\turl: entry.link,\n\t\t\tsnippet: typeof entry.snippet === \"string\" ? entry.snippet : \"\",\n\t\t});\n\t\tif (results.length >= numResults) break;\n\t}\n\treturn { answer: buildAnswer(results), results };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf-protection.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ssrf-protection.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAChE,MAAM,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AACpE,KAAK,KAAK,GAAG,OAAO,KAAK,CAAC;AA2C1B,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAID,wBAAgB,4BAA4B,IAAI,YAAY,CAkB3D;AA2BD,wBAAgB,cAAc,IAAI,UAAU,CAwB3C;AAED,UAAU,iBAAiB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,UAAU,uBAAuB;IAChC,IAAI,EAAE,GAAG,CAAC;IACV,EAAE,EAAE,GAAG,CAAC;IACR,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACnB;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACrD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,WAAW,CAAC;CAC5D;AAMD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,CA0C3G;AAED,wBAAsB,cAAc,CACnC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"ssrf-protection.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ssrf-protection.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,aAAa,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAChE,MAAM,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;AACpE,KAAK,KAAK,GAAG,OAAO,KAAK,CAAC;AA2C1B,MAAM,WAAW,UAAU;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAID,wBAAgB,4BAA4B,IAAI,YAAY,CAkB3D;AA2BD,wBAAgB,cAAc,IAAI,UAAU,CAwB3C;AAED,UAAU,iBAAiB;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qFAAqF;IACrF,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,UAAU,uBAAuB;IAChC,IAAI,EAAE,GAAG,CAAC;IACV,EAAE,EAAE,GAAG,CAAC;IACR,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;CACnB;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACrD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,WAAW,CAAC;CAC5D;AAMD,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,CA0C3G;AAED,wBAAsB,cAAc,CACnC,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,GAAE,WAAgB,EACtB,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,QAAQ,CAAC,CA4BnB"}
|
|
@@ -169,6 +169,7 @@ export async function fetchRemoteUrl(url, init = {}, options = {}) {
|
|
|
169
169
|
const fetchImpl = options.fetch ?? fetch;
|
|
170
170
|
const maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;
|
|
171
171
|
let current = await validateRemoteUrl(url, options);
|
|
172
|
+
const configuredOrigin = current.origin;
|
|
172
173
|
let requestInit = init;
|
|
173
174
|
for (let redirects = 0; redirects <= maxRedirects; redirects++) {
|
|
174
175
|
const response = await fetchImpl(current, { ...requestInit, redirect: "manual" });
|
|
@@ -180,7 +181,10 @@ export async function fetchRemoteUrl(url, init = {}, options = {}) {
|
|
|
180
181
|
if (redirects === maxRedirects)
|
|
181
182
|
throw new Error(`Too many redirects fetching ${current.toString()}`);
|
|
182
183
|
const from = current;
|
|
183
|
-
|
|
184
|
+
const next = new URL(location, current);
|
|
185
|
+
// allowLoopback exempts an explicitly configured endpoint, never a redirect target: a loopback
|
|
186
|
+
// base must not be able to pivot the request onto a different loopback origin.
|
|
187
|
+
current = await validateRemoteUrl(next, next.origin === configuredOrigin ? options : { ...options, allowLoopback: false });
|
|
184
188
|
if (response.status === 303 || ((response.status === 301 || response.status === 302) && requestInit.method?.toUpperCase() === "POST")) {
|
|
185
189
|
const { body: _body, ...nextInit } = requestInit;
|
|
186
190
|
requestInit = { ...nextInit, method: "GET" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssrf-protection.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ssrf-protection.ts"],"names":[],"mappings":"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","sourcesContent":["import { lookup as dnsLookup } from \"node:dns/promises\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { getActiveProxy, getWebSearchConfigPath, hasScopedProxyDecision, isProxyBypassedUrl } from \"./utils.ts\";\n\nconst DEFAULT_MAX_REDIRECTS = 5;\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\nconst LOOPBACK_ALLOW_RANGES = [\"127.0.0.0/8\", \"::1\", \"::ffff:127.0.0.0/104\"];\n\nexport type LookupAddress = { address: string; family: number };\nexport type Lookup = (hostname: string) => Promise<LookupAddress[]>;\ntype Fetch = typeof fetch;\n\nconst WEB_SEARCH_CONFIG_PATH = getWebSearchConfigPath();\n\nlet cachedConfigRoot: { signature: string; value: Record<string, unknown> | null } | null = null;\n\nfunction loadConfigRoot(): Record<string, unknown> | null {\n\tif (!existsSync(WEB_SEARCH_CONFIG_PATH)) return null;\n\n\tlet signature: string;\n\ttry {\n\t\tconst stat = statSync(WEB_SEARCH_CONFIG_PATH);\n\t\tsignature = `${stat.mtimeMs}:${stat.size}`;\n\t} catch {\n\t\treturn null;\n\t}\n\n\tif (cachedConfigRoot?.signature === signature) return cachedConfigRoot.value;\n\n\tlet raw: string;\n\ttry {\n\t\traw = readFileSync(WEB_SEARCH_CONFIG_PATH, \"utf-8\");\n\t} catch {\n\t\t// Do not memoize read failures: a chmod fix changes neither mtime nor size,\n\t\t// so a cached failure would permanently fail-open the domain policy.\n\t\treturn null;\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${WEB_SEARCH_CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst value = parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n\t\t? parsed as Record<string, unknown>\n\t\t: null;\n\tcachedConfigRoot = { signature, value };\n\treturn value;\n}\n\nexport interface SsrfConfig {\n\tallowRanges: string[];\n\ttrustEnvProxy: boolean;\n}\n\nexport interface DomainPolicy {\n\tallow: string[];\n\tdeny: string[];\n}\n\nconst DEFAULT_DOMAIN_POLICY: DomainPolicy = { allow: [], deny: [] };\n\nexport function loadFetchContentDomainPolicy(): DomainPolicy {\n\tconst parsed = loadConfigRoot();\n\tif (!parsed) return { ...DEFAULT_DOMAIN_POLICY };\n\tconst fetchContent = parsed.fetchContent;\n\tif (fetchContent === undefined || fetchContent === null) return { ...DEFAULT_DOMAIN_POLICY };\n\tif (typeof fetchContent !== \"object\" || Array.isArray(fetchContent)) {\n\t\tthrow new Error(`fetchContent in ${WEB_SEARCH_CONFIG_PATH} must be an object`);\n\t}\n\tconst policy = (fetchContent as { domainPolicy?: unknown }).domainPolicy;\n\tif (policy === undefined || policy === null) return { ...DEFAULT_DOMAIN_POLICY };\n\tif (typeof policy !== \"object\" || Array.isArray(policy)) {\n\t\tthrow new Error(`fetchContent.domainPolicy in ${WEB_SEARCH_CONFIG_PATH} must be an object`);\n\t}\n\tconst config = policy as { allow?: unknown; deny?: unknown };\n\treturn {\n\t\tallow: parseDomainEntries(config.allow, \"allow\"),\n\t\tdeny: parseDomainEntries(config.deny, \"deny\"),\n\t};\n}\n\nfunction parseDomainEntries(value: unknown, field: \"allow\" | \"deny\"): string[] {\n\tif (value === undefined || value === null) return [];\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`fetchContent.domainPolicy.${field} in ${WEB_SEARCH_CONFIG_PATH} must be an array of hostnames`);\n\t}\n\treturn value.map((entry, index) => {\n\t\tif (typeof entry !== \"string\") {\n\t\t\tthrow new Error(`fetchContent.domainPolicy.${field} in ${WEB_SEARCH_CONFIG_PATH} must contain only hostnames; entry ${index + 1} is ${typeof entry}`);\n\t\t}\n\t\tconst hostname = normalizeDomainEntry(entry);\n\t\tif (!hostname) {\n\t\t\tthrow new Error(`fetchContent.domainPolicy.${field} in ${WEB_SEARCH_CONFIG_PATH} contains an invalid hostname: ${JSON.stringify(entry)}`);\n\t\t}\n\t\treturn hostname;\n\t});\n}\n\nfunction normalizeDomainEntry(entry: string): string | null {\n\tconst hostname = normalizeHostname(entry.trim());\n\tif (!hostname || /\\s|[\\\\/?:#@]/.test(hostname)) return null;\n\tif (net.isIP(hostname)) return hostname;\n\tif (hostname.length > 253 || !/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(hostname)) return null;\n\treturn hostname;\n}\n\nexport function loadSsrfConfig(): SsrfConfig {\n\tconst parsed = loadConfigRoot();\n\tif (!parsed) return { allowRanges: [], trustEnvProxy: false };\n\tconst ssrf = parsed.ssrf;\n\tif (ssrf === undefined || ssrf === null) return { allowRanges: [], trustEnvProxy: false };\n\tif (typeof ssrf !== \"object\" || Array.isArray(ssrf)) {\n\t\tthrow new Error(`ssrf in ${WEB_SEARCH_CONFIG_PATH} must be an object`);\n\t}\n\tconst config = ssrf as { allowRanges?: unknown; trustEnvProxy?: unknown };\n\tif (config.allowRanges !== undefined && config.allowRanges !== null && !Array.isArray(config.allowRanges)) {\n\t\tthrow new Error(`ssrf.allowRanges in ${WEB_SEARCH_CONFIG_PATH} must be an array of CIDR strings`);\n\t}\n\tif (config.trustEnvProxy !== undefined && typeof config.trustEnvProxy !== \"boolean\") {\n\t\tthrow new Error(`ssrf.trustEnvProxy in ${WEB_SEARCH_CONFIG_PATH} must be a boolean`);\n\t}\n\tconst allowRangesValue: unknown[] = Array.isArray(config.allowRanges) ? config.allowRanges : [];\n\tconst allowRanges = allowRangesValue.map((entry, index) => {\n\t\tif (typeof entry !== \"string\") {\n\t\t\tthrow new Error(`ssrf.allowRanges in ${WEB_SEARCH_CONFIG_PATH} must contain only CIDR strings; entry ${index + 1} is ${typeof entry}`);\n\t\t}\n\t\treturn entry.trim();\n\t}).filter(Boolean);\n\tparseAllowRanges(allowRanges);\n\treturn { allowRanges, trustEnvProxy: config.trustEnvProxy === true };\n}\n\ninterface ValidationOptions {\n\tlookup?: Lookup;\n\t/** Optional hostname policy for fetch_content target URLs. */\n\tdomainPolicy?: DomainPolicy;\n\t/**\n\t * CIDR ranges (e.g. \"198.18.0.0/15\") to exempt from the SSRF guard.\n\t * Useful when a host runs a TUN/fake-IP proxy (Surge, Clash, Mihomo, ...)\n\t * that resolves public domains into a reserved range. Entries are validated\n\t * strictly; an invalid entry throws so misconfiguration is not silent.\n\t */\n\tallowRanges?: string[];\n\t/**\n\t * When true, trust an explicitly-configured HTTP(S) proxy for hostname\n\t * resolution instead of performing local DNS lookups inside the sandbox.\n\t * Literal IPs and localhost remain blocked, and NO_PROXY hosts still use\n\t * the local SSRF preflight. This does not configure proxy transport.\n\t */\n\ttrustEnvProxy?: boolean;\n\t/** Allow loopback URLs for explicit provider base endpoints, not fetched targets. */\n\tallowLoopback?: boolean;\n}\n\n/** Parsed entry from `allowRanges`: a network address (4 or 16 bytes) + prefix length. */\ninterface ParsedCidr {\n\tbytes: Uint8Array;\n\tprefix: number;\n}\n\ninterface RedirectRequestInitArgs {\n\tfrom: URL;\n\tto: URL;\n\tinit: RequestInit;\n\tresponse: Response;\n}\n\ninterface FetchRemoteOptions extends ValidationOptions {\n\tfetch?: Fetch;\n\tmaxRedirects?: number;\n\tonRedirect?: (args: RedirectRequestInitArgs) => RequestInit;\n}\n\nasync function defaultLookup(hostname: string): Promise<LookupAddress[]> {\n\treturn dnsLookup(hostname, { all: true, verbatim: true });\n}\n\nexport async function validateRemoteUrl(rawUrl: string | URL, options: ValidationOptions = {}): Promise<URL> {\n\tconst url = rawUrl instanceof URL ? rawUrl : new URL(rawUrl);\n\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n\t\tthrow new Error(\"Only HTTP and HTTPS URLs can be fetched remotely\");\n\t}\n\n\tconst hostname = normalizeHostname(url.hostname);\n\tif (!hostname) throw new Error(\"URL must include a hostname\");\n\tif (hostname === \"localhost\") {\n\t\tif (options.allowLoopback === true) return url;\n\t\tthrow new Error(`Blocked internal hostname: ${hostname}`);\n\t}\n\tif (hostname.endsWith(\".localhost\")) {\n\t\tthrow new Error(`Blocked internal hostname: ${hostname}`);\n\t}\n\n\tconst allowRanges = parseAllowRanges(options.allowRanges);\n\tassertDomainPolicy(hostname, options.domainPolicy);\n\n\tif (net.isIP(hostname)) {\n\t\tconst addressAllowRanges = options.allowLoopback === true\n\t\t\t? [...allowRanges, ...parseAllowRanges(LOOPBACK_ALLOW_RANGES)]\n\t\t\t: allowRanges;\n\t\tassertPublicAddress(hostname, hostname, addressAllowRanges);\n\t\treturn url;\n\t}\n\n\tif (shouldTrustEnvProxy(url, options.trustEnvProxy === true)) return url;\n\n\tlet addresses: LookupAddress[];\n\ttry {\n\t\taddresses = await (options.lookup ?? defaultLookup)(hostname);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to resolve ${hostname}: ${message}`);\n\t}\n\n\tif (addresses.length === 0) throw new Error(`Failed to resolve ${hostname}: no addresses returned`);\n\tfor (const { address } of addresses) {\n\t\tassertPublicAddress(address, hostname, allowRanges);\n\t}\n\treturn url;\n}\n\nexport async function fetchRemoteUrl(\n\turl: string | URL,\n\tinit: RequestInit = {},\n\toptions: FetchRemoteOptions = {},\n): Promise<Response> {\n\tconst fetchImpl = options.fetch ?? fetch;\n\tconst maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;\n\tlet current = await validateRemoteUrl(url, options);\n\tlet requestInit = init;\n\n\tfor (let redirects = 0; redirects <= maxRedirects; redirects++) {\n\t\tconst response = await fetchImpl(current, { ...requestInit, redirect: \"manual\" });\n\t\tif (!REDIRECT_STATUSES.has(response.status)) return response;\n\n\t\tconst location = response.headers.get(\"location\");\n\t\tif (!location) return response;\n\t\tif (redirects === maxRedirects) throw new Error(`Too many redirects fetching ${current.toString()}`);\n\n\t\tconst from = current;\n\t\tcurrent = await validateRemoteUrl(new URL(location, current), options);\n\t\tif (response.status === 303 || ((response.status === 301 || response.status === 302) && requestInit.method?.toUpperCase() === \"POST\")) {\n\t\t\tconst { body: _body, ...nextInit } = requestInit;\n\t\t\trequestInit = { ...nextInit, method: \"GET\" };\n\t\t}\n\t\tif (options.onRedirect) requestInit = options.onRedirect({ from, to: current, init: requestInit, response });\n\t}\n\n\tthrow new Error(`Too many redirects fetching ${current.toString()}`);\n}\n\nfunction normalizeHostname(hostname: string): string {\n\treturn hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\").replace(/\\.$/, \"\");\n}\n\nfunction assertDomainPolicy(hostname: string, policy?: DomainPolicy): void {\n\tif (!policy) return;\n\tif (policy.deny.some((entry) => domainMatches(hostname, entry))) {\n\t\tthrow new Error(`Blocked hostname by fetch_content domain policy: ${hostname}`);\n\t}\n\tif (policy.allow.length > 0 && !policy.allow.some((entry) => domainMatches(hostname, entry))) {\n\t\tthrow new Error(`Hostname not allowed by fetch_content domain policy: ${hostname}`);\n\t}\n}\n\nfunction domainMatches(hostname: string, entry: string): boolean {\n\treturn hostname === entry || hostname.endsWith(`.${entry}`);\n}\n\nfunction getProxyForProtocol(protocol: string): string {\n\tconst candidates = protocol === \"http:\"\n\t\t? [process.env.HTTP_PROXY, process.env.http_proxy, process.env.ALL_PROXY, process.env.all_proxy]\n\t\t: protocol === \"https:\"\n\t\t\t? [process.env.HTTPS_PROXY, process.env.https_proxy, process.env.HTTP_PROXY, process.env.http_proxy, process.env.ALL_PROXY, process.env.all_proxy]\n\t\t\t: [];\n\tfor (const candidate of candidates) {\n\t\tconst value = candidate?.trim();\n\t\tif (!value) continue;\n\t\ttry {\n\t\t\tconst proxyUrl = new URL(value);\n\t\t\tif ((proxyUrl.protocol === \"http:\" || proxyUrl.protocol === \"https:\") && proxyUrl.hostname) return value;\n\t\t} catch {\n\t\t\t// Invalid proxy env vars should not weaken local DNS SSRF checks.\n\t\t}\n\t}\n\treturn \"\";\n}\n\nfunction hostnameMatchesNoProxy(hostname: string, port: string, entry: string): boolean {\n\tconst trimmed = entry.trim();\n\tif (!trimmed) return false;\n\tif (trimmed === \"*\") return true;\n\n\t// NO_PROXY entries may include a port. Strip it only after handling\n\t// bracketed IPv6 literals, which can contain several colons.\n\tlet hostEntry = trimmed;\n\tlet entryPort: string | undefined;\n\tif (hostEntry.startsWith(\"[\")) {\n\t\tconst closingBracket = hostEntry.indexOf(\"]\");\n\t\tif (closingBracket >= 0) {\n\t\t\tconst suffix = hostEntry.slice(closingBracket + 1);\n\t\t\tif (/^:\\\\d+$/.test(suffix)) entryPort = suffix.slice(1);\n\t\t\thostEntry = hostEntry.slice(0, closingBracket + 1);\n\t\t}\n\t} else {\n\t\tconst colon = hostEntry.lastIndexOf(\":\");\n\t\tif (colon > -1 && /^\\d+$/.test(hostEntry.slice(colon + 1))) {\n\t\t\tentryPort = hostEntry.slice(colon + 1);\n\t\t\thostEntry = hostEntry.slice(0, colon);\n\t\t}\n\t}\n\tif (entryPort !== undefined && entryPort !== port) return false;\n\n\tconst normalizedEntry = normalizeHostname(hostEntry);\n\tif (!normalizedEntry) return false;\n\tif (normalizedEntry === hostname) return true;\n\tconst suffix = normalizedEntry.startsWith(\"*.\")\n\t\t? normalizedEntry.slice(1)\n\t\t: normalizedEntry.startsWith(\".\")\n\t\t\t? normalizedEntry\n\t\t\t: `.${normalizedEntry}`;\n\treturn hostname.endsWith(suffix);\n}\n\nfunction shouldTrustEnvProxy(url: URL, enabled: boolean): boolean {\n\tif (!enabled || !getProxyForProtocol(url.protocol)) return false;\n\tif (hasScopedProxyDecision()) return false;\n\tconst activeProxy = getActiveProxy();\n\tif (activeProxy && !isProxyBypassedUrl(url)) return false;\n\tconst hostname = normalizeHostname(url.hostname);\n\tconst port = url.port || (url.protocol === \"https:\" ? \"443\" : \"80\");\n\tconst noProxy = process.env.NO_PROXY || process.env.no_proxy || \"\";\n\treturn !noProxy.split(\",\").some(entry => hostnameMatchesNoProxy(hostname, port, entry));\n}\n\nfunction assertPublicAddress(address: string, hostname: string, allowRanges: ParsedCidr[] = []): void {\n\tconst normalized = normalizeHostname(address);\n\tconst ipVersion = net.isIP(normalized);\n\tif (ipVersion === 0) throw new Error(`Resolved non-IP address for ${hostname}: ${address}`);\n\t// Explicitly-allowed ranges bypass the private/reserved checks below. This lets\n\t// users exempt synthetic ranges produced by TUN/fake-IP proxies (e.g. 198.18/15).\n\tif (isInAllowedRange(normalized, ipVersion, allowRanges)) return;\n\tif (ipVersion === 4 && isBlockedIPv4(normalized)) {\n\t\tconst hint = isFakeIpProxyAddress(normalized)\n\t\t\t? '. This address is in 198.18.0.0/15, commonly used by TUN/fake-IP proxies. If that matches your setup, configure ssrf.allowRanges with [\"198.18.0.0/15\"] in web-search.json.'\n\t\t\t: \"\";\n\t\tthrow new Error(`Blocked internal address for ${hostname}: ${normalized}${hint}`);\n\t}\n\tif (ipVersion === 6 && isBlockedIPv6(normalized)) {\n\t\tthrow new Error(`Blocked internal address for ${hostname}: ${normalized}`);\n\t}\n}\n\nfunction isFakeIpProxyAddress(address: string): boolean {\n\tconst [a, b] = address.split(\".\").map(part => Number(part));\n\treturn a === 198 && (b === 18 || b === 19);\n}\n\nfunction isBlockedIPv4(address: string): boolean {\n\tconst parts = address.split(\".\").map(part => Number(part));\n\tif (parts.length !== 4 || parts.some(part => !Number.isInteger(part) || part < 0 || part > 255)) return true;\n\tconst [a, b] = parts;\n\treturn a === 0 ||\n\t\ta === 10 ||\n\t\ta === 127 ||\n\t\t(a === 100 && b >= 64 && b <= 127) ||\n\t\t(a === 169 && b === 254) ||\n\t\t(a === 172 && b >= 16 && b <= 31) ||\n\t\t(a === 192 && b === 168) ||\n\t\tisFakeIpProxyAddress(address) ||\n\t\ta >= 224;\n}\n\nfunction isBlockedIPv6(address: string): boolean {\n\tconst groups = parseIPv6(address);\n\tif (!groups) return true;\n\n\tconst first = groups[0];\n\tif (groups.every(group => group === 0)) return true;\n\tif (groups.slice(0, 7).every(group => group === 0) && groups[7] === 1) return true;\n\tif ((first & 0xfe00) === 0xfc00) return true;\n\tif ((first & 0xffc0) === 0xfe80) return true;\n\n\tconst isMappedIPv4 = groups.slice(0, 5).every(group => group === 0) && groups[5] === 0xffff;\n\tif (isMappedIPv4) {\n\t\tconst ipv4 = [groups[6] >> 8, groups[6] & 0xff, groups[7] >> 8, groups[7] & 0xff].join(\".\");\n\t\treturn isBlockedIPv4(ipv4);\n\t}\n\n\treturn false;\n}\n\nfunction parseIPv6(address: string): number[] | null {\n\tif (address.includes(\".\")) {\n\t\tconst lastColon = address.lastIndexOf(\":\");\n\t\tconst ipv4 = address.slice(lastColon + 1);\n\t\tif (net.isIP(ipv4) !== 4) return null;\n\t\tconst octets = ipv4.split(\".\").map(part => Number(part));\n\t\taddress = `${address.slice(0, lastColon)}:${((octets[0] << 8) | octets[1]).toString(16)}:${((octets[2] << 8) | octets[3]).toString(16)}`;\n\t}\n\n\tconst pieces = address.split(\"::\");\n\tif (pieces.length > 2) return null;\n\n\tconst left = pieces[0] ? pieces[0].split(\":\") : [];\n\tconst right = pieces.length === 2 && pieces[1] ? pieces[1].split(\":\") : [];\n\tconst missing = 8 - left.length - right.length;\n\tif (pieces.length === 1 && missing !== 0) return null;\n\tif (pieces.length === 2 && missing < 0) return null;\n\n\tconst groups = [...left, ...Array(missing).fill(\"0\"), ...right].map(part => {\n\t\tif (!/^[0-9a-f]{1,4}$/i.test(part)) return -1;\n\t\treturn parseInt(part, 16);\n\t});\n\treturn groups.length === 8 && groups.every(group => group >= 0 && group <= 0xffff) ? groups : null;\n}\n\n/** Parse `allowRanges` config value into validated CIDR rules. Throws on malformed entries. */\nfunction parseAllowRanges(input: unknown): ParsedCidr[] {\n\tif (input === undefined || input === null) return [];\n\tif (!Array.isArray(input)) {\n\t\tthrow new Error(\"ssrf.allowRanges must be an array of CIDR strings\");\n\t}\n\tconst rules: ParsedCidr[] = [];\n\tfor (const entry of input) {\n\t\tif (typeof entry !== \"string\") {\n\t\t\tthrow new Error(`ssrf.allowRanges entries must be strings, got ${typeof entry}`);\n\t\t}\n\t\tconst rule = parseCidr(entry.trim());\n\t\tif (!rule) {\n\t\t\tthrow new Error(`Invalid CIDR notation in ssrf.allowRanges: \"${entry}\"`);\n\t\t}\n\t\trules.push(rule);\n\t}\n\treturn rules;\n}\n\n/** Parse a single CIDR (e.g. \"198.18.0.0/15\", \"fd00::/8\") or bare host (\"1.2.3.4\"). Returns null if invalid. */\nfunction parseCidr(raw: string): ParsedCidr | null {\n\tif (!raw) return null;\n\tconst slash = raw.lastIndexOf(\"/\");\n\tconst addrPart = slash >= 0 ? raw.slice(0, slash) : raw;\n\tconst prefixPart = slash >= 0 ? raw.slice(slash + 1) : null;\n\t// A slash must be followed by digits. Number(\"\")/Number(\" \") are 0, which\n\t// would silently turn \"198.18.0.0/\" into /0 and exempt every address.\n\tif (prefixPart !== null && !/^\\d+$/.test(prefixPart)) return null;\n\tconst version = net.isIP(addrPart);\n\n\tif (version === 4) {\n\t\tconst bytes = ipv4ToBytes(addrPart);\n\t\tif (!bytes) return null;\n\t\tconst prefix = prefixPart === null ? 32 : Number(prefixPart);\n\t\tif (!Number.isInteger(prefix) || prefix < 1 || prefix > 32) return null;\n\t\treturn { bytes, prefix };\n\t}\n\tif (version === 6) {\n\t\tconst groups = parseIPv6(addrPart);\n\t\tif (!groups) return null;\n\t\tconst prefix = prefixPart === null ? 128 : Number(prefixPart);\n\t\tif (!Number.isInteger(prefix) || prefix < 1 || prefix > 128) return null;\n\t\treturn { bytes: ipv6GroupsToBytes(groups), prefix };\n\t}\n\treturn null;\n}\n\nfunction ipv4ToBytes(address: string): Uint8Array | null {\n\tconst parts = address.split(\".\");\n\tif (parts.length !== 4) return null;\n\tconst bytes = new Uint8Array(4);\n\tfor (let i = 0; i < 4; i++) {\n\t\tconst octet = Number(parts[i]);\n\t\tif (!Number.isInteger(octet) || octet < 0 || octet > 255) return null;\n\t\tbytes[i] = octet;\n\t}\n\treturn bytes;\n}\n\nfunction ipv6GroupsToBytes(groups: number[]): Uint8Array {\n\tconst bytes = new Uint8Array(16);\n\tfor (let i = 0; i < 8; i++) {\n\t\tbytes[i * 2] = groups[i] >> 8;\n\t\tbytes[i * 2 + 1] = groups[i] & 0xff;\n\t}\n\treturn bytes;\n}\n\nfunction ipToBytes(address: string, version: number): Uint8Array | null {\n\tif (version === 4) return ipv4ToBytes(address);\n\tif (version === 6) {\n\t\tconst groups = parseIPv6(address);\n\t\treturn groups ? ipv6GroupsToBytes(groups) : null;\n\t}\n\treturn null;\n}\n\n/** True if `address` (already validated as `ipVersion`) falls within any allowed CIDR. */\nfunction isInAllowedRange(address: string, ipVersion: number, allowRanges: ParsedCidr[]): boolean {\n\tif (allowRanges.length === 0) return false;\n\tconst addrBytes = ipToBytes(address, ipVersion);\n\tif (!addrBytes) return false;\n\tfor (const rule of allowRanges) {\n\t\t// Only compare same-family rules (4-byte IPv4 vs 16-byte IPv6).\n\t\tif (rule.bytes.length !== addrBytes.length) continue;\n\t\tif (bytesMatchPrefix(addrBytes, rule.bytes, rule.prefix)) return true;\n\t}\n\treturn false;\n}\n\n/** Compare the leading `prefix` bits of two equal-length byte arrays. */\nfunction bytesMatchPrefix(addr: Uint8Array, network: Uint8Array, prefix: number): boolean {\n\tconst fullBytes = prefix >> 3;\n\tconst remBits = prefix & 7;\n\tfor (let i = 0; i < fullBytes; i++) {\n\t\tif (addr[i] !== network[i]) return false;\n\t}\n\tif (remBits > 0 && fullBytes < addr.length) {\n\t\tconst mask = (0xff << (8 - remBits)) & 0xff;\n\t\tif ((addr[fullBytes] & mask) !== (network[fullBytes] & mask)) return false;\n\t}\n\treturn true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ssrf-protection.js","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/ssrf-protection.ts"],"names":[],"mappings":"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","sourcesContent":["import { lookup as dnsLookup } from \"node:dns/promises\";\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { getActiveProxy, getWebSearchConfigPath, hasScopedProxyDecision, isProxyBypassedUrl } from \"./utils.ts\";\n\nconst DEFAULT_MAX_REDIRECTS = 5;\nconst REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);\nconst LOOPBACK_ALLOW_RANGES = [\"127.0.0.0/8\", \"::1\", \"::ffff:127.0.0.0/104\"];\n\nexport type LookupAddress = { address: string; family: number };\nexport type Lookup = (hostname: string) => Promise<LookupAddress[]>;\ntype Fetch = typeof fetch;\n\nconst WEB_SEARCH_CONFIG_PATH = getWebSearchConfigPath();\n\nlet cachedConfigRoot: { signature: string; value: Record<string, unknown> | null } | null = null;\n\nfunction loadConfigRoot(): Record<string, unknown> | null {\n\tif (!existsSync(WEB_SEARCH_CONFIG_PATH)) return null;\n\n\tlet signature: string;\n\ttry {\n\t\tconst stat = statSync(WEB_SEARCH_CONFIG_PATH);\n\t\tsignature = `${stat.mtimeMs}:${stat.size}`;\n\t} catch {\n\t\treturn null;\n\t}\n\n\tif (cachedConfigRoot?.signature === signature) return cachedConfigRoot.value;\n\n\tlet raw: string;\n\ttry {\n\t\traw = readFileSync(WEB_SEARCH_CONFIG_PATH, \"utf-8\");\n\t} catch {\n\t\t// Do not memoize read failures: a chmod fix changes neither mtime nor size,\n\t\t// so a cached failure would permanently fail-open the domain policy.\n\t\treturn null;\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to parse ${WEB_SEARCH_CONFIG_PATH}: ${message}`);\n\t}\n\n\tconst value = parsed && typeof parsed === \"object\" && !Array.isArray(parsed)\n\t\t? parsed as Record<string, unknown>\n\t\t: null;\n\tcachedConfigRoot = { signature, value };\n\treturn value;\n}\n\nexport interface SsrfConfig {\n\tallowRanges: string[];\n\ttrustEnvProxy: boolean;\n}\n\nexport interface DomainPolicy {\n\tallow: string[];\n\tdeny: string[];\n}\n\nconst DEFAULT_DOMAIN_POLICY: DomainPolicy = { allow: [], deny: [] };\n\nexport function loadFetchContentDomainPolicy(): DomainPolicy {\n\tconst parsed = loadConfigRoot();\n\tif (!parsed) return { ...DEFAULT_DOMAIN_POLICY };\n\tconst fetchContent = parsed.fetchContent;\n\tif (fetchContent === undefined || fetchContent === null) return { ...DEFAULT_DOMAIN_POLICY };\n\tif (typeof fetchContent !== \"object\" || Array.isArray(fetchContent)) {\n\t\tthrow new Error(`fetchContent in ${WEB_SEARCH_CONFIG_PATH} must be an object`);\n\t}\n\tconst policy = (fetchContent as { domainPolicy?: unknown }).domainPolicy;\n\tif (policy === undefined || policy === null) return { ...DEFAULT_DOMAIN_POLICY };\n\tif (typeof policy !== \"object\" || Array.isArray(policy)) {\n\t\tthrow new Error(`fetchContent.domainPolicy in ${WEB_SEARCH_CONFIG_PATH} must be an object`);\n\t}\n\tconst config = policy as { allow?: unknown; deny?: unknown };\n\treturn {\n\t\tallow: parseDomainEntries(config.allow, \"allow\"),\n\t\tdeny: parseDomainEntries(config.deny, \"deny\"),\n\t};\n}\n\nfunction parseDomainEntries(value: unknown, field: \"allow\" | \"deny\"): string[] {\n\tif (value === undefined || value === null) return [];\n\tif (!Array.isArray(value)) {\n\t\tthrow new Error(`fetchContent.domainPolicy.${field} in ${WEB_SEARCH_CONFIG_PATH} must be an array of hostnames`);\n\t}\n\treturn value.map((entry, index) => {\n\t\tif (typeof entry !== \"string\") {\n\t\t\tthrow new Error(`fetchContent.domainPolicy.${field} in ${WEB_SEARCH_CONFIG_PATH} must contain only hostnames; entry ${index + 1} is ${typeof entry}`);\n\t\t}\n\t\tconst hostname = normalizeDomainEntry(entry);\n\t\tif (!hostname) {\n\t\t\tthrow new Error(`fetchContent.domainPolicy.${field} in ${WEB_SEARCH_CONFIG_PATH} contains an invalid hostname: ${JSON.stringify(entry)}`);\n\t\t}\n\t\treturn hostname;\n\t});\n}\n\nfunction normalizeDomainEntry(entry: string): string | null {\n\tconst hostname = normalizeHostname(entry.trim());\n\tif (!hostname || /\\s|[\\\\/?:#@]/.test(hostname)) return null;\n\tif (net.isIP(hostname)) return hostname;\n\tif (hostname.length > 253 || !/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(hostname)) return null;\n\treturn hostname;\n}\n\nexport function loadSsrfConfig(): SsrfConfig {\n\tconst parsed = loadConfigRoot();\n\tif (!parsed) return { allowRanges: [], trustEnvProxy: false };\n\tconst ssrf = parsed.ssrf;\n\tif (ssrf === undefined || ssrf === null) return { allowRanges: [], trustEnvProxy: false };\n\tif (typeof ssrf !== \"object\" || Array.isArray(ssrf)) {\n\t\tthrow new Error(`ssrf in ${WEB_SEARCH_CONFIG_PATH} must be an object`);\n\t}\n\tconst config = ssrf as { allowRanges?: unknown; trustEnvProxy?: unknown };\n\tif (config.allowRanges !== undefined && config.allowRanges !== null && !Array.isArray(config.allowRanges)) {\n\t\tthrow new Error(`ssrf.allowRanges in ${WEB_SEARCH_CONFIG_PATH} must be an array of CIDR strings`);\n\t}\n\tif (config.trustEnvProxy !== undefined && typeof config.trustEnvProxy !== \"boolean\") {\n\t\tthrow new Error(`ssrf.trustEnvProxy in ${WEB_SEARCH_CONFIG_PATH} must be a boolean`);\n\t}\n\tconst allowRangesValue: unknown[] = Array.isArray(config.allowRanges) ? config.allowRanges : [];\n\tconst allowRanges = allowRangesValue.map((entry, index) => {\n\t\tif (typeof entry !== \"string\") {\n\t\t\tthrow new Error(`ssrf.allowRanges in ${WEB_SEARCH_CONFIG_PATH} must contain only CIDR strings; entry ${index + 1} is ${typeof entry}`);\n\t\t}\n\t\treturn entry.trim();\n\t}).filter(Boolean);\n\tparseAllowRanges(allowRanges);\n\treturn { allowRanges, trustEnvProxy: config.trustEnvProxy === true };\n}\n\ninterface ValidationOptions {\n\tlookup?: Lookup;\n\t/** Optional hostname policy for fetch_content target URLs. */\n\tdomainPolicy?: DomainPolicy;\n\t/**\n\t * CIDR ranges (e.g. \"198.18.0.0/15\") to exempt from the SSRF guard.\n\t * Useful when a host runs a TUN/fake-IP proxy (Surge, Clash, Mihomo, ...)\n\t * that resolves public domains into a reserved range. Entries are validated\n\t * strictly; an invalid entry throws so misconfiguration is not silent.\n\t */\n\tallowRanges?: string[];\n\t/**\n\t * When true, trust an explicitly-configured HTTP(S) proxy for hostname\n\t * resolution instead of performing local DNS lookups inside the sandbox.\n\t * Literal IPs and localhost remain blocked, and NO_PROXY hosts still use\n\t * the local SSRF preflight. This does not configure proxy transport.\n\t */\n\ttrustEnvProxy?: boolean;\n\t/** Allow loopback URLs for explicit provider base endpoints, not fetched targets. */\n\tallowLoopback?: boolean;\n}\n\n/** Parsed entry from `allowRanges`: a network address (4 or 16 bytes) + prefix length. */\ninterface ParsedCidr {\n\tbytes: Uint8Array;\n\tprefix: number;\n}\n\ninterface RedirectRequestInitArgs {\n\tfrom: URL;\n\tto: URL;\n\tinit: RequestInit;\n\tresponse: Response;\n}\n\ninterface FetchRemoteOptions extends ValidationOptions {\n\tfetch?: Fetch;\n\tmaxRedirects?: number;\n\tonRedirect?: (args: RedirectRequestInitArgs) => RequestInit;\n}\n\nasync function defaultLookup(hostname: string): Promise<LookupAddress[]> {\n\treturn dnsLookup(hostname, { all: true, verbatim: true });\n}\n\nexport async function validateRemoteUrl(rawUrl: string | URL, options: ValidationOptions = {}): Promise<URL> {\n\tconst url = rawUrl instanceof URL ? rawUrl : new URL(rawUrl);\n\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n\t\tthrow new Error(\"Only HTTP and HTTPS URLs can be fetched remotely\");\n\t}\n\n\tconst hostname = normalizeHostname(url.hostname);\n\tif (!hostname) throw new Error(\"URL must include a hostname\");\n\tif (hostname === \"localhost\") {\n\t\tif (options.allowLoopback === true) return url;\n\t\tthrow new Error(`Blocked internal hostname: ${hostname}`);\n\t}\n\tif (hostname.endsWith(\".localhost\")) {\n\t\tthrow new Error(`Blocked internal hostname: ${hostname}`);\n\t}\n\n\tconst allowRanges = parseAllowRanges(options.allowRanges);\n\tassertDomainPolicy(hostname, options.domainPolicy);\n\n\tif (net.isIP(hostname)) {\n\t\tconst addressAllowRanges = options.allowLoopback === true\n\t\t\t? [...allowRanges, ...parseAllowRanges(LOOPBACK_ALLOW_RANGES)]\n\t\t\t: allowRanges;\n\t\tassertPublicAddress(hostname, hostname, addressAllowRanges);\n\t\treturn url;\n\t}\n\n\tif (shouldTrustEnvProxy(url, options.trustEnvProxy === true)) return url;\n\n\tlet addresses: LookupAddress[];\n\ttry {\n\t\taddresses = await (options.lookup ?? defaultLookup)(hostname);\n\t} catch (err) {\n\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\tthrow new Error(`Failed to resolve ${hostname}: ${message}`);\n\t}\n\n\tif (addresses.length === 0) throw new Error(`Failed to resolve ${hostname}: no addresses returned`);\n\tfor (const { address } of addresses) {\n\t\tassertPublicAddress(address, hostname, allowRanges);\n\t}\n\treturn url;\n}\n\nexport async function fetchRemoteUrl(\n\turl: string | URL,\n\tinit: RequestInit = {},\n\toptions: FetchRemoteOptions = {},\n): Promise<Response> {\n\tconst fetchImpl = options.fetch ?? fetch;\n\tconst maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;\n\tlet current = await validateRemoteUrl(url, options);\n\tconst configuredOrigin = current.origin;\n\tlet requestInit = init;\n\n\tfor (let redirects = 0; redirects <= maxRedirects; redirects++) {\n\t\tconst response = await fetchImpl(current, { ...requestInit, redirect: \"manual\" });\n\t\tif (!REDIRECT_STATUSES.has(response.status)) return response;\n\n\t\tconst location = response.headers.get(\"location\");\n\t\tif (!location) return response;\n\t\tif (redirects === maxRedirects) throw new Error(`Too many redirects fetching ${current.toString()}`);\n\n\t\tconst from = current;\n\t\tconst next = new URL(location, current);\n\t\t// allowLoopback exempts an explicitly configured endpoint, never a redirect target: a loopback\n\t\t// base must not be able to pivot the request onto a different loopback origin.\n\t\tcurrent = await validateRemoteUrl(next, next.origin === configuredOrigin ? options : { ...options, allowLoopback: false });\n\t\tif (response.status === 303 || ((response.status === 301 || response.status === 302) && requestInit.method?.toUpperCase() === \"POST\")) {\n\t\t\tconst { body: _body, ...nextInit } = requestInit;\n\t\t\trequestInit = { ...nextInit, method: \"GET\" };\n\t\t}\n\t\tif (options.onRedirect) requestInit = options.onRedirect({ from, to: current, init: requestInit, response });\n\t}\n\n\tthrow new Error(`Too many redirects fetching ${current.toString()}`);\n}\n\nfunction normalizeHostname(hostname: string): string {\n\treturn hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\").replace(/\\.$/, \"\");\n}\n\nfunction assertDomainPolicy(hostname: string, policy?: DomainPolicy): void {\n\tif (!policy) return;\n\tif (policy.deny.some((entry) => domainMatches(hostname, entry))) {\n\t\tthrow new Error(`Blocked hostname by fetch_content domain policy: ${hostname}`);\n\t}\n\tif (policy.allow.length > 0 && !policy.allow.some((entry) => domainMatches(hostname, entry))) {\n\t\tthrow new Error(`Hostname not allowed by fetch_content domain policy: ${hostname}`);\n\t}\n}\n\nfunction domainMatches(hostname: string, entry: string): boolean {\n\treturn hostname === entry || hostname.endsWith(`.${entry}`);\n}\n\nfunction getProxyForProtocol(protocol: string): string {\n\tconst candidates = protocol === \"http:\"\n\t\t? [process.env.HTTP_PROXY, process.env.http_proxy, process.env.ALL_PROXY, process.env.all_proxy]\n\t\t: protocol === \"https:\"\n\t\t\t? [process.env.HTTPS_PROXY, process.env.https_proxy, process.env.HTTP_PROXY, process.env.http_proxy, process.env.ALL_PROXY, process.env.all_proxy]\n\t\t\t: [];\n\tfor (const candidate of candidates) {\n\t\tconst value = candidate?.trim();\n\t\tif (!value) continue;\n\t\ttry {\n\t\t\tconst proxyUrl = new URL(value);\n\t\t\tif ((proxyUrl.protocol === \"http:\" || proxyUrl.protocol === \"https:\") && proxyUrl.hostname) return value;\n\t\t} catch {\n\t\t\t// Invalid proxy env vars should not weaken local DNS SSRF checks.\n\t\t}\n\t}\n\treturn \"\";\n}\n\nfunction hostnameMatchesNoProxy(hostname: string, port: string, entry: string): boolean {\n\tconst trimmed = entry.trim();\n\tif (!trimmed) return false;\n\tif (trimmed === \"*\") return true;\n\n\t// NO_PROXY entries may include a port. Strip it only after handling\n\t// bracketed IPv6 literals, which can contain several colons.\n\tlet hostEntry = trimmed;\n\tlet entryPort: string | undefined;\n\tif (hostEntry.startsWith(\"[\")) {\n\t\tconst closingBracket = hostEntry.indexOf(\"]\");\n\t\tif (closingBracket >= 0) {\n\t\t\tconst suffix = hostEntry.slice(closingBracket + 1);\n\t\t\tif (/^:\\\\d+$/.test(suffix)) entryPort = suffix.slice(1);\n\t\t\thostEntry = hostEntry.slice(0, closingBracket + 1);\n\t\t}\n\t} else {\n\t\tconst colon = hostEntry.lastIndexOf(\":\");\n\t\tif (colon > -1 && /^\\d+$/.test(hostEntry.slice(colon + 1))) {\n\t\t\tentryPort = hostEntry.slice(colon + 1);\n\t\t\thostEntry = hostEntry.slice(0, colon);\n\t\t}\n\t}\n\tif (entryPort !== undefined && entryPort !== port) return false;\n\n\tconst normalizedEntry = normalizeHostname(hostEntry);\n\tif (!normalizedEntry) return false;\n\tif (normalizedEntry === hostname) return true;\n\tconst suffix = normalizedEntry.startsWith(\"*.\")\n\t\t? normalizedEntry.slice(1)\n\t\t: normalizedEntry.startsWith(\".\")\n\t\t\t? normalizedEntry\n\t\t\t: `.${normalizedEntry}`;\n\treturn hostname.endsWith(suffix);\n}\n\nfunction shouldTrustEnvProxy(url: URL, enabled: boolean): boolean {\n\tif (!enabled || !getProxyForProtocol(url.protocol)) return false;\n\tif (hasScopedProxyDecision()) return false;\n\tconst activeProxy = getActiveProxy();\n\tif (activeProxy && !isProxyBypassedUrl(url)) return false;\n\tconst hostname = normalizeHostname(url.hostname);\n\tconst port = url.port || (url.protocol === \"https:\" ? \"443\" : \"80\");\n\tconst noProxy = process.env.NO_PROXY || process.env.no_proxy || \"\";\n\treturn !noProxy.split(\",\").some(entry => hostnameMatchesNoProxy(hostname, port, entry));\n}\n\nfunction assertPublicAddress(address: string, hostname: string, allowRanges: ParsedCidr[] = []): void {\n\tconst normalized = normalizeHostname(address);\n\tconst ipVersion = net.isIP(normalized);\n\tif (ipVersion === 0) throw new Error(`Resolved non-IP address for ${hostname}: ${address}`);\n\t// Explicitly-allowed ranges bypass the private/reserved checks below. This lets\n\t// users exempt synthetic ranges produced by TUN/fake-IP proxies (e.g. 198.18/15).\n\tif (isInAllowedRange(normalized, ipVersion, allowRanges)) return;\n\tif (ipVersion === 4 && isBlockedIPv4(normalized)) {\n\t\tconst hint = isFakeIpProxyAddress(normalized)\n\t\t\t? '. This address is in 198.18.0.0/15, commonly used by TUN/fake-IP proxies. If that matches your setup, configure ssrf.allowRanges with [\"198.18.0.0/15\"] in web-search.json.'\n\t\t\t: \"\";\n\t\tthrow new Error(`Blocked internal address for ${hostname}: ${normalized}${hint}`);\n\t}\n\tif (ipVersion === 6 && isBlockedIPv6(normalized)) {\n\t\tthrow new Error(`Blocked internal address for ${hostname}: ${normalized}`);\n\t}\n}\n\nfunction isFakeIpProxyAddress(address: string): boolean {\n\tconst [a, b] = address.split(\".\").map(part => Number(part));\n\treturn a === 198 && (b === 18 || b === 19);\n}\n\nfunction isBlockedIPv4(address: string): boolean {\n\tconst parts = address.split(\".\").map(part => Number(part));\n\tif (parts.length !== 4 || parts.some(part => !Number.isInteger(part) || part < 0 || part > 255)) return true;\n\tconst [a, b] = parts;\n\treturn a === 0 ||\n\t\ta === 10 ||\n\t\ta === 127 ||\n\t\t(a === 100 && b >= 64 && b <= 127) ||\n\t\t(a === 169 && b === 254) ||\n\t\t(a === 172 && b >= 16 && b <= 31) ||\n\t\t(a === 192 && b === 168) ||\n\t\tisFakeIpProxyAddress(address) ||\n\t\ta >= 224;\n}\n\nfunction isBlockedIPv6(address: string): boolean {\n\tconst groups = parseIPv6(address);\n\tif (!groups) return true;\n\n\tconst first = groups[0];\n\tif (groups.every(group => group === 0)) return true;\n\tif (groups.slice(0, 7).every(group => group === 0) && groups[7] === 1) return true;\n\tif ((first & 0xfe00) === 0xfc00) return true;\n\tif ((first & 0xffc0) === 0xfe80) return true;\n\n\tconst isMappedIPv4 = groups.slice(0, 5).every(group => group === 0) && groups[5] === 0xffff;\n\tif (isMappedIPv4) {\n\t\tconst ipv4 = [groups[6] >> 8, groups[6] & 0xff, groups[7] >> 8, groups[7] & 0xff].join(\".\");\n\t\treturn isBlockedIPv4(ipv4);\n\t}\n\n\treturn false;\n}\n\nfunction parseIPv6(address: string): number[] | null {\n\tif (address.includes(\".\")) {\n\t\tconst lastColon = address.lastIndexOf(\":\");\n\t\tconst ipv4 = address.slice(lastColon + 1);\n\t\tif (net.isIP(ipv4) !== 4) return null;\n\t\tconst octets = ipv4.split(\".\").map(part => Number(part));\n\t\taddress = `${address.slice(0, lastColon)}:${((octets[0] << 8) | octets[1]).toString(16)}:${((octets[2] << 8) | octets[3]).toString(16)}`;\n\t}\n\n\tconst pieces = address.split(\"::\");\n\tif (pieces.length > 2) return null;\n\n\tconst left = pieces[0] ? pieces[0].split(\":\") : [];\n\tconst right = pieces.length === 2 && pieces[1] ? pieces[1].split(\":\") : [];\n\tconst missing = 8 - left.length - right.length;\n\tif (pieces.length === 1 && missing !== 0) return null;\n\tif (pieces.length === 2 && missing < 0) return null;\n\n\tconst groups = [...left, ...Array(missing).fill(\"0\"), ...right].map(part => {\n\t\tif (!/^[0-9a-f]{1,4}$/i.test(part)) return -1;\n\t\treturn parseInt(part, 16);\n\t});\n\treturn groups.length === 8 && groups.every(group => group >= 0 && group <= 0xffff) ? groups : null;\n}\n\n/** Parse `allowRanges` config value into validated CIDR rules. Throws on malformed entries. */\nfunction parseAllowRanges(input: unknown): ParsedCidr[] {\n\tif (input === undefined || input === null) return [];\n\tif (!Array.isArray(input)) {\n\t\tthrow new Error(\"ssrf.allowRanges must be an array of CIDR strings\");\n\t}\n\tconst rules: ParsedCidr[] = [];\n\tfor (const entry of input) {\n\t\tif (typeof entry !== \"string\") {\n\t\t\tthrow new Error(`ssrf.allowRanges entries must be strings, got ${typeof entry}`);\n\t\t}\n\t\tconst rule = parseCidr(entry.trim());\n\t\tif (!rule) {\n\t\t\tthrow new Error(`Invalid CIDR notation in ssrf.allowRanges: \"${entry}\"`);\n\t\t}\n\t\trules.push(rule);\n\t}\n\treturn rules;\n}\n\n/** Parse a single CIDR (e.g. \"198.18.0.0/15\", \"fd00::/8\") or bare host (\"1.2.3.4\"). Returns null if invalid. */\nfunction parseCidr(raw: string): ParsedCidr | null {\n\tif (!raw) return null;\n\tconst slash = raw.lastIndexOf(\"/\");\n\tconst addrPart = slash >= 0 ? raw.slice(0, slash) : raw;\n\tconst prefixPart = slash >= 0 ? raw.slice(slash + 1) : null;\n\t// A slash must be followed by digits. Number(\"\")/Number(\" \") are 0, which\n\t// would silently turn \"198.18.0.0/\" into /0 and exempt every address.\n\tif (prefixPart !== null && !/^\\d+$/.test(prefixPart)) return null;\n\tconst version = net.isIP(addrPart);\n\n\tif (version === 4) {\n\t\tconst bytes = ipv4ToBytes(addrPart);\n\t\tif (!bytes) return null;\n\t\tconst prefix = prefixPart === null ? 32 : Number(prefixPart);\n\t\tif (!Number.isInteger(prefix) || prefix < 1 || prefix > 32) return null;\n\t\treturn { bytes, prefix };\n\t}\n\tif (version === 6) {\n\t\tconst groups = parseIPv6(addrPart);\n\t\tif (!groups) return null;\n\t\tconst prefix = prefixPart === null ? 128 : Number(prefixPart);\n\t\tif (!Number.isInteger(prefix) || prefix < 1 || prefix > 128) return null;\n\t\treturn { bytes: ipv6GroupsToBytes(groups), prefix };\n\t}\n\treturn null;\n}\n\nfunction ipv4ToBytes(address: string): Uint8Array | null {\n\tconst parts = address.split(\".\");\n\tif (parts.length !== 4) return null;\n\tconst bytes = new Uint8Array(4);\n\tfor (let i = 0; i < 4; i++) {\n\t\tconst octet = Number(parts[i]);\n\t\tif (!Number.isInteger(octet) || octet < 0 || octet > 255) return null;\n\t\tbytes[i] = octet;\n\t}\n\treturn bytes;\n}\n\nfunction ipv6GroupsToBytes(groups: number[]): Uint8Array {\n\tconst bytes = new Uint8Array(16);\n\tfor (let i = 0; i < 8; i++) {\n\t\tbytes[i * 2] = groups[i] >> 8;\n\t\tbytes[i * 2 + 1] = groups[i] & 0xff;\n\t}\n\treturn bytes;\n}\n\nfunction ipToBytes(address: string, version: number): Uint8Array | null {\n\tif (version === 4) return ipv4ToBytes(address);\n\tif (version === 6) {\n\t\tconst groups = parseIPv6(address);\n\t\treturn groups ? ipv6GroupsToBytes(groups) : null;\n\t}\n\treturn null;\n}\n\n/** True if `address` (already validated as `ipVersion`) falls within any allowed CIDR. */\nfunction isInAllowedRange(address: string, ipVersion: number, allowRanges: ParsedCidr[]): boolean {\n\tif (allowRanges.length === 0) return false;\n\tconst addrBytes = ipToBytes(address, ipVersion);\n\tif (!addrBytes) return false;\n\tfor (const rule of allowRanges) {\n\t\t// Only compare same-family rules (4-byte IPv4 vs 16-byte IPv6).\n\t\tif (rule.bytes.length !== addrBytes.length) continue;\n\t\tif (bytesMatchPrefix(addrBytes, rule.bytes, rule.prefix)) return true;\n\t}\n\treturn false;\n}\n\n/** Compare the leading `prefix` bits of two equal-length byte arrays. */\nfunction bytesMatchPrefix(addr: Uint8Array, network: Uint8Array, prefix: number): boolean {\n\tconst fullBytes = prefix >> 3;\n\tconst remBits = prefix & 7;\n\tfor (let i = 0; i < fullBytes; i++) {\n\t\tif (addr[i] !== network[i]) return false;\n\t}\n\tif (remBits > 0 && fullBytes < addr.length) {\n\t\tconst mask = (0xff << (8 - remBits)) & 0xff;\n\t\tif ((addr[fullBytes] & mask) !== (network[fullBytes] & mask)) return false;\n\t}\n\treturn true;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAKpD,QAAA,MAAM,mBAAmB,IAAI,CAAC;AAS9B,UAAU,gBAAgB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAUD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACtB,OAAO,EAAE,OAAO,mBAAmB,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,sBAAsB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../../src/humain/web-access/vendor/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAKpD,QAAA,MAAM,mBAAmB,IAAI,CAAC;AAS9B,UAAU,gBAAgB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAUD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACtB,OAAO,EAAE,OAAO,mBAAmB,CAAC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,sBAAsB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAwWD,wBAAgB,sBAAsB,CAAC,GAAG,SAAa,EAAE,eAAe,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAI1G;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEpE;AAED,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,gBAAgB,EAAE,CAAA;CAAE,GAAG,gBAAgB,CAW5I;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAM7D;AAED,wBAAgB,aAAa,IAAI,gBAAgB,EAAE,CAElD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAehD;AAED,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAkBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAa9D"}
|
|
@@ -392,8 +392,16 @@ function readCachedFetchData(data, now = Date.now()) {
|
|
|
392
392
|
catch { }
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
|
+
function pruneExpiredFetchedResults(now) {
|
|
396
|
+
for (const [id, data] of storedResults) {
|
|
397
|
+
if (data.type === "fetch" && now - data.timestamp >= CACHE_TTL_MS) {
|
|
398
|
+
storedResults.set(id, unavailableFetchData(data, "Cached fetched content is missing or expired"));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
395
402
|
export function pruneExpiredFetchCache(now = Date.now(), requestedLimits) {
|
|
396
403
|
const limits = cacheLimits(requestedLimits);
|
|
404
|
+
pruneExpiredFetchedResults(now);
|
|
397
405
|
try {
|
|
398
406
|
pruneFetchCache(now, limits);
|
|
399
407
|
}
|
|
@@ -403,6 +411,7 @@ export function storeResult(id, data) {
|
|
|
403
411
|
storedResults.set(id, data);
|
|
404
412
|
}
|
|
405
413
|
export function storeFetchedContentResult(id, data) {
|
|
414
|
+
pruneExpiredFetchedResults(Date.now());
|
|
406
415
|
let ref = null;
|
|
407
416
|
let cacheError;
|
|
408
417
|
try {
|