.js
JavaScript
(text/javascript)
#!/usr/bin/node

const { HttpClient } = require("./http_client");
// const { HttpClient } = require("/home/debian/http_client.js");
const fs = require("fs");

const LOGS_FILE = "/opt/ssh_commands.log";

function log(message, ...args) {
  try {
    fs.appendFileSync(
      LOGS_FILE,
      JSON.stringify({
        timestamp: new Date().toISOString(),
        message,
        args,
      }) + "\n",
      { encoding: "utf8" },
    );
  } catch (err) {
    // console.log(message, ...args);
  }
}

async function main(args, sshOriginalCommand) {
  const [_, __, username] = args;

  if (username == null || username.trim() === "") {
    process.exit(128);
  }

  if (sshOriginalCommand == null) {
    process.exit(128);
  }

  const authorizedKeysBuffer = fs.readFileSync(
    "/home/git/.ssh/authorized_keys",
    { encoding: "utf8" },
  );

  const authKeys = authorizedKeysBuffer
    .split("\n")
    .map((line) =>
      line.startsWith("#")
        ? { type: "comment", text: line }
        : line.trim() !== ""
          ? { type: "key", text: line.trim() }
          : null,
    )
    .filter((x) => x != null && x.type === "key");

  // console.log("authkeys:", authKeys);
  // console.log("username", username);

  let userPk = authKeys.find(
    (key) =>
      key.text.includes(`command="ssh_command ${username}"`) ||
      key.text.includes(`command="/usr/bin/ssh_command ${username}"`),
  );

  if (userPk == null) {
    log("No key matched ssh connection in authorized_keys file.", { username });
    return process.exit(128);
  }

  const pk = userPk.text;

  const sshRsaIndex = pk.indexOf("ssh-rsa");
  const publicKey = pk.substring(sshRsaIndex);

  const [command, repoSlug] = sshOriginalCommand
    .split(" ")
    .map((part) => part.replace(/\'/g, "").trim());

  const data = JSON.stringify({
    command,
    repoSlug,
    username,
    publicKey,
  });

  log("Will authenticate through /_ssh/auth", {
    command,
    repoSlug,
    username,
    publicKey,
  });

  const client = new HttpClient();

  // console.log("HttpClient.instance:", client);

  const res = await client.post("http://localhost:1337/_ssh/auth", {
    headers: {
      "Content-Type": "application/json",
      "Content-Length": Buffer.byteLength(data),
    },
    body: data,
  });

  // console.log("res:", res);

  if (res.ok === false) {
    log(
      "/_ssh/auth response is an error:",
      res.statusCode,
      res.statusText,
      await res.text(),
    );
    return process.exit(128);
  }

  if ((await res.isJson()) === false) {
    log(
      "/_ssh/auth response is not json:",
      res.statusCode,
      res.statusText,
      await res.text(),
    );
    return process.exit(128);
  }

  const json = await res.json();

  log("/_ssh/auth response json:", res.statusCode, res.statusText, json);

  if (json.success === false) {
    log(
      "/_ssh/auth response is not successful:",
      res.statusCode,
      res.statusText,
      json,
    );
    return process.exit(128);
  }

  json.gitRepositoryDir = `/home/debian/data/gitfoss_repos/${repoSlug.replace(/\.git$/, "")}`;
  console.log(JSON.stringify(json));

  // success!
  log("/_ssh/auth response success!", json);
  process.exit(0);
}

main(process.argv, process.env.SSH_ORIGINAL_COMMAND);