This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { copyFile, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
||||
import { createHash } from "node:crypto";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
||||
import process from "node:process";
|
||||
|
||||
const root = resolve(new URL("..", import.meta.url).pathname.replace(/^\/(.:)/, "$1"));
|
||||
const destination = resolve(process.argv[2] ?? "");
|
||||
if (!process.argv[2] || destination === root || relative(root, destination).split(sep).includes("..") === false)
|
||||
throw new Error("Choose an empty export directory outside the canonical repository.");
|
||||
if (execFileSync("git", ["status", "--porcelain"], { cwd: root, encoding: "utf8" }).trim())
|
||||
throw new Error("The canonical worktree must be clean before export.");
|
||||
await stat(join(root, "LICENSE")).catch(() => { throw new Error("Confirm and commit a root LICENSE before public export."); });
|
||||
|
||||
const rules = (await readFile(join(root, "public-source.allowlist"), "utf8"))
|
||||
.split(/\r?\n/).map(line => line.trim()).filter(line => line && !line.startsWith("#"));
|
||||
const tracked = execFileSync("git", ["ls-files", "-z"], { cwd: root, encoding: "utf8" })
|
||||
.split("\0").filter(Boolean).map(path => path.replaceAll("\\", "/"));
|
||||
const allowed = path => rules.some(rule => rule.endsWith("/**") ?
|
||||
path.startsWith(rule.slice(0, -3) + "/") : path === rule);
|
||||
const files = tracked.filter(allowed).sort();
|
||||
const missing = rules.filter(rule => !rule.endsWith("/**") && !tracked.includes(rule));
|
||||
if (missing.length) throw new Error(`Allowlisted files are missing: ${missing.join(", ")}`);
|
||||
|
||||
const proprietaryPayload = /\.(?:iso|rom|bin|cue|chd|rvz|wbfs|xci|nsp|keys|exe|nes|pbp)(?:\.|$)/i;
|
||||
const privateMarkers = [
|
||||
["192", "168", "10", "150"].join("."),
|
||||
["ludarium", "itworx", "tech"].join("."),
|
||||
["player", "ludarium", "itworx", "tech"].join("."),
|
||||
];
|
||||
const binaryExtensions = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif", ".ico", ".mp4", ".woff", ".woff2", ".7z"]);
|
||||
const extension = path => path.slice(path.lastIndexOf(".")).toLowerCase();
|
||||
|
||||
await rm(destination, { recursive: true, force: true });
|
||||
await mkdir(destination, { recursive: true });
|
||||
const manifestFiles = [];
|
||||
for (const path of files) {
|
||||
if (isAbsolute(path) || path.split("/").includes("..")) throw new Error(`Unsafe allowlisted path: ${path}`);
|
||||
const syntheticFixture = path.startsWith("fixtures/synthetic/");
|
||||
if (proprietaryPayload.test(path) && !syntheticFixture)
|
||||
throw new Error(`Proprietary payload extension is not publishable: ${path}`);
|
||||
const source = join(root, path);
|
||||
const metadata = await stat(source);
|
||||
if (!metadata.isFile() || metadata.size > 50 * 1024 * 1024 || (syntheticFixture && metadata.size > 1024 * 1024))
|
||||
throw new Error(`Irregular or oversized public file: ${path}`);
|
||||
const data = await readFile(source);
|
||||
if (!binaryExtensions.has(extension(path))) {
|
||||
const text = data.toString("utf8");
|
||||
const marker = privateMarkers.find(value => text.toLowerCase().includes(value));
|
||||
if (marker) throw new Error(`Private infrastructure marker found in ${path}`);
|
||||
}
|
||||
const target = join(destination, path);
|
||||
await mkdir(dirname(target), { recursive: true });
|
||||
await copyFile(source, target);
|
||||
manifestFiles.push({ path, bytes: metadata.size, sha256: createHash("sha256").update(data).digest("hex") });
|
||||
}
|
||||
|
||||
const sourceRevision = execFileSync("git", ["rev-parse", "HEAD"], { cwd: root, encoding: "utf8" }).trim();
|
||||
await writeFile(join(destination, "PUBLIC_SOURCE_MANIFEST.json"), JSON.stringify({
|
||||
schemaVersion: 1,
|
||||
sourceRevision,
|
||||
generatedAt: new Date().toISOString(),
|
||||
files: manifestFiles,
|
||||
}, null, 2) + "\n");
|
||||
console.log(`Exported ${files.length} reviewed files from ${sourceRevision} to ${destination}`);
|
||||
@@ -0,0 +1,33 @@
|
||||
import { readFile, readdir, stat } from "node:fs/promises";
|
||||
import { createHash } from "node:crypto";
|
||||
import { dirname, join, resolve } from "node:path";
|
||||
|
||||
const root = resolve(new URL("..", import.meta.url).pathname.replace(/^\/(.:)/, "$1"));
|
||||
const manifest = JSON.parse(await readFile(join(root, "PUBLIC_SOURCE_MANIFEST.json"), "utf8"));
|
||||
if (manifest.schemaVersion !== 1 || !/^[0-9a-f]{40}$/.test(manifest.sourceRevision) || !Array.isArray(manifest.files))
|
||||
throw new Error("The public source manifest is malformed.");
|
||||
|
||||
const expected = new Map(manifest.files.map(entry => [entry.path, entry]));
|
||||
if (expected.size !== manifest.files.length || !expected.has("LICENSE"))
|
||||
throw new Error("The public source manifest has duplicate entries or no LICENSE.");
|
||||
async function walk(directory, prefix = "") {
|
||||
const found = [];
|
||||
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
||||
if (!prefix && entry.name === ".git") continue;
|
||||
const path = prefix ? `${prefix}/${entry.name}` : entry.name;
|
||||
if (entry.isDirectory()) found.push(...await walk(join(directory, entry.name), path));
|
||||
else if (entry.isFile() && path !== "PUBLIC_SOURCE_MANIFEST.json") found.push(path);
|
||||
else if (!entry.isFile()) throw new Error(`Irregular public entry: ${path}`);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
const actual = (await walk(root)).sort();
|
||||
if (actual.length !== expected.size || actual.some(path => !expected.has(path)))
|
||||
throw new Error("Files outside the reviewed public manifest are present.");
|
||||
for (const path of actual) {
|
||||
const data = await readFile(join(root, path));
|
||||
const entry = expected.get(path);
|
||||
if ((await stat(join(root, path))).size !== entry.bytes || createHash("sha256").update(data).digest("hex") !== entry.sha256)
|
||||
throw new Error(`Public source integrity check failed: ${path}`);
|
||||
}
|
||||
console.log(`Validated ${actual.length} public files from canonical revision ${manifest.sourceRevision}`);
|
||||
Reference in New Issue
Block a user