T-HUB/packages/media-sandbox/src/command.test.ts
glass beadian aa5e262f3a Tactical Media Broadcast Hub — initial release
Self-hosted multi-platform broadcast newsroom for activist collectives:
publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style
column wall with hostile-content-safe rendering, live control room with Auto
Director, bridged chat governance with polls and quorum, distributed sandboxed
transcode workers, encrypted content-addressed archive, monthly analytics.

MIT licensed. See README.md and docs/.
2026-10-10 11:56:42 +00:00

56 lines
4.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { assertMediaCommand, MediaCommandBuilder, type Demuxer } from "./command";
import { DEFAULT_LIMITS, limitsWith, sandboxEnabled, sandboxEnvironment } from "./profile";
import { validateProbe } from "./probe";
const id = "b".repeat(64); const builder = new MediaCommandBuilder();
describe("argv-only media commands", () => {
it("uses minted ids and fixed sandbox paths for probe and transcode", () => {
const probe = builder.probe(id, "mov");
expect(probe.argv).toContain(`file:/upload/${id}`);
expect(probe.argv.slice(probe.argv.indexOf("-protocol_whitelist"), probe.argv.indexOf("-protocol_whitelist") + 4)).toEqual(["-protocol_whitelist", "file", "-f", "mov"]);
expect(builder.transcode(id, "mov", id, { width: 1280, height: 720 }).argv.at(-1)).toBe(`file:/scratch/${id}.mp4`);
expect(Object.isFrozen(probe.argv)).toBe(true);
expect(() => assertMediaCommand({ binary: "ffmpeg", argv: [] })).toThrow(/builder/i);
});
it.each(["filename.mp4", "../escape", "file:/etc/passwd", "concat:a|b", "https://example.com", "rtmp://example.com/key", "a;id", "a\u0000b"])("rejects paths/protocols as asset id: %s", value => {
expect(() => builder.probe(value, "mov")).toThrow(/asset/);
});
it.each(["concat", "hls", "dash", "lavfi", "sdp", "http", "file"])("rejects non-allowlisted demuxer %s", format => {
expect(() => builder.probe(id, format as Demuxer)).toThrow(/demuxer/);
});
it.each([0, 1, 3, 4098, NaN, Infinity])("rejects dimensions %s", width => {
expect(() => builder.transcode(id, "mov", id, { width, height: 720 })).toThrow();
});
it("confines existing supervisor pipes and forces a demuxer on legacy remuxes", () => {
expect(builder.supervisor("ffmpeg", ["-i", "pipe:0", "-c", "copy", "-f", "mpegts", "pipe:1"], "/job").argv).toEqual(["-f", "mpegts", "-protocol_whitelist", "pipe", "-i", "pipe:0", "-c", "copy", "-f", "mpegts", "pipe:1"]);
});
it.each(["file:/etc/passwd", "concat:a|b", "https://example.org", "tcp://127.0.0.1:80"])("rejects a remote manifest endpoint %s", input => {
expect(() => builder.supervisor("ffmpeg", ["-f", "mpegts", "-i", input], "/job")).toThrow();
});
it("rejects IO filters and arbitrary options; permits minted overlay ids", () => {
expect(() => builder.supervisor("ffmpeg", ["-vf", "movie=/etc/passwd"], "/job")).toThrow();
expect(() => builder.supervisor("ffmpeg", ["-report"], "/job")).toThrow();
expect(builder.supervisor("ffmpeg", ["-i", `file:/job/${id}.png`, "-f", "null", "-"], "/job").argv).toContain("png_pipe");
expect(() => builder.supervisor("ffmpeg", ["-i", "file:/job/user-name.png"], "/job")).toThrow();
});
});
it("local defaults off, production defaults on and cannot opt out", () => {
expect(sandboxEnabled({})).toBe(false);
expect(sandboxEnabled({ MEDIA_SANDBOX: "on" })).toBe(true);
expect(sandboxEnabled({ NODE_ENV: "production" })).toBe(true);
expect(() => sandboxEnabled({ NODE_ENV: "production", MEDIA_SANDBOX: "off" })).toThrow(/requires/);
expect(() => sandboxEnabled({ MEDIA_SANDBOX: "maybe" })).toThrow();
expect(sandboxEnvironment()).toEqual({ PATH: "/usr/bin:/bin", LANG: "C", HOME: "/tmp" });
});
it("validates every CPU/memory/pids/time/size limit", () => {
for (const key of Object.keys(DEFAULT_LIMITS)) expect(() => limitsWith({ [key]: 0 })).toThrow();
expect(() => limitsWith({ cpuPeriodUs: 1 })).toThrow();
});
it("validates bounded probe schema without untrusted tags or arbitrary strings", () => {
expect(validateProbe({ format: { format_name: "mov,mp4", duration: "1.3" }, streams: [{ index: 0, codec_type: "video", width: 1920, height: 1080 }] }).streams).toHaveLength(1);
for (const invalid of [null, {}, { format: {}, streams: [], tags: {} }, { format: { format_name: "secret-token" }, streams: [] },
{ format: {}, streams: [{ index: 0, codec_type: "video", width: -1 }] }, { format: {}, streams: Array(65).fill({ index: 0, codec_type: "audio" }) },
{ format: {}, streams: [{ index: 0, codec_type: "audio" }, { index: 0, codec_type: "audio" }] }]) {
expect(() => validateProbe(invalid)).toThrow(/invalid probe/);
}
});