codex-plugin-doctor 1.11.0 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/core/review-bundle.js +25 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -358,9 +358,9 @@ jobs:
|
|
|
358
358
|
runs-on: ubuntu-latest
|
|
359
359
|
steps:
|
|
360
360
|
- uses: actions/checkout@v5
|
|
361
|
-
- uses: Esquetta/CodexPluginDoctor@v1.
|
|
361
|
+
- uses: Esquetta/CodexPluginDoctor@v1.12.1
|
|
362
362
|
with:
|
|
363
|
-
version: "1.
|
|
363
|
+
version: "1.12.1"
|
|
364
364
|
path: .
|
|
365
365
|
runtime: "true"
|
|
366
366
|
policy: codex-publish
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { mkdir, readFile, realpath, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { buildDoctorAttestation, renderDoctorAttestationJson, verifyDoctorAttestation } from "./attestation.js";
|
|
5
5
|
import { buildDoctorReleaseEvidenceReport, renderDoctorReleaseEvidenceJson, verifyDoctorReleaseEvidence } from "./release-evidence.js";
|
|
@@ -50,6 +50,21 @@ function isPathInsideDirectory(candidatePath, directoryPath) {
|
|
|
50
50
|
const relativePath = path.relative(directoryPath, candidatePath);
|
|
51
51
|
return relativePath === "" || (!relativePath.startsWith("..") && !path.isAbsolute(relativePath));
|
|
52
52
|
}
|
|
53
|
+
async function resolveBundleArtifactPath(bundleDirectory, relativePath) {
|
|
54
|
+
const resolvedBundleDirectory = path.resolve(bundleDirectory);
|
|
55
|
+
const artifactPath = path.resolve(resolvedBundleDirectory, relativePath);
|
|
56
|
+
if (!isPathInsideDirectory(artifactPath, resolvedBundleDirectory)) {
|
|
57
|
+
throw new Error("Bundle artifact path resolves outside the bundle directory.");
|
|
58
|
+
}
|
|
59
|
+
const [canonicalBundleDirectory, canonicalArtifactPath] = await Promise.all([
|
|
60
|
+
realpath(resolvedBundleDirectory),
|
|
61
|
+
realpath(artifactPath)
|
|
62
|
+
]);
|
|
63
|
+
if (!isPathInsideDirectory(canonicalArtifactPath, canonicalBundleDirectory)) {
|
|
64
|
+
throw new Error("Bundle artifact canonical path resolves outside the bundle directory.");
|
|
65
|
+
}
|
|
66
|
+
return canonicalArtifactPath;
|
|
67
|
+
}
|
|
53
68
|
function bundleStatus(runtimePolicy, releaseEvidence) {
|
|
54
69
|
if (runtimePolicy.status === "fail" || releaseEvidence.status === "fail") {
|
|
55
70
|
return "fail";
|
|
@@ -171,7 +186,7 @@ export function renderDoctorReviewBundleJson(bundle) {
|
|
|
171
186
|
return JSON.stringify(bundle.manifest, null, 2);
|
|
172
187
|
}
|
|
173
188
|
async function readBundleJsonFile(bundleDirectory, relativePath) {
|
|
174
|
-
return readJsonFile(
|
|
189
|
+
return readJsonFile(await resolveBundleArtifactPath(bundleDirectory, relativePath));
|
|
175
190
|
}
|
|
176
191
|
async function readBundleDiffSnapshot(bundleDirectory) {
|
|
177
192
|
const manifestArtifact = await readBundleJsonFile(bundleDirectory, "manifest.json");
|
|
@@ -348,15 +363,7 @@ export async function verifyDoctorReviewBundle(bundleDirectory, options) {
|
|
|
348
363
|
const files = manifest?.files ?? relativeBundleFiles();
|
|
349
364
|
for (const [fileKey, relativePath] of Object.entries(files)) {
|
|
350
365
|
try {
|
|
351
|
-
const artifactPath =
|
|
352
|
-
if (!isPathInsideDirectory(artifactPath, resolvedBundleDirectory)) {
|
|
353
|
-
checks.push({
|
|
354
|
-
id: `review_bundle.file.${fileKey}`,
|
|
355
|
-
status: "fail",
|
|
356
|
-
message: `${relativePath} resolves outside the review bundle directory.`
|
|
357
|
-
});
|
|
358
|
-
continue;
|
|
359
|
-
}
|
|
366
|
+
const artifactPath = await resolveBundleArtifactPath(resolvedBundleDirectory, relativePath);
|
|
360
367
|
const fileStat = await stat(artifactPath);
|
|
361
368
|
checks.push({
|
|
362
369
|
id: `review_bundle.file.${fileKey}`,
|
|
@@ -427,8 +434,8 @@ export async function verifyDoctorReviewBundle(bundleDirectory, options) {
|
|
|
427
434
|
});
|
|
428
435
|
continue;
|
|
429
436
|
}
|
|
430
|
-
const
|
|
431
|
-
if (!isPathInsideDirectory(
|
|
437
|
+
const resolvedIntegrityPath = path.resolve(resolvedBundleDirectory, expected.path);
|
|
438
|
+
if (!isPathInsideDirectory(resolvedIntegrityPath, resolvedBundleDirectory)) {
|
|
432
439
|
integrityStatus = "fail";
|
|
433
440
|
checks.push({
|
|
434
441
|
id: `review_bundle.integrity.${fileKey}.path`,
|
|
@@ -437,6 +444,7 @@ export async function verifyDoctorReviewBundle(bundleDirectory, options) {
|
|
|
437
444
|
});
|
|
438
445
|
continue;
|
|
439
446
|
}
|
|
447
|
+
const integrityPath = await resolveBundleArtifactPath(resolvedBundleDirectory, expected.path);
|
|
440
448
|
const content = await readFile(integrityPath);
|
|
441
449
|
const digest = sha256(content);
|
|
442
450
|
const matches = digest === expected.digest && content.byteLength === expected.bytes;
|
|
@@ -505,7 +513,8 @@ export async function verifyDoctorReviewBundle(bundleDirectory, options) {
|
|
|
505
513
|
});
|
|
506
514
|
}
|
|
507
515
|
try {
|
|
508
|
-
|
|
516
|
+
const attestationPath = await resolveBundleArtifactPath(resolvedBundleDirectory, files.attestationJson);
|
|
517
|
+
attestation = await verifyDoctorAttestation(attestationPath, targetPath, { signingKey: options.signingKey });
|
|
509
518
|
checks.push({
|
|
510
519
|
id: "review_bundle.attestation",
|
|
511
520
|
status: attestation.status,
|
|
@@ -522,7 +531,8 @@ export async function verifyDoctorReviewBundle(bundleDirectory, options) {
|
|
|
522
531
|
});
|
|
523
532
|
}
|
|
524
533
|
try {
|
|
525
|
-
|
|
534
|
+
const releaseEvidencePath = await resolveBundleArtifactPath(resolvedBundleDirectory, files.releaseEvidenceJson);
|
|
535
|
+
releaseEvidence = await verifyDoctorReleaseEvidence(releaseEvidencePath, {
|
|
526
536
|
signingKey: options.signingKey,
|
|
527
537
|
targetPath
|
|
528
538
|
});
|
package/package.json
CHANGED