100 lines
3.5 KiB
TypeScript
100 lines
3.5 KiB
TypeScript
/**
|
|
* Dep-graph + fixture-inventory conformance: ensures the parser /
|
|
* verifier subpath surfaces contain zero DOM type references and that
|
|
* every documented attestation format has at least one fixture builder
|
|
* registered. Runs against the on-disk source tree (no spawn).
|
|
*/
|
|
import { readdirSync, readFileSync, statSync } from "node:fs";
|
|
import { join, relative } from "node:path";
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
|
|
const ROOT = join(__dirname, "..");
|
|
const PARSER_DIR = join(ROOT, "src", "parser");
|
|
const VERIFIER_DIR = join(ROOT, "src", "verifier");
|
|
const ATTESTATION_DIR = join(ROOT, "src", "attestation");
|
|
const COSE_KEY_FILE = join(PARSER_DIR, "cose-key.ts");
|
|
const ATTESTATION_OBJECT_FILE = join(PARSER_DIR, "attestation-object.ts");
|
|
|
|
function listSourceFiles(dir: string): string[] {
|
|
const out: string[] = [];
|
|
for (const entry of readdirSync(dir)) {
|
|
const full = join(dir, entry);
|
|
const st = statSync(full);
|
|
if (st.isDirectory()) {
|
|
out.push(...listSourceFiles(full));
|
|
} else if (entry.endsWith(".ts") && !entry.endsWith(".test.ts")) {
|
|
out.push(full);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
const FORBIDDEN_DOM = [
|
|
/\bdocument\b/i,
|
|
/\bWindow\b/,
|
|
/\bNavigator\b/,
|
|
/\bCredentialsContainer\b/,
|
|
/\bPublicKeyCredential\b/,
|
|
];
|
|
|
|
describe("dep-graph: subpath tier separation", () => {
|
|
it("parser subpath has no DOM type references", { timeout: 5000 }, () => {
|
|
for (const file of listSourceFiles(PARSER_DIR)) {
|
|
const text = readFileSync(file, "utf8");
|
|
for (const pattern of FORBIDDEN_DOM) {
|
|
if (pattern.test(text)) {
|
|
throw new Error(
|
|
`Parser file ${relative(ROOT, file)} contains DOM reference ${pattern}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
it("verifier subpath has no DOM type references", { timeout: 5000 }, () => {
|
|
for (const dir of [VERIFIER_DIR, ATTESTATION_DIR]) {
|
|
for (const file of listSourceFiles(dir)) {
|
|
const text = readFileSync(file, "utf8");
|
|
for (const pattern of FORBIDDEN_DOM) {
|
|
if (pattern.test(text)) {
|
|
throw new Error(
|
|
`Verifier file ${relative(ROOT, file)} contains DOM reference ${pattern}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("dep-graph: CBOR consumption", () => {
|
|
it("COSE_Key decoder consumes @suaveplan/cbor", { timeout: 5000 }, () => {
|
|
const text = readFileSync(COSE_KEY_FILE, "utf8");
|
|
expect(text).toMatch(/from\s+["']@suaveplan\/cbor/);
|
|
});
|
|
it("attestation-object decoder consumes @suaveplan/cbor", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const text = readFileSync(ATTESTATION_OBJECT_FILE, "utf8");
|
|
expect(text).toMatch(/from\s+["']@suaveplan\/cbor/);
|
|
});
|
|
});
|
|
|
|
describe("dep-graph: every attestation format directory exists", () => {
|
|
it("ships verifiers for every documented format", { timeout: 5000 }, () => {
|
|
const fmts = [
|
|
"packed",
|
|
"fido-u2f",
|
|
"tpm",
|
|
"android-key",
|
|
"android-safetynet",
|
|
"apple",
|
|
"none",
|
|
];
|
|
for (const fmt of fmts) {
|
|
const dir = join(ATTESTATION_DIR, fmt);
|
|
const stat = statSync(dir);
|
|
expect(stat.isDirectory()).toBe(true);
|
|
}
|
|
});
|
|
});
|