fix(browser): unify extension relay auth on gateway token

This commit is contained in:
Peter Steinberger
2026-02-19 08:39:34 +01:00
parent 781b1c1e09
commit 7e54b6c96f
8 changed files with 146 additions and 70 deletions

View File

@@ -20,3 +20,4 @@ Purpose: attach OpenClaw to an existing Chrome tab so the Gateway can automate i
## Options
- `Relay port`: defaults to `18792`.
- `Gateway token`: required. Set this to `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`).

View File

@@ -42,6 +42,12 @@ async function getRelayPort() {
return n
}
async function getGatewayToken() {
const stored = await chrome.storage.local.get(['gatewayToken'])
const token = String(stored.gatewayToken || '').trim()
return token || ''
}
function setBadge(tabId, kind) {
const cfg = BADGE[kind]
void chrome.action.setBadgeText({ tabId, text: cfg.text })
@@ -55,8 +61,11 @@ async function ensureRelayConnection() {
relayConnectPromise = (async () => {
const port = await getRelayPort()
const gatewayToken = await getGatewayToken()
const httpBase = `http://127.0.0.1:${port}`
const wsUrl = `ws://127.0.0.1:${port}/extension`
const wsUrl = gatewayToken
? `ws://127.0.0.1:${port}/extension?token=${encodeURIComponent(gatewayToken)}`
: `ws://127.0.0.1:${port}/extension`
// Fast preflight: is the relay server up?
try {
@@ -65,6 +74,12 @@ async function ensureRelayConnection() {
throw new Error(`Relay server not reachable at ${httpBase} (${String(err)})`)
}
if (!gatewayToken) {
throw new Error(
'Missing gatewayToken in extension settings (chrome.storage.local.gatewayToken)',
)
}
const ws = new WebSocket(wsUrl)
relayWs = ws

View File

@@ -176,15 +176,19 @@
</div>
<div class="card">
<h2>Relay port</h2>
<h2>Relay connection</h2>
<label for="port">Port</label>
<div class="row">
<input id="port" inputmode="numeric" pattern="[0-9]*" />
</div>
<label for="token" style="margin-top: 10px">Gateway token</label>
<div class="row">
<input id="token" type="password" autocomplete="off" style="width: min(520px, 100%)" />
<button id="save" type="button">Save</button>
</div>
<div class="hint">
Default: <code>18792</code>. Extension connects to: <code id="relay-url">http://127.0.0.1:&lt;port&gt;/</code>.
Only change this if your OpenClaw profile uses a different <code>cdpUrl</code> port.
Default port: <code>18792</code>. Extension connects to: <code id="relay-url">http://127.0.0.1:&lt;port&gt;/</code>.
Gateway token must match <code>gateway.auth.token</code> (or <code>OPENCLAW_GATEWAY_TOKEN</code>).
</div>
<div class="status" id="status"></div>
</div>

View File

@@ -13,6 +13,12 @@ function updateRelayUrl(port) {
el.textContent = `http://127.0.0.1:${port}/`
}
function relayHeaders(token) {
const t = String(token || '').trim()
if (!t) return {}
return { 'x-openclaw-relay-token': t }
}
function setStatus(kind, message) {
const status = document.getElementById('status')
if (!status) return
@@ -20,18 +26,31 @@ function setStatus(kind, message) {
status.textContent = message || ''
}
async function checkRelayReachable(port) {
const url = `http://127.0.0.1:${port}/`
async function checkRelayReachable(port, token) {
const url = `http://127.0.0.1:${port}/json/version`
const trimmedToken = String(token || '').trim()
if (!trimmedToken) {
setStatus('error', 'Gateway token required. Save your gateway token to connect.')
return
}
const ctrl = new AbortController()
const t = setTimeout(() => ctrl.abort(), 900)
const t = setTimeout(() => ctrl.abort(), 1200)
try {
const res = await fetch(url, { method: 'HEAD', signal: ctrl.signal })
const res = await fetch(url, {
method: 'GET',
headers: relayHeaders(trimmedToken),
signal: ctrl.signal,
})
if (res.status === 401) {
setStatus('error', 'Gateway token rejected. Check token and save again.')
return
}
if (!res.ok) throw new Error(`HTTP ${res.status}`)
setStatus('ok', `Relay reachable at ${url}`)
setStatus('ok', `Relay reachable and authenticated at http://127.0.0.1:${port}/`)
} catch {
setStatus(
'error',
`Relay not reachable at ${url}. Start OpenClaws browser relay on this machine, then click the toolbar button again.`,
`Relay not reachable/authenticated at http://127.0.0.1:${port}/. Start OpenClaw browser relay and verify token.`,
)
} finally {
clearTimeout(t)
@@ -39,20 +58,25 @@ async function checkRelayReachable(port) {
}
async function load() {
const stored = await chrome.storage.local.get(['relayPort'])
const stored = await chrome.storage.local.get(['relayPort', 'gatewayToken'])
const port = clampPort(stored.relayPort)
const token = String(stored.gatewayToken || '').trim()
document.getElementById('port').value = String(port)
document.getElementById('token').value = token
updateRelayUrl(port)
await checkRelayReachable(port)
await checkRelayReachable(port, token)
}
async function save() {
const input = document.getElementById('port')
const port = clampPort(input.value)
await chrome.storage.local.set({ relayPort: port })
input.value = String(port)
const portInput = document.getElementById('port')
const tokenInput = document.getElementById('token')
const port = clampPort(portInput.value)
const token = String(tokenInput.value || '').trim()
await chrome.storage.local.set({ relayPort: port, gatewayToken: token })
portInput.value = String(port)
tokenInput.value = token
updateRelayUrl(port)
await checkRelayReachable(port)
await checkRelayReachable(port, token)
}
document.getElementById('save').addEventListener('click', () => void save())