Adding component to manage account api keys

parent c69be1ac
......@@ -3,6 +3,7 @@ import RoleForm from './components/RoleForm.vue';
import UserTable from './components/UserTable.vue';
import UserForm from './components/UserForm.vue';
import UserProfile from './components/UserProfile.vue';
import ApiKeys from './components/ApiKeys.vue';
const locales = window.AsgardCMS.locales;
......@@ -62,4 +63,9 @@ export default [
name: 'admin.user.users.account',
component: UserProfile,
},
{
path: '/account/api-keys',
name: 'admin.user.users.account.api-keys',
component: ApiKeys,
},
];
<template>
<div>
<div class="content-header">
<h1>
{{ trans('users.api-keys') }}
</h1>
<el-breadcrumb separator="/">
<el-breadcrumb-item>
<a href="/backend">{{ trans('core.breadcrumb.home') }}</a>
</el-breadcrumb-item>
<el-breadcrumb-item :to="{name: 'admin.user.users.account.api-keys'}">{{ trans('users.api-keys') }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="row">
<div class="col-md-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ trans('users.your api keys') }}</h3>
<div class="box-tools pull-right">
<el-button type="primary" size="small" icon="plus" @click="generateKey">
{{ trans('users.generate new api key') }}
</el-button>
</div>
</div>
<div class="box-body">
<ul class="list-unstyled">
<li style="margin-bottom: 20px;"
v-for="key in apiKeys"
:key="key.id">
<el-input v-model="key.access_token" disabled>
<el-button slot="prepend" @click="destroyApiKey(key)">
<i class="fa fa-times"></i>
</el-button>
</el-input>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
loading: false,
apiKeys: {},
};
},
methods: {
fetchApiKeys() {
this.loading = true;
axios.get(route('api.account.api.index'))
.then((response) => {
this.loading = false;
this.apiKeys = response.data.data;
});
},
generateKey() {
axios.get(route('api.account.api.create'))
.then((response) => {
this.loading = false;
this.apiKeys = response.data.data;
this.$message({
type: 'success',
message: response.data.message,
});
});
},
destroyApiKey(apiKey) {
this.$confirm(this.trans('users.delete api key confirm'), '', {
confirmButtonText: this.trans('core.button.delete'),
cancelButtonText: this.trans('core.button.cancel'),
type: 'warning',
confirmButtonClass: 'el-button--danger',
}).then(() => {
axios.delete(route('api.account.api.destroy', { userTokenId: apiKey.id }))
.then((response) => {
this.loading = false;
this.apiKeys = response.data.data;
this.$message({
type: 'success',
message: response.data.message,
});
});
})
.catch(() => {
});
},
},
mounted() {
this.fetchApiKeys();
},
};
</script>
......@@ -28,11 +28,7 @@ class ApiKeysController extends AdminBaseController
public function index()
{
$tokens = $this->userToken->allForUser($this->auth->id());
$this->assetPipeline->requireJs('clipboard.js');
return view('user::admin.account.api-keys.index', compact('tokens'));
return view('user::admin.account.api-keys.index');
}
public function create()
......
<?php
namespace Modules\User\Http\Controllers\Api;
use Illuminate\Routing\Controller;
use Modules\User\Contracts\Authentication;
use Modules\User\Entities\UserToken;
use Modules\User\Repositories\UserTokenRepository;
use Modules\User\Transformers\ApiKeysTransformer;
class ApiKeysController extends Controller
{
/**
* @var Authentication
*/
private $auth;
/**
* @var UserTokenRepository
*/
private $userToken;
public function __construct(Authentication $auth, UserTokenRepository $userToken)
{
$this->auth = $auth;
$this->userToken = $userToken;
}
public function index()
{
$tokens = $this->userToken->allForUser($this->auth->id());
return ApiKeysTransformer::collection($tokens);
}
public function create()
{
$userId = $this->auth->id();
$this->userToken->generateFor($userId);
$tokens = $this->userToken->allForUser($userId);
return response()->json([
'errors' => false,
'message' => trans('user::users.token generated'),
'data' => ApiKeysTransformer::collection($tokens),
]);
}
public function destroy(UserToken $userToken)
{
$this->userToken->destroy($userToken);
$tokens = $this->userToken->allForUser($this->auth->id());
return response()->json([
'errors' => false,
'message' => trans('user::users.token deleted'),
'data' => ApiKeysTransformer::collection($tokens),
]);
}
}
......@@ -95,6 +95,26 @@ $router->group(['prefix' => '/user', 'middleware' => ['api.token', 'auth.admin']
'as' => 'api.account.profile.update',
'uses' => 'ProfileController@update',
]);
$router->bind('userTokenId', function ($id) {
return app(\Modules\User\Repositories\UserTokenRepository::class)->find($id);
});
$router->get('api-keys', [
'as' => 'api.account.api.index',
'uses' => 'ApiKeysController@index',
'middleware' => 'can:account.api-keys.index',
]);
$router->get('api-keys/create', [
'as' => 'api.account.api.create',
'uses' => 'ApiKeysController@create',
'middleware' => 'can:account.api-keys.create',
]);
$router->delete('api-keys/{userTokenId}', [
'as' => 'api.account.api.destroy',
'uses' => 'ApiKeysController@destroy',
'middleware' => 'can:account.api-keys.destroy',
]);
});
$router->get('permissions', [
......
@extends('layouts.master')
@section('content-header')
<h1>
{{ trans('user::users.api-keys') }}
</h1>
<ol class="breadcrumb">
<li><a href="{{ route('dashboard.index') }}"><i class="fa fa-dashboard"></i> {{ trans('core::core.breadcrumb.home') }}</a></li>
<li class="active">{{ trans('user::users.api-keys') }}</li>
</ol>
@stop
@section('content')
<div class="row">
<div class="col-xs-12">
<div class="row">
<div class="btn-group pull-right" style="margin: 0 15px 15px 0;">
<a href="{{ route('admin.account.api.create') }}" class="btn btn-primary btn-flat">
<i class="fa fa-plus"></i> {{ trans('user::users.generate new api key') }}
</a>
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ trans('user::users.your api keys') }}</h3>
</div>
<div class="box-body">
<div class="col-md-4">
<?php if ($tokens->isEmpty() === false): ?>
<ul class="list-unstyled">
<?php foreach ($tokens as $token): ?>
<li style="margin-bottom: 20px;">
{!! Form::open(['route' => ['admin.account.api.destroy', $token->id], 'method' => 'delete', 'class' => '']) !!}
<div class="input-group input-group-sm">
<span class="input-group-btn">
<button type="submit" class="btn btn-danger btn-flat" onclick="return confirm('{{ trans('user::users.delete api key confirm') }}')">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</span>
<input type="text" class="form-control api-key" readonly value="{{ $token->access_token }}" >
<span class="input-group-btn">
<a href="#" class="btn btn-default btn-flat jsClipboardButton">
<i class="fa fa-clipboard" aria-hidden="true"></i>
</a>
</span>
</div>
{!! Form::close() !!}
</li>
<?php endforeach; ?>
</ul>
<?php else: ?>
<p>{{ trans('user::users.you have no api keys') }} <a href="{{ route('admin.account.api.create') }}">{{ trans('user::users.generate one') }}</a></p>
<?php endif; ?>
</div>
</div>
</div>
</div>
<!-- /.col (MAIN) -->
</div>
@include('core::partials.delete-modal')
@stop
@push('js-stack')
<script>
new Clipboard('.jsClipboardButton', {
target: function(trigger) {
return $(trigger).parent().parent().find('.api-key')[0];
}
});
</script>
@endpush
<?php
namespace Modules\User\Transformers;
use Illuminate\Http\Resources\Json\Resource;
class ApiKeysTransformer extends Resource
{
public function toArray($request)
{
return [
'id' => $this->id,
'access_token' => $this->access_token,
'created_at' => $this->created_at,
];
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment