import { describe, expect, test } from "bun:test"; import { createHash } from "node:crypto"; import { parseImageReference, resolveRegistryDigest, } from "../../server/registry"; describe("OCI registry digest resolution", () => { test("parses tags, ports, defaults, and pinned references", () => { expect(parseImageReference("localhost:5000/team/image:v1")).toMatchObject({ registry: "localhost:5000", repository: "team/image", reference: "v1", }); expect( parseImageReference("registry.example.com/team/image").reference, ).toBe("latest"); const pinned = `sha256:${"a".repeat(64)}` as const; expect( parseImageReference(`registry.example.com/team/image@${pinned}`).digest, ).toBe(pinned); expect(() => parseImageReference("image:latest")).toThrow("registry host"); expect(() => parseImageReference(`registry.example.com/../image@${pinned}`), ).toThrow("Invalid image reference"); }); test("resolves an anonymous manifest using the advertised digest", async () => { const expected = `sha256:${"b".repeat(64)}` as const; const calls: Array<{ url: string; authorization: string | null }> = []; const fetcher = async ( input: string | URL | Request, init?: RequestInit, ) => { const headers = new Headers(init?.headers); calls.push({ url: String(input), authorization: headers.get("authorization"), }); return new Response("manifest", { headers: { "docker-content-digest": expected }, }); }; expect( await resolveRegistryDigest("registry.example.com/team/image:v1", { fetch: fetcher, }), ).toBe(expected); expect(calls).toEqual([ { url: "https://registry.example.com/v2/team/image/manifests/v1", authorization: null, }, ]); }); test("resolves through a trusted internal registry origin", async () => { const expected = `sha256:${"c".repeat(64)}` as const; let requested = ""; await expect( resolveRegistryDigest("registry.example.com/team/image:v1", { origin: "http://registry.registry.svc.cluster.local:5000/", insecure: true, fetch: async (input) => { requested = String(input); return new Response("manifest", { headers: { "docker-content-digest": expected }, }); }, }), ).resolves.toBe(expected); expect(requested).toBe( "http://registry.registry.svc.cluster.local:5000/v2/team/image/manifests/v1", ); }); test("follows a standard bearer challenge and hashes a digest-less response", async () => { const body = '{"schemaVersion":2}'; const expected = `sha256:${createHash("sha256").update(body).digest("hex")}` as const; const calls: Array<{ url: string; authorization: string | null }> = []; const fetcher = async ( input: string | URL | Request, init?: RequestInit, ) => { const url = String(input); const authorization = new Headers(init?.headers).get("authorization"); calls.push({ url, authorization }); if (url.startsWith("https://auth.example/token")) { expect(new URL(url).searchParams.get("scope")).toBe( "repository:team/image:pull", ); expect(authorization).toBe( `Basic ${Buffer.from("user:pass").toString("base64")}`, ); return Response.json({ access_token: "registry-token" }); } if (authorization !== "Bearer registry-token") { return new Response("unauthorized", { status: 401, headers: { "www-authenticate": 'Bearer realm="https://auth.example/token",service="registry.example.com"', }, }); } return new Response(body, { headers: { "content-type": "application/vnd.oci.image.manifest.v1+json", }, }); }; expect( await resolveRegistryDigest("registry.example.com/team/image:v2", { fetch: fetcher, credentials: { username: "user", password: "pass" }, }), ).toBe(expected); expect(calls).toHaveLength(3); expect(calls[2]?.authorization).toBe("Bearer registry-token"); }); test("rejects unsupported challenges and malformed advertised digests", async () => { const unauthorized = async () => new Response("no", { status: 401, headers: { "www-authenticate": 'Basic realm="registry"' }, }); await expect( resolveRegistryDigest("registry.example.com/team/image", { fetch: unauthorized, }), ).rejects.toThrow("401"); const malformed = async () => new Response("body", { headers: { "docker-content-digest": "sha256:bad" }, }); await expect( resolveRegistryDigest("registry.example.com/team/image", { fetch: malformed, }), ).rejects.toThrow("Invalid SHA-256"); }); });