fix(openclaw controller): use buildOpenClawControlUiUrl for generating gateway URLs (#493)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import type { IncomingMessage, ServerResponse } from 'http';
|
import type { IncomingMessage, ServerResponse } from 'http';
|
||||||
import { PORTS } from '../../utils/config';
|
import { PORTS } from '../../utils/config';
|
||||||
|
import { buildOpenClawControlUiUrl } from '../../utils/openclaw-control-ui';
|
||||||
import { getSetting } from '../../utils/store';
|
import { getSetting } from '../../utils/store';
|
||||||
import type { HostApiContext } from '../context';
|
import type { HostApiContext } from '../context';
|
||||||
import { parseJsonBody, sendJson } from '../route-utils';
|
import { parseJsonBody, sendJson } from '../route-utils';
|
||||||
@@ -68,7 +69,7 @@ export async function handleGatewayRoutes(
|
|||||||
const status = ctx.gatewayManager.getStatus();
|
const status = ctx.gatewayManager.getStatus();
|
||||||
const token = await getSetting('gatewayToken');
|
const token = await getSetting('gatewayToken');
|
||||||
const port = status.port || PORTS.OPENCLAW_GATEWAY;
|
const port = status.port || PORTS.OPENCLAW_GATEWAY;
|
||||||
const urlValue = `http://127.0.0.1:${port}/?token=${encodeURIComponent(token)}`;
|
const urlValue = buildOpenClawControlUiUrl(port, token);
|
||||||
sendJson(res, 200, { success: true, url: urlValue, token, port });
|
sendJson(res, 200, { success: true, url: urlValue, token, port });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
sendJson(res, 500, { success: false, error: String(error) });
|
sendJson(res, 500, { success: false, error: String(error) });
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
saveProviderKeyToOpenClaw,
|
saveProviderKeyToOpenClaw,
|
||||||
removeProviderFromOpenClaw,
|
removeProviderFromOpenClaw,
|
||||||
} from '../utils/openclaw-auth';
|
} from '../utils/openclaw-auth';
|
||||||
|
import { buildOpenClawControlUiUrl } from '../utils/openclaw-control-ui';
|
||||||
import { logger } from '../utils/logger';
|
import { logger } from '../utils/logger';
|
||||||
import {
|
import {
|
||||||
saveChannelConfig,
|
saveChannelConfig,
|
||||||
@@ -1283,8 +1284,7 @@ function registerGatewayHandlers(
|
|||||||
const status = gatewayManager.getStatus();
|
const status = gatewayManager.getStatus();
|
||||||
const token = await getSetting('gatewayToken');
|
const token = await getSetting('gatewayToken');
|
||||||
const port = status.port || 18789;
|
const port = status.port || 18789;
|
||||||
// Pass token as query param - Control UI will store it in localStorage
|
const url = buildOpenClawControlUiUrl(port, token);
|
||||||
const url = `http://127.0.0.1:${port}/?token=${encodeURIComponent(token)}`;
|
|
||||||
return { success: true, url, port, token };
|
return { success: true, url, port, token };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { success: false, error: String(error) };
|
return { success: false, error: String(error) };
|
||||||
|
|||||||
17
electron/utils/openclaw-control-ui.ts
Normal file
17
electron/utils/openclaw-control-ui.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Build the external OpenClaw Control UI URL.
|
||||||
|
*
|
||||||
|
* OpenClaw 2026.3.13 imports one-time auth tokens from the URL fragment
|
||||||
|
* (`#token=...`) and strips them after load. Query-string tokens are removed
|
||||||
|
* by the UI bootstrap but are not imported for auth.
|
||||||
|
*/
|
||||||
|
export function buildOpenClawControlUiUrl(port: number, token: string): string {
|
||||||
|
const url = new URL(`http://127.0.0.1:${port}/`);
|
||||||
|
const trimmedToken = token.trim();
|
||||||
|
|
||||||
|
if (trimmedToken) {
|
||||||
|
url.hash = new URLSearchParams({ token: trimmedToken }).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toString();
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "clawx",
|
"name": "clawx",
|
||||||
"version": "0.2.3-beta.2",
|
"version": "0.2.3-beta.3",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"onlyBuiltDependencies": [
|
"onlyBuiltDependencies": [
|
||||||
"@discordjs/opus",
|
"@discordjs/opus",
|
||||||
@@ -120,4 +120,4 @@
|
|||||||
"zx": "^8.8.5"
|
"zx": "^8.8.5"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268"
|
"packageManager": "pnpm@10.31.0+sha512.e3927388bfaa8078ceb79b748ffc1e8274e84d75163e67bc22e06c0d3aed43dd153151cbf11d7f8301ff4acb98c68bdc5cadf6989532801ffafe3b3e4a63c268"
|
||||||
}
|
}
|
||||||
|
|||||||
15
tests/unit/openclaw-control-ui.test.ts
Normal file
15
tests/unit/openclaw-control-ui.test.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
import { buildOpenClawControlUiUrl } from '@electron/utils/openclaw-control-ui';
|
||||||
|
|
||||||
|
describe('buildOpenClawControlUiUrl', () => {
|
||||||
|
it('uses the URL fragment for one-time token bootstrap', () => {
|
||||||
|
expect(buildOpenClawControlUiUrl(18789, 'clawx-test-token')).toBe(
|
||||||
|
'http://127.0.0.1:18789/#token=clawx-test-token',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('omits the fragment when the token is blank', () => {
|
||||||
|
expect(buildOpenClawControlUiUrl(18789, ' ')).toBe('http://127.0.0.1:18789/');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user