evOo-local/infra/sandboxes/supervisor/src/home-ownership.test.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline
(Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/*
packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
2026-09-20 17:15:16 +02:00

124 lines
4.2 KiB
TypeScript

import { constants } from "node:fs";
import {
chmod,
lstat,
mkdir,
mkdtemp,
open,
rename,
rm,
symlink,
writeFile,
} from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { assertComputerHomeWritable, assertOpenedDirectoryBeneathRoot } from "./home-ownership.js";
const roots: string[] = [];
const DIRECTORY_OPEN_FLAGS = constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW;
afterEach(async () => {
await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
});
describe("computer home ownership", () => {
it("rejects a missing home instead of creating it as root", async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-missing-"));
roots.push(parent);
await expect(
assertComputerHomeWritable(path.join(parent, "missing"), 1000, 1000),
).rejects.toThrow(/does not exist/);
});
it("rejects a symlink as the home root", async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-root-link-"));
roots.push(parent);
const outside = path.join(parent, "outside");
const home = path.join(parent, "home");
await mkdir(outside);
await symlink(outside, home);
await expect(assertComputerHomeWritable(home, 1000, 1000)).rejects.toThrow(/symbolic link/);
});
it("rejects a writable regular file as the home root", async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-file-root-"));
roots.push(parent);
const home = path.join(parent, "home");
await writeFile(home, "{}");
await chmod(home, 0o600);
const stat = await lstat(home);
await expect(assertComputerHomeWritable(home, stat.uid, stat.gid)).rejects.toThrow(
/must be a directory/,
);
});
it("rejects an existing entry that the host-run computer cannot write", async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-writable-"));
roots.push(parent);
const home = path.join(parent, "home");
const file = path.join(home, "profile.json");
await mkdir(home);
await chmod(home, 0o777);
await writeFile(file, "{}");
await chmod(file, 0o400);
const stat = await lstat(home);
await expect(assertComputerHomeWritable(home, stat.uid + 1, stat.gid + 1)).rejects.toThrow(
/chown -R/,
);
});
it("rejects an owner-owned file that is not writable by that owner", async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-owner-mode-"));
roots.push(parent);
const home = path.join(parent, "home");
const file = path.join(home, "profile.json");
await mkdir(home);
await writeFile(file, "{}");
await chmod(file, 0o400);
const stat = await lstat(file);
await expect(assertComputerHomeWritable(home, stat.uid, stat.gid)).rejects.toThrow(/chown -R/);
});
it("does not follow symlinks while checking host-run compatibility", async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-writable-link-"));
roots.push(parent);
const home = path.join(parent, "home");
const outside = path.join(parent, "outside");
await mkdir(home);
await writeFile(outside, "outside");
await chmod(outside, 0o400);
await symlink(outside, path.join(home, "link"));
const stat = await lstat(home);
await expect(assertComputerHomeWritable(home, stat.uid, stat.gid)).resolves.toBeUndefined();
});
it.skipIf(process.platform !== "linux")(
"rejects an opened directory that was moved outside the home",
async () => {
const parent = await mkdtemp(path.join(tmpdir(), "rakazo-home-moved-"));
roots.push(parent);
const home = path.join(parent, "home");
const outside = path.join(parent, "outside");
const child = path.join(home, "nested");
await mkdir(child, { recursive: true });
await mkdir(outside, { recursive: true });
const handle = await open(child, DIRECTORY_OPEN_FLAGS);
try {
await rename(child, path.join(outside, "nested"));
await expect(assertOpenedDirectoryBeneathRoot(handle, home)).rejects.toThrow(
/escaped validated root/,
);
} finally {
await handle.close();
}
},
);
});