Skip to content

fix(connected-apps): let remote clients disconnect their own accounts - #1067

Merged
milind-soni merged 1 commit into
milind-soni:mainfrom
santhiprakash:fix/1048-remote-disconnect
Sep 12, 2026
Merged

milind-soni merged 1 commit into
milind-soni:mainfrom
santhiprakash:fix/1048-remote-disconnect

Conversation

@santhiprakash

@santhiprakash santhiprakash commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Refs #1048

What changed

The Connected apps account row now shows its Disconnect button for remote
(desktop companion) clients too, and the companion sidecar allowlists the
per-account route it calls:

  • companion/src/routes.ts — DELETE /api/connectors/:slug/accounts/:id is
    added to ALLOWED.
  • src/components/PluginsPanel.tsx — the {mayDisconnect && …} gate is
    removed (and the now-unused connectedAppsMayDisconnect helper with it), so
    every listed account offers Disconnect.
  • Tests updated for the new contract.

Why

A user who connects an account from a paired remote client gets a card that
shows the account but no way to remove it — the UI hid the button and the
companion boundary would have denied the DELETE anyway. The asymmetry was
already there for adding (POST …/authorize is allowlisted), so a remote
client could connect but never disconnect.

The revocation exclusion predates desktop remote access and was scoped to the
phone companion ("a paired phone … never remove one"). Two notes on the
boundary change, for review:

  • removeAccount still proves the account belongs to the host's own Composio
    user before revoking, so a paired device can only remove accounts it could
    already see and add.
  • The whole-service DELETE /api/connectors/:slug stays denied; only the
    per-account route the panel actually calls is opened.

How it was verified

  • pnpm typecheck — clean.
  • pnpm exec vitest run companion/test/routes.test.ts src/components/PluginsPanel.test.ts src/components/PluginsPanel.i18n.test.ts — 99/99 pass, including the new "allows DELETE …/accounts/:id" case and a path-traversal denial case.
  • Full pnpm exec vitest run — 5798 pass, 9 unrelated environment-dependent failures (linux-after-install tmpdir, control-omb fake-engine, browser-bundle linux-arm64, engine-install npm PATH).

Screenshots (UI changes)

n/a — restores a control that already renders for non-remote clients.

Checklist

  • pnpm typecheck and pnpm test pass locally
  • Server behavior changes come with tests (see CONTRIBUTING.md → Tests)
  • No dist-server/ edits (it's build output)
  • macOS-only code is platform-gated; no shell: true / cmd.exe string-building
  • No secrets in logs, responses, events, or argv

Summary by CodeRabbit

  • New Features

    • Remote clients can now disconnect individual accounts from connected apps.
    • Account-specific disconnect controls are available consistently across clients, with confirmation prompts retained.
    • Connected-app panels now support viewing accounts beyond marketplace-card limits.
  • Bug Fixes

    • Improved connected-app status recovery, loading behavior, and handling of stale or empty responses.
    • Added safeguards to prevent invalid or path-traversal account removal requests.
    • Whole-service connector removal remains restricted to the host.

Issue milind-soni#1048: a paired desktop client could add a connected-app account but
had no Disconnect control — the panel hid it behind
`connectedAppsMayDisconnect(remoteClient)`, and the companion boundary
denied the account DELETE route outright. A user who connected Gmail from a
remote client had no way to revoke it.

The revocation block predates desktop remote access: it was written for the
phone companion, where the boundary deliberately keeps host mutation small.
Paired clients may already add accounts (POST .../authorize is allowlisted),
so "connectable but never disconnectable" was an asymmetry rather than a
safety property — and the environments/session path already permits the same
DELETE for admin-scoped remote sessions.

- companion/src/routes.ts: allowlist DELETE
  /api/connectors/:slug/accounts/:accountId. The handler still proves the
  account belongs to the host's own Composio user before revoking, so a
  paired device can only remove accounts it could already see and add. The
  whole-service DELETE stays denied.
- PluginsPanel: always render the per-account Disconnect control; drop the
  remote-client gate and the now-unused connectedAppsMayDisconnect helper.
- Tests: update the allowlist contract and drop the obsolete
  remote-permission test.

Verification: pnpm typecheck; pnpm exec vitest run for the touched suites
(companion routes, PluginsPanel) — 99/99 pass; full suite 5798 pass, 9
failures are environment-dependent and unrelated (linux-after-install tmpdir,
control-omb fake-engine, browser-bundle linux-arm64, engine-install npm PATH).
@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

@santhiprakash is attempting to deploy a commit to the SupaMaus Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Sep 10, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 5bbab653-0244-4475-89cc-7c6f8dbfab71

📥 Commits

Reviewing files that changed from the base of the PR and between 6420f72 and 58db0c9.

📒 Files selected for processing (4)
  • companion/src/routes.ts
  • companion/test/routes.test.ts
  • src/components/PluginsPanel.test.ts
  • src/components/PluginsPanel.tsx
💤 Files with no reviewable changes (1)
  • src/components/PluginsPanel.test.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The companion allowlist now permits account-specific connector deletion. The plugins panel renders account disconnection controls for remote clients. Tests cover authorization boundaries, path traversal, connector state handling, and disconnect behavior.

Changes

Remote account disconnection

Layer / File(s) Summary
Allow account-specific companion deletion
companion/src/routes.ts, companion/test/routes.test.ts
The companion permits DELETE /api/connectors/{connectorId}/accounts/{accountId}. Tests allow account deletion, retain whole-service deletion denial, and reject traversal paths.
Render remote account disconnection
src/components/PluginsPanel.tsx, src/components/PluginsPanel.test.ts
The plugins panel shows account disconnect controls for all clients. Tests cover status recovery, stale responses, managed installs, account messaging, loading states, and authoritative responses.

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

Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant PluginsPanel
  participant CompanionRoutes
  participant ConnectedAppServer
  PluginsPanel->>CompanionRoutes: DELETE connector account
  CompanionRoutes->>ConnectedAppServer: Authorize account deletion
  ConnectedAppServer-->>CompanionRoutes: Verify ownership and revoke account
  CompanionRoutes-->>PluginsPanel: Return deletion result
Loading

Suggested reviewers: milind-soni, aivsomkar, philip-ulrich

Merge Risk: ⚪ Minimal · up to 58db0

Paired clients can now disconnect individual connected accounts, with ownership checks and whole-service deletion protections preserved. The change is merge-ready.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #1048 by showing Disconnect controls for connected accounts and enabling the required per-account deletion route. Ownership checks and whole-service deletion restrictions rem…
Out of Scope Changes check ✅ Passed All implementation and test changes support the stated remote connected-account disconnection objective. No unrelated code changes are evident.
Title check ✅ Passed The title clearly and concisely describes the main change: allowing remote clients to disconnect their own connected-app accounts.
Description check ✅ Passed The description includes all required sections, explains the change and rationale, documents verification results and known unrelated failures, and completes the checklist.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@milind-soni
milind-soni merged commit 24cc995 into milind-soni:main Sep 12, 2026
21 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants