Skip to content

fix: resolve Control UI token field mismatch between client and server#39716

Open
GazeKingNuWu wants to merge 3 commits intoopenclaw:mainfrom
GazeKingNuWu:fix/control-ui-token-field-mismatch
Open

fix: resolve Control UI token field mismatch between client and server#39716
GazeKingNuWu wants to merge 3 commits intoopenclaw:mainfrom
GazeKingNuWu:fix/control-ui-token-field-mismatch

Conversation

@GazeKingNuWu
Copy link
Copy Markdown
Contributor

Summary

Fixes #39667 - Control UI token field mismatch

The client was signing with deviceToken but sending auth.token (shared token) to the server.

Changes

  • Client sends both token and deviceToken in auth object
  • Client signs with deviceToken if available
  • Server prefers deviceToken over shared token when reconstructing payload

AI-assisted PR

@openclaw-barnacle openclaw-barnacle bot added app: web-ui App: web-ui gateway Gateway runtime size: XS labels Mar 8, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5e26dff475

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

signedAtMs: number;
nonce: string;
}): "v3" | "v2" | null {
const authToken = params.connectParams.auth?.deviceToken ?? params.connectParams.auth?.token ?? null;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve shared-token signature fallback when both tokens are sent

The new authToken selection in resolveDeviceSignaturePayloadVersion always prefers auth.deviceToken over auth.token, which breaks clients that send both fields but sign the payload with the shared token. This is a supported shape in the existing Gateway client (src/gateway/client.ts sets both when token and deviceToken are provided, and signs with token), so these connections now fail at device-signature validation before the auth fallback logic can run. Please keep signature verification compatible by attempting the shared-token payload when both credentials are present.

Useful? React with 👍 / 👎.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 8, 2026

Greptile Summary

This PR fixes a field mismatch between the Control UI client and the gateway server during device authentication, ensuring both sides agree on which credential value to use when building and verifying the signed payload.

Key changes:

  • Client side: The auth object now includes both the shared token and device token fields. The auth condition includes a redundant device token guard (noted in comments). For payload signing, the code explicitly prioritizes device token with fallback to shared token.
  • Server side: The token resolution now prefers device token over shared token, ensuring the server reconstructs the same payload the client signed. The resolution is extracted into a single variable reused for both V2 and V3 payload verification, reducing code duplication.

Both V2 and V3 verification paths are updated consistently, and backward compatibility with older clients is preserved via nullish coalescing fallback.

Confidence Score: 4/5

  • This PR is safe to merge; the fix is small, targeted, and logically correct with only a minor redundant condition that can be cleaned up.
  • The PR correctly aligns client and server on token preference during device authentication. Both V2 and V3 paths are updated consistently, and backward compatibility is preserved via nullish coalescing fallback. The core fix is sound. The only issue is a redundant boolean guard in the auth condition, which does not affect runtime behavior but could mislead readers about its purpose.
  • ui/src/ui/gateway.ts could be cleaned up by removing the redundant || deviceToken guard in the auth condition (line 225), as the condition is already correctly handled by the prior assignment of authToken.

Last reviewed commit: 5e26dff

authToken = explicitGatewayToken ?? deviceToken;
const auth =
authToken || this.opts.password
authToken || this.opts.password || deviceToken
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant || deviceToken in auth condition

authToken is assigned on line 223 as explicitGatewayToken ?? deviceToken, so authToken is already truthy whenever deviceToken is truthy (given explicitGatewayToken is always either a non-empty string or undefined per line 217's .trim() || undefined logic). The added || deviceToken guard never introduces a new truthy branch and could mislead future readers into thinking it handles a distinct case.

Suggested change
authToken || this.opts.password || deviceToken
authToken || this.opts.password
Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/ui/gateway.ts
Line: 225

Comment:
Redundant `|| deviceToken` in auth condition

`authToken` is assigned on line 223 as `explicitGatewayToken ?? deviceToken`, so `authToken` is already truthy whenever `deviceToken` is truthy (given `explicitGatewayToken` is always either a non-empty string or `undefined` per line 217's `.trim() || undefined` logic). The added `|| deviceToken` guard never introduces a new truthy branch and could mislead future readers into thinking it handles a distinct case.

```suggestion
      authToken || this.opts.password
```

How can I resolve this? If you propose a fix, please make it concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui gateway Gateway runtime size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Control UI "device signature invalid" — token field mismatch between client signing and server

1 participant