Skip to content

Commit 795bf58

Browse files
authored
Fix banner crash in multi-panel/multi-guard setups (#137)
Only render the impersonation banner when the current panel's auth guard matches the impersonator's original guard. This prevents a TypeError crash when navigating between panels with different guards while impersonating. Fixes #65, #87 Related to #114
1 parent 7275f77 commit 795bf58

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

resources/views/components/banner.blade.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
@props(['style', 'display', 'fixed', 'position'])
22

3-
@if(app('impersonate')->isImpersonating())
3+
@php
4+
$impersonatorGuard = app('impersonate')->getImpersonatorGuardUsingName();
5+
$currentPanelGuard = Filament\Facades\Filament::getAuthGuard();
6+
$shouldShowBanner = app('impersonate')->isImpersonating()
7+
&& $currentPanelGuard
8+
&& $impersonatorGuard === $currentPanelGuard;
9+
@endphp
10+
11+
@if($shouldShowBanner)
412

513
@php
614
$user = Filament\Facades\Filament::auth()->user();

tests/BannerTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,43 @@
155155
});
156156
});
157157

158+
describe('banner multi-guard support', function () {
159+
it('does not render when impersonator guard differs from current panel guard', function () {
160+
// Start impersonation
161+
$action = Impersonate::make()->backTo('/admin');
162+
$action->impersonate($this->targetUser);
163+
164+
// Simulate being in a different panel with a different guard
165+
// The impersonator guard is 'web', but we'll check with a different guard
166+
$impersonatorGuard = app('impersonate')->getImpersonatorGuardUsingName();
167+
expect($impersonatorGuard)->toBe('web');
168+
169+
// Mock the scenario where we're in a different panel
170+
// by directly testing the condition logic
171+
$currentPanelGuard = 'admin'; // Different from 'web'
172+
$shouldShow = app('impersonate')->isImpersonating()
173+
&& $currentPanelGuard
174+
&& $impersonatorGuard === $currentPanelGuard;
175+
176+
expect($shouldShow)->toBeFalse();
177+
});
178+
179+
it('renders when impersonator guard matches current panel guard', function () {
180+
// Start impersonation
181+
$action = Impersonate::make()->backTo('/admin');
182+
$action->impersonate($this->targetUser);
183+
184+
$impersonatorGuard = app('impersonate')->getImpersonatorGuardUsingName();
185+
$currentPanelGuard = 'web'; // Same as impersonator guard
186+
187+
$shouldShow = app('impersonate')->isImpersonating()
188+
&& $currentPanelGuard
189+
&& $impersonatorGuard === $currentPanelGuard;
190+
191+
expect($shouldShow)->toBeTrue();
192+
});
193+
});
194+
158195
describe('banner translations', function () {
159196
it('contains impersonating translation key', function () {
160197
$action = Impersonate::make()->backTo('/admin');

0 commit comments

Comments
 (0)