├── docs └── preview.jpg ├── src ├── resources │ ├── views │ │ └── vue-impersonate.blade.php │ └── js │ │ └── vue-impersonate.vue ├── routes.php ├── Controllers │ └── VueImpersonateController.php ├── config │ └── vue_impersonate.php ├── Services │ └── VueImpersonateService.php └── VueImpersonateServiceProvider.php ├── composer.json └── README.md /docs/preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OwenMelbz/vue-impersonate/HEAD/docs/preview.jpg -------------------------------------------------------------------------------- /src/resources/views/vue-impersonate.blade.php: -------------------------------------------------------------------------------- 1 | <{{ $component_name }} :is-impersonating="{{ $is_impersonating ? 'true' : 'false' }}" :routes="{{ $routes }}"> -------------------------------------------------------------------------------- /src/routes.php: -------------------------------------------------------------------------------- 1 | name('impersonate.users') 7 | ->middleware('web'); -------------------------------------------------------------------------------- /src/Controllers/VueImpersonateController.php: -------------------------------------------------------------------------------- 1 | user())->canImpersonate()) { 14 | return []; 15 | } 16 | 17 | return (new VueImpersonateService)->getImpersonatable(); 18 | } 19 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "owenmelbz/vue-impersonate", 3 | "description": "Laravel 5.5+ helper and VueJS 2 component for lab404/laravel-impersonate", 4 | "keywords": ["laravel", "vuejs", "impersonate", "lab404"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Owen Melbourne", 9 | "email": "owenmelbz@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "lab404/laravel-impersonate": "1.*" 14 | }, 15 | "autoload": { 16 | "psr-4": { 17 | "OwenMelbz\\VueImpersonate\\": "src/" 18 | } 19 | }, 20 | "extra": { 21 | "laravel": { 22 | "providers": ["OwenMelbz\\VueImpersonate\\VueImpersonateServiceProvider"] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/config/vue_impersonate.php: -------------------------------------------------------------------------------- 1 | 'users', 10 | 11 | /* 12 | |-------------------------------------------------------------------------- 13 | | The field to display in the user dropdown. 14 | |-------------------------------------------------------------------------- 15 | */ 16 | 17 | 'display_name_field' => 'email', 18 | 19 | /* 20 | |-------------------------------------------------------------------------- 21 | | If you want to use a custom route to return the user list, place the url 22 | | here and we'll use it instead. default (null) 23 | |-------------------------------------------------------------------------- 24 | */ 25 | 26 | 'custom_route' => null, 27 | 28 | /* 29 | |-------------------------------------------------------------------------- 30 | | By default the view component is called `vue-impersonate` if you want a 31 | | different directive name then place it here. default (vue-impersonate) 32 | |-------------------------------------------------------------------------- 33 | */ 34 | 35 | 'custom_directive' => 'vue-impersonate', 36 | 37 | ]; 38 | -------------------------------------------------------------------------------- /src/Services/VueImpersonateService.php: -------------------------------------------------------------------------------- 1 | manager = $manager = app('impersonate'); 14 | } 15 | 16 | public function isImpersonating() 17 | { 18 | return $this->manager->isImpersonating(); 19 | } 20 | 21 | public function getRoutes() 22 | { 23 | return collect([ 24 | 'take' => route('impersonate', '@userid'), 25 | 'leave' => route('impersonate.leave'), 26 | 'users' => $this->getUsersRoute(), 27 | ]); 28 | } 29 | 30 | public function getUsersRoute() 31 | { 32 | if (config('vue_impersonate.custom_route')) { 33 | return asset( 34 | config('vue_impersonate.custom_route') 35 | ); 36 | } 37 | 38 | return route('impersonate.users'); 39 | } 40 | 41 | public function getImpersonatable() 42 | { 43 | $model = config('auth.providers.' . config('vue_impersonate.provider') . '.model'); 44 | $displayField = config('vue_impersonate.display_name_field'); 45 | 46 | return $model::all()->filter(function ($user) { 47 | return $user->canBeImpersonated(); 48 | }) 49 | ->sortBy($displayField) 50 | ->values() 51 | ->transform(function ($user) use ($displayField) { 52 | return [ 53 | 'id' => $user->getKey(), 54 | 'display_name' => $user->{$displayField} 55 | ]; 56 | }); 57 | } 58 | 59 | public function render() 60 | { 61 | if (optional(request()->user())->canImpersonate()) { 62 | return view('vue_impersonate::vue-impersonate') 63 | ->with('is_impersonating', $this->isImpersonating()) 64 | ->with('routes', $this->getRoutes()) 65 | ->with('component_name', config('vue_impersonate.custom_directive')); 66 | } 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /src/VueImpersonateServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 29 | __DIR__ . '/config/vue_impersonate.php' => config_path($this->packageName . '.php'), 30 | __DIR__ . '/resources/views/vue-impersonate.blade.php' => $this->resource_path('views/vue-impersonate.blade.php'), 31 | __DIR__ . '/resources/js/vue-impersonate.vue' => $this->resource_path('assets/js/components/vue-impersonate.vue'), 32 | ], 'vue-impersonate-all'); 33 | 34 | $this->publishes([ 35 | __DIR__ . '/resources/js/vue-impersonate.vue' => $this->resource_path('assets/js/components/vue-impersonate.vue'), 36 | ], 'vue-impersonate-javascript (required)'); 37 | 38 | $this->publishes([ 39 | __DIR__ . '/config/vue_impersonate.php' => config_path($this->packageName . '.php'), 40 | ], 'vue-impersonate-config'); 41 | 42 | 43 | // Load the views 44 | $this->loadViewsFrom(__DIR__.'/resources/views', 'vue_impersonate'); 45 | 46 | // Load the routes 47 | if (config('vue_impersonate.custom_route') === null) { 48 | $this->loadRoutesFromLegacy(__DIR__ . '/routes.php'); 49 | } 50 | 51 | $this->loadBladeDirectives(); 52 | } 53 | 54 | /** 55 | * Register the application services. 56 | * 57 | * @return void 58 | */ 59 | public function register() 60 | { 61 | $this->mergeConfigFrom( __DIR__.'/config/vue_impersonate.php', $this->packageName); 62 | } 63 | 64 | protected function resource_path($filename) 65 | { 66 | if (function_exists('resource_path')) { 67 | return resource_path($filename); 68 | } 69 | 70 | return app_path('resources/' . trim($filename, '/')); 71 | } 72 | 73 | protected function loadBladeDirectives() 74 | { 75 | Blade::directive('vueImpersonate', function () { 76 | return "render(); ?>"; 77 | }); 78 | } 79 | 80 | protected function loadRoutesFromLegacy($path) 81 | { 82 | if (method_exists($this, 'loadRoutesFrom')) { 83 | return $this->loadRoutesFrom($path); 84 | } 85 | 86 | if (!$this->app->routesAreCached()) { 87 | require $path; 88 | } 89 | } 90 | 91 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VueJS Frontend Component for integration for Laravel Impersonate 2 | 3 | This package adds a really simple frontend component written as a self contained Vuejs 2 component to allow you users to easily impersonate others via the API provided by https://github.com/404labfr/laravel-impersonate. 4 | 5 | ## Preview 6 | 7 | ![Preview](/docs/preview.jpg) 8 | 9 | ## Usage 10 | 11 | 1. Install via composer `composer require owenmelbz/vue-impersonate` 12 | 13 | 2. Register the service provider (if the auto discovery does not work) - typically done inside the `app.php` providers array e.g `OwenMelbz\VueImpersonate\VueImpersonateServiceProvider::class` 14 | 15 | 3. There are 3 publishable components - the only `required` component is the javascript which you can publish with `php artisan vendor:publish` then select `vue-impersonate-javascript (required)`. This will copy the .vue component into `resources/js/components/vue-impersonate.vue` - feel free to move this. 16 | 17 | 4. You must then include the component in your javascript bundle, typically achieved from within an entry point such as `app.js` e.g `Vue.component('vue-impersonate', require('./components/vue-impersonate.vue'));` 18 | 19 | 5. Once published you should make sure you've set up laravel-impersonate correctly by including the correct traits, and methods and routes to allow impersonating. 20 | 21 | 6. Once laravel-impersonate is set up you should include the blade directive within your template `@vueImpersonate` - this should be housed within your vuejs container e.g `#app` - it will only render for users who possess the `canImpersonate` permissions. 22 | 23 | ## Configuration 24 | 25 | ### Display name 26 | 27 | You can change what is displayed in the dropdown by changing the `display_name_field` from within the published config - you can use accessors/mutators here or normal database columns. 28 | 29 | ### Custom vue directive 30 | 31 | If you want to rename the component from `vue-impersonate` you must publish the config file via `php artisan vendor:publish` and change it within the config under the `custom_directive` param. 32 | 33 | ### Custom user provider 34 | 35 | By default laravel uses providers to log in users, this is defined within the `config/auth.php` then within the `providers` array. We use the class defined within the `model` property of the provider you define. By default it is called `users` so that we'll also uses the configured class to populate the list of users on the frontend. 36 | 37 | ### Custom list of users 38 | 39 | If you want more fine-grain control over which users show in the dropdown, you can set your own route and define it within the `custom_route` and we'll use that to display the users. You must return a JSON array with each user object containing at least an `id` and `display_name` field. e.g 40 | 41 | ```js 42 | [ 43 | { 44 | id: 12, 45 | display_name: 'User X :: user.x@gmail.com', 46 | }, 47 | { 48 | id: 14, 49 | display_name: 'User Y :: user.y@gmail.com', 50 | }, 51 | ]; 52 | ``` 53 | -------------------------------------------------------------------------------- /src/resources/js/vue-impersonate.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 85 | 86 | 175 | --------------------------------------------------------------------------------