Problem
The admin.impersonation.destroy route sits inside the ['auth', 'can:access-admin'] middleware group. Once an admin impersonates a regular user, the session user is that non-admin. Hitting DELETE /admin/impersonation returns a 403 — the admin is permanently locked in with no way out.
Additionally, ImpersonationController::store() has no guard against:
- Self-impersonation (
$user->id === $request->user()->id)
- Impersonating another admin
The existing impersonation test (ImpersonationTest.php) masks this bug by calling $this->actingAs($admin) before the DELETE request — bypassing the real session state.
Required Changes
- Move
admin.impersonation.destroy route out of the can:access-admin middleware group into the plain auth group
- In
ImpersonationController::destroy(), replace Gate::authorize('access-admin') with abort_unless($request->session()->has('impersonator_id'), 403)
- In
ImpersonationController::store(), add guards: abort 422 if self-impersonating; abort 422 if target user is an admin
- Fix
ImpersonationTest to test the real session flow (logs in, starts impersonation, then destroys without re-authing)
Files
routes/web.php
app/Http/Controllers/Admin/ImpersonationController.php
tests/Feature/Admin/ImpersonationTest.php
Problem
The
admin.impersonation.destroyroute sits inside the['auth', 'can:access-admin']middleware group. Once an admin impersonates a regular user, the session user is that non-admin. HittingDELETE /admin/impersonationreturns a 403 — the admin is permanently locked in with no way out.Additionally,
ImpersonationController::store()has no guard against:$user->id === $request->user()->id)The existing impersonation test (
ImpersonationTest.php) masks this bug by calling$this->actingAs($admin)before theDELETErequest — bypassing the real session state.Required Changes
admin.impersonation.destroyroute out of thecan:access-adminmiddleware group into the plainauthgroupImpersonationController::destroy(), replaceGate::authorize('access-admin')withabort_unless($request->session()->has('impersonator_id'), 403)ImpersonationController::store(), add guards: abort 422 if self-impersonating; abort 422 if target user is an adminImpersonationTestto test the real session flow (logs in, starts impersonation, then destroys without re-authing)Files
routes/web.phpapp/Http/Controllers/Admin/ImpersonationController.phptests/Feature/Admin/ImpersonationTest.php