Files
clean-architecture-frontend…/tests/unit/image-cdn-runtime.test.ts
T

1409 lines
41 KiB
TypeScript

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> = {},
): 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> = {},
): 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<BackendIssuedImageAsset> = {},
): Promise<BackendIssuedImageAsset> {
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<PublicImmutableImageAsset>),
),
).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<typeof runtime.presentation.resolve>[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<ImageCdnHardLimits>[] = [
{ 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<string>(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<boolean>((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<string, unknown>[] = [];
const verifierDeadline =
manualCapabilityVerificationScheduler();
const stalledVerifier = vi.fn(
() => new Promise<boolean>(() => 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<ArrayBuffer>(() => 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<boolean>(() => 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<boolean>((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<boolean>(() => 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<never>(() => 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<string, unknown>[] = [];
const observer = {
record(observation: Record<string, unknown>) {
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",
]);
});
});