Darkwing's round 2 candidate, approved by Filbert (#1518 comment 26730). build-r2.patch a27890d5, manifest 869168c7, 34 files, applied on HEAD and checked 34/34. Integration gate on an export of HEAD plus the patch: business 60/60 on Node 24 and 26, every package test and every scripts/test-*.sh green, test-task 98/98 with the live-provider cases. Conductor, queue, conversation and discord confirmed in git worktrees of HEAD with and without the patch, identical results. Lead decision 63 accepts the vocabulary location, the example path and the business branch. Co-Authored-By: Claude Opus 5.5 <[email protected]>
115 lines
6.5 KiB
JavaScript
115 lines
6.5 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { chmodSync, mkdirSync, symlinkSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { BusinessError, checkCredentialRef, parseCredentialRef } from "../src/index.mjs";
|
|
import { FAR_DATE, tmp, tokenFile } from "./helpers.mjs";
|
|
|
|
function refuses(fn, pattern) {
|
|
assert.throws(fn, (error) => {
|
|
assert.ok(error instanceof BusinessError, `expected BusinessError, got ${error}`);
|
|
assert.equal(error.exitCode, 2);
|
|
assert.match(error.message, pattern);
|
|
return true;
|
|
});
|
|
}
|
|
|
|
const NOW = new Date("2026-10-04T12:00:00Z");
|
|
|
|
test("parse: exactly one of file or env, plus the service's date", () => {
|
|
assert.deepEqual({ ...parseCredentialRef({ file: "/s/pm-gitea.token", rotateBy: FAR_DATE }, "gitea", "r") },
|
|
{ service: "gitea", file: "/s/pm-gitea.token", rotateBy: FAR_DATE });
|
|
assert.deepEqual({ ...parseCredentialRef({ env: "PM_VIKUNJA_TOKEN", expires: FAR_DATE }, "vikunja", "r") },
|
|
{ service: "vikunja", env: "PM_VIKUNJA_TOKEN", expires: FAR_DATE });
|
|
refuses(() => parseCredentialRef({ file: "/a", env: "A", rotateBy: FAR_DATE }, "gitea", "r"), /exactly one/);
|
|
refuses(() => parseCredentialRef({ rotateBy: FAR_DATE }, "gitea", "r"), /exactly one/);
|
|
refuses(() => parseCredentialRef({ file: "/a" }, "gitea", "r"), /needs "rotateBy"/);
|
|
refuses(() => parseCredentialRef({ file: "/a", expires: FAR_DATE }, "gitea", "r"), /unsupported r key: "expires"/);
|
|
refuses(() => parseCredentialRef({ file: "/a", rotateBy: FAR_DATE }, "vikunja", "r"), /unsupported r key: "rotateBy"/);
|
|
refuses(() => parseCredentialRef({ file: "/a", expires: FAR_DATE, token: "x" }, "vikunja", "r"), /unsupported r key: "token"/);
|
|
refuses(() => parseCredentialRef({ file: "a/b", rotateBy: FAR_DATE }, "gitea", "r"), /normalized absolute path/);
|
|
refuses(() => parseCredentialRef({ file: "/a/../b", rotateBy: FAR_DATE }, "gitea", "r"), /normalized absolute path/);
|
|
refuses(() => parseCredentialRef({ file: "/a//b", rotateBy: FAR_DATE }, "gitea", "r"), /normalized absolute path/);
|
|
refuses(() => parseCredentialRef({ env: "pm_token", rotateBy: FAR_DATE }, "gitea", "r"), /\.env must match/);
|
|
refuses(() => parseCredentialRef({ env: "A", rotateBy: "2026-02-30" }, "gitea", "r"), /not a real date/);
|
|
refuses(() => parseCredentialRef({ env: "A", expires: "2026-10-04T00:00:00Z" }, "vikunja", "r"), /YYYY-MM-DD/);
|
|
refuses(() => parseCredentialRef({ env: "A" }, "github", "r"), /unknown credential service/);
|
|
});
|
|
|
|
test("check: a good file has no problems", () => {
|
|
const dir = tmp();
|
|
const ref = parseCredentialRef({ file: tokenFile(join(dir, "s"), "t"), expires: FAR_DATE }, "vikunja", "r");
|
|
assert.deepEqual(checkCredentialRef(ref, { now: NOW, forbiddenRoots: [join(dir, "repo")] }), { problems: [], warnings: [] });
|
|
});
|
|
|
|
test("check never opens the file: a write-only token passes", () => {
|
|
const dir = tmp();
|
|
const file = tokenFile(join(dir, "s"), "t");
|
|
chmodSync(file, 0o200);
|
|
const ref = parseCredentialRef({ file, rotateBy: FAR_DATE }, "gitea", "r");
|
|
assert.deepEqual(checkCredentialRef(ref, { now: NOW }).problems, []);
|
|
});
|
|
|
|
test("check: file problems", () => {
|
|
const dir = tmp();
|
|
const s = join(dir, "s");
|
|
const problems = (file, opts = {}) => checkCredentialRef(parseCredentialRef({ file, rotateBy: FAR_DATE }, "gitea", "r"), { now: NOW, ...opts }).problems;
|
|
assert.match(problems(join(s, "absent")).join(), /not found/);
|
|
|
|
const loose = tokenFile(s, "loose");
|
|
chmodSync(loose, 0o640);
|
|
assert.match(problems(loose).join(), /mode 640 gives group or other access/);
|
|
|
|
const empty = join(s, "empty");
|
|
writeFileSync(empty, "");
|
|
chmodSync(empty, 0o600);
|
|
assert.match(problems(empty).join(), /empty/);
|
|
|
|
const link = join(s, "link");
|
|
symlinkSync(tokenFile(s, "real"), link);
|
|
assert.match(problems(link).join(), /not a symbolic link/);
|
|
|
|
mkdirSync(join(s, "dir"));
|
|
assert.match(problems(join(s, "dir")).join(), /regular file/);
|
|
|
|
assert.deepEqual(problems(tokenFile(s, "other")), []);
|
|
assert.match(problems(tokenFile(s, "uid"), { uid: process.getuid() + 1 }).join(), /owned by uid/);
|
|
});
|
|
|
|
test("check: token files can't live in the repository or dataRoot, even through a linked directory", () => {
|
|
const dir = tmp();
|
|
const repo = join(dir, "repo");
|
|
const inRepo = tokenFile(join(repo, "secrets"), "t");
|
|
const ref = (file) => parseCredentialRef({ file, rotateBy: FAR_DATE }, "gitea", "r");
|
|
assert.match(checkCredentialRef(ref(inRepo), { now: NOW, forbiddenRoots: [repo] }).problems.join(), /inside .*repo/);
|
|
symlinkSync(join(repo, "secrets"), join(dir, "elsewhere"));
|
|
const viaLink = join(dir, "elsewhere", "t");
|
|
assert.match(checkCredentialRef(ref(viaLink), { now: NOW, forbiddenRoots: [repo] }).problems.join(), /inside/);
|
|
const repoLink = join(dir, "repo-link");
|
|
symlinkSync(repo, repoLink);
|
|
assert.match(checkCredentialRef(ref(inRepo), { now: NOW, forbiddenRoots: [repoLink] }).problems.join(), /inside/);
|
|
const sibling = tokenFile(join(dir, "repo-secrets"), "t");
|
|
assert.deepEqual(checkCredentialRef(ref(sibling), { now: NOW, forbiddenRoots: [repo, join(dir, "absent-root")] }).problems, []);
|
|
});
|
|
|
|
test("check: dates and environment references", () => {
|
|
const vikunja = (expires) => checkCredentialRef(parseCredentialRef({ env: "TOK", expires }, "vikunja", "r"), { now: NOW, env: { TOK: "set" } });
|
|
assert.match(vikunja("2026-10-04").problems.join(), /expired on 2026-10-04/);
|
|
assert.match(vikunja("2026-10-01").problems.join(), /expired/);
|
|
assert.deepEqual(vikunja("2026-10-05").problems, []);
|
|
assert.match(vikunja("2026-10-05").warnings.join(), /expires on 2026-10-05/);
|
|
assert.match(vikunja("2026-10-10").warnings.join(), /expires on/);
|
|
assert.deepEqual(vikunja("2026-10-12"), { problems: [], warnings: [] });
|
|
|
|
const gitea = (rotateBy) => checkCredentialRef(parseCredentialRef({ env: "TOK", rotateBy }, "gitea", "r"), { now: NOW, env: { TOK: "set" } });
|
|
assert.deepEqual(gitea("2026-10-01").problems, []);
|
|
assert.match(gitea("2026-10-01").warnings.join(), /rotation was due on 2026-10-01/);
|
|
assert.deepEqual(gitea(FAR_DATE), { problems: [], warnings: [] });
|
|
|
|
const unset = checkCredentialRef(parseCredentialRef({ env: "TOK", rotateBy: FAR_DATE }, "gitea", "r"), { now: NOW, env: {} });
|
|
assert.deepEqual(unset.problems, []);
|
|
assert.match(unset.warnings.join(), /not set in this environment/);
|
|
const blank = checkCredentialRef(parseCredentialRef({ env: "TOK", rotateBy: FAR_DATE }, "gitea", "r"), { now: NOW, env: { TOK: "" } });
|
|
assert.match(blank.warnings.join(), /not set/);
|
|
});
|