113 lines
4.1 KiB
JavaScript
113 lines
4.1 KiB
JavaScript
import console from "node:console";
|
|
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { validateAndHashStage } from "./lib/package-integrity.ts";
|
|
|
|
const root = mkdtempSync(join(tmpdir(), "wrnexus-stage-integrity-"));
|
|
const manifest = {
|
|
name: "@wrnexus/probe",
|
|
version: "0.8.0",
|
|
description: "Integrity probe.",
|
|
license: "MIT",
|
|
main: "./dist/index.js",
|
|
module: "./dist/index.js",
|
|
types: "./dist/index.d.ts",
|
|
exports: { ".": { import: "./dist/index.js", types: "./dist/index.d.ts" } },
|
|
files: ["dist", "README.md"],
|
|
repository: { type: "git", url: "https://example.test/repository.git" },
|
|
homepage: "https://example.test",
|
|
bugs: { url: "https://example.test/issues" },
|
|
keywords: ["probe"],
|
|
engines: { bun: ">=1.3.0" },
|
|
publishConfig: { registry: "https://registry.npmjs.org/", access: "restricted" },
|
|
};
|
|
try {
|
|
const safe = join(root, "safe");
|
|
mkdirSync(join(safe, "dist"), { recursive: true });
|
|
writeFileSync(join(safe, "dist", "index.js"), "export const safe = true;\n");
|
|
writeFileSync(join(safe, "dist", "index.d.ts"), "export declare const safe: true;\n");
|
|
const result = validateAndHashStage(safe, manifest);
|
|
if (result.files.length !== 2 || result.files.some((file) => file.sha256.length !== 64)) {
|
|
throw new Error("Safe stage did not produce deterministic SHA-256 records.");
|
|
}
|
|
|
|
const forbidden = join(root, "forbidden");
|
|
mkdirSync(forbidden);
|
|
writeFileSync(join(forbidden, ".env"), "TOKEN=secret\n");
|
|
let rejected = false;
|
|
try {
|
|
validateAndHashStage(forbidden, manifest);
|
|
} catch {
|
|
rejected = true;
|
|
}
|
|
if (!rejected) throw new Error("Secret-like stage file was not rejected.");
|
|
|
|
const temporaryShim = join(root, "temporary-shim");
|
|
mkdirSync(temporaryShim);
|
|
writeFileSync(join(temporaryShim, "focus-shims.d.ts"), "declare const Bun: any;\n");
|
|
rejected = false;
|
|
try {
|
|
validateAndHashStage(temporaryShim, manifest);
|
|
} catch {
|
|
rejected = true;
|
|
}
|
|
if (!rejected) throw new Error("Temporary typecheck shim was not rejected.");
|
|
|
|
const sourceMap = join(root, "source-map");
|
|
mkdirSync(sourceMap);
|
|
writeFileSync(join(sourceMap, "index.js.map"), "{}\n");
|
|
rejected = false;
|
|
try {
|
|
validateAndHashStage(sourceMap, manifest);
|
|
} catch {
|
|
rejected = true;
|
|
}
|
|
if (!rejected) throw new Error("Source map was not rejected.");
|
|
|
|
const leaked = join(root, "leaked-secret");
|
|
mkdirSync(join(leaked, "dist"), { recursive: true });
|
|
writeFileSync(
|
|
join(leaked, "dist", "index.js"),
|
|
`-----BEGIN PRIVATE KEY-----\n${"A".repeat(64)}\n${"B".repeat(64)}\n-----END PRIVATE KEY-----\n`,
|
|
);
|
|
writeFileSync(join(leaked, "dist", "index.d.ts"), "export {};\n");
|
|
rejected = false;
|
|
try {
|
|
validateAndHashStage(leaked, manifest);
|
|
} catch {
|
|
rejected = true;
|
|
}
|
|
if (!rejected) throw new Error("High-confidence secret content was not rejected.");
|
|
|
|
const keyHandlingSource = join(root, "key-handling-source");
|
|
mkdirSync(join(keyHandlingSource, "dist"), { recursive: true });
|
|
writeFileSync(
|
|
join(keyHandlingSource, "dist", "index.js"),
|
|
'export const header = "-----BEGIN PRIVATE KEY-----\\n" + generatedBytes;\n',
|
|
);
|
|
writeFileSync(join(keyHandlingSource, "dist", "index.d.ts"), "export {};\n");
|
|
validateAndHashStage(keyHandlingSource, manifest);
|
|
|
|
const missingWrnImport = join(root, "missing-wrn-import");
|
|
mkdirSync(join(missingWrnImport, "dist"), { recursive: true });
|
|
mkdirSync(join(missingWrnImport, "components"), { recursive: true });
|
|
writeFileSync(join(missingWrnImport, "dist", "index.js"), "export {};\n");
|
|
writeFileSync(join(missingWrnImport, "dist", "index.d.ts"), "export {};\n");
|
|
writeFileSync(
|
|
join(missingWrnImport, "components", "Select.wrn"),
|
|
'import Styles from "../styles/SelectStyles.wrn"\ncomponent Select {}\n',
|
|
);
|
|
rejected = false;
|
|
try {
|
|
validateAndHashStage(missingWrnImport, manifest);
|
|
} catch {
|
|
rejected = true;
|
|
}
|
|
if (!rejected) throw new Error("Missing relative WRN import was not rejected.");
|
|
|
|
console.log("Package staging integrity probes passed.");
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|