├── 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 }}">{{ $component_name }}>
--------------------------------------------------------------------------------
/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 | 
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 |
2 |
3 |
4 |
5 |
8 |
9 |
12 |
13 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
85 |
86 |
175 |
--------------------------------------------------------------------------------