Skip to content

fix(oauth): expose live device hints and hide callback paste - #5915

Closed
codingbooo wants to merge 1 commit into
lidge-jun:devfrom
codingbooo:fix/issue-5881-meta-muse-oauth
Closed

codingbooo wants to merge 1 commit into
lidge-jun:devfrom
codingbooo:fix/issue-5881-meta-muse-oauth

Conversation

@codingbooo

@codingbooo codingbooo commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #5881.

For device-code OAuth flows (such as Meta Muse), the add-provider UI previously continued rendering the manual callback/redirect paste affordance, and subsequent onAuth hint transitions during polling were not reliably projected to the client status surface.

Implemented via Codex (gpt-6-astra):

  • Retain current deviceCode, url, and instructions in login flow state and project them in getLoginStatus.
  • In gui/src/components/login-url-block.tsx, gate the manual callback/redirect paste input on the absence of an active deviceCode.
  • In use-add-provider-oauth.ts, update live auth hints dynamically from polled status.
  • Ensure cancellation clears active hints and settled device authorization requires no manual callback input.
  • Added comprehensive regression tests in gui/tests/login-url-block.test.tsx and tests/oauth/.

Verification

  • bun run typecheck passed cleanly.
  • bun run lint:gui passed.
  • bun test gui/tests/ tests/oauth/ passed cleanly.
  • Privacy scan and structural checks passed.

Review readiness checklist

  • Required local validation passed; commands, results, and any full-suite exception are documented.
  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • I resolved all correct Codex and CodeRabbit findings.
  • My PR is ready for review.

Checklist

  • Target branch is dev
  • Followed repository TypeScript and testing guidelines

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • New Features

    • Meta Muse login can use browser-based device approval when local credentials are unavailable. The login screen displays the verification URL, device code, and instructions, then updates its status while approval is pending.
    • After approval, credentials are saved automatically. The device code and instructions clear when the flow is cancelled or completed.
  • Bug Fixes

    • Prevented outdated login attempts from replacing the current approval details.
    • Hid the callback-paste field while a device code is active; it remains available as a fallback when no device code is provided.

@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/index.ts, src/oauth/login-flow-state.ts.

@github-actions github-actions Bot added the bug Something isn't working label Sep 26, 2026
@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 4abffb5f-09d8-42ac-a1e0-906adf3f0031

📥 Commits

Reviewing files that changed from the base of the PR and between e807e1e and 991a50f.

📒 Files selected for processing (11)
  • docs-site/src/content/docs/guides/providers.md
  • gui/src/components/login-url-block.tsx
  • gui/src/components/use-add-provider-oauth.ts
  • gui/tests/add-provider-oauth-url-leak.test.tsx
  • gui/tests/login-url-block.test.tsx
  • src/oauth/index.ts
  • src/oauth/login-flow-state.ts
  • structure/gui-and-management-api.md
  • structure/providers-and-adapters.md
  • tests/oauth/oauth-login-open-browser.test.ts
  • tests/oauth/oauth-reauth-bind.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

OAuth login status now exposes the active URL, device code, and instructions. The add-provider interface refreshes these hints during polling, hides callback paste while a device code is active, and clears the URL when the login settles.

Changes

Live OAuth device-login hints

Layer / File(s) Summary
Store and expose active login hints
src/oauth/login-flow-state.ts (1, 14), src/oauth/index.ts (1767, 1798, 1853–1854), tests/oauth/oauth-login-open-browser.test.ts (76–104), tests/oauth/oauth-reauth-bind.test.ts (4, 312–335)
Flow state stores the latest auth hint. getLoginStatus exposes the hint while the flow is unfinished, and callbacks from superseded controllers are ignored. Tests cover hint replacement, cancellation, and device approval settling without callback input.
Refresh and display device-login hints
gui/src/components/use-add-provider-oauth.ts (3, 127–140, 159–162), gui/src/components/login-url-block.tsx (122), gui/tests/add-provider-oauth-url-leak.test.tsx (757–783), gui/tests/login-url-block.test.tsx (6, 180–194), docs-site/src/content/docs/guides/providers.md (758–762), structure/gui-and-management-api.md (185), structure/providers-and-adapters.md (16–19)
The add-provider hook updates the displayed hints from status responses and requires done !== false for success. The paste fallback is hidden while a device code is present. Tests and documentation cover hint updates, fallback behavior, and cancellation or settlement clearing hints.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant OAuthController
  participant loginState
  participant getLoginStatus
  participant useAddProviderOAuth
  participant LoginHint
  OAuthController->>loginState: Store current onAuth hint
  useAddProviderOAuth->>getLoginStatus: Poll provider status
  getLoginStatus->>loginState: Read active hint
  getLoginStatus-->>useAddProviderOAuth: Return URL, device code, instructions, and done
  useAddProviderOAuth->>LoginHint: Update displayed login hint
Loading

Possibly related PRs

  • lidge-jun/opencodex#2530: Adds shared device-code login hints and UI support that this change extends through OAuth flow state and status polling.

Merge Risk: ⚪ Minimal · up to 991a5

Live device-login hints reach the add-provider interface. No identified issue prevents merging after normal checks.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 991a5

Live device-login codes can now be read through the login-status endpoint by other authorized management clients, not just the client that started the login. Whether that sharing is intended needs review. The endpoint is authenticated, and the code is removed when the flow settles.

Retained concerns

  • Medium · security · observed: The newly exposed active device code and instructions are keyed only by provider. A separately authorized management client can query the initiating client's live hint; for Meta Muse, status does not apply the dashboard-principal check required to start login.
Security review details

Security Blast Radius

  • inferred — The new exposure is limited to an active login for a queried public provider and a client admitted to the management API. No evidence establishes unauthenticated access, cross-environment propagation, or disclosure of stored OAuth credentials.

Security Findings and Attack Paths

  • observed — After a dashboard client starts a Meta Muse flow, another management-authorized client can request status by provider and receive the active device hint without satisfying the login route's dashboard-principal check. Whether sharing that hint violates the intended client-ownership policy remains unresolved.

Trust Boundaries and Controls

  • observed — The public-provider check and upstream management authentication constrain status access. Controller ownership and done-gated projection constrain stale or completed hints, but neither binds a live hint to its initiating client.

Resilience and Maintainability Implications

  • observed — Cancellation records a terminal state and deletes the active controller; delayed callbacks are checked against controller identity before updating hints. The management cancellation route remains provider-scoped rather than caller-scoped.

Hardening Proposals

  • proposed — Decide whether live hints are intended to be shared among management clients. If not, bind status visibility to an initiating session or opaque flow identity and apply the same policy consistently to cancellation; preserve the existing terminal-state cleanup.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 8 files. (3 skipped: 3… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #5881 coding requirements are covered. src/oauth/login-flow-state.ts stores the latest onAuth hint, and src/oauth/index.ts exposes its url, deviceCode, and instructions through activ…
Out of Scope Changes check ✅ Passed The changes stay within Issue #5881. The documentation updates in docs-site/src/content/docs/guides/providers.md, structure/gui-and-management-api.md, and structure/providers-and-adapters.md des…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main changes: exposing live OAuth device hints and hiding the callback paste field during device-code login.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 8 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • UI screenshot required. hygiene: unsponsored_surface.

What to do

  • Add a screenshot of the UI change to the PR description.
  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/index.ts, src/oauth/login-flow-state.ts.

Review readiness checklist

  • ✅ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ✅ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

✅ 4/4 boxes ticked.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.

@github-actions
github-actions Bot marked this pull request as draft September 26, 2026 08:49
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 51 / 80

Meta Muse처럼 브라우저에서 코드를 승인하는 로그인에서, 화면이 예전 안내를 붙들거나 코드를 보여 주면서도 콜백 주소를 붙여 넣으라고 하는 문제를 고칩니다. 이슈 #5881을 닫는 PR입니다.

서버는 진행 중인 로그인의 주소, 기기 코드, 안내 문구를 기억합니다. 상태 조회는 그 최신 값을 돌려주고, 로그인이 끝나거나 취소되면 안내를 지웁니다. 이미 취소된 로그인이 나중에 보낸 안내는 무시합니다.

추가 공급자 화면은 기기 코드가 있는 동안 붙여 넣기 칸을 숨깁니다. 코드가 빠지고 수동 입력으로 바뀌면 칸이 다시 나옵니다. 예전에 로그인된 계정이 있어도, 이번 시도가 끝나기 전에는 성공으로 치지 않습니다.

src/oauth/index.ts:1798 - 진행 중일 때 주소, 기기 코드, 안내 문구를 상태 JSON의 맨 위 필드로 넣습니다. 그 응답을 그대로 주는 GET /api/oauth/status(src/server/management/oauth-account-routes.ts:309)는 Meta Muse 로그인 시작에 있는 대시보드 세션 검사를 하지 않습니다. 관리 API를 호출할 수 있는 다른 클라이언트도 진행 중인 기기 코드를 읽습니다.

gui/src/pages/use-providers-oauth.ts:124 - 공급자 페이지는 로그인 시작 응답의 안내만 화면에 올립니다. 132번째 줄의 폴링은 끝난 여부만 보고, 새 주소나 기기 코드로 화면을 바꾸지 않습니다. 152번째 줄은 이미 로그인된 상태(loggedIn)를 이번 로그인의 성공으로 칩니다.

메인테이너의 판단이 필요한 지점

#5911도 #5881을 닫겠다고 되어 있고, 같은 로그인 안내와 붙여 넣기 칸을 고칩니다. #5911은 안내를 hint 객체 안에 두고 공급자 페이지 폴링까지 갱신합니다. 이 PR은 안내를 상태 JSON 맨 위에 펼칩니다. 어느 응답 모양을 남길지 정해야 합니다. 기기 코드를 대시보드 세션 밖으로 보여 줄지도 같이 정하면 됩니다.

너의 추천

#5911에 이 PR만의 차이가 없으면 이 PR은 닫으세요. 이 쪽을 살린다면 공급자 페이지 폴링도 최신 안내를 따라가게 하고, 상태 조회에 로그인 시작과 같은 대시보드 세션 조건을 거세요. 화면 캡처, 본문 아래쪽 체크리스트 4개, maintainer-sponsored가 있어야 draft에서 나옵니다.

이 댓글은 grok-bot이 작성했습니다

@codingbooo
codingbooo marked this pull request as ready for review September 26, 2026 13:27
@github-actions
github-actions Bot marked this pull request as draft September 26, 2026 13:28
@codingbooo
codingbooo marked this pull request as ready for review September 26, 2026 13:28
@github-actions
github-actions Bot marked this pull request as draft September 26, 2026 13:29
@codingbooo
codingbooo marked this pull request as ready for review September 26, 2026 13:40
@github-actions
github-actions Bot marked this pull request as draft September 26, 2026 13:40
@codingbooo
codingbooo marked this pull request as ready for review September 26, 2026 13:49
@github-actions
github-actions Bot marked this pull request as draft September 26, 2026 13:49
@codingbooo
codingbooo marked this pull request as ready for review September 26, 2026 13:50
@github-actions
github-actions Bot marked this pull request as draft September 26, 2026 13:51
@codingbooo codingbooo closed this Sep 26, 2026
@codingbooo codingbooo reopened this Sep 26, 2026
lidge-jun added a commit that referenced this pull request Sep 26, 2026
…ards (batch 9D) (#5986)

A second `ocx` instance now leaves the live proxy's shared client routing alone across startup, management requests, restart, and stop. The batch also makes Home-side Remote Link usable from the local dashboard, keeps OAuth device guidance current, and offers one-time pairing on an authenticated remote hub that lacks a GUI session.

| PR | Change | Author |
|---|---|---|
| #5926 | Isolate sibling startup, shared writes, restart and stop from the live owner. | JUN (lidge-jun) |
| #5928 | Admit the local Home dashboard to SSH host discovery/probe/apply, improve SSH resolution and bounded errors, and keep Child join paired-only. | JUN (lidge-jun) |
| #5911 | Show Meta Muse OAuth only to eligible GUI sessions and replace stale device hints through login. | Ingwannu, with shared device-hint work credited to codingbo |
| #5978 | Show the one-time pairing form on Remote Link for a remote hub without a GUI session. | RHODIZSECURITY |

The owner's three original commits retain JUN authorship. Each contributor PR remains one attributed squash commit. The older device-hint variant (#5915) is outside this branch because #5911 covers the same login behavior; its shared implementation is credited to codingbo.

Follow-up commits after independent review:

| Commit | Result |
|---|---|
| `66967095d0` | Restrict the new pairing display path to hub runtimes; a non-loopback standalone keeps its local-session guidance. |
| `fa182b9d2d` | Keep sibling-home roster updates available while skipping the shared Claude Desktop profile auto-apply, including after asynchronous discovery. |
| `32d7893113` | Require a fresh, home-bound listener proof before an orphan stop can signal a discovered proxy. |
| `dda805fbad` | Require a short-lived, one-use sibling restart handoff record bound to the prior sibling runtime and home; a port env alone cannot claim sibling status. |
| `37f368cf20` | Keep the connected-client sibling recycle path valid when its runtime record has no server attestation secret; the same-home PID, ports and process-local mark still gate issuance. |
| `a42fcac751` | Capture the connected sibling's one-use handoff before link recycle stops the listener and removes its runtime record; spawn with that captured environment. |
| `d3cc7b80bb` | Remove the Kiro cooldown test's timestamp-order race exposed by macOS CI. |

`dev` advanced during review. Merge commit `a4d9aff73e` brought in `177c647d9c` and kept both the SSH PATH and listener-before-supervisor Remote Link contracts. Merge commit `43d314287c` brings in current `dev` `93e5d5bea5` without changing the owner's commits. Their combined dashboard structure document exceeded its line budget; `1e93a8401b` reflows the existing OAuth paragraph from 603 to 600 lines without raising the cap. The Kiro timing correction also landed independently on `dev`; the merge keeps that current test.

Screenshots from the built GUI (demo session and responses only):

![Home SSH host candidates](https://github.com/lidge-jun/opencodex/blob/506401dea3857034b87d296e8b74b38b0f2ce7b3/260926-remote-link-ssh-hosts/03-home-sheet-candidates.png?raw=true)
![OAuth device hint with callback paste hidden](https://github.com/lidge-jun/opencodex/blob/a5d102c17e03caf10766d0bb15c32ac365dbc094/260927-codex-bug-train-9d/9d-oauth.png?raw=true)
![Remote hub one-time pairing form](https://github.com/lidge-jun/opencodex/blob/f53b699ce5e1ac4cb3d6772f4e86c0dec10808e3/260927-codex-bug-train-9d/9d-pairing.png?raw=true)

Security re-review should focus on sibling start/stop and handoff (`src/codex/sibling-start.ts`, `src/codex/sibling-handoff.ts`, `src/client/runtime.ts`, `src/cli/index.ts`, `src/server/proxy-liveness.ts`), Desktop auto-apply (`src/server/management/agent-settings-routes.ts`), Remote Link admission and SSH (`src/server/management/link-routes.ts`, `src/link/ssh-argv.ts`, `src/link/ssh-runner.ts`), OAuth state and principal discovery (`src/oauth/index.ts`, `src/oauth/login-flow-state.ts`, `src/server/management/oauth-account-routes.ts`), and the hub-only pairing gate (`gui/src/App.tsx`). Independent reviewer sign-off remains required before merge.

Co-authored-by: Ingwannu <ingwannu@users.noreply.github.com>
Co-authored-by: codingbo <cnsdbo@163.com>
Co-authored-by: RHODIZSECURITY <180237049+RHODIZSECURITY@users.noreply.github.com>
@lidge-jun

Copy link
Copy Markdown
Owner

Closing as superseded: #5911 covers the same Meta Muse device-hint and callback-paste problem more fully, including principal-aware discovery and stale-flow fencing. It landed on dev through bug-PR merge train batch 9D, #5986 (merge 6b2b66d), with a Co-authored-by trailer crediting you for the overlapping work. Thank you.

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

Labels

bug Something isn't working intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants