ReviewOS

stacks/uplink

fix(app): a wrong token is stored before it is checked, and then overrides a working login

#15
Open glennmichael123 opened this 8 days ago ·
8 days ago

Part of #5.

A person who was fully set up can break their install by pasting the wrong token once, and there is no way to undo it from the popover.

What is there today

POST /api/token (app/Uplink/desktop-agent.ts#L309) validates only the shape, then writes and activates the token before checking whether it works:

  • writeToken(cleaned) at app/Uplink/desktop-agent.ts#L313 persists it to the Keychain.
  • process.env.CLAUDE_CODE_OAUTH_TOKEN = cleaned at #L315 injects it into the running process.
  • checkClaude() at #L316 runs afterwards, and its answer changes nothing that was just written.

tokenLooksValid (app/Uplink/settings.ts#L101) matches /^sk-ant-/, so a token that is expired, for the wrong account, or copied from another Mac passes.

Then ClaudeEngine only drops the variable when it is empty (app/Uplink/engine.ts#L91), so a bad token now overrides a claude CLI that was logged in interactively and working. The person's install was fine before they touched it.

There is also no way back: deleteToken exists (app/Uplink/settings.ts#L88) and nothing in the popover calls it.

Proposal

  1. Check before storing. Probe with the candidate token in a temporary environment, and write to the Keychain only if it answers.
  2. On failure, say which failure it was. "That token was rejected" is different from "that does not look like a whole token", and the existing wrapped-paste message (app/Uplink/desktop-agent.ts#L312) should stay for the shape case.
  3. Add a remove action that calls deleteToken, so a person can fall back to the CLI's own login.
  4. When the CLI is already logged in and working without a token, say so, and do not ask for one. The token exists for the background service case, not as a requirement.

Requirements

  • Never persist a credential that has not answered once.
  • Never leave the process environment holding a token the Keychain does not have, or a restart silently changes behaviour.
  • Removing the token must restore the previous state, which means not having clobbered it: read what was there before deciding.
  • Keep cleanToken (app/Uplink/settings.ts#L92). The wrapped-paste case already bit this project once and the comment says so.

Acceptance

  • Pasting a shape-valid but rejected token leaves the Keychain unchanged and reports the rejection.
  • Removing the token restores a working CLI-login install.
  • A Mac with a logged-in CLI and no token shows the sign-in step as satisfied.

Sign in to comment on this issue.