fix(POSTV1-02): 修复便携版网页入口门禁
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
Dada P0-A isolated Windows CI / validate-and-package (push) Waiting to run
This commit is contained in:
+12
-3
@@ -238,6 +238,7 @@ export interface CreateAppOptions {
|
||||
assetReleases?: AssetReleaseReader;
|
||||
bootstrap?: () => BootstrapResponse | Promise<BootstrapResponse>;
|
||||
browserGate?: boolean;
|
||||
productIndexHtml?: string;
|
||||
browserSupportRelease?: BrowserSupportRelease;
|
||||
browserSupportSecret?: Buffer;
|
||||
credits?: CreditService;
|
||||
@@ -273,7 +274,7 @@ const supportGateHtml = readFileSync(resolve(supportGateDirectory, "index.html")
|
||||
const supportGateCss = readFileSync(resolve(supportGateDirectory, "support-gate.css"), "utf8");
|
||||
const supportGateJavaScript = readFileSync(resolve(supportGateDirectory, "support-gate.js"), "utf8");
|
||||
const productWebRoot = resolve(process.env.DADA_WEB_ROOT ?? "apps/web/dist");
|
||||
const productIndexHtml = existsSync(resolve(productWebRoot, "index.html"))
|
||||
const packagedProductIndexHtml = existsSync(resolve(productWebRoot, "index.html"))
|
||||
? readFileSync(resolve(productWebRoot, "index.html"), "utf8")
|
||||
: undefined;
|
||||
const clientHints = "Sec-CH-UA, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Platform";
|
||||
@@ -714,6 +715,7 @@ export async function createApp(options: CreateAppOptions = {}) {
|
||||
)
|
||||
: undefined);
|
||||
const browserGate = options.browserGate ?? true;
|
||||
const productIndexHtml = options.productIndexHtml ?? packagedProductIndexHtml;
|
||||
const browserSupportSecret = options.browserSupportSecret ?? randomBytes(32);
|
||||
const browserSupportRelease = options.browserSupportRelease;
|
||||
const app = Fastify({
|
||||
@@ -905,9 +907,16 @@ export async function createApp(options: CreateAppOptions = {}) {
|
||||
});
|
||||
|
||||
for (const route of ["/", "/app", "/app/*", "/admin", "/admin/*"]) {
|
||||
app.get(route, { schema: { hide: true } }, async (_request, reply) => {
|
||||
app.get(route, { schema: { hide: true } }, async (request, reply) => {
|
||||
reply.type("text/html; charset=utf-8");
|
||||
return productIndexHtml ?? supportGateHtml;
|
||||
if (!browserGate) return productIndexHtml ?? supportGateHtml;
|
||||
const verified = verifyBrowserSupportCookie({
|
||||
cookieHeader: headerValue(request.headers.cookie),
|
||||
release: browserSupportRelease,
|
||||
secChUa: headerValue(request.headers["sec-ch-ua"]),
|
||||
secret: browserSupportSecret,
|
||||
});
|
||||
return verified.supported && productIndexHtml ? productIndexHtml : supportGateHtml;
|
||||
});
|
||||
}
|
||||
app.get("/assets/*", { schema: { hide: true } }, async (request, reply) => {
|
||||
|
||||
@@ -69,6 +69,7 @@ async function checkSupport() {
|
||||
browserValue.textContent = `${result.browser.brand} ${result.browser.major}`;
|
||||
supportedValue.textContent = supportedLabel(result.supported_browsers);
|
||||
window.dispatchEvent(new CustomEvent("dada:support-ready"));
|
||||
window.location.replace(window.location.pathname.startsWith("/admin") ? "/admin" : "/app");
|
||||
return;
|
||||
}
|
||||
showBlocked(
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
import { buildAndValidatePortablePackage } from "./lib/portable-package.mjs";
|
||||
import { validateFinalReleaseRecord } from "./lib/wp7-07-final-release.mjs";
|
||||
|
||||
const outputIndex = process.argv.indexOf("--output");
|
||||
const outputRoot = outputIndex >= 0 ? resolve(process.argv[outputIndex + 1]) : resolve(".build", "portable-release");
|
||||
const result = await buildAndValidatePortablePackage({ outputRoot });
|
||||
const previousRelease = JSON.parse(readFileSync(resolve("RELEASE.json"), "utf8"));
|
||||
const releaseRecord = validateFinalReleaseRecord({
|
||||
...previousRelease,
|
||||
buildCommit: execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim(),
|
||||
maintenanceFromCommit: previousRelease.buildCommit,
|
||||
recordedAt: new Date().toISOString(),
|
||||
});
|
||||
const result = await buildAndValidatePortablePackage({ outputRoot, releaseRecord });
|
||||
console.log(JSON.stringify({
|
||||
package: result.packageManifest.package_name,
|
||||
sha256: result.packageManifest.zip_sha256,
|
||||
|
||||
@@ -125,7 +125,12 @@ afterAll(async () => {
|
||||
|
||||
describe("TDD-WP0-BRW-001 supported browser contract", () => {
|
||||
it("cross-checks UA-CH and issues only a short-lived signed support cookie", async () => {
|
||||
const app = await createApp({ browserSupportRelease: testBrowserSupportRelease } as never);
|
||||
const app = await createApp({
|
||||
browserSupportRelease: testBrowserSupportRelease,
|
||||
productIndexHtml: "<!doctype html><title>Dada product test</title><div id=\"root\"></div>",
|
||||
} as never);
|
||||
const gate = await app.inject({ headers: { host: "127.0.0.1:43121" }, method: "GET", url: "/" });
|
||||
expect(gate.body).toContain("当前浏览器无法使用 Dada");
|
||||
const checked = await app.inject({
|
||||
headers: supportedEdge.headers,
|
||||
method: "POST",
|
||||
@@ -150,6 +155,14 @@ describe("TDD-WP0-BRW-001 supported browser contract", () => {
|
||||
|
||||
const cookie = supportCookie(checked);
|
||||
expect(cookie).toBeDefined();
|
||||
const productHtml = await app.inject({
|
||||
headers: { cookie, host: "127.0.0.1:43121", "sec-ch-ua": supportedEdge.headers["sec-ch-ua"] },
|
||||
method: "GET",
|
||||
url: "/app",
|
||||
});
|
||||
expect(productHtml.statusCode).toBe(200);
|
||||
expect(productHtml.body).toContain("Dada product test");
|
||||
expect(productHtml.body).not.toContain("当前浏览器无法使用 Dada");
|
||||
const product = await app.inject({
|
||||
headers: {
|
||||
cookie,
|
||||
|
||||
@@ -125,18 +125,20 @@ test("portable package serves the product and keeps SQLite data across API resta
|
||||
let api = startApi(configPath, dataRoot);
|
||||
try {
|
||||
await waitForHealth(api);
|
||||
const initialPage = await fetch(`http://127.0.0.1:${port}/`, { headers: { host: `127.0.0.1:${port}` } });
|
||||
assert.equal(initialPage.status, 200);
|
||||
assert.match(await initialPage.text(), /当前浏览器无法使用 Dada/);
|
||||
const support = await fetch(`http://127.0.0.1:${port}/api/v1/support/check`, {
|
||||
method: "POST",
|
||||
headers: { host: `127.0.0.1:${port}`, origin: `http://127.0.0.1:${port}`, "content-type": "application/json", "sec-ch-ua": '"Google Chrome";v="150"', "sec-ch-ua-full-version-list": '"Google Chrome";v="150.0.0.0"', "sec-ch-ua-platform": '"Windows"' },
|
||||
body: JSON.stringify({ brands: [{ brand: "Google Chrome", version: "150" }], full_version_list: [{ brand: "Google Chrome", version: "150.0.0.0" }], platform: "Windows" }),
|
||||
});
|
||||
assert.ok([200, 426].includes(support.status));
|
||||
if (support.status === 200) {
|
||||
assert.equal(support.status, 200);
|
||||
const cookie = support.headers.get("set-cookie")?.split(";", 1)[0];
|
||||
const page = await fetch(`http://127.0.0.1:${port}/app`, { headers: { host: `127.0.0.1:${port}`, cookie } });
|
||||
assert.ok(cookie);
|
||||
const page = await fetch(`http://127.0.0.1:${port}/app`, { headers: { host: `127.0.0.1:${port}`, cookie, "sec-ch-ua": '"Google Chrome";v="150"' } });
|
||||
assert.equal(page.status, 200);
|
||||
assert.match(await page.text(), /<div id="root"><\/div>/);
|
||||
}
|
||||
assert.ok(existsSync(join(dataRoot, "db", "dada.sqlite3")));
|
||||
await verifyWorkerStartup(configPath);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user