Files
vpn-proxy/src/server/clientSettings.js
Dmitriy Petrov 95edefa84f
All checks were successful
Build and Deploy Gateway / build-and-push (push) Successful in 11s
Build and Deploy Gateway / deploy (push) Successful in 0s
feat: link mac client to shared gateway proxy
2026-05-19 22:47:05 +03:00

102 lines
2.8 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
import { settings } from "./config.js";
const DEFAULT_CLIENT_SETTINGS = {
homeBypassEnabled: false,
sharedProxyEnabled: false,
sharedProxyControlUrl: "",
sharedProxy: null,
};
function normalizeProxyPort(value, fallback = settings.proxyPort) {
const parsed = Number.parseInt(value, 10);
const min = Number.isInteger(settings.clientProxyPortStart)
? settings.clientProxyPortStart
: settings.proxyPort;
const max = Number.isInteger(settings.clientProxyPortEnd)
? settings.clientProxyPortEnd
: min;
const fallbackPort =
Number.isInteger(fallback) && fallback >= min && fallback <= max
? fallback
: min;
if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
return fallbackPort;
}
return parsed;
}
function readJson(filePath, fallback) {
try {
if (!fs.existsSync(filePath)) return fallback;
return JSON.parse(fs.readFileSync(filePath, "utf8"));
} catch {
return fallback;
}
}
function writeJson(filePath, value) {
fs.mkdirSync(path.dirname(filePath), { recursive: true });
fs.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf8");
}
function normalizeUrl(value) {
const raw = String(value || "").trim();
if (!raw) return "";
try {
const url = new URL(raw);
if (!["http:", "https:"].includes(url.protocol)) return "";
url.hash = "";
url.search = "";
return url.toString().replace(/\/$/, "");
} catch {
return "";
}
}
function normalizeSharedProxy(value) {
if (!value || typeof value !== "object") return null;
const host = String(value.host || "").trim();
const port = Number.parseInt(value.port, 10);
const protocol = value.protocol === "http" ? "http" : "socks5";
if (!host || !Number.isInteger(port) || port <= 0 || port > 65535) {
return null;
}
return {
host,
port,
protocol,
checkedAt: value.checkedAt || null,
};
}
export function normalizeClientSettings(input = {}) {
const sharedProxy = normalizeSharedProxy(input.sharedProxy);
const sharedProxyEnabled = Boolean(input.sharedProxyEnabled && sharedProxy);
return {
homeBypassEnabled: Boolean(input.homeBypassEnabled),
proxyPort: normalizeProxyPort(input.proxyPort),
sharedProxyEnabled,
sharedProxyControlUrl: normalizeUrl(input.sharedProxyControlUrl),
sharedProxy,
};
}
export function readClientSettings() {
return normalizeClientSettings({
...DEFAULT_CLIENT_SETTINGS,
proxyPort: settings.proxyPort,
...readJson(settings.clientSettingsPath, {}),
});
}
export function writeClientSettings(input) {
const normalized = normalizeClientSettings({
...readClientSettings(),
...(input && typeof input === "object" ? input : {}),
});
writeJson(settings.clientSettingsPath, normalized);
return normalized;
}