diff --git a/src/authentication-method.ts b/src/authentication-method.ts index 37229a4..42fc0e0 100644 --- a/src/authentication-method.ts +++ b/src/authentication-method.ts @@ -6,11 +6,12 @@ import type { AuthenticatorCredentials } from "./user"; export async function authenticationMethodFromEnv(env: Env) { if (env.JWT_REGISTRY_TOKENS_PUBLIC_KEY) { return await newRegistryTokens(env.JWT_REGISTRY_TOKENS_PUBLIC_KEY); - } else if (env.USERNAME && env.PASSWORD) { - const credentials: AuthenticatorCredentials[] = [ - { username: env.USERNAME, password: env.PASSWORD, capabilities: ["pull", "push"] } - ]; + } else if ((env.USERNAME && env.PASSWORD) || (env.READONLY_USERNAME && env.READONLY_PASSWORD)) { + const credentials: AuthenticatorCredentials[] = []; + if (env.USERNAME && env.PASSWORD) { + credentials.push({ username: env.USERNAME, password: env.PASSWORD, capabilities: ["pull", "push"] }); + } if (env.READONLY_USERNAME && env.READONLY_PASSWORD) { credentials.push({ username: env.READONLY_USERNAME, password: env.READONLY_PASSWORD, capabilities: ["pull"] }); } @@ -18,7 +19,7 @@ export async function authenticationMethodFromEnv(env: Env) { return new UserAuthenticator(credentials); } - console.error("Either env.JWT_REGISTRY_TOKENS_PUBLIC_KEY must be set or both env.USERNAME, env.PASSWORD must be set."); + console.error("Either env.JWT_REGISTRY_TOKENS_PUBLIC_KEY must be set or both env.USERNAME, env.PASSWORD must be set or both env.READONLY_USERNAME, env.READONLY_PASSWORD must be set."); // invalid configuration return undefined; diff --git a/test/index.test.ts b/test/index.test.ts index 5c65e35..09d7472 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -466,6 +466,30 @@ describe("http client", () => { expect("exists" in res && res.exists).toBe(false); }); + + test("test manifest exists with readonly", async () => { + envBindings = { ...bindings }; + envBindings.JWT_REGISTRY_TOKENS_PUBLIC_KEY = ""; + envBindings.PASSWORD = ""; + envBindings.USERNAME = ""; + envBindings.READONLY_PASSWORD = "world"; + envBindings.READONLY_USERNAME = "hello"; + envBindings.REGISTRIES_JSON = undefined; + global.fetch = async function (r: RequestInfo): Promise { + return fetch(new Request(r)); + }; + const client = new RegistryHTTPClient(envBindings, { + registry: "https://localhost", + password_env: "PASSWORD", + username: "hello", + }); + const res = await client.manifestExists("namespace/hello", "latest"); + if ("response" in res) { + expect(await res.response.json()).toEqual({ status: res.response.status }); + } + + expect("exists" in res && res.exists).toBe(false); + }); }); describe("push and catalog", () => {