Add home bypass mode for the Mac client
This commit is contained in:
43
src/server/clientSettings.js
Normal file
43
src/server/clientSettings.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { settings } from "./config.js";
|
||||
|
||||
const DEFAULT_CLIENT_SETTINGS = {
|
||||
homeBypassEnabled: false,
|
||||
};
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
export function normalizeClientSettings(input = {}) {
|
||||
return {
|
||||
homeBypassEnabled: Boolean(input.homeBypassEnabled),
|
||||
};
|
||||
}
|
||||
|
||||
export function readClientSettings() {
|
||||
return normalizeClientSettings({
|
||||
...DEFAULT_CLIENT_SETTINGS,
|
||||
...readJson(settings.clientSettingsPath, {}),
|
||||
});
|
||||
}
|
||||
|
||||
export function writeClientSettings(input) {
|
||||
const normalized = normalizeClientSettings({
|
||||
...readClientSettings(),
|
||||
...(input && typeof input === "object" ? input : {}),
|
||||
});
|
||||
writeJson(settings.clientSettingsPath, normalized);
|
||||
return normalized;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ export const settings = {
|
||||
statePath: path.join(dataDir, "state.json"),
|
||||
customRulesPath: path.join(dataDir, "custom-rules.json"),
|
||||
customRuleSetsPath: path.join(dataDir, "custom-rule-sets.json"),
|
||||
clientSettingsPath: path.join(dataDir, "client-settings.json"),
|
||||
devicesPath: path.join(dataDir, "devices.json"),
|
||||
deviceRulesPath: path.join(dataDir, "device-rules.json"),
|
||||
subscriptionCachePath: path.join(dataDir, "subscription-cache.json"),
|
||||
|
||||
@@ -17,6 +17,10 @@ import {
|
||||
readDeviceProfiles,
|
||||
writeDeviceProfiles,
|
||||
} from "./devices.js";
|
||||
import {
|
||||
readClientSettings,
|
||||
writeClientSettings,
|
||||
} from "./clientSettings.js";
|
||||
import { matchRoute, detectRuleConflicts } from "./routeMatcher.js";
|
||||
import { tcpPing, resolveHost } from "./ping.js";
|
||||
|
||||
@@ -602,6 +606,7 @@ function publicState() {
|
||||
proxyBindIp: settings.bindIp,
|
||||
tproxyPort: settings.appMode === "gateway" ? settings.tproxyPort : null,
|
||||
routingRuDirect: settings.routingRuDirect,
|
||||
clientSettings: readClientSettings(),
|
||||
configExists: fs.existsSync(settings.configPath),
|
||||
singboxRunning: Boolean(singboxProcess),
|
||||
singboxStartedAt,
|
||||
@@ -924,6 +929,33 @@ async function handleApi(req, res) {
|
||||
});
|
||||
}
|
||||
|
||||
if (req.method === "GET" && req.url === "/api/client-settings") {
|
||||
return sendJson(res, 200, {
|
||||
success: true,
|
||||
clientSettings: readClientSettings(),
|
||||
});
|
||||
}
|
||||
|
||||
if (req.method === "PUT" && req.url === "/api/client-settings") {
|
||||
const body = await readBody(req);
|
||||
const clientSettings = writeClientSettings(body.clientSettings || body);
|
||||
const prevState = readJson(settings.statePath, {});
|
||||
|
||||
if (
|
||||
settings.appMode === "client" &&
|
||||
prevState.selectedTag &&
|
||||
readJson(settings.subscriptionCachePath, null)?.config
|
||||
) {
|
||||
await applySelectedServer(prevState.selectedTag);
|
||||
}
|
||||
|
||||
return sendJson(res, 200, {
|
||||
success: true,
|
||||
clientSettings,
|
||||
singboxRunning: Boolean(singboxProcess),
|
||||
});
|
||||
}
|
||||
|
||||
if (req.method === "GET" && req.url === "/api/rule-sets") {
|
||||
return sendJson(res, 200, {
|
||||
success: true,
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
normalizeCidr,
|
||||
readDeviceProfiles,
|
||||
} from "./devices.js";
|
||||
import { readClientSettings } from "./clientSettings.js";
|
||||
|
||||
const PROXY_TYPES = new Set([
|
||||
"vless",
|
||||
@@ -259,7 +260,11 @@ export function buildGatewayConfig(
|
||||
|
||||
const customRuleSets = readCustomRuleSets();
|
||||
const clientMode = settings.appMode === "client";
|
||||
const proxyOnlyRules = [{ inbound: [MIXED_INBOUND], outbound: vpnOutbound.tag }];
|
||||
const clientSettings = clientMode ? readClientSettings() : null;
|
||||
const clientOutbound = clientSettings?.homeBypassEnabled
|
||||
? "direct"
|
||||
: vpnOutbound.tag;
|
||||
const proxyOnlyRules = [{ inbound: [MIXED_INBOUND], outbound: clientOutbound }];
|
||||
const inbounds = [
|
||||
...(clientMode
|
||||
? []
|
||||
|
||||
Reference in New Issue
Block a user