diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0985d2c --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +config/ci_com_pub.pem: config/ci_com.pem + openssl rsa -pubout -in $< -out $@ + chmod 777 $@ + +config/ci_com.pem: + openssl genrsa -out $@ 1024 + chmod 700 $@ diff --git a/app/controllers/decrypt.js b/app/controllers/decrypt.js new file mode 100644 index 0000000..731cecd --- /dev/null +++ b/app/controllers/decrypt.js @@ -0,0 +1,36 @@ +var ursa = require('ursa'); +var fs = require('fs'); + +var decrypt = {}; + +decrypt.decrypter = false; + +decrypt.whenOk = function (cb) { + if (this.encrypter) { + cb(); + } else { + this.prepare(cb); + } +}; + +decrypt.prepare = function (cb) { + fs.readFile('config/ci_com.pem', function(err, data) { + if (err) { + throw err; + } + this.decrypter = ursa.createPrivateKey(data); + cb(); + }); +}; + +decrypt.preload = function(cb) { + this.whenOk(cb); +}; + +decrypt.decrypt = function (string, cb) { + this.whenOk(function() { + cb(this.decrypter.decrypt(string, 'base64', 'utf8', ursa.RSA_PKCS1_PADDING)); + }); +}; + +module.exports = decrypt; diff --git a/app/controllers/sessions.js b/app/controllers/sessions.js index 9be7d5a..f4cbba0 100644 --- a/app/controllers/sessions.js +++ b/app/controllers/sessions.js @@ -115,4 +115,4 @@ sessions.open = function (data, cb) { }); } -module.exports = sessions; \ No newline at end of file +module.exports = sessions; diff --git a/app/routes/api.js b/app/routes/api.js index 0502a7a..940d3bd 100644 --- a/app/routes/api.js +++ b/app/routes/api.js @@ -1,97 +1,100 @@ var membres = require('../controllers/membres'); var sessions = require('../controllers/sessions'); +var decrypt = require('../controllers/decrypt'); var express = require('express'); -var api = express() +var api = express(); // Sessions api.get('/session', function (req, res) { // Informations sur la session - if (req.cookies && req.cookies.session) { - sessions.use(req.cookies.session, function (err) { - if (err) { - res.send(err) - } else { - res.send(sessions.cur) - } - }) - // TODO si pas bon : res.clearCookie('session') - } else { - res.send('missing'); - } + if (req.cookies && req.cookies.session) { + sessions.use(req.cookies.session, function (err) { + if (err) { + res.send(err); + } else { + res.send(sessions.cur); + } + }); + // TODO si pas bon : res.clearCookie('session') + } else { + res.send('missing'); + } }); api.post('/session', function (req, res) { // Se connecter - sessions.open(req.body, function (err) { - if (err) { - res.send(err) - } else { - res.cookie('session', sessions.cur._id); - res.send(sessions.cur) - } - }) -}) + decrypt.decrypt(req.body[0], function (data) { + sessions.open(JSON.parse(data), function (err) { + if (err) { + res.send(err); + } else { + res.cookie('session', sessions.cur._id); + res.send(sessions.cur); + } + }); + }); +}); api.delete('/session', function (req, res) { // Se déconnecter - if (req.cookies.session) { - sessions.delete(req.cookies.session, function () { - res.clearCookie('session'); - res.end() - }) - } else { - res.send('missing') - } -}) + if (req.cookies.session) { + sessions.delete(req.cookies.session, function () { + res.clearCookie('session'); + res.end(); + }); + } else { + res.send('missing'); + } +}); ifPermission = function (req, res, perm, cb) { - sessions.use(req.cookies.session, function (err) { - if (err) { - res.status(403).end() - } else { - if (sessions.cur[perm]) { - cb() - } else { - res.status(403).end() - } - } - }) -} + sessions.use(req.cookies.session, function (err) { + if (err) { + res.status(403).end(); + } else { + if (sessions.cur[perm]) { + cb(); + } else { + res.status(403).end(); + } + } + }); +}; // Membres api.get('/membres', function (req, res) { // Liste des membres - membres.list(function (err, membres) { - if (err) - res.send(err); - res.json(membres); - }); + membres.list(function (err, membres) { + if (err) + res.send(err); + res.json(membres); + }); }); api.post('/membres', function (req, res) { // Ajout d'un membre - ifPermission(req, res, 'canAddMembre', function () { - membres.add(req.body, function (err, membre) { - if (err) - res.send(err); - membres.list(function (err, membres) { - if (err) - res.send(err); - res.json(membres); - }); - }); - }) + ifPermission(req, res, 'canAddMembre', function () { + membres.add(req.body, function (err, membre) { + if (err) + res.send(err); + membres.list(function (err, membres) { + if (err) + res.send(err); + res.json(membres); + }); + }); + }); }); api.delete('/membres/:membre_id', function (req, res) { // Supression d'un membre - ifPermission(req, res, 'canDelMembre', function () { - membres.remove(req.params.membre_id, function (err, membre) { - if (err) - res.send(err); - membres.list(function (err, membres) { - if (err) - res.send(err); - res.json(membres); - }); - }); - }) -}) + ifPermission(req, res, 'canDelMembre', function () { + membres.remove(req.params.membre_id, function (err, membre) { + if (err) + res.send(err); + membres.list(function (err, membres) { + if (err) + res.send(err); + res.json(membres); + }); + }); + }); +}); -module.exports = api; \ No newline at end of file +module.exports = api; diff --git a/bower.json b/bower.json index f6fad6b..8945875 100644 --- a/bower.json +++ b/bower.json @@ -5,6 +5,7 @@ "font-awesome": "latest", "angular": "latest", "angular-route": "latest", - "bootswatch-dist": "3.3.2-cerulean" + "bootswatch-dist": "3.3.2-cerulean", + "jsencrypt": "~2.1.0" } } diff --git a/package.json b/package.json index c7c5744..9ff333a 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "method-override": "^2.3.1", "mongoose": "^3.8.25", "morgan": "^1.5.1", - "node-line-reader": "0.0.2" + "node-line-reader": "0.0.2", + "ursa": "^0.8.4" } } diff --git a/public/com/ci_com.pem b/public/com/ci_com.pem new file mode 100644 index 0000000..dbe6b9e --- /dev/null +++ b/public/com/ci_com.pem @@ -0,0 +1 @@ +Même pas en rêve ! diff --git a/public/com/ci_com_priv.pem b/public/com/ci_com_priv.pem new file mode 120000 index 0000000..72a5024 --- /dev/null +++ b/public/com/ci_com_priv.pem @@ -0,0 +1 @@ +ci_com.pem \ No newline at end of file diff --git a/public/com/ci_com_pub.pem b/public/com/ci_com_pub.pem new file mode 120000 index 0000000..856176f --- /dev/null +++ b/public/com/ci_com_pub.pem @@ -0,0 +1 @@ +../../config/ci_com_pub.pem \ No newline at end of file diff --git a/public/js/app.js b/public/js/app.js index 736dc1a..8770dbe 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1 +1 @@ -angular.module('ciApp', ['ngRoute', 'appRoutes', 'SessionsServ', 'SessionsCtrl', 'ConnectCtrl', 'MembreCtrl']); \ No newline at end of file +angular.module('ciApp', ['ngRoute', 'appRoutes', 'EncryptServ', 'SessionsServ', 'SessionsCtrl', 'ConnectCtrl', 'MembreCtrl']); diff --git a/public/js/controllers/ConnectCtrl.js b/public/js/controllers/ConnectCtrl.js index e861ddb..3e1661e 100644 --- a/public/js/controllers/ConnectCtrl.js +++ b/public/js/controllers/ConnectCtrl.js @@ -1,9 +1,12 @@ -angular.module('ConnectCtrl', []).controller('ConnectController', ['$scope', 'SessionService', - function ($scope, SessionService) { - $scope.connect = { - connect: function () { - SessionService.connect($scope.connect.login, $scope.connect.pass) - } - } - } -]); \ No newline at end of file +angular.module('ConnectCtrl', []).controller('ConnectController', ['$scope', 'SessionService', 'EncryptService', + function ($scope, SessionService, EncryptService) { + EncryptService.preload(function () { + return undefined; + }); + $scope.connect = { + connect: function () { + SessionService.connect($scope.connect.login, $scope.connect.pass); + } + }; + } +]); diff --git a/public/js/services/EncryptServ.js b/public/js/services/EncryptServ.js new file mode 100644 index 0000000..e7cd25a --- /dev/null +++ b/public/js/services/EncryptServ.js @@ -0,0 +1,30 @@ +angular.module('EncryptServ', []).service('EncryptService', ['$http', + function ($http) { + a = { + encrypter: false, + whenOk: function (cb) { + if (this.encrypter) { + cb(); + } else { + this.prepare(cb); + } + }, + prepare: function (cb) { + $http.get('/com/ci_com_pub.pem').success(function (key) { + this.encrypter = new JSEncrypt(); + this.encrypter.setPublicKey(key); + cb(); + }); + }, + preload: function(cb) { + this.whenOk(cb); + }, + encrypt: function (string, cb) { + this.whenOk(function() { + cb(this.encrypter.encrypt(string)); + }); + } + }; + return a; + } +]); diff --git a/public/js/services/SessionServ.js b/public/js/services/SessionServ.js index 48eba9b..cee6238 100644 --- a/public/js/services/SessionServ.js +++ b/public/js/services/SessionServ.js @@ -1,67 +1,70 @@ -angular.module('SessionsServ', []).service('SessionService', ['$http', - function ($http) { - a = { - cur: false, - status: 0, - changeHandlers: [], - onChange: function (fun) { - this.changeHandlers.push(fun) - }, - triggerChange: function () { - for (fun in this.changeHandlers) { - this.changeHandlers[fun]() - } - }, - updateSessionInfos: function (data) { - console.log("Connection:", data) - if (typeof data === 'object') { - this.cur = data - } else { - this.cur = false - } - this.triggerChange() - }, - get: function (cb) { // Fetch infos if needed - if (status == 0) { - this.status = 1 // Fetching - _this = this - // TODO Verify if cookies to prevent uneeded request - $http.get('/api/session').success(function (body) { - _this.updateSessionInfos(body) - if (cb) { - if (this.logged) { - cb(null) - } else { - cb(body) - } - } - }) - } else { - console.warn("Unnecessary get() call") - } - }, - connect: function (login, pass, cb) { - _this = this - $http.post('/api/session', { - login: login, - pass: pass - }).success(function (body) { - _this.updateSessionInfos(body) - if (cb) { - if (this.logged) { - cb(null) - } else { - cb(body) - } - } - }) - }, - disconnect: function () { - this.updateSessionInfos(false) - $http.delete('/api/session') +angular.module('SessionsServ', []).service('SessionService', ['$http', 'EncryptService', + function ($http, EncryptService) { + a = { + cur: false, + status: 0, + changeHandlers: [], + onChange: function (fun) { + this.changeHandlers.push(fun); + }, + triggerChange: function () { + for (var fun in this.changeHandlers) { + this.changeHandlers[fun](); + } + }, + updateSessionInfos: function (data) { + console.log("Connection:", data); + if (typeof data === 'object') { + this.cur = data; + } else { + this.cur = false; + } + this.triggerChange(); + }, + get: function (cb) { // Fetch infos if needed + if (status === 0) { + this.status = 1; // Fetching + _this = this; + // TODO Verify if cookies to prevent uneeded request + $http.get('/api/session').success(function (body) { + _this.updateSessionInfos(body); + if (cb) { + if (this.logged) { + cb(null); + } else { + cb(body); + } } + }); + } else { + console.warn("Unnecessary get() call"); } - a.get() - return a - } -]) \ No newline at end of file + }, + connect: function (login, pass, cb) { + _this = this; + data = JSON.stringify({ + login: login, + pass: pass + }); + EncryptService.encrypt(data, function (dataCrypt) { + $http.post('/api/session', [dataCrypt]).success(function (body) { + _this.updateSessionInfos(body); + if (cb) { + if (this.logged) { + cb(null); + } else { + cb(body); + } + } + }); + }); + }, + disconnect: function () { + this.updateSessionInfos(false); + $http.delete('/api/session'); + } + }; + a.get(); + return a; + } +]); diff --git a/public/views/connect.html b/public/views/connect.html index 67fd8c0..9ec25e6 100644 --- a/public/views/connect.html +++ b/public/views/connect.html @@ -1,7 +1,5 @@