/**
 * auditor-smtp-ssrf smoke — guards the 2026-06-01 SSRF fix on
 * /api/notifications/test.
 *
 * Auditor finding: user-supplied `smtpHost` was passed to nodemailer
 * with NO SSRF validation. The pre-existing `resolveHostForIpv4` is a
 * plain DNS forcer (no private-range check) AND was only invoked when
 * `smtpIgnoreTls=true`. EDITORs could exfiltrate via
 * 169.254.169.254 (cloud metadata) or port-scan internal services.
 *
 * Fix: route smtpHost through `resolveAndValidate` from
 * network-security/ssrf-guard, unconditionally. This smoke walks the
 * source to confirm the call is present, runs BEFORE createTransport,
 * and is NOT gated on smtpIgnoreTls.
 */
import './_lib';
import { ok, fail } from './_lib';
import { readFileSync } from 'fs';
import path from 'path';

const ROOT = path.resolve(__dirname, '../..');
const read = (rel: string): string => readFileSync(path.join(ROOT, rel), 'utf8');

function assert(label: string, cond: boolean, detail: string): void {
    if (!cond) fail(label, detail);
    ok(label);
}

function main(): void {
    const route = read('src/app/api/notifications/test/route.ts');

    assert('SMTP route: imports resolveAndValidate + BlockedHostError',
        /from\s+['"]@\/lib\/network-security\/ssrf-guard['"]/.test(route)
            && /resolveAndValidate/.test(route)
            && /BlockedHostError/.test(route),
        'notifications/test/route.ts no longer imports the SSRF guard — SMTP SSRF may have regressed.');

    assert('SMTP route: calls resolveAndValidate on smtpHost',
        /resolveAndValidate\(smtpHost\)/.test(route),
        'notifications/test/route.ts no longer calls resolveAndValidate(smtpHost).');

    // The guard runs BEFORE createTransport (so a bad host never opens a socket).
    const resolveIdx = route.indexOf('resolveAndValidate(smtpHost)');
    const transportIdx = route.indexOf('createTransport({');
    assert('SMTP route: resolveAndValidate runs BEFORE createTransport',
        resolveIdx > 0 && transportIdx > 0 && resolveIdx < transportIdx,
        `Guard call must precede transport creation (resolveIdx=${resolveIdx}, transportIdx=${transportIdx}).`);

    // Unconditional — NOT gated inside an `if (isHostingMode)` block.
    // We assert it sits at the function-body indent, not inside a deeper block.
    const hostingBlock = route.match(/if \(isHostingMode\)\s*\{[\s\S]*?\}/);
    const guardInsideHosting = hostingBlock && hostingBlock[0].includes('resolveAndValidate');
    assert('SMTP route: SSRF guard is NOT conditional on isHostingMode',
        !guardInsideHosting,
        'resolveAndValidate is gated inside `if (isHostingMode)` — SSRF only fires for one path.');

    // The transport must receive the resolved IP, not the original hostname.
    assert('SMTP route: nodemailer host = resolvedIp',
        /host:\s*resolvedIp/.test(route),
        'nodemailer transport host is no longer the resolved IP — DNS rebinding bypass possible.');

    // 400 response on blocked host.
    assert('SMTP route: returns 400 on BlockedHostError',
        /e instanceof BlockedHostError[\s\S]*?status:\s*400/.test(route),
        'BlockedHostError no longer returns 400.');

    // Test coverage.
    const test = read('src/app/api/notifications/test/__tests__/route.test.ts');
    assert('SMTP route: unit test asserts rejection on blocked range',
        /resolves to a blocked range|169\.254\.169\.254|loopback/i.test(test),
        'Unit test no longer asserts SSRF rejection on blocked ranges.');

    ok('auditor-smtp-ssrf', '/api/notifications/test guards smtpHost via SSRF guard unconditionally');
}

main();
