Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Receipts are a different artifact from certificates, with a different trust root
(`/.well-known/certifieddata-public-key.pem` rather than the keys document).

```bash
npx @certifieddata/verify <receipt-uuid> --type receipt
npx --package github:certifieddata/verify cd-verify <receipt-uuid> --type receipt
```

The canonicalization, the exact bytes that are signed, and the test vectors are
Expand Down
16 changes: 12 additions & 4 deletions RECEIPT-VERIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,17 @@ Note the key id: **`ed25519-prod-2025-02`**. Some older documentation shows
### Reproduce it

```bash
npx @certifieddata/verify 2492a060-8fbc-40ae-beab-7258aefb0608 --type receipt
npx --package github:certifieddata/verify cd-verify 2492a060-8fbc-40ae-beab-7258aefb0608 --type receipt
```

> **Windows note:** invoke the `cd-verify` bin explicitly, as above. The short
> form `npx github:certifieddata/verify …` selects the bin named `verify`, and
> `verify` is a **cmd.exe built-in command** — cmd intercepts the bare name
> before PATH is consulted, so on Windows the built-in swallows the invocation
> (exit 1, no output). POSIX shells have no such built-in, so the short form
> works there. CI missed this because tests spawn the shim by *path*, and
> built-ins only shadow *bare names*.

Expected:

```
Expand All @@ -147,15 +155,15 @@ In `fixtures/`:
With the repo checked out:

```bash
npx github:certifieddata/verify fixtures/valid-receipt.json --type receipt # VALID
npx github:certifieddata/verify fixtures/tampered-receipt.json --type receipt # INVALID
npx -p github:certifieddata/verify cd-verify fixtures/valid-receipt.json --type receipt # VALID
npx -p github:certifieddata/verify cd-verify fixtures/tampered-receipt.json --type receipt # INVALID
```

Without checking anything out — pipe the fixture in on stdin:

```bash
curl -s https://raw.githubusercontent.com/certifieddata/verify/main/fixtures/tampered-receipt.json \
| npx github:certifieddata/verify - --type receipt
| npx -p github:certifieddata/verify cd-verify - --type receipt
# → ✗ INVALID ed25519 signature does not verify against the RFC 8785 canonical payload
```

Expand Down
35 changes: 35 additions & 0 deletions dist/bin-invocation.test.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/bin-invocation.test.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions src/bin-invocation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,47 @@ test("invoking through a symlinked path still runs — no silent no-op", () => {
}
});

// ── Bare-name invocation through the shell ──────────────────────────────────
//
// npx invokes the selected bin as a BARE NAME through the platform shell. On
// Windows, cmd.exe built-ins shadow bare names before PATH is consulted — and
// `verify` IS a cmd.exe built-in (it toggles disk write verification). So
// `npx github:certifieddata/verify …` silently dies on Windows: cmd's built-in
// swallows the name, prints "An incorrect parameter was entered for the
// command." to a console nobody sees, and exits 1 with no output.
//
// Every other test here spawns the shim by PATH, which built-ins cannot
// shadow — which is exactly why six green CI legs, including two on Windows,
// shipped this. This test does what npx does: bare name, through the shell,
// with .bin on PATH.
//
// `verify` itself is unfixable on Windows (you cannot beat a cmd built-in), so
// the documented cross-platform command uses `cd-verify`, and THIS test pins
// that guarantee. The `verify` alias stays for POSIX convenience only.

test("documented bin `cd-verify` works as a bare name through the shell", () => {
assert.ok(binPath, "bin was not installed — setup failed");
const binDir = dirname(binPath!);
const r = spawnSync("cd-verify", ["--version"], {
encoding: "utf8",
shell: true, // bare name + shell = the npx invocation shape
env: {
...process.env,
NO_COLOR: "1",
PATH: `${binDir}${isWindows ? ";" : ":"}${process.env.PATH ?? ""}`,
Path: `${binDir};${process.env.Path ?? process.env.PATH ?? ""}`,
},
});
const combined = (r.stdout ?? "") + (r.stderr ?? "");
assert.notEqual(
combined.trim(),
"",
"cd-verify produced no output as a bare shell name — the documented command is broken",
);
assert.match(r.stdout ?? "", /@certifieddata\/verify/);
assert.equal(r.status, 0, `combined: ${combined}`);
});

// ── Network: the case the reviewer reproduced ───────────────────────────────

test("bin fails closed on a nonsense id — never exit 0", async () => {
Expand Down
Loading