fix(v2): authenticate Gitea clones without URL credentials
This commit is contained in:
@@ -244,18 +244,23 @@ async function firstDeploy(
|
|||||||
|
|
||||||
const giteaPat = user.giteaPAT ? decrypt(user.giteaPAT) : "";
|
const giteaPat = user.giteaPAT ? decrypt(user.giteaPAT) : "";
|
||||||
const parsedUrl = new URL(cloneUrl.startsWith("http") ? cloneUrl : `https://${cloneUrl}`);
|
const parsedUrl = new URL(cloneUrl.startsWith("http") ? cloneUrl : `https://${cloneUrl}`);
|
||||||
parsedUrl.username = encodeURIComponent(user.giteaUsername || "");
|
parsedUrl.username = "";
|
||||||
parsedUrl.password = encodeURIComponent(giteaPat);
|
parsedUrl.password = "";
|
||||||
const authCloneUrl = parsedUrl.toString();
|
const cleanCloneUrl = parsedUrl.toString();
|
||||||
|
const authHeader = Buffer.from(`${user.giteaUsername || ""}:${giteaPat}`).toString("base64");
|
||||||
|
|
||||||
// Log a masked version so PAT is not exposed in preview logs
|
// Keep the PAT out of both preview logs and the URL. Gitea deployments can
|
||||||
const maskedUrl = `${parsedUrl.protocol}//${parsedUrl.username}:****@${parsedUrl.hostname}${parsedUrl.port ? ":" + parsedUrl.port : ""}${parsedUrl.pathname}`;
|
// reject userinfo URLs, while Git's per-command HTTP header works for both
|
||||||
await appendLog(previewId, `$ git clone '${maskedUrl}' /opt/app\n`);
|
// private repositories and reverse proxies.
|
||||||
const cloneResult = await sshSession.exec(`git clone '${authCloneUrl}' /opt/app`);
|
await appendLog(previewId, `$ git clone '${cleanCloneUrl}' /opt/app\n`);
|
||||||
|
const cloneCommand = giteaPat
|
||||||
|
? `git -c http.extraHeader='Authorization: Basic ${authHeader}' clone '${cleanCloneUrl}' /opt/app`
|
||||||
|
: `git clone '${cleanCloneUrl}' /opt/app`;
|
||||||
|
const cloneResult = await sshSession.exec(cloneCommand);
|
||||||
if (cloneResult.stdout) await appendLog(previewId, cloneResult.stdout);
|
if (cloneResult.stdout) await appendLog(previewId, cloneResult.stdout);
|
||||||
if (cloneResult.stderr) {
|
if (cloneResult.stderr) {
|
||||||
// Mask PAT in stderr output too
|
// Mask PAT in stderr output too
|
||||||
const maskedStderr = cloneResult.stderr.replace(encodeURIComponent(giteaPat), "****").replace(giteaPat, "****");
|
const maskedStderr = cloneResult.stderr.replace(giteaPat, "****").replace(authHeader, "****");
|
||||||
await appendLog(previewId, maskedStderr);
|
await appendLog(previewId, maskedStderr);
|
||||||
}
|
}
|
||||||
if (cloneResult.code !== 0) throw new Error(`git clone failed with exit code ${cloneResult.code}`);
|
if (cloneResult.code !== 0) throw new Error(`git clone failed with exit code ${cloneResult.code}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user