Skip to content

fix(auth): recover cleanly when an impersonation session expires#5692

Merged
TheodoreSpeaks merged 2 commits into
stagingfrom
fix/impersonate-auth-failure
Jul 15, 2026
Merged

fix(auth): recover cleanly when an impersonation session expires#5692
TheodoreSpeaks merged 2 commits into
stagingfrom
fix/impersonate-auth-failure

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • Detect impersonation-session expiry in the client: the session query polls (60s) and refetches on window focus, only while impersonatedBy is set — normal sessions are unaffected
  • When the impersonation session expires mid-use, a minimal full-screen state ("The impersonation session expired. Signing you out…") runs a clean sign-out and lands on /login — previously the tab silently broke with no way out
  • Close the refresh loop fix(workspace): recover from stale sessions instead of blank loader after impersonation #5688 leaves open: after expiry the dead session cookies are never cleared server-side (better-auth's customSession plugin drops the cookie-deletion headers on null get-session responses), so the middleware bounces /login back to /workspace and the clean-null branch spins forever. That branch now recovers through recoverFromStaleSession() (sign-out clears the cookies without needing a live session) instead of a bare replace('/login')

Type of Change

  • Bug fix

Testing

Tested manually end to end in the browser: impersonate → forced expiry → auto sign-out → login, and refresh-after-expiry no longer loops (reproduced the loop on current staging first). tsc, lint, and check:api-validation:strict pass.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 15, 2026 7:03pm

Request Review

@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches auth session polling, sign-out recovery, and workspace entry redirects; behavior is scoped to impersonation and stale-cookie cases but mistakes could affect normal login flows.

Overview
Fixes broken UX and redirect loops when admin impersonation sessions expire while stale auth cookies remain.

Adds ImpersonationExpired on the workspace layout: it watches for a session that had impersonatedBy and then settles to no user, shows a full-screen “signing you out” state, and runs shared recovery via recoverFromStaleSession (with retry on failure).

Extracts recoverFromStaleSession into stale-session-recovery.ts and reuses it from the /workspace loader: unauthenticated users no longer get a bare replace('/login') (which looped with middleware when cookies still existed); 401 stale-session paths use the same sign-out → clear client state → /login flow.

Session query changes apply only while impersonatedBy is set: 60s polling, refetch on window focus, and disableCookieCache on those refetches so server-side expiry is detected instead of a cached session.

Reviewed by Cursor Bugbot for commit d675f0b. Bugbot is set up for automated code reviews on this repo. Configure here.

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds clean recovery when an impersonation session expires. The main changes are:

  • Polls active impersonation sessions and refreshes them when the window regains focus.
  • Bypasses cached session data during impersonation refreshes.
  • Signs out stale sessions before navigating to login.
  • Shows an expiry screen with a retry action when sign-out fails.

Confidence Score: 5/5

This looks safe to merge.

  • The latest changes address cached impersonation-session refreshes.
  • Failed sign-out attempts no longer navigate with stale cookies.
  • No blocking issues were found in the updated recovery paths.

Important Files Changed

Filename Overview
apps/sim/hooks/queries/session.ts Adds polling, focus refreshes, and cookie-cache bypass for active impersonation sessions.
apps/sim/app/workspace/[workspaceId]/components/impersonation-banner/impersonation-expired.tsx Adds automatic stale-session recovery and retry UI when impersonation expires.
apps/sim/lib/auth/stale-session-recovery.ts Centralizes sign-out, client-state cleanup, and navigation to login.
apps/sim/app/workspace/page.tsx Routes clean-null sessions through stale-cookie recovery before login navigation.
apps/sim/app/workspace/[workspaceId]/layout.tsx Mounts the impersonation-expiry recovery screen in the workspace layout.

Reviews (4): Last reviewed commit: "fix(auth): share stale-session recovery ..." | Re-trigger Greptile

Comment thread apps/sim/hooks/queries/session.ts
Comment thread apps/sim/app/workspace/page.tsx
@greptile-apps

greptile-apps Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds recovery for expired impersonation sessions. The main changes are:

  • Polls impersonated sessions and refetches them when the window gains focus.
  • Shows a full-screen sign-out state after an impersonation session disappears.
  • Clears stale auth cookies before redirecting clean-null workspace sessions to login.

Confidence Score: 4/5

The impersonation recovery path can still miss expiry or restart the login/workspace loop.

  • Polling can reuse cached impersonation data instead of observing server-side expiry.
  • A failed sign-out still redirects with the stale cookie intact.
  • The imports, layout boundary, and clean-null workspace fallback appear consistent.

apps/sim/hooks/queries/session.ts and apps/sim/app/workspace/[workspaceId]/components/impersonation-banner/impersonation-expired.tsx

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/components/impersonation-banner/impersonation-expired.tsx Adds the expiry screen and sign-out effect, but redirects even when sign-out fails to clear the stale cookie.
apps/sim/hooks/queries/session.ts Adds impersonation polling and focus refetching without bypassing Better Auth's client session cache.
apps/sim/app/workspace/page.tsx Routes clean-null sessions through the existing stale-session recovery helper and exposes its failure state.
apps/sim/app/workspace/[workspaceId]/layout.tsx Mounts the new client recovery component in the workspace layout.
apps/sim/app/workspace/[workspaceId]/components/impersonation-banner/index.ts Exports the new impersonation expiry component through the existing barrel.
apps/sim/app/workspace/[workspaceId]/layout.test.tsx Updates the layout mock for the new component but does not test expiry recovery.

Reviews (2): Last reviewed commit: "fix(auth): recover cleanly when an imper..." | Re-trigger Greptile

Comment thread apps/sim/hooks/queries/session.ts Outdated
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d675f0b. Configure here.

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile review

@TheodoreSpeaks TheodoreSpeaks merged commit bfe8386 into staging Jul 15, 2026
18 checks passed
@TheodoreSpeaks TheodoreSpeaks deleted the fix/impersonate-auth-failure branch July 15, 2026 19:45
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