75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
import crypto from "node:crypto";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
|
|
import { resolveStateDir } from "../config/paths.js";
|
|
|
|
export type NodeHostGatewayConfig = {
|
|
host?: string;
|
|
port?: number;
|
|
tls?: boolean;
|
|
tlsFingerprint?: string;
|
|
};
|
|
|
|
export type NodeHostConfig = {
|
|
version: 1;
|
|
nodeId: string;
|
|
token?: string;
|
|
displayName?: string;
|
|
gateway?: NodeHostGatewayConfig;
|
|
};
|
|
|
|
const NODE_HOST_FILE = "node.json";
|
|
|
|
export function resolveNodeHostConfigPath(): string {
|
|
return path.join(resolveStateDir(), NODE_HOST_FILE);
|
|
}
|
|
|
|
function normalizeConfig(config: Partial<NodeHostConfig> | null): NodeHostConfig {
|
|
const base: NodeHostConfig = {
|
|
version: 1,
|
|
nodeId: "",
|
|
token: config?.token,
|
|
displayName: config?.displayName,
|
|
gateway: config?.gateway,
|
|
};
|
|
if (config?.version === 1 && typeof config.nodeId === "string") {
|
|
base.nodeId = config.nodeId.trim();
|
|
}
|
|
if (!base.nodeId) {
|
|
base.nodeId = crypto.randomUUID();
|
|
}
|
|
return base;
|
|
}
|
|
|
|
export async function loadNodeHostConfig(): Promise<NodeHostConfig | null> {
|
|
const filePath = resolveNodeHostConfigPath();
|
|
try {
|
|
const raw = await fs.readFile(filePath, "utf8");
|
|
const parsed = JSON.parse(raw) as Partial<NodeHostConfig>;
|
|
return normalizeConfig(parsed);
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export async function saveNodeHostConfig(config: NodeHostConfig): Promise<void> {
|
|
const filePath = resolveNodeHostConfigPath();
|
|
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
const payload = JSON.stringify(config, null, 2);
|
|
await fs.writeFile(filePath, `${payload}\n`, { mode: 0o600 });
|
|
try {
|
|
await fs.chmod(filePath, 0o600);
|
|
} catch {
|
|
// best-effort on platforms without chmod
|
|
}
|
|
}
|
|
|
|
export async function ensureNodeHostConfig(): Promise<NodeHostConfig> {
|
|
const existing = await loadNodeHostConfig();
|
|
const normalized = normalizeConfig(existing);
|
|
await saveNodeHostConfig(normalized);
|
|
return normalized;
|
|
}
|
|
|