feat: add user impersonation service
This commit is contained in:
@@ -9,7 +9,9 @@ use App\Filament\Resources\UserResource\Pages\ListUsers;
|
||||
use App\Filament\Resources\UserResource\RelationManagers\LogsRelationManager;
|
||||
use App\Filament\Resources\UserResource\RelationManagers\UsageLogsRelationManager;
|
||||
use App\Models\User;
|
||||
use App\Services\ImpersonationService;
|
||||
use BackedEnum;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
@@ -49,6 +51,12 @@ class UserResource extends Resource
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('password')
|
||||
->password()
|
||||
->required()
|
||||
->minLength(6)
|
||||
->maxLength(255)
|
||||
->visibleOn('create'),
|
||||
TextInput::make('email_verified_at')
|
||||
->label('Email Verification Status')
|
||||
->disabled()
|
||||
@@ -149,8 +157,65 @@ class UserResource extends Resource
|
||||
])
|
||||
->recordActions([
|
||||
EditAction::make(),
|
||||
Action::make('impersonate')
|
||||
->label('Login as User')
|
||||
->icon('heroicon-o-arrow-right-on-rectangle')
|
||||
->color('warning')
|
||||
->requiresConfirmation()
|
||||
->modalHeading('Start User Impersonation')
|
||||
->modalDescription('This will open a new tab where you will be logged in as this user. All actions will be logged for security. Your admin panel will remain open in this tab.')
|
||||
->modalSubmitActionLabel('Start Impersonation')
|
||||
->modalCancelActionLabel('Cancel')
|
||||
->visible(fn (User $record): bool => auth()->user()?->isSuperAdmin() &&
|
||||
$record->isNormalUser() &&
|
||||
! app(ImpersonationService::class)->isImpersonating()
|
||||
)
|
||||
->url(function (User $record): string {
|
||||
$admin = auth()->user();
|
||||
$impersonationService = app(ImpersonationService::class);
|
||||
|
||||
if (! $impersonationService->canImpersonate($admin, $record)) {
|
||||
Notification::make()
|
||||
->title('Impersonation Failed')
|
||||
->body('Unable to start impersonation. Please check permissions and try again.')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return '#';
|
||||
}
|
||||
|
||||
// Return impersonation URL
|
||||
return route('impersonation.start', $record);
|
||||
})
|
||||
->openUrlInNewTab(),
|
||||
])
|
||||
->toolbarActions([
|
||||
Action::make('stopImpersonation')
|
||||
->label('Stop Impersonating')
|
||||
->icon('heroicon-o-arrow-left-on-rectangle')
|
||||
->color('danger')
|
||||
->visible(fn (): bool => app(ImpersonationService::class)->isImpersonating())
|
||||
->action(function () {
|
||||
$impersonationService = app(ImpersonationService::class);
|
||||
|
||||
if (! $impersonationService->stopImpersonation(request())) {
|
||||
Notification::make()
|
||||
->title('Failed to Stop Impersonation')
|
||||
->body('Unable to stop impersonation session.')
|
||||
->danger()
|
||||
->send();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Notification::make()
|
||||
->title('Impersonation Ended')
|
||||
->body('You have been returned to your admin account.')
|
||||
->success()
|
||||
->send();
|
||||
|
||||
return redirect()->to(\Filament\Pages\Dashboard::getUrl());
|
||||
}),
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
BulkAction::make('updateLevel')
|
||||
|
||||
@@ -6,7 +6,9 @@ use App\Filament\Resources\UserResource;
|
||||
use App\Models\User;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\DeleteAction;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Filament\Support\Icons\Heroicon;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
|
||||
class EditUser extends EditRecord
|
||||
@@ -17,6 +19,25 @@ class EditUser extends EditRecord
|
||||
{
|
||||
return [
|
||||
DeleteAction::make(),
|
||||
Action::make('mark_email_verified')
|
||||
->label('Mark Email as Verified')
|
||||
->icon(Heroicon::OutlinedEnvelope)
|
||||
->action(function (User $user) {
|
||||
if (! $user->hasVerifiedEmail()) {
|
||||
$user->markEmailAsVerified();
|
||||
Notification::make('email_verified_successfully')
|
||||
->title('Email Verified Successfully')
|
||||
->icon(Heroicon::OutlinedEnvelope)
|
||||
->success()
|
||||
->send();
|
||||
} else {
|
||||
Notification::make('email_already_verified')
|
||||
->title('Email Already Verified')
|
||||
->icon(Heroicon::OutlinedEnvelope)
|
||||
->warning()
|
||||
->send();
|
||||
}
|
||||
}),
|
||||
Action::make('download_report')
|
||||
->label('Download User Report')
|
||||
->icon('heroicon-o-user')
|
||||
|
||||
Reference in New Issue
Block a user