You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(webapp): clear impersonation before the consent action's admin check
Two review findings, both about "who is this request" being answered
differently in different places.
The consent page's action went straight from requireUser to the admin
check. requireUser resolves to the impersonated user whenever the
impersonation cookie is set, so user.admin was false for a legitimate
admin who already had an impersonation session: render the consent page
with nothing active, start impersonating in another tab, then press
Impersonate on the still-open page, and the POST redirected to / with no
explanation. The action now mirrors the loader's ordering — clear the
impersonation first and come back to the same URL (search included) under
the admin's own identity, where the normal flow re-authorizes them and
they can confirm. The impersonation mutation never runs on a request whose
resolved identity is the impersonated user.
The view-as-user flag had two definitions. requireUser required the
impersonated id to match the resolved user; the root loader only required
that some impersonated id was present in the session. Those disagree in
exactly one state: getUserId deliberately falls back to the real admin's
id when they are no longer an admin, so the cookie still names a target
that is not the resolved user. The client-side flag read true while the
server-computed user.isViewingAsUser read false, and client-hidden admin
UI drifted from server-computed display flags.
The strict rule now lives in one place, resolveImpersonationState, with
getImpersonationState reading the cookie and delegating to it. requireUser,
the root loader and the bulk-action loader all go through it, so the value
published to the client is the value the server computed. A de-admined
session correctly reports neither impersonating nor viewing as user, which
also restores its admin chrome — right, since it is not an admin session
any more.
The organization loader's own isImpersonating is left as it was; it is
pre-existing and nothing here depends on it.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.bulkaction.tsx
+6-6Lines changed: 6 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -56,7 +56,7 @@ import { CreateBulkActionPresenter } from "~/presenters/v3/CreateBulkActionPrese
0 commit comments