feat(v2): full spec implementation — root SSH, bootstrap sentinel, HMAC webhook, all parametric routes fixed #1

Merged
space merged 9 commits from v2/full-spec-implementation into main 2026-07-26 14:26:39 +02:00
Showing only changes of commit 714090c0ec - Show all commits
+13 -8
View File
@@ -244,18 +244,23 @@ async function firstDeploy(
const giteaPat = user.giteaPAT ? decrypt(user.giteaPAT) : "";
const parsedUrl = new URL(cloneUrl.startsWith("http") ? cloneUrl : `https://${cloneUrl}`);
parsedUrl.username = encodeURIComponent(user.giteaUsername || "");
parsedUrl.password = encodeURIComponent(giteaPat);
const authCloneUrl = parsedUrl.toString();
parsedUrl.username = "";
parsedUrl.password = "";
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
const maskedUrl = `${parsedUrl.protocol}//${parsedUrl.username}:****@${parsedUrl.hostname}${parsedUrl.port ? ":" + parsedUrl.port : ""}${parsedUrl.pathname}`;
await appendLog(previewId, `$ git clone '${maskedUrl}' /opt/app\n`);
const cloneResult = await sshSession.exec(`git clone '${authCloneUrl}' /opt/app`);
// Keep the PAT out of both preview logs and the URL. Gitea deployments can
// reject userinfo URLs, while Git's per-command HTTP header works for both
// private repositories and reverse proxies.
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.stderr) {
// 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);
}
if (cloneResult.code !== 0) throw new Error(`git clone failed with exit code ${cloneResult.code}`);