mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 00:01:24 +00:00
fix(browser): authenticate sandbox browser bridge server
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
import type { BrowserBridge } from "../../browser/bridge-server.js";
|
||||
|
||||
export const BROWSER_BRIDGES = new Map<string, { bridge: BrowserBridge; containerName: string }>();
|
||||
export const BROWSER_BRIDGES = new Map<
|
||||
string,
|
||||
{
|
||||
bridge: BrowserBridge;
|
||||
containerName: string;
|
||||
authToken?: string;
|
||||
authPassword?: string;
|
||||
}
|
||||
>();
|
||||
|
||||
@@ -90,6 +90,7 @@ export async function ensureSandboxBrowser(params: {
|
||||
agentWorkspaceDir: string;
|
||||
cfg: SandboxConfig;
|
||||
evaluateEnabled?: boolean;
|
||||
bridgeAuth?: { token?: string; password?: string };
|
||||
}): Promise<SandboxBrowserContext | null> {
|
||||
if (!params.cfg.browser.enabled) {
|
||||
return null;
|
||||
@@ -148,19 +149,29 @@ export async function ensureSandboxBrowser(params: {
|
||||
? await readDockerPort(containerName, params.cfg.browser.noVncPort)
|
||||
: null;
|
||||
|
||||
const desiredAuthToken = params.bridgeAuth?.token?.trim() || undefined;
|
||||
const desiredAuthPassword = params.bridgeAuth?.password?.trim() || undefined;
|
||||
|
||||
const existing = BROWSER_BRIDGES.get(params.scopeKey);
|
||||
const existingProfile = existing
|
||||
? resolveProfile(existing.bridge.state.resolved, DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME)
|
||||
: null;
|
||||
const shouldReuse =
|
||||
existing && existing.containerName === containerName && existingProfile?.cdpPort === mappedCdp;
|
||||
const authMatches =
|
||||
!existing ||
|
||||
(existing.authToken === desiredAuthToken && existing.authPassword === desiredAuthPassword);
|
||||
if (existing && !shouldReuse) {
|
||||
await stopBrowserBridgeServer(existing.bridge.server).catch(() => undefined);
|
||||
BROWSER_BRIDGES.delete(params.scopeKey);
|
||||
}
|
||||
if (existing && shouldReuse && !authMatches) {
|
||||
await stopBrowserBridgeServer(existing.bridge.server).catch(() => undefined);
|
||||
BROWSER_BRIDGES.delete(params.scopeKey);
|
||||
}
|
||||
|
||||
const bridge = (() => {
|
||||
if (shouldReuse && existing) {
|
||||
if (shouldReuse && authMatches && existing) {
|
||||
return existing.bridge;
|
||||
}
|
||||
return null;
|
||||
@@ -196,15 +207,19 @@ export async function ensureSandboxBrowser(params: {
|
||||
headless: params.cfg.browser.headless,
|
||||
evaluateEnabled: params.evaluateEnabled ?? DEFAULT_BROWSER_EVALUATE_ENABLED,
|
||||
}),
|
||||
authToken: desiredAuthToken,
|
||||
authPassword: desiredAuthPassword,
|
||||
onEnsureAttachTarget,
|
||||
});
|
||||
};
|
||||
|
||||
const resolvedBridge = await ensureBridge();
|
||||
if (!shouldReuse) {
|
||||
if (!shouldReuse || !authMatches) {
|
||||
BROWSER_BRIDGES.set(params.scopeKey, {
|
||||
bridge: resolvedBridge,
|
||||
containerName,
|
||||
authToken: desiredAuthToken,
|
||||
authPassword: desiredAuthPassword,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ import fs from "node:fs/promises";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { SandboxContext, SandboxWorkspaceInfo } from "./types.js";
|
||||
import { DEFAULT_BROWSER_EVALUATE_ENABLED } from "../../browser/constants.js";
|
||||
import { ensureBrowserControlAuth, resolveBrowserControlAuth } from "../../browser/control-auth.js";
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { syncSkillsToWorkspace } from "../skills.js";
|
||||
@@ -76,12 +78,30 @@ export async function resolveSandboxContext(params: {
|
||||
|
||||
const evaluateEnabled =
|
||||
params.config?.browser?.evaluateEnabled ?? DEFAULT_BROWSER_EVALUATE_ENABLED;
|
||||
|
||||
const bridgeAuth = cfg.browser.enabled
|
||||
? await (async () => {
|
||||
// Sandbox browser bridge server runs on a loopback TCP port; always wire up
|
||||
// the same auth that loopback browser clients will send (token/password).
|
||||
const cfgForAuth = params.config ?? loadConfig();
|
||||
let browserAuth = resolveBrowserControlAuth(cfgForAuth);
|
||||
try {
|
||||
const ensured = await ensureBrowserControlAuth({ cfg: cfgForAuth });
|
||||
browserAuth = ensured.auth;
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : JSON.stringify(error);
|
||||
defaultRuntime.error?.(`Sandbox browser auth ensure failed: ${message}`);
|
||||
}
|
||||
return browserAuth;
|
||||
})()
|
||||
: undefined;
|
||||
const browser = await ensureSandboxBrowser({
|
||||
scopeKey,
|
||||
workspaceDir,
|
||||
agentWorkspaceDir,
|
||||
cfg,
|
||||
evaluateEnabled,
|
||||
bridgeAuth,
|
||||
});
|
||||
|
||||
const sandboxContext: SandboxContext = {
|
||||
|
||||
Reference in New Issue
Block a user