feat: complete TASK-WP0-03 browser gate
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { createApp } from "../../apps/api/src/app.js";
|
||||
|
||||
describe("TDD-WP0-BND-001 loopback origin", () => {
|
||||
it("serves only the minimal gate shell on the fixed loopback authority", async () => {
|
||||
const app = await createApp();
|
||||
const response = await app.inject({
|
||||
headers: { host: "127.0.0.1:43121" },
|
||||
method: "GET",
|
||||
url: "/",
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(200);
|
||||
expect(response.headers["accept-ch"]).toContain("Sec-CH-UA-Full-Version-List");
|
||||
expect(response.headers["content-security-policy"]).toContain("default-src 'self'");
|
||||
expect(response.body).toContain("当前浏览器无法使用 Dada");
|
||||
expect(response.body).not.toContain("/src/main.tsx");
|
||||
expect(response.body).toContain("没有“仍然继续”入口,也不会提供绕过令牌或参数。");
|
||||
expect(response.body).not.toMatch(/<(?:a|button)[^>]*>[^<]*仍然继续/u);
|
||||
await app.close();
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
headers: { host: "192.168.1.10:43121" },
|
||||
method: "GET" as const,
|
||||
name: "LAN Host",
|
||||
url: "/",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
host: "127.0.0.1:43121",
|
||||
origin: "http://attacker.invalid",
|
||||
},
|
||||
method: "POST" as const,
|
||||
name: "foreign Origin",
|
||||
url: "/api/v1/support/check",
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
"access-control-request-method": "POST",
|
||||
host: "127.0.0.1:43121",
|
||||
origin: "http://attacker.invalid",
|
||||
},
|
||||
method: "OPTIONS" as const,
|
||||
name: "CORS preflight",
|
||||
url: "/api/v1/support/check",
|
||||
},
|
||||
])("rejects $name without a CORS grant", async ({ headers, method, url }) => {
|
||||
const app = await createApp();
|
||||
const response = await app.inject({ headers, method, url });
|
||||
|
||||
expect(response.statusCode).toBe(426);
|
||||
expect(response.headers).not.toHaveProperty("access-control-allow-origin");
|
||||
expect(response.json()).toMatchObject({
|
||||
error: {
|
||||
code: "BROWSER_UNSUPPORTED",
|
||||
details: { reason: "identity_unavailable" },
|
||||
message_key: "browser.unsupported",
|
||||
},
|
||||
});
|
||||
await app.close();
|
||||
});
|
||||
|
||||
it("keeps the production and Supervisor endpoint fixed", () => {
|
||||
const main = readFileSync("apps/api/src/main.ts", "utf8");
|
||||
const supervisor = readFileSync("supervisor/Dada.Supervisor/LoopbackEndpoint.cs", "utf8");
|
||||
|
||||
expect(main).toContain('host: "127.0.0.1"');
|
||||
expect(main).toContain("port: 43121");
|
||||
expect(supervisor).toContain('Host = "127.0.0.1"');
|
||||
expect(supervisor).toContain("Port = 43121");
|
||||
expect(supervisor).not.toContain("0.0.0.0");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user