From 37175dc7d9f3932b9c8bec7cfa69866c84b1cdad Mon Sep 17 00:00:00 2001 From: Vegard Stenhjem Hagen Date: Sun, 28 Jan 2024 20:26:49 +0100 Subject: [PATCH] fix: Use processed token when getting upload URL (#41) Using raw supplied auth when getting the upload URL fails with e.g. GitLab when we need to process the authentication to get a valid token --- CHANGELOG.md | 6 ++++++ README.md | 2 +- package.json | 2 +- src/registry.ts | 44 ++++++++++++++++++++++++-------------------- src/version.ts | 2 +- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b72c5..227b86b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [3.1.1] - 2024-01-28 + +### Fixed + +- Use processed token instead of raw supplied auth to get upload URL + ## [3.1.0] - 2024-01-27 ### Added diff --git a/README.md b/README.md index ad0be17..32230a2 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ This will take the `nginx:alpine` image, and copy the files from `./dist/` into 1. Create the repository in GitLab 2. Login using your username and password, [CI-credentials](https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html), or [obtain a token from GitLab](https://docs.gitlab.com/ee/api/container_registry.html#obtain-token-from-gitlab) -3. Example using CI-credentials `containerify --toToken "Basic $(echo -n '${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}' | base64)" --to registry.gitlab.com//:` +3. Example using CI-credentials `containerify --toToken "Basic $(echo -n "${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}" | base64)" --to registry.gitlab.com//:` ### Command line options diff --git a/package.json b/package.json index 99c8677..1bdde9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "containerify", - "version": "3.1.0", + "version": "3.1.1", "description": "Build node.js docker images without docker", "main": "./lib/cli.js", "scripts": { diff --git a/src/registry.ts b/src/registry.ts index 5e06e29..9ca7b1f 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -160,31 +160,35 @@ async function processToken( ): Promise { const { hostname } = URL.parse(registryBaseUrl); const image = parseImage(imagePath); - if (hostname?.endsWith(".docker.io") && !token) { - const resp = await dlJson<{ token: string }>( - `https://auth.docker.io/token?service=registry.docker.io&scope=repository:${image.path}:pull`, - {}, - allowInsecure, - ); - return `Bearer ${resp.token}`; - } - if (hostname?.endsWith(".gitlab.com") && token?.startsWith("Basic")) { - if (token?.includes(":")) { - token = "Basic " + Buffer.from(token?.replace("Basic ", "")).toString("base64"); - } - const resp = await dlJson<{ token: string }>( - `https://gitlab.com/jwt/auth?service=container_registry&scope=repository:${image.path}:pull,push`, - { Authorization: token }, - allowInsecure, - ); - return `Bearer ${resp.token}`; - } + if (hostname?.endsWith(".docker.io") && !token) return getDockerToken(image.path, allowInsecure) if (!token) return ""; //We allow to pull from tokenless registries + if (hostname?.endsWith(".gitlab.com") && token.startsWith("Basic ")) return getGitLabToken(token, image.path, allowInsecure) if (token.startsWith("Basic ")) return token; if (token.startsWith("ghp_")) return "Bearer " + Buffer.from(token).toString("base64"); return "Bearer " + token; } +async function getDockerToken(imagePath: string, allowInsecure: InsecureRegistrySupport) { + const resp = await dlJson<{ token: string }>( + `https://auth.docker.io/token?service=registry.docker.io&scope=repository:${imagePath}:pull`, + {}, + allowInsecure, + ); + return `Bearer ${resp.token}`; +} + +async function getGitLabToken(token: string, imagePath: string, allowInsecure: InsecureRegistrySupport) { + if (token.includes(":")) { + token = "Basic " + Buffer.from(token?.replace("Basic ", "")).toString("base64"); + } + const resp = await dlJson<{ token: string }>( + `https://gitlab.com/jwt/auth?service=container_registry&scope=repository:${imagePath}:pull,push`, + { Authorization: token }, + allowInsecure, + ); + return `Bearer ${resp.token}`; +} + type Mount = { mount: string; from: string }; type UploadURL = { uploadUrl: string }; type UploadURLorMounted = UploadURL | { mountSuccess: true }; @@ -223,7 +227,7 @@ export async function createRegistry( const url = `${registryBaseUrl}${image.path}/blobs/uploads/${parameters.size > 0 ? "?" + parameters : ""}`; const options: https.RequestOptions = URL.parse(url); options.method = "POST"; - if (auth) options.headers = { authorization: auth }; + if (token) options.headers = { authorization: token }; request(options, allowInsecure, (res) => { logger.debug("POST", `${url}`, res.statusCode); if (res.statusCode == 202) { diff --git a/src/version.ts b/src/version.ts index 4fe4e83..08e95e5 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = "3.1.0"; +export const VERSION = "3.1.1";