113 lines
3.8 KiB
TypeScript
113 lines
3.8 KiB
TypeScript
import type { IncomingMessage, ServerResponse } from 'http';
|
|
import { applyProxySettings } from '../../main/proxy';
|
|
import { syncLaunchAtStartupSettingFromStore } from '../../main/launch-at-startup';
|
|
import { syncProxyConfigToOpenClaw } from '../../utils/openclaw-proxy';
|
|
import { getAllSettings, getSetting, resetSettings, setSetting, type AppSettings } from '../../utils/store';
|
|
import type { HostApiContext } from '../context';
|
|
import { parseJsonBody, sendJson } from '../route-utils';
|
|
|
|
async function handleProxySettingsChange(ctx: HostApiContext): Promise<void> {
|
|
const settings = await getAllSettings();
|
|
await syncProxyConfigToOpenClaw(settings, { preserveExistingWhenDisabled: false });
|
|
await applyProxySettings(settings);
|
|
if (ctx.gatewayManager.getStatus().state === 'running') {
|
|
await ctx.gatewayManager.restart();
|
|
}
|
|
}
|
|
|
|
function patchTouchesProxy(patch: Partial<AppSettings>): boolean {
|
|
return Object.keys(patch).some((key) => (
|
|
key === 'proxyEnabled' ||
|
|
key === 'proxyServer' ||
|
|
key === 'proxyHttpServer' ||
|
|
key === 'proxyHttpsServer' ||
|
|
key === 'proxyAllServer' ||
|
|
key === 'proxyBypassRules'
|
|
));
|
|
}
|
|
|
|
function patchTouchesLaunchAtStartup(patch: Partial<AppSettings>): boolean {
|
|
return Object.prototype.hasOwnProperty.call(patch, 'launchAtStartup');
|
|
}
|
|
|
|
export async function handleSettingsRoutes(
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
url: URL,
|
|
ctx: HostApiContext,
|
|
): Promise<boolean> {
|
|
if (url.pathname === '/api/settings' && req.method === 'GET') {
|
|
sendJson(res, 200, await getAllSettings());
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/settings' && req.method === 'PUT') {
|
|
try {
|
|
const patch = await parseJsonBody<Partial<AppSettings>>(req);
|
|
const entries = Object.entries(patch) as Array<[keyof AppSettings, AppSettings[keyof AppSettings]]>;
|
|
for (const [key, value] of entries) {
|
|
await setSetting(key, value);
|
|
}
|
|
if (patchTouchesProxy(patch)) {
|
|
await handleProxySettingsChange(ctx);
|
|
}
|
|
if (patchTouchesLaunchAtStartup(patch)) {
|
|
await syncLaunchAtStartupSettingFromStore();
|
|
}
|
|
sendJson(res, 200, { success: true });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname.startsWith('/api/settings/') && req.method === 'GET') {
|
|
const key = url.pathname.slice('/api/settings/'.length) as keyof AppSettings;
|
|
try {
|
|
sendJson(res, 200, { value: await getSetting(key) });
|
|
} catch (error) {
|
|
sendJson(res, 404, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname.startsWith('/api/settings/') && req.method === 'PUT') {
|
|
const key = url.pathname.slice('/api/settings/'.length) as keyof AppSettings;
|
|
try {
|
|
const body = await parseJsonBody<{ value: AppSettings[keyof AppSettings] }>(req);
|
|
await setSetting(key, body.value);
|
|
if (
|
|
key === 'proxyEnabled' ||
|
|
key === 'proxyServer' ||
|
|
key === 'proxyHttpServer' ||
|
|
key === 'proxyHttpsServer' ||
|
|
key === 'proxyAllServer' ||
|
|
key === 'proxyBypassRules'
|
|
) {
|
|
await handleProxySettingsChange(ctx);
|
|
}
|
|
if (key === 'launchAtStartup') {
|
|
await syncLaunchAtStartupSettingFromStore();
|
|
}
|
|
sendJson(res, 200, { success: true });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (url.pathname === '/api/settings/reset' && req.method === 'POST') {
|
|
try {
|
|
await resetSettings();
|
|
await handleProxySettingsChange(ctx);
|
|
await syncLaunchAtStartupSettingFromStore();
|
|
sendJson(res, 200, { success: true, settings: await getAllSettings() });
|
|
} catch (error) {
|
|
sendJson(res, 500, { success: false, error: String(error) });
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|