mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
Browser relay: accept raw gateway token in extension auth
(cherry picked from commit e682a768d0)
This commit is contained in:
committed by
Peter Steinberger
parent
d00d814ad1
commit
bb8f538cd4
@@ -3,6 +3,7 @@ import type { AddressInfo } from "node:net";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
probeAuthenticatedOpenClawRelay,
|
||||
resolveRelayAcceptedTokensForPort,
|
||||
resolveRelayAuthTokenForPort,
|
||||
} from "./extension-relay-auth.js";
|
||||
import { getFreePort } from "./test-port.js";
|
||||
@@ -51,6 +52,13 @@ describe("extension-relay-auth", () => {
|
||||
expect(tokenA1).not.toBe(TEST_GATEWAY_TOKEN);
|
||||
});
|
||||
|
||||
it("accepts both relay-scoped and raw gateway tokens for compatibility", () => {
|
||||
const tokens = resolveRelayAcceptedTokensForPort(18790);
|
||||
expect(tokens).toContain(TEST_GATEWAY_TOKEN);
|
||||
expect(tokens[0]).not.toBe(TEST_GATEWAY_TOKEN);
|
||||
expect(tokens[0]).toBe(resolveRelayAuthTokenForPort(18790));
|
||||
});
|
||||
|
||||
it("accepts authenticated openclaw relay probe responses", async () => {
|
||||
let seenToken: string | undefined;
|
||||
await withRelayServer(
|
||||
|
||||
@@ -27,14 +27,22 @@ function deriveRelayAuthToken(gatewayToken: string, port: number): string {
|
||||
return createHmac("sha256", gatewayToken).update(`${RELAY_TOKEN_CONTEXT}:${port}`).digest("hex");
|
||||
}
|
||||
|
||||
export function resolveRelayAuthTokenForPort(port: number): string {
|
||||
export function resolveRelayAcceptedTokensForPort(port: number): string[] {
|
||||
const gatewayToken = resolveGatewayAuthToken();
|
||||
if (gatewayToken) {
|
||||
return deriveRelayAuthToken(gatewayToken, port);
|
||||
if (!gatewayToken) {
|
||||
throw new Error(
|
||||
"extension relay requires gateway auth token (set gateway.auth.token or OPENCLAW_GATEWAY_TOKEN)",
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
"extension relay requires gateway auth token (set gateway.auth.token or OPENCLAW_GATEWAY_TOKEN)",
|
||||
);
|
||||
const relayToken = deriveRelayAuthToken(gatewayToken, port);
|
||||
if (relayToken === gatewayToken) {
|
||||
return [relayToken];
|
||||
}
|
||||
return [relayToken, gatewayToken];
|
||||
}
|
||||
|
||||
export function resolveRelayAuthTokenForPort(port: number): string {
|
||||
return resolveRelayAcceptedTokensForPort(port)[0];
|
||||
}
|
||||
|
||||
export async function probeAuthenticatedOpenClawRelay(params: {
|
||||
|
||||
@@ -277,6 +277,23 @@ describe("chrome extension relay server", () => {
|
||||
ext.close();
|
||||
});
|
||||
|
||||
it("accepts raw gateway token for relay auth compatibility", async () => {
|
||||
const port = await getFreePort();
|
||||
cdpUrl = `http://127.0.0.1:${port}`;
|
||||
await ensureChromeExtensionRelayServer({ cdpUrl });
|
||||
|
||||
const versionRes = await fetch(`${cdpUrl}/json/version`, {
|
||||
headers: { "x-openclaw-relay-token": TEST_GATEWAY_TOKEN },
|
||||
});
|
||||
expect(versionRes.status).toBe(200);
|
||||
|
||||
const ext = new WebSocket(
|
||||
`ws://127.0.0.1:${port}/extension?token=${encodeURIComponent(TEST_GATEWAY_TOKEN)}`,
|
||||
);
|
||||
await waitForOpen(ext);
|
||||
ext.close();
|
||||
});
|
||||
|
||||
it(
|
||||
"tracks attached page targets and exposes them via CDP + /json/list",
|
||||
async () => {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { isLoopbackAddress, isLoopbackHost } from "../gateway/net.js";
|
||||
import { rawDataToString } from "../infra/ws.js";
|
||||
import {
|
||||
probeAuthenticatedOpenClawRelay,
|
||||
resolveRelayAcceptedTokensForPort,
|
||||
resolveRelayAuthTokenForPort,
|
||||
} from "./extension-relay-auth.js";
|
||||
|
||||
@@ -219,6 +220,7 @@ export async function ensureChromeExtensionRelayServer(opts: {
|
||||
}
|
||||
|
||||
const relayAuthToken = resolveRelayAuthTokenForPort(info.port);
|
||||
const relayAuthTokens = new Set(resolveRelayAcceptedTokensForPort(info.port));
|
||||
|
||||
let extensionWs: WebSocket | null = null;
|
||||
const cdpClients = new Set<WebSocket>();
|
||||
@@ -365,8 +367,8 @@ export async function ensureChromeExtensionRelayServer(opts: {
|
||||
const path = url.pathname;
|
||||
|
||||
if (path.startsWith("/json")) {
|
||||
const token = getHeader(req, RELAY_AUTH_HEADER);
|
||||
if (!token || token !== relayAuthToken) {
|
||||
const token = getHeader(req, RELAY_AUTH_HEADER)?.trim();
|
||||
if (!token || !relayAuthTokens.has(token)) {
|
||||
res.writeHead(401);
|
||||
res.end("Unauthorized");
|
||||
return;
|
||||
@@ -489,7 +491,7 @@ export async function ensureChromeExtensionRelayServer(opts: {
|
||||
|
||||
if (pathname === "/extension") {
|
||||
const token = getRelayAuthTokenFromRequest(req, url);
|
||||
if (!token || token !== relayAuthToken) {
|
||||
if (!token || !relayAuthTokens.has(token)) {
|
||||
rejectUpgrade(socket, 401, "Unauthorized");
|
||||
return;
|
||||
}
|
||||
@@ -514,7 +516,7 @@ export async function ensureChromeExtensionRelayServer(opts: {
|
||||
|
||||
if (pathname === "/cdp") {
|
||||
const token = getRelayAuthTokenFromRequest(req, url);
|
||||
if (!token || token !== relayAuthToken) {
|
||||
if (!token || !relayAuthTokens.has(token)) {
|
||||
rejectUpgrade(socket, 401, "Unauthorized");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user