@@ -0,0 +1,61 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { execFileSync, spawnSync } from "node:child_process";
|
||||
import { randomBytes } from "node:crypto";
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
rmSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { delimiter, join, resolve } from "node:path";
|
||||
import { test } from "node:test";
|
||||
|
||||
const GITHUB_TOKEN_RANDOM_BYTES = 18;
|
||||
|
||||
test("pre-commit scans the index, redacts findings and fails closed", () => {
|
||||
const hook = resolve(".husky/pre-commit");
|
||||
const cwd = mkdtempSync(join(tmpdir(), "frontend-hook-"));
|
||||
const bin = join(cwd, "bin");
|
||||
const marker = join(cwd, "downstream");
|
||||
const token = `ghp_${randomBytes(GITHUB_TOKEN_RANDOM_BYTES).toString("hex")}`;
|
||||
const git = (...args) => execFileSync("git", args, { cwd, stdio: "pipe" });
|
||||
const run = (path = `${bin}${delimiter}${process.env.PATH}`) =>
|
||||
spawnSync("/bin/sh", ["-e", hook], {
|
||||
cwd,
|
||||
env: { ...process.env, PATH: path },
|
||||
encoding: "utf8",
|
||||
});
|
||||
try {
|
||||
mkdirSync(bin);
|
||||
for (const command of ["npx", "npm"]) {
|
||||
writeFileSync(join(bin, command), "#!/bin/sh\necho ran >> downstream\n", {
|
||||
mode: 0o755,
|
||||
});
|
||||
}
|
||||
git("init", "--quiet");
|
||||
writeFileSync(join(cwd, "sample.txt"), "safe staged content\n");
|
||||
git("add", "sample.txt");
|
||||
// An unstaged secret must not be mistaken for the index being committed.
|
||||
writeFileSync(join(cwd, "sample.txt"), `token=${token}\n`);
|
||||
let result = run();
|
||||
assert.equal(
|
||||
result.status,
|
||||
0,
|
||||
"clean index must pass; install Gitleaks first",
|
||||
);
|
||||
assert.ok(existsSync(marker));
|
||||
rmSync(marker);
|
||||
git("add", "sample.txt");
|
||||
result = run();
|
||||
assert.equal(result.status, 1, "staged secret must block commit");
|
||||
assert.ok(!`${result.stdout}${result.stderr}`.includes(token));
|
||||
assert.ok(!existsSync(marker), "formatting/dependency checks must not run");
|
||||
result = run(bin);
|
||||
assert.notEqual(result.status, 0, "missing Gitleaks must block commit");
|
||||
assert.ok(!existsSync(marker));
|
||||
} finally {
|
||||
rmSync(cwd, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user