Add isolated artifact owner consent page

This commit is contained in:
Thomas Durieux committed 2026-09-27 14:56:06 +00:00
1 parent 7b60979c96
commit e4334bc9a7
10 files changed
+443 -3

No files matched your search

+4
View File
@@ -40,6 +40,9 @@ import { createLogger, serializeError } from "../core/logger";
import { createReviewCapabilities } from "./service/review-capabilities";
import { createReviewConsentPage, isReviewConsentPagePath } from "./review-consent-page";
const reviewConsentPage = createReviewConsentPage();
const logger = createLogger("server");
// Lazily build the templated index.html on first request so the server
@@ -77,6 +80,7 @@ function getIndexHtml(): string {
}
function indexResponse(req: express.Request, res: express.Response) {
if (isReviewConsentPagePath(req.path)) return reviewConsentPage(req, res);
if (
req.path.startsWith("/script") ||
req.path.startsWith("/css") ||
+58
View File
@@ -0,0 +1,58 @@
import { Request, Response } from "express";
import { existsSync, readFileSync } from "fs";
import { resolve } from "path";
// Reserve aliases too: they must never fall through to the ordinary page,
// which loads third-party scripts. Only the canonical URL serves this page.
export function isReviewConsentPagePath(path: string): boolean {
try {
return (
decodeURIComponent(path).toLowerCase().replace(/\/+$/, "") ===
"/review-link"
);
} catch {
return false;
}
}
export function createReviewConsentPage(
manifestPath = resolve("public", "asset-manifest.json"),
) {
return (req: Request, res: Response): void => {
res.set({
"Cache-Control": "no-store",
"Referrer-Policy": "no-referrer",
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"Content-Security-Policy":
"default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; frame-src 'none'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'",
});
if (
req.originalUrl !== "/review-link" ||
(req.method !== "GET" && req.method !== "HEAD")
) {
res.status(404).json({ error: "not_found" });
return;
}
let manifest: Record<string, unknown> = {};
try {
if (existsSync(manifestPath)) {
const parsed: unknown = JSON.parse(readFileSync(manifestPath, "utf8"));
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
manifest = parsed as Record<string, unknown>;
}
} catch {
// A missing or malformed manifest uses the ordinary unhashed assets.
}
const asset = (name: string): string => {
const value = manifest[name];
const extension = name.endsWith(".js") ? "js" : "css";
return typeof value === "string" &&
new RegExp(`^[A-Za-z0-9][A-Za-z0-9_.-]*\\.${extension}$`).test(value)
? value
: name;
};
res.type("html").send(`<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="referrer" content="no-referrer"><meta name="review-consent-page" content="1"><title>Artifact consent · Anonymous GitHub</title><link rel="stylesheet" href="/css/${asset("all.min.css")}"></head><body><div id="app"></div><script src="/script/${asset("core.min.js")}"></script><script defer src="/script/${asset("vendor.min.js")}"></script></body></html>`);
};
}