test: add gateway tls helper coverage
This commit is contained in:
156
src/infra/tls/gateway.test.ts
Normal file
156
src/infra/tls/gateway.test.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { X509Certificate } from "node:crypto";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { createTrackedTempDirs } from "../../test-utils/tracked-temp-dirs.js";
|
||||
import { normalizeFingerprint } from "./fingerprint.js";
|
||||
import { loadGatewayTlsRuntime } from "./gateway.js";
|
||||
|
||||
const tempDirs = createTrackedTempDirs();
|
||||
const createTempDir = () => tempDirs.make("openclaw-gateway-tls-test-");
|
||||
|
||||
const KEY_PEM = [
|
||||
"-----BEGIN PRIVATE KEY-----", // pragma: allowlist secret
|
||||
"MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDrur5CWp4psMMb",
|
||||
"DTPY1aN46HPDxRchGgh8XedNkrlc4z1KFiyLUsXpVIhuyoXq1fflpTDz7++pGEDJ",
|
||||
"Q5pEdChn3fuWgi7gC+pvd5VQ1eAX/7qVE72fhx14NxhaiZU3hCzXjG2SflTEEExk",
|
||||
"UkQTm0rdHSjgLVMhTM3Pqm6Kzfdgtm9ZyXwlAsorE/pvgbUxG3Q4xKNBGzbirZ+1",
|
||||
"EzPDwsjf3fitNtakZJkymu6Kg5lsUihQVXOP0U7f989FmevoTMvJmkvJzsoTRd7s",
|
||||
"XNSOjzOwJr8da8C4HkXi21md1yEccyW0iSh7tWvDrpWDAgW6RMuMHC0tW4bkpDGr",
|
||||
"FpbQOgzVAgMBAAECggEAIMhwf8Ve9CDVTWyNXpU9fgnj2aDOCeg3MGaVzaO/XCPt",
|
||||
"KOHDEaAyDnRXYgMP0zwtFNafo3klnSBWmDbq3CTEXseQHtsdfkKh+J0KmrqXxval",
|
||||
"YeikKSyvBEIzRJoYMqeS3eo1bddcXgT/Pr9zIL/qzivpPJ4JDttBzyTeaTbiNaR9",
|
||||
"KphGNueo+MTQMLreMqw5VAyJ44gy7Z/2TMiMEc/d95wfubcOSsrIfpOKnMvWd/rl",
|
||||
"vxIS33s95L7CjREkixskj5Yo5Wpt3Yf5b0Zi70YiEsCfAZUDrPW7YzMlylzmhMzm",
|
||||
"MARZKfN1Tmo74SGpxUrBury+iPwf1sYcRnsHR+zO8QKBgQD6ISQHRzPboZ3J/60+",
|
||||
"fRLETtrBa9WkvaH9c+woF7l47D4DIlvlv9D3N1KGkUmhMnp2jNKLIlalBNDxBdB+",
|
||||
"iwZP1kikGz4629Ch3/KF/VYscLTlAQNPE42jOo7Hj7VrdQx9zQrK9ZBLteXmSvOh",
|
||||
"bB3aXwXPF3HoTMt9gQ9thhXZJQKBgQDxQxUnQSw43dRlqYOHzPUEwnJkGkuW/qxn",
|
||||
"aRc8eopP5zUaebiDFmqhY36x2Wd+HnXrzufy2o4jkXkWTau8Ns+OLhnIG3PIU9L/",
|
||||
"LYzJMckGb75QYiK1YKMUUSQzlNCS8+TFVCTAvG2u2zCCk7oTIe8aT516BQNjWDjK",
|
||||
"gWo2f87N8QKBgHoVANO4kfwJxszXyMPuIeHEpwquyijNEap2EPaEldcKXz4CYB4j",
|
||||
"4Cc5TkM12F0gGRuRohWcnfOPBTgOYXPSATOoX+4RCe+KaCsJ9gIl4xBvtirrsqS+",
|
||||
"42ue4h9O6fpXt9AS6sii0FnTnzEmtgC8l1mE9X3dcJA0I0HPYytOvY0tAoGAAYJj",
|
||||
"7Xzw4+IvY/ttgTn9BmyY/ptTgbxSI8t6g7xYhStzH5lHWDqZrCzNLBuqFBXosvL2",
|
||||
"bISFgx9z3Hnb6y+EmOUc8C2LyeMMXOBSEygmk827KRGUGgJiwsvHKDN0Ipc4BSwD",
|
||||
"ltkW7pMceJSoA1qg/k8lMxA49zQkFtA8c97U0mECgYEAk2DDN78sRQI8RpSECJWy",
|
||||
"l1O1ikVUAYVeh5HdZkpt++ddfpo695Op9OeD2Eq27Y5EVj8Xl58GFxNk0egLUnYq",
|
||||
"YzSbjcNkR2SbVvuLaV1zlQKm6M5rfvhj4//YrzrrPUQda7Q4eR0as/3q91uzAO2O",
|
||||
"++pfnSCVCyp/TxSkhEDEawU=",
|
||||
"-----END PRIVATE KEY-----",
|
||||
].join("\n");
|
||||
|
||||
const CERT_PEM = `-----BEGIN CERTIFICATE-----
|
||||
MIIDCTCCAfGgAwIBAgIUel0Lv05cjrViyI/H3tABBJxM7NgwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDEyMDEyMjEzMloXDTI2MDEy
|
||||
MTEyMjEzMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEA67q+QlqeKbDDGw0z2NWjeOhzw8UXIRoIfF3nTZK5XOM9
|
||||
ShYsi1LF6VSIbsqF6tX35aUw8+/vqRhAyUOaRHQoZ937loIu4Avqb3eVUNXgF/+6
|
||||
lRO9n4cdeDcYWomVN4Qs14xtkn5UxBBMZFJEE5tK3R0o4C1TIUzNz6puis33YLZv
|
||||
Wcl8JQLKKxP6b4G1MRt0OMSjQRs24q2ftRMzw8LI3934rTbWpGSZMpruioOZbFIo
|
||||
UFVzj9FO3/fPRZnr6EzLyZpLyc7KE0Xe7FzUjo8zsCa/HWvAuB5F4ttZndchHHMl
|
||||
tIkoe7Vrw66VgwIFukTLjBwtLVuG5KQxqxaW0DoM1QIDAQABo1MwUTAdBgNVHQ4E
|
||||
FgQUwNdNkEQtd0n/aofzN7/EeYPPPbIwHwYDVR0jBBgwFoAUwNdNkEQtd0n/aofz
|
||||
N7/EeYPPPbIwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnOnw
|
||||
o8Az/bL0A6bGHTYra3L9ArIIljMajT6KDHxylR4LhliuVNAznnhP3UkcZbUdjqjp
|
||||
MNOM0lej2pNioondtQdXUskZtqWy6+dLbTm1RYQh1lbCCZQ26o7o/oENzjPksLAb
|
||||
jRM47DYxRweTyRWQ5t9wvg/xL0Yi1tWq4u4FCNZlBMgdwAEnXNwVWTzRR9RHwy20
|
||||
lmUzM8uQ/p42bk4EvPEV4PI1h5G0khQ6x9CtkadCTDs/ZqoUaJMwZBIDSrdJJSLw
|
||||
4Vh8Lqzia1CFB4um9J4S1Gm/VZMBjjeGGBJk7VSYn4ZmhPlbPM+6z39lpQGEG0x4
|
||||
r1USnb+wUdA7Zoj/mQ==
|
||||
-----END CERTIFICATE-----`;
|
||||
|
||||
afterEach(async () => {
|
||||
await tempDirs.cleanup();
|
||||
});
|
||||
|
||||
describe("loadGatewayTlsRuntime", () => {
|
||||
it("disables tls when config is absent or disabled", async () => {
|
||||
await expect(loadGatewayTlsRuntime(undefined)).resolves.toEqual({
|
||||
enabled: false,
|
||||
required: false,
|
||||
});
|
||||
await expect(loadGatewayTlsRuntime({ enabled: false })).resolves.toEqual({
|
||||
enabled: false,
|
||||
required: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("loads existing cert, key, and optional ca files", async () => {
|
||||
const dir = await createTempDir();
|
||||
const certPath = path.join(dir, "gateway-cert.pem");
|
||||
const keyPath = path.join(dir, "gateway-key.pem");
|
||||
const caPath = path.join(dir, "gateway-ca.pem");
|
||||
await writeFile(certPath, CERT_PEM, "utf8");
|
||||
await writeFile(keyPath, KEY_PEM, "utf8");
|
||||
await writeFile(caPath, CERT_PEM, "utf8");
|
||||
|
||||
const result = await loadGatewayTlsRuntime({
|
||||
enabled: true,
|
||||
certPath,
|
||||
keyPath,
|
||||
caPath,
|
||||
autoGenerate: false,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
enabled: true,
|
||||
required: true,
|
||||
certPath,
|
||||
keyPath,
|
||||
caPath,
|
||||
fingerprintSha256: normalizeFingerprint(new X509Certificate(CERT_PEM).fingerprint256 ?? ""),
|
||||
tlsOptions: {
|
||||
cert: CERT_PEM,
|
||||
key: KEY_PEM,
|
||||
ca: CERT_PEM,
|
||||
minVersion: "TLSv1.3",
|
||||
},
|
||||
});
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it("fails closed when cert/key are missing and auto generation is disabled", async () => {
|
||||
const dir = await createTempDir();
|
||||
const certPath = path.join(dir, "missing-cert.pem");
|
||||
const keyPath = path.join(dir, "missing-key.pem");
|
||||
|
||||
await expect(
|
||||
loadGatewayTlsRuntime({
|
||||
enabled: true,
|
||||
certPath,
|
||||
keyPath,
|
||||
autoGenerate: false,
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
enabled: false,
|
||||
required: true,
|
||||
certPath,
|
||||
keyPath,
|
||||
error: "gateway tls: cert/key missing",
|
||||
});
|
||||
});
|
||||
|
||||
it("reports load failures for invalid pem files", async () => {
|
||||
const dir = await createTempDir();
|
||||
const certPath = path.join(dir, "gateway-cert.pem");
|
||||
const keyPath = path.join(dir, "gateway-key.pem");
|
||||
await writeFile(certPath, "not a certificate\n", "utf8");
|
||||
await writeFile(keyPath, KEY_PEM, "utf8");
|
||||
|
||||
const result = await loadGatewayTlsRuntime({
|
||||
enabled: true,
|
||||
certPath,
|
||||
keyPath,
|
||||
autoGenerate: false,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
enabled: false,
|
||||
required: true,
|
||||
certPath,
|
||||
keyPath,
|
||||
});
|
||||
expect(result.error).toContain("gateway tls: failed to load cert");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user