fix(dashboard): graceful UX when an impersonation grant is revoked mid-session#1293
Merged
Conversation
…d-session Revoking (or expiring) an in-progress impersonation left the dead impersonation token installed: every request 401d but the page just rendered a stuck error band under a half-loaded surface while the "End impersonation" banner lingered. Detect the case (a 401 while the active token carries the act_sub impersonation claim - a durable signal, since prod keeps the 401 body opaque) in the global query/mutation error hook and route to a calm full-screen "Impersonation ended" terminal page that clears the dead token via "Back to sign in". Mirrors the existing tenant-deactivated flow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Revoking (or expiring) an in-progress impersonation left the dead impersonation token installed in the dashboard: every request
401d, but the page just rendered a stuck red error band under a half-loaded surface while the "End impersonation" banner lingered — a confusing, broken-looking state.The dashboard now detects this and routes to a calm full-screen Impersonation ended terminal page that clears the dead token via Back to sign in. Mirrors the existing deactivated-tenant flow.
How
api-client.ts— newisImpersonationRevokedError(): true on a401while the active token carries theact_subimpersonation claim. This is the durable signal — production deliberately blanks the401body (the "Impersonation grant revoked or ended" reason is dev-only), and impersonation sessions never hold a refresh token, so such a401always propagates to the hook instead of being silently refreshed-and-retried.query-client.ts— extended the global query/mutation error hook (alongside the existing tenant-deactivated branch) to route to/impersonation-ended, passing the dev-only reason via router state. Does not clear the token here (would raceProtectedRouteto/login).pages/impersonation-ended.tsx— new top-level terminal page mirroringtenant-deactivated.tsx.routes.tsx— lazy import + top-level route (outsideProtectedRoute/AppShell).Tests
tests/impersonation/impersonation-ended.spec.ts(2 specs): a401on an impersonation session routes to the page; Back to sign in clears the token and lands on/login. Both green.tsc -bclean,eslintclean.Docs
Changelog entry (2026-06-09) added in the separate docs repo.
🤖 Generated with Claude Code