fix(browser): use source config for proxy decisions

This commit is contained in:
Peter Steinberger
2026-04-30 15:56:40 +01:00
parent eb8e892df9
commit 29a35f04a9
4 changed files with 48 additions and 10 deletions

View File

@@ -22,10 +22,10 @@ export async function startBrowserControlServiceFromConfig(): Promise<BrowserSer
}
const cfg = getRuntimeConfig();
if (!isDefaultBrowserPluginEnabled(cfg)) {
const browserCfg = loadBrowserConfigForRuntimeRefresh();
if (!isDefaultBrowserPluginEnabled(browserCfg)) {
return null;
}
const browserCfg = loadBrowserConfigForRuntimeRefresh();
const resolved = resolveBrowserConfig(browserCfg.browser, browserCfg);
if (!resolved.enabled) {
return null;

View File

@@ -17,17 +17,19 @@ const configMocks = vi.hoisted(() => ({
browser: {},
nodeHost: { browserProxy: { enabled: true, allowProfiles: [] as string[] } },
})),
sourceConfig: null as Record<string, unknown> | null,
}));
const browserConfigMocks = vi.hoisted(() => ({
resolveBrowserConfig: vi.fn(() => ({
resolveBrowserConfig: vi.fn((browser?: { defaultProfile?: string }) => ({
enabled: true,
defaultProfile: "openclaw",
defaultProfile: browser?.defaultProfile ?? "openclaw",
})),
}));
vi.mock("../sdk-config.js", () => ({
getRuntimeConfig: configMocks.loadConfig,
getRuntimeConfigSourceSnapshot: () => configMocks.sourceConfig,
loadConfig: configMocks.loadConfig,
}));
@@ -150,6 +152,7 @@ describe("runBrowserProxyCommand", () => {
}));
controlServiceMocks.createBrowserControlContext.mockReset().mockReturnValue({ control: true });
controlServiceMocks.startBrowserControlServiceFromConfig.mockReset().mockResolvedValue(true);
configMocks.sourceConfig = null;
configMocks.loadConfig.mockReset().mockReturnValue({
browser: {},
nodeHost: { browserProxy: { enabled: true, allowProfiles: [] as string[] } },
@@ -304,6 +307,41 @@ describe("runBrowserProxyCommand", () => {
expect(dispatcherMocks.dispatch).not.toHaveBeenCalled();
});
it("uses the browser source snapshot for proxy default-profile decisions", async () => {
configMocks.loadConfig.mockReturnValue({
browser: { defaultProfile: "openclaw" },
nodeHost: { browserProxy: { enabled: true, allowProfiles: ["work"] } },
});
configMocks.sourceConfig = {
browser: { defaultProfile: "work" },
nodeHost: { browserProxy: { enabled: true, allowProfiles: ["work"] } },
};
browserConfigMocks.resolveBrowserConfig.mockImplementation(
(browser?: { defaultProfile?: string }) => ({
enabled: true,
defaultProfile: browser?.defaultProfile ?? "openclaw",
}),
);
dispatcherMocks.dispatch.mockResolvedValue({
status: 200,
body: { ok: true },
});
await runBrowserProxyCommand(
JSON.stringify({
method: "GET",
path: "/snapshot",
timeoutMs: 50,
}),
);
expect(dispatcherMocks.dispatch).toHaveBeenCalledWith(
expect.objectContaining({
path: "/snapshot",
}),
);
});
it("rejects unauthorized body.profile when allowProfiles is configured", async () => {
configMocks.loadConfig.mockReturnValue({
browser: {},

View File

@@ -1,5 +1,6 @@
import fsPromises from "node:fs/promises";
import { redactCdpUrl } from "../browser/cdp.helpers.js";
import { loadBrowserConfigForRuntimeRefresh } from "../browser/config-refresh-source.js";
import { resolveBrowserConfig } from "../browser/config.js";
import {
isPersistentBrowserProfileMutation,
@@ -11,7 +12,6 @@ import {
createBrowserControlContext,
startBrowserControlServiceFromConfig,
} from "../control-service.js";
import { getRuntimeConfig } from "../sdk-config.js";
import { withTimeout } from "../sdk-node-runtime.js";
import { detectMime } from "../sdk-setup-tools.js";
@@ -44,7 +44,7 @@ function normalizeProfileAllowlist(raw?: string[]): string[] {
}
function resolveBrowserProxyConfig() {
const cfg = getRuntimeConfig();
const cfg = loadBrowserConfigForRuntimeRefresh();
const proxy = cfg.nodeHost?.browserProxy;
const allowProfiles = normalizeProfileAllowlist(proxy?.allowProfiles);
const enabled = proxy?.enabled !== false;
@@ -64,7 +64,7 @@ async function ensureBrowserControlService(): Promise<void> {
return browserControlReady;
}
browserControlReady = (async () => {
const cfg = getRuntimeConfig();
const cfg = loadBrowserConfigForRuntimeRefresh();
const resolved = resolveBrowserConfig(cfg.browser, cfg);
if (!resolved.enabled) {
throw new Error("browser control disabled");
@@ -231,7 +231,7 @@ export async function runBrowserProxyCommand(paramsJSON?: string | null): Promis
}
await ensureBrowserControlService();
const cfg = getRuntimeConfig();
const cfg = loadBrowserConfigForRuntimeRefresh();
const resolved = resolveBrowserConfig(cfg.browser, cfg);
const method = typeof params.method === "string" ? params.method.toUpperCase() : "GET";
const path = normalizeBrowserRequestPath(pathValue);

View File

@@ -35,10 +35,10 @@ export async function startBrowserControlServerFromConfig(): Promise<BrowserServ
}
const cfg = getRuntimeConfig();
if (!isDefaultBrowserPluginEnabled(cfg)) {
const browserCfg = loadBrowserConfigForRuntimeRefresh();
if (!isDefaultBrowserPluginEnabled(browserCfg)) {
return null;
}
const browserCfg = loadBrowserConfigForRuntimeRefresh();
const resolved = resolveBrowserConfig(browserCfg.browser, browserCfg);
if (!resolved.enabled) {
return null;