From ca888b4eb76b0ed42dc4ca35cdd2ba6fb64449ce Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 4 Mar 2026 20:30:46 +0100 Subject: [PATCH] fix: impersonation navigation uses full page reload Replace router.push() with window.location.href for both start and end impersonation to ensure the updated JWT cookie is sent with the new request. Client-side routing can race with cookie propagation, causing the server to see the old session and redirect back to admin. Co-Authored-By: Claude Opus 4.6 --- src/components/admin/user-actions.tsx | 10 ++++------ src/components/shared/impersonation-banner.tsx | 5 ++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/components/admin/user-actions.tsx b/src/components/admin/user-actions.tsx index 33bfc53..a593685 100644 --- a/src/components/admin/user-actions.tsx +++ b/src/components/admin/user-actions.tsx @@ -126,9 +126,9 @@ export function UserActions({ userId, userEmail, userStatus, userRole, userRoles try { const result = await startImpersonation.mutateAsync({ targetUserId: userId }) await update({ impersonate: userId }) - toast.success(`Now impersonating ${userEmail}`) - router.push(getRoleHomePath(result.targetRole) as Route) - router.refresh() + // Full page navigation to ensure the updated JWT cookie is sent + // (router.push can race with cookie propagation) + window.location.href = getRoleHomePath(result.targetRole) } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to start impersonation') } @@ -302,9 +302,7 @@ export function UserMobileActions({ try { const result = await startImpersonation.mutateAsync({ targetUserId: userId }) await update({ impersonate: userId }) - toast.success(`Now impersonating ${userEmail}`) - router.push(getRoleHomePath(result.targetRole) as Route) - router.refresh() + window.location.href = getRoleHomePath(result.targetRole) } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to start impersonation') } diff --git a/src/components/shared/impersonation-banner.tsx b/src/components/shared/impersonation-banner.tsx index 544f651..f818331 100644 --- a/src/components/shared/impersonation-banner.tsx +++ b/src/components/shared/impersonation-banner.tsx @@ -18,9 +18,8 @@ export function ImpersonationBanner() { try { await endImpersonation.mutateAsync() await update({ endImpersonation: true }) - toast.success('Returned to admin account') - router.push('/admin/members') - router.refresh() + // Full page navigation to ensure updated JWT cookie is sent + window.location.href = '/admin/members' } catch (error) { toast.error(error instanceof Error ? error.message : 'Failed to end impersonation') }