Skip to content

fix(credentials): a refused revoke must say so where the user is looking - #243

Merged
pythonlearner1025 merged 1 commit into
mainfrom
fix/credential-revoke-error-placement
Sep 6, 2026
Merged

fix(credentials): a refused revoke must say so where the user is looking#243
pythonlearner1025 merged 1 commit into
mainfrom
fix/credential-revoke-error-placement

Conversation

@pythonlearner1025

Copy link
Copy Markdown
Member

What part this touches

Settings → Credentials. Each stored secret gets a row with Rotate and
Revoke. Revoke opens ConfirmationDialog, the shared yes/no modal used
across the webApp.

That dialog already accepts two props no caller had ever passed: busy, which
disables its buttons and blocks dismissal, and error, which draws a message
in its own body.

The bug

Press Revoke on a credential, confirm, and let the request fail. The
confirmation vanishes, the credential is still listed, and no explanation is
visible.

Two things hid it:

  • setRevokeTarget(null) ran BEFORE the request. The dialog was already gone
    when the failure landed.
  • The catch wrote the panel-wide error. That message draws once, directly
    under the panel header. On a list of fifteen credentials the row is far
    below it, off screen.

This is the same defect #234 fixed for Save access in this same file. That
fix gave the access editor its own accessError, drawn beside the button.
Revoke was the sibling action and kept the old shape.

The fix

  • The confirmation stays open while the request runs, with busy set.
  • The dialog closes only on success.
  • A failure fills the dialog's own error prop, so the message draws beside
    the button that caused it.
  • The message clears when the dialog is dismissed, and when Revoke opens a
    confirmation for another credential.
  • The panel-wide error keeps load, add and rotate failures. The two are not
    folded together.

No new markup and no new CSS. ConfirmationDialog already drew both states.

The risk trade

The dialog now lives longer. It stays on screen for the length of the request
instead of closing at once, so a slow revoke feels slower.

busy covers that: both buttons disable and the overlay stops dismissing, so
the wait reads as work rather than as a stuck modal. The existing
if (revoking !== null) return; guard already blocked a second revoke.

Rejected alternative: draw the message under the credential's row. It
duplicates what the dialog can already show, and it puts the text where the
user is not looking, which is the bug being fixed.

Tests

packages/webapp/test/org-credentials-panel.test.tsx, two new tests:

  • a rejected revoke leaves the dialog open, draws the message inside it, and
    keeps the credential listed;
  • dismissing and revoking a different credential shows no stale message, and a
    later success closes the dialog.

Counts in this worktree:

test/org-credentials-panel.test.tsx   12 passed (2 failed without the fix)
npm run typecheck                     green
npm run lint:gate                     green, 43 anti-slop, 0 blitz-house

Reverting only OrgCredentialsPanel.tsx fails both, and the message is the
bug stated plainly:

Error: missing [role="dialog"]

The dialog is gone before the failure can be shown.

Deploy

One artifact ships it: the control-plane Worker, which carries the webApp
bundle.

git merge --ff-only fix/credential-revoke-error-placement

A push to main deploys canary. No migration. No box or payload change.

Rollback:

git revert <merge sha>

A revert restores the silent close. It loses no data.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LGizvh2GBb4wnVqs7qKNtP

Revoking a credential closed its confirmation before the request ran, then
reported failure through the panel-wide error under the panel header. On a
long list the row sits far below that, so the dialog just vanished and the
credential stayed.

ConfirmationDialog already carried busy and error props that no caller used.
The confirmation now stays open while the request runs, closes only on
success, and draws the failure in its own body.

This is the Revoke sibling of the Save access fix in #234.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGizvh2GBb4wnVqs7qKNtP
@pythonlearner1025
pythonlearner1025 merged commit 8c25562 into main Sep 6, 2026
12 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.

1 participant