60 lines
2.4 KiB
TypeScript
60 lines
2.4 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { spawnSync } from "node:child_process";
|
|
import { resolve } from "node:path";
|
|
import { test } from "node:test";
|
|
|
|
const fixture = "synthetic-git-protocol-fixture";
|
|
const helper = resolve("scripts/git-credential.sh");
|
|
const request = "protocol=https\nhost=git.garvis.dev\npath=dmg/purpur-potato.git\n\n";
|
|
const environment = {
|
|
PATH: process.env.PATH, RELEASE_CREDENTIAL: fixture, LC_ALL: "C",
|
|
GIT_ASKPASS: "echo", GIT_TERMINAL_PROMPT: "0",
|
|
GIT_CONFIG_NOSYSTEM: "1", GIT_CONFIG_GLOBAL: "/dev/null",
|
|
};
|
|
|
|
test("real Git obtains the credential even when semantic-release forces GIT_ASKPASS=echo", () => {
|
|
const child = spawnSync("git", [
|
|
"-c", "credential.helper=", "-c", `credential.helper=${helper}`,
|
|
"-c", "credential.useHttpPath=true", "credential", "fill",
|
|
], { encoding: "utf8", input: request, env: environment });
|
|
assert.equal(child.status, 0);
|
|
assert.ok(child.stdout.split("\n").includes("username=dmg"));
|
|
assert.ok(child.stdout.split("\n").includes(`password=${fixture}`));
|
|
assert.equal(child.stderr, "");
|
|
});
|
|
|
|
for (const input of [
|
|
request.replace("https", "http"), request.replace("git.garvis.dev", "evil.invalid"),
|
|
request.replace("purpur-potato.git", "another-project.git"),
|
|
request.replace("\n\n", "\nusername=other\n\n"),
|
|
]) {
|
|
test(`refuses mismatched credential scope: ${JSON.stringify(input)}`, () => {
|
|
const child = spawnSync("/bin/sh", [helper, "get"], { encoding: "utf8", input, env: environment });
|
|
assert.notEqual(child.status, 0);
|
|
assert.equal(child.stdout, "");
|
|
assert.equal(child.stderr, "");
|
|
});
|
|
}
|
|
|
|
for (const action of ["store", "erase"]) {
|
|
test(`ignores ${action} without emitting or persisting credentials`, () => {
|
|
const child = spawnSync("/bin/sh", [helper, action], {
|
|
encoding: "utf8", input: request, env: environment,
|
|
});
|
|
assert.equal(child.status, 0);
|
|
assert.equal(child.stdout, "");
|
|
assert.equal(child.stderr, "");
|
|
});
|
|
}
|
|
|
|
for (const value of ["", "bad\npassword=injected", "trailing-space "]) {
|
|
test(`rejects absent or malformed credential input of length ${value.length}`, () => {
|
|
const child = spawnSync("/bin/sh", [helper, "get"], {
|
|
encoding: "utf8", input: request, env: { ...environment, RELEASE_CREDENTIAL: value },
|
|
});
|
|
assert.notEqual(child.status, 0);
|
|
assert.equal(child.stdout, "");
|
|
assert.equal(child.stderr, "");
|
|
});
|
|
}
|