Files
OmniRoute/tests/unit/tproxy-capture-manager.test.ts
Diego Rodrigues de Sa e Souza 3c9883bb73 Release v3.8.29 (#4126)
OmniRoute v3.8.29 — 115 commits since v3.8.28. Full CHANGELOG + 41 i18n mirrors. All content quality gates green (build, unit 8/8, vitest 188/188, PR test policy, quality gates extended, docs sync, quality ratchet). Remaining red CI checks are pre-existing release flakes (coverage-shard/integration/node-compat teardown), a new transitive undici advisory in electron devDeps, and a workflow-level CodeQL fail (0 open alerts). VPS-validated by the operator.
2026-06-19 06:49:01 -03:00

123 lines
4.2 KiB
TypeScript

/**
* Fase 3 / Epic A — TPROXY capture-mode manager (decrypt 4a/N).
*
* The manager is the singleton lifecycle a (local-only) route drives: it gates on
* native-addon availability, builds the dynamic CA, wires the injected trust-store
* installer through to the decrypt listener, counts interceptions, and reports
* status. All effectful seams are injected so this is testable without root or the
* native addon. The real intercept/decrypt path was proven in #4169/#4179/#4200.
*/
import test from "node:test";
import assert from "node:assert/strict";
import {
startCaptureMode,
stopCaptureMode,
getCaptureStatus,
__resetCaptureManager,
type StartCaptureModeOptions,
} from "../../src/mitm/tproxy/captureManager.ts";
const CFG = { dport: 443, mark: 0x2333, onPort: 8443, routeTable: 233, bypassMark: 0x539 };
interface CapturedStart {
cfg?: unknown;
options?: {
decrypt?: { installCa: (p: string) => Promise<void>; uninstallCa: () => Promise<void> };
onIntercept?: (info: { destIp: string; destPort: number }) => void;
};
stopped: boolean;
}
/** A fake `startTproxyCapture` that records what it was handed and returns a
* handle whose stop() flips a flag. */
function fakeStart(rec: CapturedStart) {
return async (cfg: unknown, options: CapturedStart["options"]) => {
rec.cfg = cfg;
rec.options = options;
return {
cfg: cfg as never,
server: {} as never,
stop: async () => {
rec.stopped = true;
},
};
};
}
function baseOptions(over: Partial<StartCaptureModeOptions> = {}): StartCaptureModeOptions {
return {
cfg: CFG,
installCa: async () => {},
uninstallCa: async () => {},
...over,
};
}
test.afterEach(() => __resetCaptureManager());
test("startCaptureMode rejects when the native addon is unavailable", async () => {
await assert.rejects(
() => startCaptureMode(baseOptions({ deps: { isAvailable: () => false } })),
/native addon|CAP_NET_ADMIN/
);
});
test("startCaptureMode wires the injected CA installer into the decrypt listener", async () => {
const rec: CapturedStart = { stopped: false };
const installCa = async () => {};
const uninstallCa = async () => {};
const status = await startCaptureMode(
baseOptions({
installCa,
uninstallCa,
deps: { isAvailable: () => true, startTproxyCapture: fakeStart(rec) as never },
})
);
assert.equal(status.running, true);
assert.equal(status.onPort, 8443);
assert.equal(rec.options?.decrypt?.installCa, installCa, "installCa is passed through to decrypt");
assert.equal(rec.options?.decrypt?.uninstallCa, uninstallCa, "uninstallCa is passed through");
});
test("startCaptureMode refuses to start a second concurrent session", async () => {
const rec: CapturedStart = { stopped: false };
const deps = { isAvailable: () => true, startTproxyCapture: fakeStart(rec) as never };
await startCaptureMode(baseOptions({ deps }));
await assert.rejects(() => startCaptureMode(baseOptions({ deps })), /already running/);
});
test("stopCaptureMode stops the handle and clears the running state", async () => {
const rec: CapturedStart = { stopped: false };
await startCaptureMode(
baseOptions({ deps: { isAvailable: () => true, startTproxyCapture: fakeStart(rec) as never } })
);
const status = await stopCaptureMode();
assert.equal(rec.stopped, true, "the handle's stop() was invoked");
assert.equal(status.running, false);
});
test("stopCaptureMode is a no-op when nothing is running", async () => {
const status = await stopCaptureMode();
assert.equal(status.running, false);
});
test("getCaptureStatus counts interceptions reported by the listener", async () => {
const rec: CapturedStart = { stopped: false };
await startCaptureMode(
baseOptions({
deps: { isAvailable: () => true, startTproxyCapture: fakeStart(rec) as never },
})
);
rec.options?.onIntercept?.({ destIp: "1.2.3.4", destPort: 443 });
rec.options?.onIntercept?.({ destIp: "5.6.7.8", destPort: 443 });
const status = getCaptureStatus();
assert.equal(status.running, true);
assert.equal(status.interceptCount, 2);
});
test("getCaptureStatus reports not-running when idle", () => {
const status = getCaptureStatus();
assert.equal(status.running, false);
assert.equal(typeof status.available, "boolean");
});