UNPKG

comfyui-mcp

Version:

Local-first, agent-native control plane for ComfyUI — MCP server + autonomous sidebar agent that drives your live graph in natural language on ANY LLM: Claude/ChatGPT/Gemini on your subscription (no API key), free local models via Ollama (fully offline),

103 lines • 3.64 kB
import { ValidationError } from "../utils/errors.js"; const TOKEN_QUERY_RE = /token|key|secret|signature|auth|password|credential/i; const REDACTED = "[REDACTED]"; const HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; const ASCII_CONTROL_RE = /[\x00-\x1F\x7F]/; const AZURE_BLOB_HOST_SUFFIX = ".blob.core.windows.net"; const AWS_PRESIGNED_QUERY_RE = /^x-amz-/i; function rejectControlChars(label, value) { if (ASCII_CONTROL_RE.test(value)) { throw new ValidationError(`${label} cannot contain ASCII control characters.`); } } function validateDownloadAuth(auth) { if (auth.type === "bearer") { rejectControlChars("Bearer token", auth.token); return; } if (auth.type === "basic") { rejectControlChars("Basic auth username", auth.username); rejectControlChars("Basic auth password", auth.password); return; } if (auth.type === "header") { if (!HEADER_NAME_RE.test(auth.header_name)) { throw new ValidationError("Header auth header_name must be a valid HTTP header token."); } rejectControlChars("Header auth header_value", auth.header_value); return; } if (auth.type === "s3") { rejectControlChars("S3 access_key_id", auth.access_key_id); rejectControlChars("S3 secret_access_key", auth.secret_access_key); if (auth.session_token) rejectControlChars("S3 session_token", auth.session_token); if (auth.region) rejectControlChars("S3 region", auth.region); if (auth.endpoint) rejectControlChars("S3 endpoint", auth.endpoint); return; } if (auth.query_param.length === 0) { throw new ValidationError("Query auth query_param must be a non-empty string."); } rejectControlChars("Query auth query_param", auth.query_param); } function shouldRedactAllQueryValues(parsed) { if (parsed.hostname.endsWith(AZURE_BLOB_HOST_SUFFIX)) return true; return [...parsed.searchParams.keys()].some((key) => AWS_PRESIGNED_QUERY_RE.test(key)); } export function redactUrlForLogs(url, extraSensitiveParams = []) { try { const parsed = new URL(url); const redactAll = shouldRedactAllQueryValues(parsed); const sensitive = new Set(extraSensitiveParams.map((p) => p.toLowerCase())); for (const key of [...parsed.searchParams.keys()]) { if (redactAll || sensitive.has(key.toLowerCase()) || TOKEN_QUERY_RE.test(key)) { parsed.searchParams.set(key, REDACTED); } } return parsed.toString(); } catch { return url; } } export function applyDownloadAuth(url, auth) { if (!auth) return { url, headers: {} }; validateDownloadAuth(auth); if (auth.type === "bearer") { return { url, headers: { Authorization: `Bearer ${auth.token}` }, }; } if (auth.type === "basic") { const encoded = Buffer.from(`${auth.username}:${auth.password}`).toString("base64"); return { url, headers: { Authorization: `Basic ${encoded}` }, }; } if (auth.type === "header") { return { url, headers: { [auth.header_name]: auth.header_value }, }; } if (auth.type === "s3") { return { url, headers: {}, }; } const parsed = new URL(url); parsed.searchParams.set(auth.query_param, auth.query_value); return { url: parsed.toString(), headers: {}, }; } //# sourceMappingURL=download-auth.js.map