tlsMaterial

tcmts.cli.sync.tlsMaterial · #xy56k6bu · term · runs on the server

uses node:fs

The certificate and key for tcm serve --tls: given files, or a self-signed pair created once with openssl and kept in .tcm/tls/. Clients pin it by fingerprint.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";

export function tlsMaterial(cb: Codebase, cert?: string, key?: string): { cert: string; key: string } {
  if (cert || key) {
    if (!cert || !key) throw new Error("--tls-cert and --tls-key go together");
    return { cert: fs.readFileSync(cert, "utf8"), key: fs.readFileSync(key, "utf8") };
  }
  const dir = path.join(cb.lay.tcmDir, "tls");
  const [c, k] = [path.join(dir, "cert.pem"), path.join(dir, "key.pem")];
  if (!fs.existsSync(c) || !fs.existsSync(k)) {
    fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
    const r = spawnSync("openssl", ["req", "-x509", "-newkey", "rsa:2048", "-nodes", "-keyout", k, "-out", c, "-days", "825", "-subj", "/CN=tcm serve"], { encoding: "utf8" });
    if (r.status !== 0) throw new Error(`could not create a certificate with openssl (${r.error?.message ?? r.stderr.trim()}); pass --tls-cert and --tls-key`);
    fs.chmodSync(k, 0o600);
  }
  return { cert: fs.readFileSync(c, "utf8"), key: fs.readFileSync(k, "utf8") };
}

uses

used by