Skip to content

Feat/assume user#3742

Merged
TheodoreSpeaks merged 6 commits intostagingfrom
feat/assume-user
Mar 24, 2026
Merged

Feat/assume user#3742
TheodoreSpeaks merged 6 commits intostagingfrom
feat/assume-user

Conversation

@TheodoreSpeaks
Copy link
Collaborator

@TheodoreSpeaks TheodoreSpeaks commented Mar 24, 2026

Summary

We need more visibility in how our users use mothership. Added an impersonate user flow to allow sim admins to view users' workspaces.

See: https://better-auth.com/docs/plugins/admin#impersonate-user

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

  • Tested only admin can assume role
  • Tested impersonated user can view resources, tasks, and workflows
  • Tested banner warns admins that they are impersonating a user.

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)

Screenshots/Videos

image

@vercel
Copy link

vercel bot commented Mar 24, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 24, 2026 11:07pm

Request Review

@TheodoreSpeaks
Copy link
Collaborator Author

@cursor review @greptile review

@cursor
Copy link

cursor bot commented Mar 24, 2026

PR Summary

High Risk
Introduces admin-driven impersonation and stop-impersonating actions, which directly affect session identity and privileges. Mistakes here could allow unintended access or leave admins operating under the wrong user context.

Overview
Adds an admin user impersonation action in the Admin settings user list, calling new useImpersonateUser/useStopImpersonating mutations and redirecting to /workspace after switching.

Updates session typing to include session.impersonatedBy and shows a destructive ImpersonationBanner across workspace pages when impersonating, with a one-click “Stop impersonating” exit. Also introduces a reusable Banner component and adjusts the workspace layout to accommodate the new top-of-page banner.

Written by Cursor Bugbot for commit 6f97d5a. This will update automatically on new commits. Configure here.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR adds an admin impersonation flow powered by better-auth's admin plugin. When an admin clicks "Impersonate" on a user in the admin panel, the session cookie is swapped to that user's identity and the page reloads. A persistent destructive banner (ImpersonationBanner) is rendered at the top of the workspace layout whenever session.session.impersonatedBy is set, giving the admin a clear visual cue and a "Stop impersonating" button that reverts the session.

  • New Banner EMCN component using CVA with default/destructive variants, exported correctly from the barrel.
  • useImpersonateUser and useStopImpersonating mutation hooks added to hooks/queries/admin-users.ts; both correctly skip query invalidation since impersonation/stop triggers a full-page reload.
  • ImpersonationBanner is placed outside WorkspacePermissionsProvider in the layout, which is correct — it only needs session data, not workspace permissions.
  • Layout restructuring (adding flex-col overflow-hidden to the outer div + flex min-h-0 flex-1 wrapper) correctly constrains the banner without breaking the existing sidebar + content layout.
  • The impersonatedBy field is added to the AppSession type — however, the existing PostHog identify call in session-provider.tsx is not guarded against impersonation, meaning admin browsing sessions will be mis-attributed to the impersonated user in analytics.

Confidence Score: 4/5

  • Safe to merge after addressing the PostHog analytics mis-attribution during impersonation sessions.
  • The implementation is clean, follows existing project patterns, and was well-tested per the PR description. The layout restructuring is minimal and correct. The one real issue is that PostHog will identify the admin's browser as the impersonated user since the impersonatedBy guard is missing from the existing identify call — this is a newly activated analytics data quality problem introduced by enabling the feature. The P2 style note on isRedirecting is non-blocking.
  • apps/sim/app/_shell/providers/session-provider.tsx — needs a guard on the PostHog identify call to skip identification during impersonation sessions.

Important Files Changed

Filename Overview
apps/sim/app/_shell/providers/session-provider.tsx Adds impersonatedBy to the session type; however the existing PostHog identify call will mis-attribute admin activity to impersonated users — the new field should gate the identify call.
apps/sim/app/workspace/[workspaceId]/impersonation-banner.tsx New client component that shows a destructive banner when impersonating; logic is sound with a minor no-op state issue in onError.
apps/sim/app/workspace/[workspaceId]/settings/components/admin/admin.tsx Adds impersonate button per user row with a client-side admin guard, pending state tracking, and error display; implementation follows existing patterns cleanly.
apps/sim/components/emcn/components/banner/banner.tsx New reusable Banner component using CVA for variants; follows EMCN component patterns with correct internal subpath imports to avoid circular dependencies.
apps/sim/hooks/queries/admin-users.ts Adds useImpersonateUser and useStopImpersonating mutation hooks; navigation-on-success design correctly skips query invalidation since the page reloads.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Admin clicks Impersonate button] --> B{Client-side role check}
    B -- Not admin --> C[Show guard error message]
    B -- Is admin --> D[Call impersonateUser mutation]
    D --> E{API response}
    E -- Error --> F[Show error, re-enable button]
    E -- Success --> G[window.location.assign to workspace]
    G --> H[Page reloads with target user session]
    H --> I{session.impersonatedBy set?}
    I -- Yes --> J[Render ImpersonationBanner]
    I -- No --> K[No banner shown]
    J --> L[Admin clicks Stop impersonating]
    L --> M[Call stopImpersonating mutation]
    M --> N{API response}
    N -- Error --> O[Re-enable button]
    N -- Success --> P[window.location.assign to workspace]
    P --> Q[Page reloads with admin session]
    Q --> K
Loading

Comments Outside Diff (1)

  1. apps/sim/app/_shell/providers/session-provider.tsx, line 80-101 (link)

    P1 PostHog will identify the admin as the impersonated user

    With impersonation now enabled, the existing posthog.identify call in the session provider will fire using the impersonated user's id, email, and name. Because better-auth replaces the session with the target user's data, data.user during an impersonation session belongs to the impersonated user — not the admin. This will pollute your analytics by attributing admin browsing activity to real user profiles.

    The impersonatedBy field is now available on data.session and can be used to short-circuit the identify call:

    // In the posthog useEffect, guard the identify call:
    if (data?.user && !data.session?.impersonatedBy) {
      posthog.identify(data.user.id, { ... })
    } else {
      posthog.reset()
    }
    

Reviews (2): Last reviewed commit: "Remove admin panel when impersonating" | Re-trigger Greptile

Copy link

@cursor cursor bot left a comment

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

@TheodoreSpeaks TheodoreSpeaks marked this pull request as ready for review March 24, 2026 19:40
@TheodoreSpeaks TheodoreSpeaks merged commit 59182d5 into staging Mar 24, 2026
12 checks passed
@TheodoreSpeaks TheodoreSpeaks deleted the feat/assume-user branch March 24, 2026 23:38
Sg312 pushed a commit that referenced this pull request Mar 25, 2026
* Allow admin users to assume user sessions

* Add explicit role check

* Fix lint

* Remove admin panel when impersonating

* Fix lint

---------

Co-authored-by: Theodore Li <theo@sim.ai>
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