import { createHash } from "node:crypto"; import { describe, expect, it } from "vitest"; import { createApp } from "../../apps/api/src/app.js"; import { MAX_PUBLIC_CACHE_BYTES, buildPublicAssetUrl, isPublicCacheDescriptor, isPublicServiceWorkerRoute, planPublicCacheWrite, type PublicAssetLruEntry, } from "../../apps/web/src/public-asset-cache.js"; const resourceIds = [ "123e4567-e89b-42d3-a456-426614174001", "123e4567-e89b-42d3-a456-426614174002", "123e4567-e89b-42d3-a456-426614174003", "123e4567-e89b-42d3-a456-426614174004", ] as const; describe("TDD-WP0-CACHE-001 public allowlist LRU", () => { it("freezes the 150 MiB policy and allows exact equality", () => { expect(MAX_PUBLIC_CACHE_BYTES).toBe(157_286_400); const plan = planPublicCacheWrite([], { bytes: MAX_PUBLIC_CACHE_BYTES, last_accessed_at: 4, release_version: "asset-20260727.2", resource_id: resourceIds[0], }, MAX_PUBLIC_CACHE_BYTES); expect(plan).toEqual({ accepted: true, evict: [], resulting_bytes: MAX_PUBLIC_CACHE_BYTES }); expect(planPublicCacheWrite([], { bytes: MAX_PUBLIC_CACHE_BYTES + 1, last_accessed_at: 4, release_version: "asset-20260727.2", resource_id: resourceIds[0], }, MAX_PUBLIC_CACHE_BYTES)).toEqual({ accepted: false, evict: [], resulting_bytes: 0 }); }); it("evicts old releases first and then the least recently used entry before writing", () => { const entries: PublicAssetLruEntry[] = [ { bytes: 40, last_accessed_at: 30, release_version: "asset-20260727.1", resource_id: resourceIds[0] }, { bytes: 40, last_accessed_at: 10, release_version: "asset-20260727.1", resource_id: resourceIds[1] }, { bytes: 40, last_accessed_at: 1, release_version: "asset-20260727.2", resource_id: resourceIds[2] }, ]; const plan = planPublicCacheWrite(entries, { bytes: 40, last_accessed_at: 40, release_version: "asset-20260727.2", resource_id: resourceIds[3], }, 120); expect(plan).toEqual({ accepted: true, evict: [resourceIds[1]], resulting_bytes: 120 }); }); it.each([ { access_class: "internal_preview_asset", cache_kind: "thumbnail" }, { access_class: "private_user_asset", cache_kind: "thumbnail" }, { access_class: "public_release_asset", cache_kind: "sticker_original" }, { access_class: "public_release_asset", cache_kind: "generation" }, { access_class: "public_release_asset", cache_kind: "export" }, { access_class: "public_release_asset", cache_kind: "project" }, { access_class: "public_release_asset", cache_kind: "prompt" }, { access_class: "public_release_asset", cache_kind: "verification_code" }, { access_class: "public_release_asset", cache_kind: "session" }, { access_class: "public_release_asset", cache_kind: "unsaved_edit" }, { access_class: "public_release_asset", cache_kind: "user_download" }, ])("rejects non-allowlisted candidate $access_class/$cache_kind", (candidate) => { expect(isPublicCacheDescriptor({ ...candidate, release_version: "asset-20260727.2", resource_id: resourceIds[0], })).toBe(false); }); it.each(["thumbnail", "template_conversion", "font"] as const)("allows public %s only", (cacheKind) => { expect(isPublicCacheDescriptor({ access_class: "public_release_asset", cache_kind: cacheKind, release_version: "asset-20260727.2", resource_id: resourceIds[0], })).toBe(true); }); it("constructs and intercepts only same-origin versioned public asset routes", () => { const url = buildPublicAssetUrl("asset-20260727.2", resourceIds[0]); expect(url).toBe(`/api/v1/assets/public/asset-20260727.2/${resourceIds[0]}`); expect(isPublicServiceWorkerRoute(new URL(url, "http://127.0.0.1:43121"), "http://127.0.0.1:43121")).toBe(true); for (const path of [ `/api/v1/assets/preview/asset-20260727.2/${resourceIds[0]}`, `/api/v1/private-assets/${resourceIds[0]}`, `/api/v1/projects/${resourceIds[0]}`, "/api/v1/support/check", "file:///C:/private.png", ]) { expect(isPublicServiceWorkerRoute(new URL(path, "http://127.0.0.1:43121"), "http://127.0.0.1:43121")).toBe(false); } }); it("serves existing public binaries as immutable versioned responses with a strong ETag", { timeout: 15_000 }, async () => { const bytes = Buffer.from("public-thumbnail"); const sha256 = createHash("sha256").update(bytes).digest("hex"); const app = await createApp({ browserGate: false, publicAssets: { read: () => ({ assetId: resourceIds[0], bytes, mimeType: "image/png", resourceVersion: "asset-20260727.2", sha256 }), }, }); const response = await app.inject({ headers: { host: "127.0.0.1:43121" }, method: "GET", url: `/api/v1/assets/public/asset-20260727.2/${resourceIds[0]}`, }); expect(response.statusCode).toBe(200); expect(response.headers["cache-control"]).toBe("public, max-age=31536000, immutable"); expect(response.headers.etag).toBe(`"sha256-${sha256}"`); expect(response.headers["x-content-type-options"]).toBe("nosniff"); await app.close(); }); });