tlsMaterial
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") }; }