openclaw-navigator 5.7.1 → 5.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli.mjs +87 -3
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -375,6 +375,22 @@ function getChatSession(sessionKey = "main") {
|
|
|
375
375
|
return chatSessions.get(sessionKey);
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
// ── Cookie jar for BFF auth ────────────────────────────────────────────
|
|
379
|
+
// Captures session cookies from web UI /api/auth responses so the bridge
|
|
380
|
+
// can make authenticated server-side requests to /api/chat (for sidepane relay).
|
|
381
|
+
let bffCookieJar = "";
|
|
382
|
+
|
|
383
|
+
function captureBFFCookies(setCookieHeaders) {
|
|
384
|
+
if (!setCookieHeaders) return;
|
|
385
|
+
const cookies = Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders];
|
|
386
|
+
// Extract just the cookie name=value (strip attributes like path, domain, etc.)
|
|
387
|
+
const extracted = cookies.map((c) => c.split(";")[0].trim()).filter(Boolean);
|
|
388
|
+
if (extracted.length > 0) {
|
|
389
|
+
bffCookieJar = extracted.join("; ");
|
|
390
|
+
console.log(` ${DIM}Captured BFF cookies: ${bffCookieJar.substring(0, 60)}...${RESET}`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
378
394
|
// ── WebSocket server for chat (minimal, no dependencies) ────────────────
|
|
379
395
|
// Tracks connected WebSocket clients. When the OC agent pushes messages
|
|
380
396
|
// via /api/sessions/respond or /api/sessions/stream, we broadcast to all
|
|
@@ -1048,6 +1064,8 @@ function handleRequest(req, res) {
|
|
|
1048
1064
|
headers["set-cookie"] = cookies.map((c) =>
|
|
1049
1065
|
c.replace(/;\s*domain=[^;]*/gi, "").replace(/;\s*secure/gi, ""),
|
|
1050
1066
|
);
|
|
1067
|
+
// Also capture these for server-side relay auth (sidepane chat)
|
|
1068
|
+
captureBFFCookies(proxyRes.headers["set-cookie"]);
|
|
1051
1069
|
}
|
|
1052
1070
|
|
|
1053
1071
|
res.writeHead(proxyRes.statusCode ?? 502, headers);
|
|
@@ -1183,6 +1201,8 @@ function handleRequest(req, res) {
|
|
|
1183
1201
|
messages: chatHistory,
|
|
1184
1202
|
stream: true,
|
|
1185
1203
|
});
|
|
1204
|
+
// Build cookie header: prefer captured BFF cookies, fall back to browser's cookies
|
|
1205
|
+
const relayCookie = bffCookieJar || req.headers.cookie || "";
|
|
1186
1206
|
const proxyOpts = {
|
|
1187
1207
|
hostname: "127.0.0.1",
|
|
1188
1208
|
port: ocUIPort,
|
|
@@ -1192,12 +1212,68 @@ function handleRequest(req, res) {
|
|
|
1192
1212
|
headers: {
|
|
1193
1213
|
"content-type": "application/json",
|
|
1194
1214
|
"content-length": Buffer.byteLength(proxyBody),
|
|
1215
|
+
...(relayCookie ? { cookie: relayCookie } : {}),
|
|
1195
1216
|
},
|
|
1196
1217
|
};
|
|
1197
1218
|
|
|
1198
|
-
console.log(` ${DIM}→ Relaying to BFF /api/chat (port ${ocUIPort}) with ${chatHistory.length} messages${RESET}`);
|
|
1219
|
+
console.log(` ${DIM}→ Relaying to BFF /api/chat (port ${ocUIPort}) with ${chatHistory.length} messages${relayCookie ? " +cookie" : " NO-COOKIE"}${RESET}`);
|
|
1220
|
+
|
|
1221
|
+
// Helper: send the relay request (with optional retry after login)
|
|
1222
|
+
function sendBFFRelay(opts, body, retryCount = 0) {
|
|
1223
|
+
const proxyReq = httpRequest(opts, (proxyRes) => {
|
|
1224
|
+
// Capture any cookies the BFF sends (login session, etc.)
|
|
1225
|
+
if (proxyRes.headers["set-cookie"]) {
|
|
1226
|
+
captureBFFCookies(proxyRes.headers["set-cookie"]);
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
// If redirect (307/302 to /login) — follow it to seed cookies, then retry
|
|
1230
|
+
if ((proxyRes.statusCode === 307 || proxyRes.statusCode === 302) && retryCount < 2) {
|
|
1231
|
+
proxyRes.resume(); // drain
|
|
1232
|
+
const loginPath = proxyRes.headers.location || "/login";
|
|
1233
|
+
console.log(` ${DIM}← BFF redirect → ${loginPath} — following to seed cookies...${RESET}`);
|
|
1234
|
+
|
|
1235
|
+
// Hit the login page to get session cookies
|
|
1236
|
+
const loginReq = httpRequest(
|
|
1237
|
+
{
|
|
1238
|
+
hostname: "127.0.0.1",
|
|
1239
|
+
port: ocUIPort,
|
|
1240
|
+
path: loginPath,
|
|
1241
|
+
method: "GET",
|
|
1242
|
+
timeout: 5000,
|
|
1243
|
+
headers: bffCookieJar ? { cookie: bffCookieJar } : {},
|
|
1244
|
+
},
|
|
1245
|
+
(loginRes) => {
|
|
1246
|
+
if (loginRes.headers["set-cookie"]) {
|
|
1247
|
+
captureBFFCookies(loginRes.headers["set-cookie"]);
|
|
1248
|
+
}
|
|
1249
|
+
loginRes.resume(); // drain
|
|
1250
|
+
console.log(` ${DIM}← Login page: ${loginRes.statusCode} — cookies: ${bffCookieJar ? "yes" : "no"}${RESET}`);
|
|
1251
|
+
|
|
1252
|
+
// Retry the original request with new cookies
|
|
1253
|
+
if (bffCookieJar) {
|
|
1254
|
+
opts.headers = { ...opts.headers, cookie: bffCookieJar };
|
|
1255
|
+
console.log(` ${DIM}→ Retrying /api/chat with cookies...${RESET}`);
|
|
1256
|
+
sendBFFRelay(opts, body, retryCount + 1);
|
|
1257
|
+
} else {
|
|
1258
|
+
console.log(` ${DIM}No cookies from login — BFF may require real auth${RESET}`);
|
|
1259
|
+
broadcastToWS({
|
|
1260
|
+
type: "chat.final",
|
|
1261
|
+
text: "⚠️ Could not authenticate with OC — try opening the web UI first to log in.",
|
|
1262
|
+
content: "⚠️ Could not authenticate with OC — try opening the web UI first to log in.",
|
|
1263
|
+
sessionKey,
|
|
1264
|
+
role: "assistant",
|
|
1265
|
+
timestamp: Date.now(),
|
|
1266
|
+
});
|
|
1267
|
+
}
|
|
1268
|
+
},
|
|
1269
|
+
);
|
|
1270
|
+
loginReq.on("error", () => {
|
|
1271
|
+
console.log(` ${DIM}Login page unreachable${RESET}`);
|
|
1272
|
+
});
|
|
1273
|
+
loginReq.end();
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1199
1276
|
|
|
1200
|
-
const proxyReq = httpRequest(proxyOpts, (proxyRes) => {
|
|
1201
1277
|
const contentType = (proxyRes.headers["content-type"] || "").toLowerCase();
|
|
1202
1278
|
const isSSE = contentType.includes("text/event-stream");
|
|
1203
1279
|
console.log(` ${DIM}← BFF response: ${proxyRes.statusCode} ${contentType || "no-content-type"}${RESET}`);
|
|
@@ -1299,8 +1375,11 @@ function handleRequest(req, res) {
|
|
|
1299
1375
|
console.log(` ${DIM}BFF relay failed: ${err.message}${RESET}`);
|
|
1300
1376
|
});
|
|
1301
1377
|
|
|
1302
|
-
proxyReq.write(
|
|
1378
|
+
proxyReq.write(body);
|
|
1303
1379
|
proxyReq.end();
|
|
1380
|
+
} // end sendBFFRelay
|
|
1381
|
+
|
|
1382
|
+
sendBFFRelay(proxyOpts, proxyBody);
|
|
1304
1383
|
})
|
|
1305
1384
|
.catch(() => sendJSON(res, 400, { ok: false, error: "Bad request body" }));
|
|
1306
1385
|
return;
|
|
@@ -1411,6 +1490,11 @@ function handleRequest(req, res) {
|
|
|
1411
1490
|
console.log(` ${DIM}← ${proxyRes.statusCode} ${ct} for ${path}${RESET}`);
|
|
1412
1491
|
}
|
|
1413
1492
|
|
|
1493
|
+
// Capture session cookies from BFF (for server-side relay auth)
|
|
1494
|
+
if (proxyRes.headers["set-cookie"]) {
|
|
1495
|
+
captureBFFCookies(proxyRes.headers["set-cookie"]);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1414
1498
|
// CORS
|
|
1415
1499
|
headers["access-control-allow-origin"] = "*";
|
|
1416
1500
|
headers["access-control-allow-methods"] = "GET, POST, PUT, DELETE, OPTIONS";
|