playbook/antigravity-awesome-skills/tools/scripts/tests/repo_hygiene_security.test.js

100 lines
3.4 KiB
JavaScript

const assert = require("assert");
const { spawnSync } = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { createSymlinkOrSkip } = require("./symlink-test-utils");
const repoRoot = path.resolve(__dirname, "../..", "..");
const pycacheDir = path.join(repoRoot, "skills", "ui-ux-pro-max", "scripts", "__pycache__");
const nestedSkillsDir = path.join(repoRoot, "skills", "skills");
const syncRecommended = fs.readFileSync(
path.join(repoRoot, "tools", "scripts", "sync_recommended_skills.sh"),
"utf8",
);
const alphaVantage = fs.readFileSync(
path.join(repoRoot, "skills", "alpha-vantage", "SKILL.md"),
"utf8",
);
assert.strictEqual(
fs.existsSync(pycacheDir),
false,
"tracked Python bytecode should not ship in skill directories",
);
assert.strictEqual(
fs.existsSync(nestedSkillsDir),
false,
"accidental skills/skills nesting should not ship in the canonical skill tree",
);
assert.match(syncRecommended, /cp -RP/, "recommended skills sync should preserve symlinks instead of dereferencing them");
assert.doesNotMatch(syncRecommended, /for item in \*\/; do\s+rm -rf "\$item"/, "recommended skills sync must not delete matched paths via naive glob iteration");
assert.match(syncRecommended, /readlink|test -L|find .* -type d/, "recommended skills sync should explicitly avoid following directory symlinks during cleanup");
assert.doesNotMatch(alphaVantage, /--- Unknown/, "alpha-vantage frontmatter should not contain malformed delimiters");
{
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "repo-audit-security-"));
try {
const targetRepo = path.join(tempDir, "target");
fs.mkdirSync(targetRepo);
fs.writeFileSync(
path.join(targetRepo, "README.md"),
"[absolute](/etc/passwd)\n[traversal](../../etc/passwd)\n[symlink](linked-secret)\n[missing](docs/missing.md)\n",
"utf8",
);
const outsideSecret = path.join(tempDir, "outside-secret");
fs.writeFileSync(outsideSecret, "secret", "utf8");
const createdSymlink = createSymlinkOrSkip(outsideSecret, path.join(targetRepo, "linked-secret"));
if (!createdSymlink) {
return;
}
const fakeBin = path.join(tempDir, "bin");
fs.mkdirSync(fakeBin);
const fakeRg = path.join(fakeBin, "rg");
fs.writeFileSync(
fakeRg,
`#!/usr/bin/env bash
set -euo pipefail
for arg in "$@"; do
if [[ "$arg" == "--quiet" ]]; then
exit 1
fi
done
last_arg="\${@: -1}"
if [[ "$last_arg" == "README.md" ]]; then
printf '%s\\n' '[absolute](/etc/passwd)' '[traversal](../../etc/passwd)' '[symlink](linked-secret)' '[missing](docs/missing.md)'
exit 0
fi
exit 1
`,
"utf8",
);
fs.chmodSync(fakeRg, 0o755);
const scriptPath = path.join(
repoRoot,
"skills",
"openclaw-github-repo-commander",
"scripts",
"repo-audit.sh",
);
const result = spawnSync("bash", [scriptPath, targetRepo], {
encoding: "utf8",
env: {
...process.env,
PATH: `${fakeBin}${path.delimiter}${process.env.PATH || ""}`,
},
});
assert.strictEqual(result.status, 1);
assert.match(result.stdout, /README local link escapes repository: \/etc\/passwd/);
assert.match(result.stdout, /README local link escapes repository: \.\.\/\.\.\/etc\/passwd/);
assert.match(result.stdout, /README local link escapes repository: linked-secret/);
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
}