import { describe, it, expect } from "vitest";
import { parseNucleiResult } from "../../../scanners/dast/nuclei.js";
describe("nuclei scanner", () => {
    describe("parseNucleiResult", () => {
        it("parses Nuclei result to DASTFinding", () => {
            const result = {
                template: "cves/2021/CVE-2021-44228.yaml",
                "template-url": "https://github.com/projectdiscovery/nuclei-templates/blob/main/cves/2021/CVE-2021-44228.yaml",
                "template-id": "CVE-2021-44228",
                "template-path": "/path/to/templates/cves/2021/CVE-2021-44228.yaml",
                info: {
                    name: "Apache Log4j RCE",
                    author: ["pdteam"],
                    tags: ["cve", "cve2021", "rce", "log4j", "apache"],
                    description: "Apache Log4j2 <=2.14.1 JNDI features...",
                    reference: [
                        "https://nvd.nist.gov/vuln/detail/CVE-2021-44228",
                        "https://logging.apache.org/log4j/2.x/security.html",
                    ],
                    severity: "critical",
                    metadata: { "max-request": 1 },
                    classification: {
                        "cve-id": ["CVE-2021-44228"],
                        "cwe-id": ["CWE-502", "CWE-400"],
                    },
                },
                type: "http",
                host: "https://vulnerable-app.com",
                matched: "https://vulnerable-app.com/api/log",
                "extracted-results": ["${jndi:ldap://...}"],
                ip: "192.168.1.1",
                timestamp: "2024-01-15T10:30:00Z",
                matcher: "regex",
                "curl-command": "curl -X POST ...",
                request: "POST /api/log HTTP/1.1\n...",
                response: "HTTP/1.1 200 OK\n...",
            };
            const finding = parseNucleiResult(result);
            expect(finding.scanner).toBe("nuclei");
            expect(finding.ruleId).toBe("nuclei-CVE-2021-44228");
            expect(finding.name).toBe("Apache Log4j RCE");
            expect(finding.severity).toBe("critical");
            expect(finding.confidence).toBe(95);
            expect(finding.url).toBe("https://vulnerable-app.com/api/log");
            expect(finding.cweIds).toContain("CWE-502");
            expect(finding.cweIds).toContain("CWE-400");
            expect(finding.cveIds).toContain("CVE-2021-44228");
            expect(finding.tags).toContain("cve");
            expect(finding.tags).toContain("log4j");
            expect(finding.evidence).toBe("${jndi:ldap://...}");
            expect(finding.references).toContain("https://nvd.nist.gov/vuln/detail/CVE-2021-44228");
            expect(finding.references).toContain("https://github.com/projectdiscovery/nuclei-templates/blob/main/cves/2021/CVE-2021-44228.yaml");
        });
        it("maps Nuclei severity levels correctly", () => {
            const severities = ["critical", "high", "medium", "low", "info", "unknown"];
            const expected = ["critical", "high", "medium", "low", "info", "info"];
            for (let i = 0; i < severities.length; i++) {
                const result = createMockNucleiResult({ severity: severities[i] });
                const finding = parseNucleiResult(result);
                expect(finding.severity).toBe(expected[i]);
            }
        });
        it("assigns confidence based on severity", () => {
            const testCases = [
                { severity: "critical", expectedConfidence: 95 },
                { severity: "high", expectedConfidence: 90 },
                { severity: "medium", expectedConfidence: 80 },
                { severity: "low", expectedConfidence: 70 },
                { severity: "info", expectedConfidence: 60 },
            ];
            for (const { severity, expectedConfidence } of testCases) {
                const result = createMockNucleiResult({ severity });
                const finding = parseNucleiResult(result);
                expect(finding.confidence).toBe(expectedConfidence);
            }
        });
        it("handles results without optional fields", () => {
            const result = {
                template: "http/misconfiguration/debug-enabled.yaml",
                "template-id": "debug-enabled",
                info: {
                    name: "Debug Mode Enabled",
                    author: ["tester"],
                    tags: ["misconfiguration"],
                    severity: "medium",
                },
                type: "http",
                host: "https://example.com",
                matched: "https://example.com/debug",
                timestamp: "2024-01-15T10:30:00Z",
            };
            const finding = parseNucleiResult(result);
            expect(finding.scanner).toBe("nuclei");
            expect(finding.ruleId).toBe("nuclei-debug-enabled");
            expect(finding.description).toBe("Debug Mode Enabled detected");
            expect(finding.cweIds).toBeUndefined();
            expect(finding.cveIds).toBeUndefined();
            expect(finding.evidence).toBeUndefined();
        });
        it("extracts HTTP method from request", () => {
            const postResult = createMockNucleiResult({ request: "POST /api/data HTTP/1.1\nHost: example.com" });
            const getResult = createMockNucleiResult({ request: "GET /api/data HTTP/1.1\nHost: example.com" });
            const putResult = createMockNucleiResult({ request: "PUT /api/data HTTP/1.1\nHost: example.com" });
            expect(parseNucleiResult(postResult).method).toBe("POST");
            expect(parseNucleiResult(getResult).method).toBe("GET");
            expect(parseNucleiResult(putResult).method).toBe("PUT");
        });
        it("uses host as url fallback when matched is not present", () => {
            const result = {
                template: "test.yaml",
                "template-id": "test",
                info: {
                    name: "Test",
                    author: ["tester"],
                    tags: [],
                    severity: "info",
                },
                type: "http",
                host: "https://example.com",
                matched: "",
                timestamp: "2024-01-15T10:30:00Z",
            };
            const finding = parseNucleiResult(result);
            expect(finding.url).toBe("https://example.com");
        });
        it("formats CWE IDs with prefix", () => {
            const result = createMockNucleiResult({
                classification: {
                    "cwe-id": ["79", "CWE-89"],
                },
            });
            const finding = parseNucleiResult(result);
            expect(finding.cweIds).toContain("CWE-79");
            expect(finding.cweIds).toContain("CWE-89");
        });
        it("joins multiple extracted results as evidence", () => {
            const result = createMockNucleiResult({
                "extracted-results": ["result1", "result2", "result3"],
            });
            const finding = parseNucleiResult(result);
            expect(finding.evidence).toBe("result1\nresult2\nresult3");
        });
    });
});
function createMockNucleiResult(overrides = {}) {
    const { severity, classification, request, "extracted-results": extractedResults, ...rest } = overrides;
    return {
        template: "test/template.yaml",
        "template-id": "test-template",
        info: {
            name: "Test Template",
            author: ["tester"],
            tags: ["test"],
            severity: severity || "medium",
            classification: classification,
        },
        type: "http",
        host: "https://test.example.com",
        matched: "https://test.example.com/path",
        timestamp: "2024-01-15T10:30:00Z",
        request: request,
        "extracted-results": extractedResults,
        ...rest,
    };
}
//# sourceMappingURL=nuclei.test.js.map