diff --git a/app/public/css/panel.css b/app/public/css/panel.css index 7930aab..9bb2cc8 100644 --- a/app/public/css/panel.css +++ b/app/public/css/panel.css @@ -200,35 +200,173 @@ body { user-select: none; } -.modal { +.key-name { + color: #2a9fd6; + font-family: 'Roboto Mono', monospace; +} + +pre { + overflow: auto; + line-height: 1.7em; + font-family: 'Roboto Mono', monospace; + border: 1px solid #666; + border-radius: 4px; display: block; + padding: 10px; + font-size: 14px; + margin: 10px 0; + background: #222; + color: #2a9fd6; +} + +.modal, +.modal-box { + z-index: 900; +} + +.modal-sandbox { position: fixed; - z-index: 1; - left: 0; - top: 0; width: 100%; height: 100%; + top: 0; + left: 0; + background: transparent; +} + +.modal { + display: none; + position: fixed; + width: 100%; + height: 100%; + left: 0; + top: 0; + background: rgb(0,0,0); + background: rgba(0,0,0,.8); overflow: auto; - background-color: rgba(0, 0, 0, 0.4); +} + +.modal-box { + position: relative; + width: 80%; + max-width: 700px; + margin: 60px auto; + animation-name: modalbox; + animation-duration: .3s; + animation-timing-function: ease; +} + +#createKey { + max-width: 920px; } .modal-header { - margin: 15% auto; - padding: 20px; - border: 1px solid #888; - width: 80%; + border: 2px solid #2a9fd6; + border-radius: 8px 8px 0 0; + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 20px 40px; + background: #000; + color: #ffffff; } .modal-body { - margin: auto; - padding: 20px; - border: 1px solid #888; - width: 80%; + border: 2px solid #2a9fd6; + border-top: none; + background: #000; + padding: 30px; } .modal-footer { - margin: auto; + display: flex; + justify-content: flex-end; + border: 2px solid #2a9fd6; + border-radius: 0 0 8px 8px; + border-top: none; + background: #000; padding: 20px; - border: 1px solid #888; - width: 80%; -} \ No newline at end of file +} + +.close-modal { + text-align: right; + font-size: 24px; + cursor: pointer; +} + +@keyframes modalbox { + 0% { + top: -250px; + opacity: 0; + } + 100% { + top: 0; + opacity: 1; + } +} + +button { + margin-left: 20px; + color: #d3d3d3; + background: #000; + border: 2px solid #2a9fd6; + border-radius: 5px; + padding: 10px; + cursor: pointer; + transition: background-color 0.25s; +} + +button:hover { + color: #fff; + background-color: #2a9fd6; + text-decoration: none; + outline: none; +} + +::-moz-focus-inner { + outline: none; +} + +.btn-del { + text-transform: uppercase; + border: 2px solid #ff6666; + color: #ccc; +} + +.btn-del:hover { + background-color: #ff6666; +} + +em { + text-transform: uppercase; + font-weight: bold; +} + +#identifier { + font-size: 14px; + background: #222; + color: #d3d3d3; + border: 1px solid #666; + border-radius: 4px; + padding: 10px; + margin: 10px 0; +} + +th { + text-transform: uppercase; + font-weight: bold; + padding: 10px; +} + +td { + padding: 10px; +} + +td input { + vertical-align: middle; +} + +td label { + margin-bottom: 2px; + padding-left: 3px; +} + diff --git a/app/public/panel/controllers/ApiCtrl.js b/app/public/panel/controllers/ApiCtrl.js index 45fc2da..b728361 100644 --- a/app/public/panel/controllers/ApiCtrl.js +++ b/app/public/panel/controllers/ApiCtrl.js @@ -1,10 +1,78 @@ var angular = require('angular'); -angular.module('ApiCtrl', ['ApiSvc', 'AuthSvc']).controller('ApiController', ['$scope', 'ApiService', 'AuthService', function($scope, ApiService, AuthService) { - $scope.getKeys = function() { - ApiService.getAll(function(keys) { +angular.module('ApiCtrl', ['ApiSvc', 'AuthSvc']).controller('ApiController', ['$scope', 'ApiService', 'AuthService', function ($scope, ApiService, AuthService) { + function splitScope(scope) { + var res = {}; + for (var i in scope) { + var perm = scope[i]; + var prefix = perm.substr(0, perm.indexOf('.')); + var postfix = perm.substr(perm.indexOf('.') + 1); + if (!res[prefix]) res[prefix] = []; + res[prefix].push({name: postfix}); + } + return res; + } + + $scope.checkCkPerm = function(prefix, perm) { + var index = $scope.scopeObj[prefix].indexOf(perm); + if ($scope.scopeObj[prefix][index].isChecked) { + $scope.ckScope.push(prefix + '.' + perm.name); + } else { + var index = $scope.ckScope.indexOf(prefix + '.' + perm.name); + $scope.ckScope.splice(index, 1); + } + }; + + $scope.parseScope = function () { + AuthService.currentUser(function (res) { + $scope.scopeObj = splitScope(res.scope); + $scope.ckScope = []; + }) + }; + + $scope.getKeys = function () { + ApiService.getAll(function (keys) { $scope.keys = keys; }); - console.log($scope.keys); }; + + $scope.hideNewKey = function () { + $scope.nModalShow = false; + }; + $scope.showNewKey = function () { + $scope.nModalShow = true; + }; + + $scope.hideKeyInfo = function () { + $scope.kModalShow = false; + }; + $scope.showKeyInfo = function (key) { + $scope.kModalShow = true; + $scope.currKey = key; + $scope.currKey.scopeObj = splitScope($scope.currKey.scope); + }; + + $scope.deleteKey = function (key) { + ApiService.deleteKey(key, function () { + var index = $scope.keys.indexOf(key); + $scope.keys.splice(index, 1); + $scope.hideKeyInfo(); + $scope.currKey = {}; + }); + }; + + $scope.createKey = function () { + if ($scope.ckScope.length === 0 || !$scope.ckIdentifier) + return; + + ApiService.createKey({ + identifier: $scope.ckIdentifier, + scope: JSON.stringify($scope.ckScope) + }, function (res) { + if (res.key) { + $scope.hideNewKey(); + $scope.getKeys(); + } + }); + } }]); \ No newline at end of file diff --git a/app/public/services/ApiSvc.js b/app/public/services/ApiSvc.js index 4135a26..e70028a 100644 --- a/app/public/services/ApiSvc.js +++ b/app/public/services/ApiSvc.js @@ -19,4 +19,38 @@ angular.module('ApiSvc', []).service('ApiService', ['$http', '$window', function cb(res.data); }); }; + + this.deleteKey = function (key, cb) { + $http({ + method: 'POST', + url: '/api/keys/delete', + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + transformRequest: function (obj) { + var str = []; + for (var p in obj) + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); + return str.join("&"); + }, + data: {key: key.key} + }).then(function (res) { + cb(res.data); + }); + }; + + this.createKey = function (key, cb) { + $http({ + method: 'POST', + url: '/api/keys/create', + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + transformRequest: function (obj) { + var str = []; + for (var p in obj) + str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); + return str.join("&"); + }, + data: key + }).then(function(res) { + cb(res.data); + }); + }; }]); diff --git a/app/routes/auth.js b/app/routes/auth.js index 33ef6bc..99b46b1 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -38,6 +38,7 @@ router.post('/register', function (req, res, next) { req.session.save(function(err) { if (err) return next(err); useInvite(req.body.invite, req.body.username); + req.session.username = req.body.username; res.status(200).json({'message': 'Registered.'}); }); }); @@ -55,6 +56,7 @@ router.post('/login', function (req, res, next) { if (!user) return res.status(401).json({'message': info}); req.logIn(user, function(err) { if (err) return next(err); + req.session.username = user; res.status(200).json({'message': 'Logged in.'}); }); })(req, res, next); diff --git a/app/routes/keys.js b/app/routes/keys.js index 36e868e..f2414b7 100644 --- a/app/routes/keys.js +++ b/app/routes/keys.js @@ -64,4 +64,11 @@ router.get('/get', function (req, res, next) { }) }); +router.post('/delete', function(req, res, next) { + Key.deleteOne({key: req.body.key}, function(err) { + if (err) next(err); + else res.status(200).json({'message': 'Successfully deleted.'}); + }); +}); + module.exports = router; diff --git a/app/routes/routes.js b/app/routes/routes.js index 1e0a6ed..5ff6175 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -12,10 +12,10 @@ var fs = require('fs'); var path = require('path'); var requireLogin = function(req, res, next) { - if (!req.session.passport.user) - res.redirect('/login'); + if (!req.session || !req.session.passport) + return res.redirect('/login'); else - next(); + return next(); }; module.exports = function(app) { diff --git a/package-lock.json b/package-lock.json index 0fb8409..8baf871 100644 --- a/package-lock.json +++ b/package-lock.json @@ -942,15 +942,6 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, - "cookie-parser": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", - "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", - "requires": { - "cookie": "0.3.1", - "cookie-signature": "1.0.6" - } - }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", diff --git a/package.json b/package.json index a36cfed..3f82582 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "body-parser": "^1.18.2", "config": "^1.26.2", "connect-mongo": "^2.0.0", - "cookie-parser": "^1.4.3", "event-stream": "^3.3.4", "express": "^4.16.2", "express-sanitizer": "^1.0.2", diff --git a/public/views/panel/api.html b/public/views/panel/api.html index b2591e3..d8dcfa9 100644 --- a/public/views/panel/api.html +++ b/public/views/panel/api.html @@ -1,30 +1,76 @@ -