"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.collectEnvSecretIssues = collectEnvSecretIssues;
exports.collectHeaderSecretIssues = collectHeaderSecretIssues;
exports.collectStdioSecretIssues = collectStdioSecretIssues;
exports.collectRemoteSecretIssues = collectRemoteSecretIssues;
exports.collectSetupSecretIssues = collectSetupSecretIssues;
const ENV_REFERENCE_PATTERN = /^\$(?:[A-Za-z_][A-Za-z0-9_]*|\{[A-Za-z_][A-Za-z0-9_]*\})$/u;
const EMBEDDED_ENV_REFERENCE_PATTERN = /\$(?:[A-Za-z_][A-Za-z0-9_]*|\{[A-Za-z_][A-Za-z0-9_]*\})/u;
const SENSITIVE_NAME_PATTERN = /(?:authorization|auth|token|secret|password|passwd|pwd|credential|api[_-]?key|access[_-]?key|private[_-]?key|cookie|session)/iu;
const LITERAL_SECRET_VALUE_PATTERNS = [
    /\bBearer\s+(?!\$(?:[A-Za-z_][A-Za-z0-9_]*|\{[A-Za-z_][A-Za-z0-9_]*\}))[A-Za-z0-9._~+/=-]{16,}/iu,
    /\bBasic\s+[A-Za-z0-9+/=]{16,}/iu,
    /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/u,
    /\bgithub_pat_[A-Za-z0-9_]{20,}\b/u,
    /\bsk-[A-Za-z0-9_-]{20,}\b/u,
    /\bxox[baprs]-[A-Za-z0-9-]{20,}\b/u,
    /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/u,
];
function collectEnvSecretIssues(env) {
    if (env === undefined) {
        return [];
    }
    const issues = [];
    for (const [key, value] of Object.entries(env)) {
        if (isSensitiveName(key) && !isEnvReference(value)) {
            issues.push({
                path: ["env", key],
                message: "sensitive env values must reference an environment variable such as $TOKEN; do not store literal secrets in MCP catalogs.",
            });
            continue;
        }
        if (looksLikeLiteralSecret(value)) {
            issues.push({
                path: ["env", key],
                message: "MCP catalog env values must not contain literal secrets.",
            });
        }
    }
    return issues;
}
function collectHeaderSecretIssues(headers) {
    if (headers === undefined) {
        return [];
    }
    const issues = [];
    for (const [key, value] of Object.entries(headers)) {
        if (key.toLowerCase() === "authorization") {
            issues.push({
                path: ["headers", key],
                message: "Authorization headers must use bearerTokenEnvVar; do not store Authorization header values in MCP catalogs.",
            });
            continue;
        }
        if (isSensitiveName(key) && !containsEnvReference(value)) {
            issues.push({
                path: ["headers", key],
                message: "sensitive header values must reference an environment variable; do not store literal secrets in MCP catalogs.",
            });
            continue;
        }
        if (looksLikeLiteralSecret(value)) {
            issues.push({
                path: ["headers", key],
                message: "MCP catalog header values must not contain literal secrets.",
            });
        }
    }
    return issues;
}
function collectStdioSecretIssues(server) {
    return [
        ...collectStringSecretIssues(["command"], server.command),
        ...(server.cwd === undefined
            ? []
            : collectStringSecretIssues(["cwd"], server.cwd)),
        ...collectArgSecretIssues(server.args),
    ];
}
function collectRemoteSecretIssues(server) {
    const issues = collectStringSecretIssues(["url"], server.url);
    let url;
    try {
        url = new URL(server.url);
    }
    catch {
        return issues;
    }
    if (url.username.length > 0 || url.password.length > 0) {
        issues.push({
            path: ["url"],
            message: "MCP catalog URLs must not include embedded credentials.",
        });
    }
    for (const [key, value] of url.searchParams.entries()) {
        if (isSensitiveName(key) &&
            value.length > 0 &&
            !containsEnvReference(value)) {
            issues.push({
                path: ["url"],
                message: "sensitive URL query values must reference an environment variable; do not store literal secrets in MCP catalogs.",
            });
            continue;
        }
        if (looksLikeLiteralSecret(value)) {
            issues.push({
                path: ["url"],
                message: "MCP catalog URLs must not contain literal secrets.",
            });
        }
    }
    return issues;
}
function collectSetupSecretIssues(setup) {
    const issues = [];
    for (const [index, value] of (setup.requiredEnv ?? []).entries()) {
        if (value.includes("=") || looksLikeLiteralSecret(value)) {
            issues.push({
                path: ["requiredEnv", String(index)],
                message: "setup.requiredEnv must contain environment variable names only, not secret values.",
            });
        }
    }
    for (const [index, value] of (setup.humanSteps ?? []).entries()) {
        issues.push(...collectStringSecretIssues(["humanSteps", String(index)], value));
    }
    return issues;
}
function collectArgSecretIssues(args) {
    if (args === undefined) {
        return [];
    }
    const issues = [];
    for (const [index, arg] of args.entries()) {
        issues.push(...collectStringSecretIssues(["args", String(index)], arg));
        const assignment = parseSensitiveAssignment(arg);
        if (assignment !== null && !containsEnvReference(assignment.value)) {
            issues.push({
                path: ["args", String(index)],
                message: "sensitive MCP command arguments must reference an environment variable; do not store literal secrets in MCP catalogs.",
            });
            continue;
        }
        if (isSensitiveFlag(arg)) {
            const next = args[index + 1];
            if (next !== undefined &&
                !next.startsWith("-") &&
                !containsEnvReference(next)) {
                issues.push({
                    path: ["args", String(index + 1)],
                    message: "sensitive MCP command arguments must reference an environment variable; do not store literal secrets in MCP catalogs.",
                });
            }
        }
    }
    return issues;
}
function collectStringSecretIssues(issuePath, value) {
    const issues = [];
    if (looksLikeLiteralSecret(value)) {
        issues.push({
            path: issuePath,
            message: "MCP catalogs must not contain literal secrets.",
        });
    }
    const assignment = parseSensitiveAssignment(value);
    if (assignment !== null && !containsEnvReference(assignment.value)) {
        issues.push({
            path: issuePath,
            message: "sensitive values must reference an environment variable; do not store literal secrets in MCP catalogs.",
        });
    }
    return issues;
}
function parseSensitiveAssignment(value) {
    const equalIndex = value.indexOf("=");
    if (equalIndex <= 0) {
        return null;
    }
    const key = value.slice(0, equalIndex).replace(/^-+/u, "");
    const assignmentValue = value.slice(equalIndex + 1).trim();
    if (!isSensitiveName(key) || assignmentValue.length === 0) {
        return null;
    }
    return { key, value: assignmentValue };
}
function isSensitiveFlag(arg) {
    if (!arg.startsWith("-") || arg.includes("=")) {
        return false;
    }
    return isSensitiveName(arg.replace(/^-+/u, ""));
}
function isSensitiveName(name) {
    return SENSITIVE_NAME_PATTERN.test(name);
}
function isEnvReference(value) {
    return ENV_REFERENCE_PATTERN.test(value.trim());
}
function containsEnvReference(value) {
    return EMBEDDED_ENV_REFERENCE_PATTERN.test(value);
}
function looksLikeLiteralSecret(value) {
    return LITERAL_SECRET_VALUE_PATTERNS.some((pattern) => pattern.test(value));
}
