diff --git a/app/routes/user.js b/app/routes/user.js index 524e0d9..c6b3718 100644 --- a/app/routes/user.js +++ b/app/routes/user.js @@ -1,6 +1,7 @@ var bodyParser = require('body-parser'); var jwt = require('jsonwebtoken'); var User = require('../models/user'); +var _ = require('underscore'); var superSecret = 'TheAmazingKreskin'; @@ -23,7 +24,8 @@ module.exports = function (app, express) { var token = jwt.sign({ name: user.name, email: user.email, - _id: user._id + _id: user._id, + permissions: user.permissions }, superSecret, { expiresInMinutes: 1440 }); @@ -116,10 +118,14 @@ module.exports = function (app, express) { }); }) .delete(function (req, res) { - User.remove({_id: req.params.user_id}, function (err, user) { - if (err) res.send(err); - res.json({}); - }) + if (_.contains(req.decoded.permissions, 'admin')){ + User.remove({_id: req.params.user_id}, function (err, user) { + if (err) res.send(err); + res.json({}); + }) + } else { + return res.status(403).send({success: false, message: 'User is not authorized to delete users'}); + } }); return userRouter; diff --git a/bower.json b/bower.json index 6eba2ea..8e8abbd 100644 --- a/bower.json +++ b/bower.json @@ -26,7 +26,8 @@ "datatables": "~1.10.5", "datatables-bootstrap3-plugin": "~0.3.0", "backbone.bootstrap-modal": "~0.9.0", - "backbone.stickit": "~0.8.0" + "backbone.stickit": "~0.8.0", + "toastr": "~2.1.0" }, "resolutions": { "jquery": ">= 1.9.1" diff --git a/package.json b/package.json index 99d2688..fce912e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "express": "^4.11.2", "jsonwebtoken": "^3.2.2", "mongoose": "^3.8.23", - "morgan": "^1.5.1" + "morgan": "^1.5.1", + "underscore": "^1.8.2" } } diff --git a/public/app/app.js b/public/app/app.js index 81b1a2c..32ac152 100644 --- a/public/app/app.js +++ b/public/app/app.js @@ -4,6 +4,7 @@ define(function (require) { var globals = require('globals'); var mediator = require('mediator'); + var Permissions = require('permissions'); function _authenticated(response) { window.localStorage.setItem(globals.auth.TOKEN_KEY, response.token); @@ -30,6 +31,7 @@ define(function (require) { var User = require('users/model'); var _user; var _applicationInfo; + var _permissions; function _initialize() { var d = $.Deferred(); @@ -53,6 +55,7 @@ define(function (require) { _user = new User({_id: window.localStorage.getItem(globals.auth.USER_KEY)}); _user.fetch().success(function () { mediator.trigger('page:updateUserInfo'); + _permissions = new Permissions(_user.get('permissions')); d.resolve(); }); } else { @@ -69,11 +72,15 @@ define(function (require) { return _user || new User(); } + function _getPermissions() { + return _permissions; + } return { isAuthenticated: _isAuthenticated, initialize: _initialize, initializeUser: _initializeUser, getApplicationInfo: _getApplicationInfo, - getUser: _getUser + getUser: _getUser, + getPermissions: _getPermissions } }); \ No newline at end of file diff --git a/public/app/main.js b/public/app/main.js index f8f31fc..9addad0 100644 --- a/public/app/main.js +++ b/public/app/main.js @@ -3,6 +3,7 @@ define(function (require) { var globals = require('globals'); var Router = require('router'); var mediator = require('mediator'); + var toastr = require('toastr'); _.extend(Backbone.View.prototype, { // Handle cleanup of view. @@ -39,6 +40,29 @@ define(function (require) { statusCode: { 401: function (context) { mediator.trigger('router:navigate', {route: 'login', options: {trigger: true}}); + }, + + 403: function(context){ + console.log('message', context.responseJSON.message); + toastr.options = { + "closeButton": false, + "debug": false, + "newestOnTop": false, + "progressBar": false, + "positionClass": "toast-top-center", + "preventDuplicates": false, + "onclick": null, + "showDuration": "300", + "hideDuration": "1000", + "timeOut": "5000", + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": "fadeIn", + "hideMethod": "fadeOut" + }; + + toastr["error"](context.responseJSON.message); } }, beforeSend: function (xhr) { diff --git a/public/app/permissions.js b/public/app/permissions.js new file mode 100644 index 0000000..28d5d6e --- /dev/null +++ b/public/app/permissions.js @@ -0,0 +1,13 @@ +define(function (require) { + + 'use strict'; + + var _ = require('underscore'); + + return function(permissions){ + this.isAdmin = function(){ + return _.contains(permissions, 'admin'); + }; + } + +}); \ No newline at end of file diff --git a/public/app/users/list.hbs b/public/app/users/list.hbs index 65e9e6b..e6ca315 100644 --- a/public/app/users/list.hbs +++ b/public/app/users/list.hbs @@ -17,7 +17,7 @@
- + {{#if ../admin}}{{/if}}
diff --git a/public/app/users/listView.js b/public/app/users/listView.js index e4f0232..b6f7379 100644 --- a/public/app/users/listView.js +++ b/public/app/users/listView.js @@ -4,6 +4,7 @@ define(function (require) { var Backbone = require('backbone'); var mediator = require('mediator'); var template = require('hbs!users/list'); + var app = require('app'); var SingleView = require('users/singleView'); require('bootstrap-modal'); @@ -24,7 +25,7 @@ define(function (require) { }, render: function () { - this.$el.html(template({users: this.collection.toJSON()})); + this.$el.html(template({users: this.collection.toJSON(), admin: app.getPermissions().isAdmin() })); this.$('table').DataTable({ "aoColumns": [ null, @@ -46,8 +47,8 @@ define(function (require) { deleteUser: function(e){ var self = this; var id = $(e.currentTarget).attr('data-id'); - var user = this.collection.get(id) - user.destroy().done(function(){ + var user = this.collection.get(id); + user.destroy({wait: true}).done(function(){ self.collection.remove(user); self.render(); }); diff --git a/public/index.html b/public/index.html index b47ef9a..2af9f44 100644 --- a/public/index.html +++ b/public/index.html @@ -8,6 +8,7 @@ + diff --git a/public/require-main.js b/public/require-main.js index 93d0399..5c59bb6 100644 --- a/public/require-main.js +++ b/public/require-main.js @@ -12,7 +12,8 @@ requirejs.config({ "datatables-bootstrap3": "../components/datatables-bootstrap3-plugin/media/js/datatables-bootstrap3", "bootstrap-modal": "../components/bootstrap/js/modal", "backbone.bootstrap-modal": "../components/backbone.bootstrap-modal/src/backbone.bootstrap-modal", - "stickit" : "../components/backbone.stickit/backbone.stickit" + "stickit" : "../components/backbone.stickit/backbone.stickit", + "toastr" : "../components/toastr/toastr" } });