import { describe, expect, it, vi } from "vitest"; import type { BackendIssuedImageAsset, ImageCapabilityVerifier, ImagePresetReference, ImageProbeRequest, PublicImmutableImageAsset, } from "../../src/application/ports/browser-transfer/image-cdn.ts"; import { IMAGE_CDN_IMPLEMENTATION_CEILINGS, ImageCdnPolicyRegistry, imageCdnPresetReference, type ImageCdnHardLimits, type ImageCdnPresetPolicy, } from "../../src/adapters/browser-transfer/image-cdn/image-cdn-policy.ts"; import { computeImageCapabilityBindingDigestHex, createImageCdnRuntime, DEFAULT_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS, MAX_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS, type ImageCapabilityVerificationScheduler, } from "../../src/adapters/browser-transfer/image-cdn/image-cdn-runtime.ts"; const hardLimits: ImageCdnHardLimits = Object.freeze({ maxIntrinsicWidth: 4_096, maxIntrinsicHeight: 4_096, maxSourcePixels: 16_777_216, maxCssDimension: 2_048, maxDpr: 2, maxQuality: 90, maxCandidateCount: 8, maxTransformedPixels: 1_048_576, maxDecodedBytes: 4_194_304, maxEncodedBytes: 524_288, maxUrlLength: 2_048, maxCapabilityLifetimeMs: 3_600_000, maxClockSkewMs: 60_000, minCapabilityRemainingMs: 30_000, maxPresetBindingsPerCapability: 8, maxConcurrentCapabilityVerifications: 8, allowedSourceMediaTypes: [ "image/avif", "image/jpeg", "image/png", "image/webp", ] as const, formatQualityCeilings: { avif: 80, jpeg: 85, png: 90, webp: 85, }, }); function acceptsTestImageKey(keyId: string): boolean { return keyId === "image-signing-2026-01"; } function createPreset( reference: ImagePresetReference, overrides: Partial = {}, ): ImageCdnPresetPolicy { return { reference, bindingId: "card-landscape-v1", width: 640, height: 360, fit: "cover", dprs: [2, 1], responsiveWidths: [640, 320], quality: 80, formats: ["avif", "webp", "jpeg"], sizes: "(max-width: 640px) 100vw, 640px", loading: "eager", decoding: "async", fetchPriority: "high", referrerPolicy: "strict-origin-when-cross-origin", probeMode: "NONE", allowUpscale: false, maxTransformedPixels: 1_048_576, maxDecodedBytes: 4_194_304, maxEncodedBytes: 524_288, ...overrides, }; } function createPolicies( presets: readonly ImageCdnPresetPolicy[], overrides: Readonly<{ hardLimits?: ImageCdnHardLimits; acceptedKeyIds?: readonly string[]; }> = {}, ): ImageCdnPolicyRegistry { return new ImageCdnPolicyRegistry({ applicationOrigin: "https://app.example.test", origins: [ { originKey: "product-images", origin: "https://images.example.test", assetPathPrefix: "/v1/assets/", minimumPublicMaxAgeSeconds: 31_536_000, }, ], presets, hardLimits: overrides.hardLimits ?? hardLimits, capability: { issuer: "image-bff", acceptedKeyIds: overrides.acceptedKeyIds ?? [ "image-signing-2026-01", ], }, }); } function publicAsset( overrides: Partial = {}, ): PublicImmutableImageAsset { return { kind: "ALLOWLISTED_PUBLIC", originKey: "product-images", assetId: "asset_Q3x8pL", revision: "rev_a8N2kP4z", mediaType: "image/jpeg", contentKind: "RASTER_STATIC", intrinsicWidth: 2_048, intrinsicHeight: 1_152, ...overrides, }; } async function privateAsset( overrides: Partial = {}, ): Promise { const base: BackendIssuedImageAsset = { kind: "BACKEND_ISSUED_PRIVATE", issuer: "image-bff", originKey: "product-images", assetId: "asset_Q3x8pL", revision: "rev_a8N2kP4z", mediaType: "image/jpeg", contentKind: "RASTER_STATIC", intrinsicWidth: 2_048, intrinsicHeight: 1_152, capabilityId: "cap_Z8m2Q7pR", issuedAtEpochMs: 1_000_000, expiresAtEpochMs: 1_300_000, allowedPresetBindingIds: ["card-landscape-v1"], signature: { algorithm: "ECDSA_P256_SHA256", keyId: "image-signing-2026-01", capabilityBindingDigestHex: "0".repeat(64), valueBase64Url: "A".repeat(86), }, ...overrides, }; const descriptor = { ...base, signature: { ...base.signature, ...(overrides.signature ?? {}), }, }; const digest = await computeImageCapabilityBindingDigestHex( globalThis.crypto.subtle, descriptor, ); return { ...descriptor, signature: { ...descriptor.signature, capabilityBindingDigestHex: digest, }, }; } import { manualCapabilityVerificationScheduler } from "./image-cdn-test-fixture.ts"; describe("production image CDN runtime", () => { it("builds sorted, duplicate-free responsive candidates from a named preset", async () => { const preset = imageCdnPresetReference( "card-landscape", "render-public-product-image", ); const runtime = createImageCdnRuntime({ policies: createPolicies([createPreset(preset)]), now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: vi.fn().mockResolvedValue(true), }, }); const accepted = runtime.assets.acceptPublicImmutable( publicAsset(), ); expect(accepted.ok).toBe(true); if (!accepted.ok) return; const resolved = await runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }); expect(resolved.ok).toBe(true); if (!resolved.ok) return; const widthDescriptors = resolved.value.srcSet .split(", ") .map((candidate) => Number(candidate.match(/ (\d+)w$/u)?.[1]), ); expect(widthDescriptors).toEqual([320, 640, 1_280]); expect(new Set(widthDescriptors).size).toBe(3); expect(resolved.value.sources.map((source) => source.type)).toEqual( ["image/avif", "image/webp"], ); expect(resolved.value.fallbackMediaType).toBe("image/jpeg"); expect(resolved.value).toMatchObject({ width: 640, height: 360, loading: "eager", decoding: "async", fetchPriority: "high", crossOrigin: "anonymous", delivery: { class: "PUBLIC_IMMUTABLE", browserCache: "PUBLIC_IMMUTABLE", sharedCache: "PUBLIC_IMMUTABLE", purge: "REVISION_ROLLOVER", expiresAtEpochMs: null, }, decodeBudget: { maximumCandidatePixels: 921_600, maximumDecodedBytes: 3_686_400, }, }); const primary = new URL(resolved.value.src); expect(primary.origin).toBe("https://images.example.test"); expect(primary.pathname).toBe( "/v1/assets/asset_Q3x8pL/rev_a8N2kP4z", ); expect([...primary.searchParams.keys()]).toEqual([ "dpr", "fit", "format", "height", "preset", "quality", "width", ]); expect(Object.fromEntries(primary.searchParams)).toEqual({ dpr: "1", fit: "cover", format: "jpeg", height: "360", preset: "card-landscape-v1", quality: "80", width: "640", }); }); it("rejects raw URL/query/transform input and forged preset or asset references", async () => { const preset = imageCdnPresetReference( "card-landscape", "render-public-product-image", ); const runtime = createImageCdnRuntime({ policies: createPolicies([createPreset(preset)]), now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: vi.fn().mockResolvedValue(true), }, }); expect( runtime.assets.acceptPublicImmutable({ ...publicAsset(), sourceUrl: `${"java"}script:alert(1)`, } as PublicImmutableImageAsset), ).toMatchObject({ ok: false, error: { code: "INVALID_INPUT" }, }); expect( runtime.assets.acceptPublicImmutable( publicAsset({ assetId: "../../admin?width=9999", }), ), ).toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); expect( runtime.assets.acceptPublicImmutable( publicAsset({ mediaType: "image/svg+xml", } as unknown as Partial), ), ).toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); const accepted = runtime.assets.acceptPublicImmutable( publicAsset(), ); expect(accepted.ok).toBe(true); if (!accepted.ok) return; await expect( runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, width: 9_999, query: "format=svg", src: "data:text/html,active", } as unknown as Parameters[0]), ).resolves.toMatchObject({ ok: false, error: { code: "INVALID_INPUT" }, }); await expect( runtime.presentation.resolve({ asset: accepted.value, preset: imageCdnPresetReference( "card-landscape", "render-public-product-image", ), signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); await expect( runtime.presentation.resolve({ asset: {} as typeof accepted.value, preset, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); }); it("deep-snapshots origin and preset policy against TOCTOU mutation", async () => { const presetReference = imageCdnPresetReference( "card-landscape", "render-public-product-image", ); const origin = { originKey: "product-images", origin: "https://images.example.test", assetPathPrefix: "/v1/assets/", minimumPublicMaxAgeSeconds: 31_536_000, }; const preset = createPreset(presetReference); const policies = new ImageCdnPolicyRegistry({ applicationOrigin: "https://app.example.test", origins: [origin], presets: [preset], hardLimits, capability: { issuer: "image-bff", acceptedKeyIds: ["image-signing-2026-01"], }, }); origin.origin = "https://attacker.invalid"; origin.assetPathPrefix = "/stolen/"; (preset.dprs as number[])[0] = 4; (preset.formats as string[])[0] = "svg"; (preset as { quality: number }).quality = 100; const runtime = createImageCdnRuntime({ policies }); const accepted = runtime.assets.acceptPublicImmutable( publicAsset(), ); expect(accepted.ok).toBe(true); if (!accepted.ok) return; const resolved = await runtime.presentation.resolve({ asset: accepted.value, preset: presetReference, signal: new AbortController().signal, }); expect(resolved.ok).toBe(true); if (!resolved.ok) return; const url = new URL(resolved.value.src); expect(url.origin).toBe("https://images.example.test"); expect(url.pathname.startsWith("/v1/assets/")).toBe(true); expect(url.searchParams.get("quality")).toBe("80"); expect(resolved.value.sources[0]?.type).toBe("image/avif"); }); it("rejects unsafe origins and preset budgets at composition time", () => { const preset = imageCdnPresetReference( "unsafe", "reject-policy", ); expect( () => new ImageCdnPolicyRegistry({ applicationOrigin: "https://app.example.test", origins: [ { originKey: "bad", origin: "http://user:password@example.test/?q=x#x", assetPathPrefix: "/../assets/", minimumPublicMaxAgeSeconds: 1, }, ], presets: [createPreset(preset)], hardLimits, capability: { issuer: "image-bff", acceptedKeyIds: ["image-signing-2026-01"], }, }), ).toThrow(/origin policy/u); expect( () => createPolicies([ createPreset(preset, { maxTransformedPixels: 100, maxDecodedBytes: 400, }), ]), ).toThrow(/pixel budget/u); const validRegistryOptions = { origins: [ { originKey: "product-images", origin: "https://images.example.test", assetPathPrefix: "/v1/assets/", minimumPublicMaxAgeSeconds: 31_536_000, }, ], presets: [createPreset(preset)], hardLimits, capability: { issuer: "image-bff", acceptedKeyIds: ["image-signing-2026-01"], }, }; expect( () => new ImageCdnPolicyRegistry({ ...validRegistryOptions, applicationOrigin: "https://images.example.test", }), ).toThrow(/cross-origin/u); for (const applicationOrigin of [ "http://app.example.test", "https://app.example.test/", ]) { expect( () => new ImageCdnPolicyRegistry({ ...validRegistryOptions, applicationOrigin, }), ).toThrow(/application origin/u); } }); it("enforces immutable implementation ceilings on every resource-bearing hard limit", () => { const preset = imageCdnPresetReference( "absolute-ceilings", "bound-image-composition", ); const ceiling = IMAGE_CDN_IMPLEMENTATION_CEILINGS; const overCeiling: readonly Partial[] = [ { maxIntrinsicWidth: ceiling.maxIntrinsicWidth + 1 }, { maxIntrinsicHeight: ceiling.maxIntrinsicHeight + 1 }, { maxSourcePixels: ceiling.maxSourcePixels + 1 }, { maxCssDimension: ceiling.maxCssDimension + 1 }, { maxDpr: ceiling.maxDpr + 1 }, { maxQuality: ceiling.maxQuality + 1 }, { maxCandidateCount: ceiling.maxCandidateCount + 1 }, { maxTransformedPixels: ceiling.maxTransformedPixels + 1, }, { maxDecodedBytes: ceiling.maxDecodedBytes + 1 }, { maxEncodedBytes: ceiling.maxEncodedBytes + 1 }, { maxUrlLength: ceiling.maxUrlLength + 1 }, { maxCapabilityLifetimeMs: ceiling.maxCapabilityLifetimeMs + 1, }, { maxClockSkewMs: ceiling.maxClockSkewMs + 1 }, { minCapabilityRemainingMs: ceiling.maxMinimumCapabilityRemainingMs + 1, }, { maxPresetBindingsPerCapability: ceiling.maxPresetBindingsPerCapability + 1, }, { maxConcurrentCapabilityVerifications: ceiling.maxConcurrentCapabilityVerifications + 1, }, ]; for (const override of overCeiling) { expect(() => createPolicies([createPreset(preset)], { hardLimits: { ...hardLimits, ...override }, }), ).toThrow(/hard limits/u); } const boundaryLimits: ImageCdnHardLimits = { ...hardLimits, maxIntrinsicWidth: ceiling.maxIntrinsicWidth, maxIntrinsicHeight: ceiling.maxIntrinsicHeight, maxSourcePixels: ceiling.maxSourcePixels, maxCssDimension: ceiling.maxCssDimension, maxDpr: ceiling.maxDpr, maxQuality: ceiling.maxQuality, maxCandidateCount: ceiling.maxCandidateCount, maxTransformedPixels: ceiling.maxTransformedPixels, maxDecodedBytes: ceiling.maxDecodedBytes, maxEncodedBytes: ceiling.maxEncodedBytes, maxUrlLength: ceiling.maxUrlLength, maxCapabilityLifetimeMs: ceiling.maxCapabilityLifetimeMs, maxClockSkewMs: ceiling.maxClockSkewMs, minCapabilityRemainingMs: ceiling.maxMinimumCapabilityRemainingMs, maxPresetBindingsPerCapability: ceiling.maxPresetBindingsPerCapability, maxConcurrentCapabilityVerifications: ceiling.maxConcurrentCapabilityVerifications, }; expect(() => createPolicies([createPreset(preset)], { hardLimits: boundaryLimits, }), ).not.toThrow(); }); it("snapshots a bounded unique capability-key overlap set", () => { const preset = imageCdnPresetReference( "key-policy", "rotate-image-signing-key", ); for (const acceptedKeyIds of [ [], ["image-key-current", "image-key-current"], Array.from( { length: IMAGE_CDN_IMPLEMENTATION_CEILINGS.maxAcceptedKeyIds + 1, }, (_, index) => `image-key-${index}`, ), ["image-key-current", "invalid/key"], ]) { expect(() => createPolicies([createPreset(preset)], { acceptedKeyIds, }), ).toThrow(/capability policy/u); } const mutableKeyIds = [ "image-signing-2026-02", "image-signing-2026-01", ]; const policies = createPolicies([createPreset(preset)], { acceptedKeyIds: mutableKeyIds, }); mutableKeyIds[0] = "image-signing-attacker"; expect(policies.capabilityPolicy().acceptedKeyIds).toEqual([ "image-signing-2026-02", "image-signing-2026-01", ]); expect( Object.isFrozen( policies.capabilityPolicy().acceptedKeyIds, ), ).toBe(true); }); it("accepts old and new overlap keys only when policy and verifier registries both cover them", async () => { const preset = imageCdnPresetReference( "key-overlap", "verify-image-key-rotation", ); const acceptedKeyIds = [ "image-signing-2026-02", "image-signing-2026-01", ] as const; const policies = createPolicies([createPreset(preset)], { acceptedKeyIds, }); const verifierKeys = new Set(acceptedKeyIds); const verify = vi.fn( async (request: { keyId: string }) => verifierKeys.has(request.keyId), ); const runtime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: (keyId) => verifierKeys.has(keyId), verify, }, }); const previous = await privateAsset(); const current = await privateAsset({ signature: { algorithm: "ECDSA_P256_SHA256", keyId: "image-signing-2026-02", capabilityBindingDigestHex: "0".repeat(64), valueBase64Url: "A".repeat(86), }, }); await expect( runtime.assets.acceptBackendIssued(previous), ).resolves.toMatchObject({ ok: true }); await expect( runtime.assets.acceptBackendIssued(current), ).resolves.toMatchObject({ ok: true }); expect(verify.mock.calls.map(([request]) => request.keyId)).toEqual( ["image-signing-2026-01", "image-signing-2026-02"], ); const unknown = await privateAsset({ signature: { algorithm: "ECDSA_P256_SHA256", keyId: "image-signing-2027-01", capabilityBindingDigestHex: "0".repeat(64), valueBase64Url: "A".repeat(86), }, }); await expect( runtime.assets.acceptBackendIssued(unknown), ).resolves.toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); expect(verify).toHaveBeenCalledTimes(2); expect(() => createImageCdnRuntime({ policies, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: (keyId) => keyId === "image-signing-2026-02", verify: vi.fn().mockResolvedValue(true), }, }), ).toThrow(/registry does not cover/u); expect(() => createImageCdnRuntime({ policies, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey() { throw new TypeError("registry unavailable"); }, verify: vi.fn().mockResolvedValue(true), }, }), ).toThrow(/registry does not cover/u); }); it("binds a private descriptor to its signed snapshot and exact preset", async () => { const preset = imageCdnPresetReference( "card-landscape", "render-private-product-image", ); const policies = createPolicies([ createPreset(preset, { probeMode: "PRIMARY_REQUIRED", }), ]); let releaseVerification: ((value: boolean) => void) | undefined; const verifierMethod = vi.fn( () => new Promise((resolve) => { releaseVerification = resolve; }), ); const verifier: ImageCapabilityVerifier = { acceptsKey: acceptsTestImageKey, verify: verifierMethod, }; let now = 1_000_000; const runtime = createImageCdnRuntime({ policies, now: () => now, subtle: globalThis.crypto.subtle, capabilityVerifier: verifier, probe: { async probe(request) { return { ok: true, value: { absoluteUrl: request.absoluteUrl, mediaType: request.expectedMediaType, encodedBytes: 1_024, decodedWidth: request.expectedWidth, decodedHeight: request.expectedHeight, }, }; }, }, }); ( verifier as { verify: ImageCapabilityVerifier["verify"]; } ).verify = vi.fn().mockResolvedValue(false); const mutable = (await privateAsset()) as { -readonly [Key in keyof BackendIssuedImageAsset]: BackendIssuedImageAsset[Key]; }; const pending = runtime.assets.acceptBackendIssued(mutable); await vi.waitFor(() => { expect(verifierMethod).toHaveBeenCalledOnce(); }); mutable.assetId = "asset_ATTACKER"; mutable.revision = "rev_ATTACKER"; mutable.expiresAtEpochMs = 9_999_999; releaseVerification?.(true); const accepted = await pending; expect(accepted.ok).toBe(true); if (!accepted.ok) return; const resolved = await runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }); expect(resolved.ok).toBe(true); if (!resolved.ok) return; const url = new URL(resolved.value.src); expect(url.pathname).toContain( "/asset_Q3x8pL/rev_a8N2kP4z", ); expect(url.pathname).not.toContain("ATTACKER"); expect([...url.searchParams.keys()]).toEqual([ "binding", "capability", "dpr", "expires", "fit", "format", "height", "key", "preset", "quality", "signature", "width", ]); expect(resolved.value).toMatchObject({ loading: "eager", referrerPolicy: "no-referrer", crossOrigin: "anonymous", delivery: { class: "PRIVATE_SIGNED", browserCache: "NO_STORE", sharedCache: "FORBIDDEN", purge: "CAPABILITY_REVOCATION_OR_EXPIRY", expiresAtEpochMs: 1_300_000, }, }); now = 1_275_001; await expect( runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "EXPIRED_RESOURCE" }, }); }); it("rejects invalid binding/signature and private lazy or low-priority presets", async () => { const eager = imageCdnPresetReference( "private-eager", "render-private", ); const lazy = imageCdnPresetReference( "private-lazy", "render-private", ); const policies = createPolicies([ createPreset(eager, { bindingId: "private-eager-v1", }), createPreset(lazy, { bindingId: "private-lazy-v1", loading: "lazy", fetchPriority: "low", }), ]); const runtime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: vi.fn().mockResolvedValue(true), }, }); const issued = await privateAsset({ allowedPresetBindingIds: [ "private-eager-v1", "private-lazy-v1", ], }); const accepted = await runtime.assets.acceptBackendIssued(issued); expect(accepted.ok).toBe(true); if (!accepted.ok) return; await expect( runtime.presentation.resolve({ asset: accepted.value, preset: eager, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); await expect( runtime.presentation.resolve({ asset: accepted.value, preset: lazy, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "POLICY_REJECTED" }, }); await expect( runtime.assets.acceptBackendIssued({ ...issued, signature: { ...issued.signature, capabilityBindingDigestHex: "f".repeat(64), }, }), ).resolves.toMatchObject({ ok: false, error: { code: "INTEGRITY_FAILED" }, }); const rejectingRuntime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: vi.fn().mockResolvedValue(false), }, }); await expect( rejectingRuntime.assets.acceptBackendIssued(issued), ).resolves.toMatchObject({ ok: false, error: { code: "INTEGRITY_FAILED" }, }); }); it("bounds digest and capability verification with a runtime-owned deadline and caller abort", async () => { const preset = imageCdnPresetReference( "deadline", "verify-private-capability", ); const policies = createPolicies([createPreset(preset)]); const issued = await privateAsset(); const observations: Record[] = []; const verifierDeadline = manualCapabilityVerificationScheduler(); const stalledVerifier = vi.fn( () => new Promise(() => undefined), ); const verifierRuntime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: stalledVerifier, }, capabilityVerificationScheduler: verifierDeadline.scheduler, observer: { record(observation) { observations.push(observation); }, }, }); const verifierPending = verifierRuntime.assets.acceptBackendIssued(issued); await vi.waitFor(() => { expect(stalledVerifier).toHaveBeenCalledOnce(); }); expect(verifierDeadline.delays).toEqual([ DEFAULT_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS, ]); verifierDeadline.fire(); await expect(verifierPending).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE", retryable: true, recovery: "RETRY", }, }); expect(verifierDeadline.clearTimeout).toHaveBeenCalledOnce(); expect(observations).toEqual([ expect.objectContaining({ operation: "IMAGE_RESOLVE", outcome: "FAILED", failureCode: "UNAVAILABLE", countBucket: "ZERO", }), ]); const digestDeadline = manualCapabilityVerificationScheduler(); const stalledDigest = vi.fn( () => new Promise(() => undefined), ); const digestVerifier = vi.fn().mockResolvedValue(true); const digestRuntime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: { digest: stalledDigest as SubtleCrypto["digest"], }, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: digestVerifier, }, capabilityVerificationTimeoutMs: MAX_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS, capabilityVerificationScheduler: digestDeadline.scheduler, }); const digestPending = digestRuntime.assets.acceptBackendIssued(issued); await vi.waitFor(() => { expect(stalledDigest).toHaveBeenCalledOnce(); }); expect(digestDeadline.delays).toEqual([ MAX_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS, ]); digestDeadline.fire(); await expect(digestPending).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE" }, }); expect(digestVerifier).not.toHaveBeenCalled(); const abortDeadline = manualCapabilityVerificationScheduler(); const abortVerifier = vi.fn( () => new Promise(() => undefined), ); const abortRuntime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: abortVerifier, }, capabilityVerificationScheduler: abortDeadline.scheduler, }); const controller = new AbortController(); const abortPending = abortRuntime.assets.acceptBackendIssued( issued, { signal: controller.signal }, ); await vi.waitFor(() => { expect(abortVerifier).toHaveBeenCalledOnce(); }); controller.abort(); await expect(abortPending).resolves.toMatchObject({ ok: false, error: { code: "ABORTED" }, }); expect(abortDeadline.clearTimeout).toHaveBeenCalledOnce(); }); /** * TR-RR-07. The concurrency cap exists to bound *physical* verification work. * Releasing the slot when the wrapper's abort resolved let an abandoned * verifier keep running while a new one was admitted, so repeated aborts * produced more concurrent work than the configured cap allows. */ it("holds the verification slot until the raw verifier settles", async () => { const preset = imageCdnPresetReference( "verification-concurrency", "bound-image-verification-concurrency", ); const policies = createPolicies([createPreset(preset)], { hardLimits: { ...hardLimits, maxConcurrentCapabilityVerifications: 1, }, }); let verificationAttempt = 0; let releaseFirst: ((value: boolean) => void) | undefined; const verify = vi.fn(() => { verificationAttempt += 1; return verificationAttempt === 1 ? new Promise((resolve) => { releaseFirst = resolve; }) : Promise.resolve(true); }); const runtime = createImageCdnRuntime({ policies, now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify, }, }); const issued = await privateAsset(); const controller = new AbortController(); const first = runtime.assets.acceptBackendIssued(issued, { signal: controller.signal, }); await vi.waitFor(() => { expect(verify).toHaveBeenCalledOnce(); }); await expect( runtime.assets.acceptBackendIssued(issued), ).resolves.toMatchObject({ ok: false, error: { code: "LIMIT_EXCEEDED" }, }); expect(verify).toHaveBeenCalledOnce(); controller.abort(); await expect(first).resolves.toMatchObject({ ok: false, error: { code: "ABORTED" }, }); // The caller's wait ended, but the raw verifier has not. Admitting a second // one here would put two physical verifications under a cap of one. await expect( runtime.assets.acceptBackendIssued(issued), ).resolves.toMatchObject({ ok: false, error: { code: "LIMIT_EXCEEDED" }, }); expect(verify).toHaveBeenCalledOnce(); // Once the raw verifier settles the slot is free again. releaseFirst?.(true); await vi.waitFor(async () => { await expect( runtime.assets.acceptBackendIssued(issued), ).resolves.toMatchObject({ ok: true }); }); expect(verify).toHaveBeenCalledTimes(2); }); it("fails fast on invalid capability verification deadline composition", () => { const preset = imageCdnPresetReference( "deadline-config", "validate-private-capability-deadline", ); const policies = createPolicies([createPreset(preset)]); expect( DEFAULT_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS, ).toBe(5_000); expect(MAX_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS).toBe( 60_000, ); for (const capabilityVerificationTimeoutMs of [ 0, 1.5, MAX_IMAGE_CAPABILITY_VERIFICATION_TIMEOUT_MS + 1, ]) { expect(() => createImageCdnRuntime({ policies, capabilityVerificationTimeoutMs, }), ).toThrow(/verification timeout/u); } expect(() => createImageCdnRuntime({ policies, capabilityVerificationScheduler: { setTimeout: null, clearTimeout: vi.fn(), } as unknown as ImageCapabilityVerificationScheduler, }), ).toThrow(/verification scheduler/u); }); it("closes terminally and idempotently, revoking old references and rejecting every later operation", async () => { const preset = imageCdnPresetReference( "lifecycle", "close-image-runtime", ); const runtime = createImageCdnRuntime({ policies: createPolicies([createPreset(preset)]), now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: vi.fn().mockResolvedValue(true), }, }); const accepted = runtime.assets.acceptPublicImmutable(publicAsset()); expect(accepted.ok).toBe(true); if (!accepted.ok) return; await expect( runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: true }); const acceptedPrivate = await runtime.assets.acceptBackendIssued( await privateAsset(), ); expect(acceptedPrivate.ok).toBe(true); if (!acceptedPrivate.ok) return; runtime.close(); expect(() => runtime.close()).not.toThrow(); await expect( runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE", retryable: false, recovery: "NONE", }, }); await expect( runtime.presentation.resolve({ asset: acceptedPrivate.value, preset, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE" }, }); expect( runtime.assets.acceptPublicImmutable(publicAsset()), ).toMatchObject({ ok: false, error: { code: "UNAVAILABLE" }, }); await expect( runtime.assets.acceptBackendIssued(await privateAsset()), ).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE" }, }); }); it("close aborts stalled private verification and image probing", async () => { const verifierPreset = imageCdnPresetReference( "close-verifier", "abort-image-verification", ); const verifierDeadline = manualCapabilityVerificationScheduler(); const stalledVerifier = vi.fn( () => new Promise(() => undefined), ); const verifierRuntime = createImageCdnRuntime({ policies: createPolicies([ createPreset(verifierPreset), ]), now: () => 1_000_000, subtle: globalThis.crypto.subtle, capabilityVerifier: { acceptsKey: acceptsTestImageKey, verify: stalledVerifier, }, capabilityVerificationScheduler: verifierDeadline.scheduler, }); const verificationPending = verifierRuntime.assets.acceptBackendIssued( await privateAsset(), ); await vi.waitFor(() => { expect(stalledVerifier).toHaveBeenCalledOnce(); }); verifierRuntime.close(); await expect(verificationPending).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE", retryable: false }, }); expect(verifierDeadline.clearTimeout).toHaveBeenCalledOnce(); const probePreset = imageCdnPresetReference( "close-probe", "abort-image-probe", ); const stalledProbe = vi.fn( (_request: ImageProbeRequest) => new Promise(() => undefined), ); const probeRuntime = createImageCdnRuntime({ policies: createPolicies([ createPreset(probePreset, { probeMode: "PRIMARY_REQUIRED", }), ]), probe: { probe: stalledProbe }, }); const accepted = probeRuntime.assets.acceptPublicImmutable(publicAsset()); expect(accepted.ok).toBe(true); if (!accepted.ok) return; const caller = new AbortController(); const probePending = probeRuntime.presentation.resolve({ asset: accepted.value, preset: probePreset, signal: caller.signal, }); await vi.waitFor(() => { expect(stalledProbe).toHaveBeenCalledOnce(); }); const runtimeSignal = stalledProbe.mock.calls[0]?.[0].signal; expect(runtimeSignal).not.toBe(caller.signal); probeRuntime.close(); await expect(probePending).resolves.toMatchObject({ ok: false, error: { code: "UNAVAILABLE", retryable: false }, }); expect(runtimeSignal?.aborted).toBe(true); }); it("requires and validates the bounded probe receipt when the preset says so", async () => { const preset = imageCdnPresetReference( "probed", "render-verified-image", ); const policy = createPreset(preset, { bindingId: "probed-v1", probeMode: "PRIMARY_REQUIRED", }); const withoutProbe = createImageCdnRuntime({ policies: createPolicies([policy]), }); const noProbeAsset = withoutProbe.assets.acceptPublicImmutable(publicAsset()); expect(noProbeAsset.ok).toBe(true); if (!noProbeAsset.ok) return; await expect( withoutProbe.presentation.resolve({ asset: noProbeAsset.value, preset, signal: new AbortController().signal, }), ).resolves.toMatchObject({ ok: false, error: { code: "UNSUPPORTED" }, }); const probe = vi.fn(async (request: ImageProbeRequest) => ({ ok: true as const, value: { absoluteUrl: request.absoluteUrl, mediaType: request.expectedMediaType, encodedBytes: 1_024, decodedWidth: request.expectedWidth, decodedHeight: request.expectedHeight, }, })); const runtime = createImageCdnRuntime({ policies: createPolicies([policy]), probe: { probe }, }); const accepted = runtime.assets.acceptPublicImmutable(publicAsset()); expect(accepted.ok).toBe(true); if (!accepted.ok) return; const resolved = await runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }); expect(resolved.ok).toBe(true); expect(probe).toHaveBeenCalledWith( expect.objectContaining({ expectedMediaType: "image/jpeg", expectedWidth: 640, expectedHeight: 360, maxEncodedBytes: 524_288, maxDecodedBytes: 4_194_304, delivery: "PUBLIC_IMMUTABLE", }), ); }); it("records only safe terminal buckets for accept, probe and resolve", async () => { const preset = imageCdnPresetReference( "observed", "render-observed-image", ); const observations: Record[] = []; const observer = { record(observation: Record) { observations.push(observation); }, }; const runtime = createImageCdnRuntime({ policies: createPolicies([ createPreset(preset, { bindingId: "observed-v1", probeMode: "PRIMARY_REQUIRED", }), ]), observer, probe: { async probe(request) { return { ok: true, value: { absoluteUrl: request.absoluteUrl, mediaType: request.expectedMediaType, encodedBytes: 2_048, decodedWidth: request.expectedWidth, decodedHeight: request.expectedHeight, }, }; }, }, }); observer.record = () => { throw new TypeError("mutated observer must not be observed"); }; const accepted = runtime.assets.acceptPublicImmutable(publicAsset()); expect(accepted.ok).toBe(true); if (!accepted.ok) return; const resolved = await runtime.presentation.resolve({ asset: accepted.value, preset, signal: new AbortController().signal, }); expect(resolved.ok).toBe(true); expect(observations).toHaveLength(3); for (const observation of observations) { expect(observation).toMatchObject({ operation: "IMAGE_RESOLVE", outcome: "SUCCEEDED", }); expect(Object.keys(observation)).not.toEqual( expect.arrayContaining([ "assetId", "preset", "capability", "signature", "url", ]), ); expect(JSON.stringify(observation)).not.toContain( "images.example.test", ); } expect(observations.map((value) => value.countBucket)).toEqual([ "ONE", "ONE", "TWO_TO_TEN", ]); expect(observations.map((value) => value.byteBucket)).toEqual([ undefined, "LT1MIB", "LT1MIB", ]); }); });