feat: add support for https

This commit is contained in:
Aarnav Tale
2026-05-30 19:39:02 -04:00
parent 8c508e0602
commit ea27c846e2
6 changed files with 135 additions and 2 deletions
+8
View File
@@ -35,6 +35,14 @@ try {
exit(1);
}
if ((config.server.tls_cert_path || config.server.tls_key_path) && !config.server.cookie_secure) {
log.warn(
"server",
"TLS is enabled but `server.cookie_secure` is false; forcing it to true (browsers reject Secure-less cookies over HTTPS)",
);
config.server.cookie_secure = true;
}
const ctx = await createAppContext(config);
ctx.startServices();
+9
View File
@@ -42,6 +42,12 @@ const serverConfig = type({
cookie_secure: "boolean = true",
cookie_domain: "string.lower?",
cookie_max_age: "number.integer = 86400",
// TLS termination. When both `tls_cert_path` and `tls_key_path`
// are provided, Headplane serves HTTPS on `server.port`. When
// either is set, `cookie_secure` is forced to `true`.
tls_cert_path: "string?",
tls_key_path: "string?",
});
const partialServerConfig = type({
@@ -55,6 +61,9 @@ const partialServerConfig = type({
cookie_secure: "boolean?",
cookie_domain: "string.lower?",
cookie_max_age: "number.integer?",
tls_cert_path: "string?",
tls_key_path: "string?",
});
const headscaleConfig = type({
+26 -1
View File
@@ -8,19 +8,44 @@
// Vite, and the dev-only `runtime/vite-plugin.ts` dispatches requests
// straight to `./app`'s default export.
import { readFile } from "node:fs/promises";
import { dirname, resolve } from "node:path";
import { exit } from "node:process";
import { fileURLToPath } from "node:url";
import { composeListener, startHttpServer } from "../../runtime/http";
import log from "~/utils/log";
import { type StartOptions, composeListener, startHttpServer } from "../../runtime/http";
import requestListener, { config, dispose } from "./app";
// `import.meta.url` resolves to `build/server/index.js`; the built
// client lives next to it at `build/client/`.
const clientDir = resolve(dirname(fileURLToPath(import.meta.url)), "../client");
let tls: StartOptions["tls"];
const { tls_cert_path: certPath, tls_key_path: keyPath } = config.server;
if (certPath || keyPath) {
if (!certPath || !keyPath) {
log.error(
"server",
"TLS misconfigured: both `server.tls_cert_path` and `server.tls_key_path` must be provided",
);
exit(1);
}
try {
const [cert, key] = await Promise.all([readFile(certPath), readFile(keyPath)]);
tls = { cert, key };
} catch (err) {
log.error("server", "Failed to read TLS material: %s", err);
exit(1);
}
}
startHttpServer({
host: config.server.host,
port: config.server.port,
tls,
listener: composeListener({
basename: __PREFIX__,
staticRoot: clientDir,