mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 16:26:36 +00:00
* fix(cli)!: retain repeated WASM input paths BREAKING CHANGE: caller_input_paths values may now be ordered arrays of strings as well as strings. Clients must accept both forms. * fix(capture): retain safe caller path selections * fix(evidence): retain auxiliary selections in direct summaries * test(wasm): separate SDK schema and acquired-input coverage
125 lines
4.6 KiB
TypeScript
125 lines
4.6 KiB
TypeScript
import { mkdir, writeFile } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { expect } from "vitest";
|
|
import { deliverAnalysisEvidence } from "../../../src/application/EvidenceBundleCommands.js";
|
|
import { parseEvidence } from "../../../src/domain/evidence.js";
|
|
import {
|
|
protobufCaptureDescriptor,
|
|
protobufHar,
|
|
} from "../../fixtures/protobufCapture.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { connectLocalToolsMcp } from "../../fixtures/localToolsMcp.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
|
|
cliTest(
|
|
"retains selected capture paths without exposing declared sensitive values",
|
|
async ({ cli }) => {
|
|
const root = await createTestTempDirectory("rea-capture-selected-");
|
|
const cwd = join(root, "secret-parent");
|
|
await mkdir(cwd);
|
|
await writeFile(join(cwd, "capture.har"), protobufHar());
|
|
await writeFile(join(cwd, "capture.pb"), protobufCaptureDescriptor());
|
|
const args = [
|
|
"inspect-web-network-capture",
|
|
"./capture.har",
|
|
"har",
|
|
"--record",
|
|
"0",
|
|
"--protobuf-schema",
|
|
"./capture.pb",
|
|
"--protobuf-message",
|
|
"capture.Message",
|
|
"--json",
|
|
];
|
|
const result = await cli.run({ cwd, arguments: args });
|
|
expect(result.exitCode, result.stderr).toBe(0);
|
|
const evidence = parseEvidence(result.json);
|
|
expect(evidence.caller_input_path).toBe("./capture.har");
|
|
expect(evidence.caller_input_paths).toEqual({
|
|
descriptor_set_path: "./capture.pb",
|
|
});
|
|
const parentExcluded = await cli.run({
|
|
cwd,
|
|
arguments: [...args, "--sensitive-value", "secret-parent"],
|
|
});
|
|
expect(parentExcluded.exitCode, parentExcluded.stderr).toBe(0);
|
|
expect(JSON.stringify(parentExcluded.json)).not.toContain("secret-parent");
|
|
expect(parseEvidence(parentExcluded.json).caller_input_path).toBe(
|
|
"./capture.har",
|
|
);
|
|
const originalExcluded = await cli.run({
|
|
cwd,
|
|
arguments: [...args, "--sensitive-value", "capture.har"],
|
|
});
|
|
expect(originalExcluded.exitCode, originalExcluded.stderr).toBe(0);
|
|
expect(JSON.stringify(originalExcluded.json)).not.toContain("capture.har");
|
|
const safe = parseEvidence(originalExcluded.json);
|
|
expect(safe.caller_input_path).toBeUndefined();
|
|
expect(safe.caller_input_paths).toEqual({
|
|
descriptor_set_path: "./capture.pb",
|
|
});
|
|
const summaryExcluded = await cli.run({
|
|
cwd,
|
|
arguments: [
|
|
...args,
|
|
"--sensitive-value",
|
|
"capture.har",
|
|
"--detail",
|
|
"summary",
|
|
"--evidence_output",
|
|
"./safe-evidence.json",
|
|
],
|
|
});
|
|
expect(summaryExcluded.exitCode, summaryExcluded.stderr).toBe(0);
|
|
const summary = parseEvidence(
|
|
(summaryExcluded.json as { summary: unknown }).summary,
|
|
);
|
|
expect(summary.caller_input_path).toBeUndefined();
|
|
expect(summary.caller_input_paths).toEqual({
|
|
descriptor_set_path: "./capture.pb",
|
|
});
|
|
expect(JSON.stringify(summaryExcluded.json)).not.toContain("capture.har");
|
|
const applicationSummary = await deliverAnalysisEvidence(
|
|
safe,
|
|
join(cwd, "application-evidence.json"),
|
|
"summary",
|
|
);
|
|
if (!applicationSummary.ok) throw applicationSummary.error;
|
|
expect(applicationSummary.value.caller_input_path).toBeUndefined();
|
|
expect(applicationSummary.value.caller_input_paths).toEqual({
|
|
descriptor_set_path: "./capture.pb",
|
|
});
|
|
const descriptorExcluded = await cli.run({
|
|
cwd,
|
|
arguments: [...args, "--sensitive-value", "capture.pb"],
|
|
});
|
|
expect(descriptorExcluded.exitCode, descriptorExcluded.stderr).toBe(0);
|
|
expect(JSON.stringify(descriptorExcluded.json)).not.toContain("capture.pb");
|
|
const safeDescriptor = parseEvidence(descriptorExcluded.json);
|
|
expect(safeDescriptor.caller_input_path).toBe("./capture.har");
|
|
expect(safeDescriptor.caller_input_paths).toBeUndefined();
|
|
const { client, call } = await connectLocalToolsMcp();
|
|
try {
|
|
const response = await call("inspect_web_network_capture", {
|
|
capture_path: join(cwd, "capture.har"),
|
|
format: "har",
|
|
record_ordinals: [0],
|
|
protobuf: {
|
|
schema: {
|
|
descriptor_set_path: join(cwd, "capture.pb"),
|
|
message_type: "capture.Message",
|
|
},
|
|
},
|
|
sensitive_values: ["secret-parent"],
|
|
});
|
|
expect(response.isError, JSON.stringify(response)).not.toBe(true);
|
|
expect(JSON.stringify(response)).not.toContain("secret-parent");
|
|
expect(
|
|
parseEvidence(response.structuredContent).caller_input_path,
|
|
).toBeUndefined();
|
|
} finally {
|
|
await client.close();
|
|
}
|
|
},
|
|
);
|