diff --git a/Modules/User/Assets/js/UserRoutes.js b/Modules/User/Assets/js/UserRoutes.js
index 39d371cbd..24fe2d4ac 100644
--- a/Modules/User/Assets/js/UserRoutes.js
+++ b/Modules/User/Assets/js/UserRoutes.js
@@ -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,
+ },
];
diff --git a/Modules/User/Assets/js/components/ApiKeys.vue b/Modules/User/Assets/js/components/ApiKeys.vue
new file mode 100644
index 000000000..72573b791
--- /dev/null
+++ b/Modules/User/Assets/js/components/ApiKeys.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
diff --git a/Modules/User/Http/Controllers/Admin/Account/ApiKeysController.php b/Modules/User/Http/Controllers/Admin/Account/ApiKeysController.php
index 5be5e6ebe..ec5dff8a7 100644
--- a/Modules/User/Http/Controllers/Admin/Account/ApiKeysController.php
+++ b/Modules/User/Http/Controllers/Admin/Account/ApiKeysController.php
@@ -28,11 +28,7 @@ public function __construct(Authentication $auth, UserTokenRepository $userToken
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()
diff --git a/Modules/User/Http/Controllers/Api/ApiKeysController.php b/Modules/User/Http/Controllers/Api/ApiKeysController.php
new file mode 100644
index 000000000..406ff40d0
--- /dev/null
+++ b/Modules/User/Http/Controllers/Api/ApiKeysController.php
@@ -0,0 +1,59 @@
+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),
+ ]);
+ }
+}
diff --git a/Modules/User/Http/apiRoutes.php b/Modules/User/Http/apiRoutes.php
index 8845ff147..6ba9024fb 100644
--- a/Modules/User/Http/apiRoutes.php
+++ b/Modules/User/Http/apiRoutes.php
@@ -95,6 +95,26 @@
'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', [
diff --git a/Modules/User/Resources/views/admin/account/api-keys/index.blade.php b/Modules/User/Resources/views/admin/account/api-keys/index.blade.php
index 5acaeba24..f48998190 100644
--- a/Modules/User/Resources/views/admin/account/api-keys/index.blade.php
+++ b/Modules/User/Resources/views/admin/account/api-keys/index.blade.php
@@ -1,73 +1,7 @@
@extends('layouts.master')
@section('content-header')
-
- {{ trans('user::users.api-keys') }}
-
-
- - {{ trans('core::core.breadcrumb.home') }}
- - {{ trans('user::users.api-keys') }}
-
-
@stop
@section('content')
-
-
-
-
-
-
-
- isEmpty() === false): ?>
-
-
- -
- {!! Form::open(['route' => ['admin.account.api.destroy', $token->id], 'method' => 'delete', 'class' => '']) !!}
-
- {!! Form::close() !!}
-
-
-
-
-
{{ trans('user::users.you have no api keys') }} {{ trans('user::users.generate one') }}
-
-
-
-
-
-
-
-
- @include('core::partials.delete-modal')
@stop
-
-@push('js-stack')
-
-@endpush
diff --git a/Modules/User/Transformers/ApiKeysTransformer.php b/Modules/User/Transformers/ApiKeysTransformer.php
new file mode 100644
index 000000000..7f005addf
--- /dev/null
+++ b/Modules/User/Transformers/ApiKeysTransformer.php
@@ -0,0 +1,17 @@
+ $this->id,
+ 'access_token' => $this->access_token,
+ 'created_at' => $this->created_at,
+ ];
+ }
+}
diff --git a/public/js/app.js b/public/js/app.js
index 823a9828e..494987feb 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -101875,6 +101875,13 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
//
//
//
+//
+//
+//
+//
+//
+//
+//
exports.default = {
mixins: [_Slugify2.default, _ShortcutHelper2.default, _ActiveEditor2.default, _SingleFileSelector2.default],
@@ -102610,6 +102617,47 @@ var render = function() {
1
),
_vm._v(" "),
+ _c(
+ "el-form-item",
+ {
+ class: {
+ "el-form-item is-error": _vm.form.errors.has(
+ locale + ".status"
+ )
+ },
+ attrs: { label: _vm.trans("page.status") }
+ },
+ [
+ _c(
+ "el-checkbox",
+ {
+ model: {
+ value: _vm.page[locale].status,
+ callback: function($$v) {
+ _vm.page[locale].status = $$v
+ },
+ expression: "page[locale].status"
+ }
+ },
+ [_vm._v(_vm._s(_vm.trans("page.status")))]
+ ),
+ _vm._v(" "),
+ _vm.form.errors.has(locale + ".status")
+ ? _c("div", {
+ staticClass: "el-form-item__error",
+ domProps: {
+ textContent: _vm._s(
+ _vm.form.errors.first(
+ locale + ".status"
+ )
+ )
+ }
+ })
+ : _vm._e()
+ ],
+ 1
+ ),
+ _vm._v(" "),
_c(
"div",
{ staticClass: "panel box box-primary" },
@@ -103026,7 +103074,7 @@ var render = function() {
attrs: {
zone: "image",
entity: "Modules\\Page\\Entities\\Page",
- "entity-id": _vm.page.id
+ "entity-id": _vm.$route.params.pageId
},
on: {
singleFileSelected: function($event) {
@@ -105829,6 +105877,10 @@ var _UserProfile = __webpack_require__(520);
var _UserProfile2 = _interopRequireDefault(_UserProfile);
+var _ApiKeys = __webpack_require__(562);
+
+var _ApiKeys2 = _interopRequireDefault(_ApiKeys);
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var locales = window.AsgardCMS.locales;
@@ -105883,6 +105935,10 @@ exports.default = [
path: '/account/profile',
name: 'admin.user.users.account',
component: _UserProfile2.default
+}, {
+ path: '/account/api-keys',
+ name: 'admin.user.users.account.api-keys',
+ component: _ApiKeys2.default
}];
/***/ }),
@@ -109347,7 +109403,7 @@ var render = function() {
_vm._v(" "),
_c(
"el-breadcrumb-item",
- { attrs: { to: { name: "admin.user.users.profile" } } },
+ { attrs: { to: { name: "admin.user.users.account" } } },
[
_vm._v(
_vm._s(_vm.trans("users.breadcrumb.edit-profile")) +
@@ -110572,7 +110628,7 @@ exports.default = {
props: {
zone: { type: String, required: true },
entity: { type: String, required: true },
- entityId: { type: Number },
+ entityId: { default: null },
label: { type: String }
},
components: {
@@ -110636,6 +110692,9 @@ exports.default = {
mounted: function mounted() {
var _this2 = this;
+ if (this.entityId) {
+ this.fetchMedia();
+ }
this.eventName = 'fileWasSelected' + this.makeId() + Math.floor(Math.random() * 999999);
this.$events.listen(this.eventName, function (mediaData) {
@@ -110985,5 +111044,313 @@ if (false) {
// removed by extract-text-webpack-plugin
+/***/ }),
+/* 550 */,
+/* 551 */,
+/* 552 */,
+/* 553 */,
+/* 554 */,
+/* 555 */,
+/* 556 */,
+/* 557 */,
+/* 558 */,
+/* 559 */,
+/* 560 */,
+/* 561 */,
+/* 562 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var disposed = false
+var normalizeComponent = __webpack_require__(6)
+/* script */
+var __vue_script__ = __webpack_require__(563)
+/* template */
+var __vue_template__ = __webpack_require__(564)
+/* template functional */
+ var __vue_template_functional__ = false
+/* styles */
+var __vue_styles__ = null
+/* scopeId */
+var __vue_scopeId__ = null
+/* moduleIdentifier (server only) */
+var __vue_module_identifier__ = null
+var Component = normalizeComponent(
+ __vue_script__,
+ __vue_template__,
+ __vue_template_functional__,
+ __vue_styles__,
+ __vue_scopeId__,
+ __vue_module_identifier__
+)
+Component.options.__file = "Modules/User/Assets/js/components/ApiKeys.vue"
+if (Component.esModule && Object.keys(Component.esModule).some(function (key) { return key !== "default" && key.substr(0, 2) !== "__"})) { console.error("named exports are not supported in *.vue files.")}
+
+/* hot reload */
+if (false) {(function () {
+ var hotAPI = require("vue-hot-reload-api")
+ hotAPI.install(require("vue"), false)
+ if (!hotAPI.compatible) return
+ module.hot.accept()
+ if (!module.hot.data) {
+ hotAPI.createRecord("data-v-66a1f586", Component.options)
+ } else {
+ hotAPI.reload("data-v-66a1f586", Component.options)
+' + ' }
+ module.hot.dispose(function (data) {
+ disposed = true
+ })
+})()}
+
+module.exports = Component.exports
+
+
+/***/ }),
+/* 563 */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _axios = __webpack_require__(12);
+
+var _axios2 = _interopRequireDefault(_axios);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = {
+ data: function data() {
+ return {
+ loading: false,
+ apiKeys: {}
+ };
+ },
+
+ methods: {
+ fetchApiKeys: function fetchApiKeys() {
+ var _this = this;
+
+ this.loading = true;
+ _axios2.default.get(route('api.account.api.index')).then(function (response) {
+ _this.loading = false;
+ _this.apiKeys = response.data.data;
+ });
+ },
+ generateKey: function generateKey() {
+ var _this2 = this;
+
+ _axios2.default.get(route('api.account.api.create')).then(function (response) {
+ _this2.loading = false;
+ _this2.apiKeys = response.data.data;
+ _this2.$message({
+ type: 'success',
+ message: response.data.message
+ });
+ });
+ },
+ destroyApiKey: function destroyApiKey(apiKey) {
+ var _this3 = this;
+
+ 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(function () {
+ _axios2.default.delete(route('api.account.api.destroy', { userTokenId: apiKey.id })).then(function (response) {
+ _this3.loading = false;
+ _this3.apiKeys = response.data.data;
+ _this3.$message({
+ type: 'success',
+ message: response.data.message
+ });
+ });
+ }).catch(function () {});
+ }
+ },
+ mounted: function mounted() {
+ this.fetchApiKeys();
+ }
+}; //
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+
+/***/ }),
+/* 564 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var render = function() {
+ var _vm = this
+ var _h = _vm.$createElement
+ var _c = _vm._self._c || _h
+ return _c("div", [
+ _c(
+ "div",
+ { staticClass: "content-header" },
+ [
+ _c("h1", [
+ _vm._v(
+ "\n " +
+ _vm._s(_vm.trans("users.api-keys")) +
+ "\n "
+ )
+ ]),
+ _vm._v(" "),
+ _c(
+ "el-breadcrumb",
+ { attrs: { separator: "/" } },
+ [
+ _c("el-breadcrumb-item", [
+ _c("a", { attrs: { href: "/backend" } }, [
+ _vm._v(_vm._s(_vm.trans("core.breadcrumb.home")))
+ ])
+ ]),
+ _vm._v(" "),
+ _c(
+ "el-breadcrumb-item",
+ { attrs: { to: { name: "admin.user.users.account.api-keys" } } },
+ [_vm._v(_vm._s(_vm.trans("users.api-keys")) + "\n ")]
+ )
+ ],
+ 1
+ )
+ ],
+ 1
+ ),
+ _vm._v(" "),
+ _c("div", { staticClass: "row" }, [
+ _c("div", { staticClass: "col-md-12" }, [
+ _c("div", { staticClass: "box box-primary" }, [
+ _c("div", { staticClass: "box-header with-border" }, [
+ _c("h3", { staticClass: "box-title" }, [
+ _vm._v(_vm._s(_vm.trans("users.your api keys")))
+ ]),
+ _vm._v(" "),
+ _c(
+ "div",
+ { staticClass: "box-tools pull-right" },
+ [
+ _c(
+ "el-button",
+ {
+ attrs: { type: "primary", size: "small", icon: "plus" },
+ on: { click: _vm.generateKey }
+ },
+ [
+ _vm._v(
+ "\n " +
+ _vm._s(_vm.trans("users.generate new api key")) +
+ "\n "
+ )
+ ]
+ )
+ ],
+ 1
+ )
+ ]),
+ _vm._v(" "),
+ _c("div", { staticClass: "box-body" }, [
+ _c(
+ "ul",
+ { staticClass: "list-unstyled" },
+ _vm._l(_vm.apiKeys, function(key) {
+ return _c(
+ "li",
+ { key: key.id, staticStyle: { "margin-bottom": "20px" } },
+ [
+ _c(
+ "el-input",
+ {
+ attrs: { disabled: "" },
+ model: {
+ value: key.access_token,
+ callback: function($$v) {
+ key.access_token = $$v
+ },
+ expression: "key.access_token"
+ }
+ },
+ [
+ _c(
+ "el-button",
+ {
+ attrs: { slot: "prepend" },
+ on: {
+ click: function($event) {
+ _vm.destroyApiKey(key)
+ }
+ },
+ slot: "prepend"
+ },
+ [_c("i", { staticClass: "fa fa-times" })]
+ )
+ ],
+ 1
+ )
+ ],
+ 1
+ )
+ })
+ )
+ ])
+ ])
+ ])
+ ])
+ ])
+}
+var staticRenderFns = []
+render._withStripped = true
+module.exports = { render: render, staticRenderFns: staticRenderFns }
+if (false) {
+ module.hot.accept()
+ if (module.hot.data) {
+ require("vue-hot-reload-api") .rerender("data-v-66a1f586", module.exports)
+ }
+}
+
/***/ })
/******/ ]);
\ No newline at end of file