From d2921d7b14c14781b50a6ba970456eb6e4529ce7 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Tue, 27 Sep 2016 10:17:44 -0300 Subject: [PATCH 01/50] First raw version of a simulation model --- src/libs/models/simulation.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/libs/models/simulation.js diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js new file mode 100644 index 00000000..29de3315 --- /dev/null +++ b/src/libs/models/simulation.js @@ -0,0 +1,16 @@ +const mongoose = require('mongoose'); +const libs = `${process.cwd()}/libs`; +const log = require(`${libs}/log`)(module); +const Schema = mongoose.Schema; + +// set up a mongoose model +var SimulationSchema = new Schema({ + location: { + type: Number, + required: true + }, + time: { + type: Number, + required: true + } +}); -- GitLab From a3ae2306a2796a5227cbf299b0ad54751000014b Mon Sep 17 00:00:00 2001 From: Vytor Calixto <vytorcalixto@gmail.com> Date: Wed, 28 Sep 2016 10:34:06 -0300 Subject: [PATCH 02/50] Fix cache problem in route /user Changes: * Cache is defined in `api.js`, not in `app.js` anymore * Enrollment cache lasts for 1 day, states, regions, citys and schools lastas for 15 days Closes simcaq/SCRUM#58 --- src/libs/app.js | 3 --- src/libs/routes/api.js | 16 +++++++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libs/app.js b/src/libs/app.js index f03e2282..73625720 100644 --- a/src/libs/app.js +++ b/src/libs/app.js @@ -8,13 +8,11 @@ const compression = require('compression'); const log = require('./log')(module); const config = require('./config'); -const cache = require('apicache').options({ debug: config.get('debug') }).middleware; const app = express(); const api = require('./routes/api'); - const passport = require('passport'); app.use(passport.initialize()); @@ -26,7 +24,6 @@ app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(cors()); app.use(methodOverride()); -app.use(cache('1 day')); app.use(compression(9)); app.use(api); diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index a1805696..ac005ffb 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -2,6 +2,12 @@ const express = require('express'); const api = express(); +const libs = `${process.cwd()}/libs`; + +const config = require(`${libs}/config`); + +const cache = require('apicache').options({ debug: config.get('debug') }).middleware; + const enrollment = require('./enrollment'); const state = require('./state'); @@ -19,11 +25,11 @@ api.get('/', (req, res) => { }); // mount API routes -api.use('/api/v1/enrollment', enrollment); -api.use('/api/v1/state', state); -api.use('/api/v1/region', region); -api.use('/api/v1/city', city); -api.use('/api/v1/school', school); +api.use('/api/v1/enrollment', cache('1 day'), enrollment); +api.use('/api/v1/state', cache('15 day'), state); +api.use('/api/v1/region', cache('15 day'), region); +api.use('/api/v1/city', cache('15 day'), city); +api.use('/api/v1/school', cache('15 day'), school); api.use('/api/v1/user', user); module.exports = api; -- GitLab From a6f63136d34c3cce94485c176e5daee8deb57a6a Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Wed, 28 Sep 2016 11:24:48 -0300 Subject: [PATCH 03/50] Changed simulation to object and set locations --- src/libs/models/locations.js | 22 +++++++++++++++++++ src/libs/models/simulation.js | 41 +++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 src/libs/models/locations.js diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js new file mode 100644 index 00000000..c5b7e6f9 --- /dev/null +++ b/src/libs/models/locations.js @@ -0,0 +1,22 @@ +// Location types +class City { + constructor(id) { + this.id = id; + } +} + +class State { + constructor(id) { + this.id = id; + } +} + +class Region { + constructor(id) { + this.id = id; + } +} + +const locations = { city: City, state: State, region: Region }; + +module.exports = locations; diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index 29de3315..bc7c1eb5 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -1,16 +1,33 @@ -const mongoose = require('mongoose'); const libs = `${process.cwd()}/libs`; const log = require(`${libs}/log`)(module); -const Schema = mongoose.Schema; -// set up a mongoose model -var SimulationSchema = new Schema({ - location: { - type: Number, - required: true - }, - time: { - type: Number, - required: true +const locations = require(`${libs}/models/locations`); + +class Simulation { + /* Simulation object to manage parameters and storing */ + constructor(in_object = null) { + this.name = null; + this.location = null; + this.sim_time = null; + this.goals = { + care: null, + inclusion: null, + }; + + if (in_object) { + for (let prop in in_object) { + this[prop] = in_object[prop]; + } + } } -}); + run() { + /* Runs the Simulation with given parameters */ + // if (!this.name || !this.location || !this.time) { + // console.log('This is supposed to be an error.'); + // } + // identify of location type can be tested with instanceof operator. + // Example: if (this.location instanceof locations.city) *Do some stuff* + } +} + +module.exports = Simulation; -- GitLab From 9d567436527fdce3e886d9e39f9a151a12b7321d Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Wed, 28 Sep 2016 11:39:03 -0300 Subject: [PATCH 04/50] Extending locations and simulations... --- src/libs/models/locations.js | 11 ++++++++--- src/libs/models/simulation.js | 26 +++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js index c5b7e6f9..ccfab379 100644 --- a/src/libs/models/locations.js +++ b/src/libs/models/locations.js @@ -1,17 +1,22 @@ +/* These classes are defined to allow checking of location type with the +instanceof operator. */ + +class Location + // Location types -class City { +class City extends Location{ constructor(id) { this.id = id; } } -class State { +class State extends Location{ constructor(id) { this.id = id; } } -class Region { +class Region extends Location{ constructor(id) { this.id = id; } diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index bc7c1eb5..a3134e92 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -3,12 +3,16 @@ const log = require(`${libs}/log`)(module); const locations = require(`${libs}/models/locations`); +// Should define this somewhere else +const MAX_SIMULATION_TIME = 10; + + class Simulation { /* Simulation object to manage parameters and storing */ constructor(in_object = null) { this.name = null; this.location = null; - this.sim_time = null; + this.time = null; this.goals = { care: null, inclusion: null, @@ -20,6 +24,26 @@ class Simulation { } } } + setTime(t) { + t = parseInt(t, 10); + if(t>MAX_SIMULATION_TIME){ + // Throw an error? + return; + } + this.time = t; + } + setLocation(l) { + // Should sanitize + this.location = l; + } + setCareGoals(g) { + // Should sanitize + this.goals.care = g; + } + setInclusionGoals(g) { + // Should sanitize + this.goals.inclusion = g; + } run() { /* Runs the Simulation with given parameters */ // if (!this.name || !this.location || !this.time) { -- GitLab From d1e63a57409471544a6cbb7e793ca2c7d7bf9dca Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 29 Sep 2016 09:39:10 -0300 Subject: [PATCH 05/50] Revert "small fix" This reverts commit c8b441a72ec649289c1ed1217b7b5ed7871364af. --- src/libs/routes/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 4cb42c04..274e68bb 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -55,7 +55,7 @@ userApp.post('/authenticate', (req, res) => { if (err) throw err; if(!user){ - res.json({success: false, msg: 'Authentication failed. User not found.'}); + res.send({success: false, msg: 'Authentication failed. User not found.'}); } else { user.comparePassword(req.body.password, (err, isMatch) => { -- GitLab From 4512efc1ab3170462dfed478e292bd661498f30f Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Thu, 29 Sep 2016 11:40:22 -0300 Subject: [PATCH 06/50] Changed simulation object back to mongoose schema --- src/libs/models/locations.js | 17 +++++-- src/libs/models/simulation.js | 92 ++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js index ccfab379..e169e53b 100644 --- a/src/libs/models/locations.js +++ b/src/libs/models/locations.js @@ -1,27 +1,34 @@ /* These classes are defined to allow checking of location type with the instanceof operator. */ -class Location +class Location {} // Location types -class City extends Location{ +class City extends Location { constructor(id) { + super(); this.id = id; } } -class State extends Location{ +class State extends Location { constructor(id) { + super(); this.id = id; } } -class Region extends Location{ +class Region extends Location { constructor(id) { + super(); this.id = id; } } -const locations = { city: City, state: State, region: Region }; +const locations = { + location: Location, + city: City, + state: State, + region: Region }; module.exports = locations; diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index a3134e92..dfefc8bc 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -1,57 +1,59 @@ +const mongoose = require('mongoose') + const libs = `${process.cwd()}/libs`; const log = require(`${libs}/log`)(module); const locations = require(`${libs}/models/locations`); +const Schema = mongoose.Schema; + // Should define this somewhere else const MAX_SIMULATION_TIME = 10; -class Simulation { - /* Simulation object to manage parameters and storing */ - constructor(in_object = null) { - this.name = null; - this.location = null; - this.time = null; - this.goals = { - care: null, - inclusion: null, - }; - - if (in_object) { - for (let prop in in_object) { - this[prop] = in_object[prop]; - } - } - } - setTime(t) { - t = parseInt(t, 10); - if(t>MAX_SIMULATION_TIME){ - // Throw an error? - return; - } - this.time = t; - } - setLocation(l) { - // Should sanitize - this.location = l; - } - setCareGoals(g) { - // Should sanitize - this.goals.care = g; - } - setInclusionGoals(g) { - // Should sanitize - this.goals.inclusion = g; +let SimulationSchema = new Schema({ + name: { + type: String, + required: true, + }, + location: Object, + time: Number, + failure_rate: Array, + goals_care: Array, + goals_inclusion: Array, +}); + +SimulationSchema.methods.setTime = (t) => { + t = parseInt(t, 10); + if(!t || t>MAX_SIMULATION_TIME){ + // Throw an error? + return; } - run() { - /* Runs the Simulation with given parameters */ - // if (!this.name || !this.location || !this.time) { - // console.log('This is supposed to be an error.'); - // } - // identify of location type can be tested with instanceof operator. - // Example: if (this.location instanceof locations.city) *Do some stuff* + this.time = t; +}; +SimulationSchema.methods.setLocation = (l) => { + // Should sanitize + if(!(l instanceof locations.location)){ + // Throw an error? + return; } -} + this.location = l; +}; +SimulationSchema.methods.setCareGoals = (g) => { + // Should sanitize + this.goals.care = g; +}; +SimulationSchema.methods.setInclusionGoals = (g) => { + // Should sanitize + this.goals.inclusion = g; +}; +SimulationSchema.methods.run = () => { + /* Runs the Simulation with given parameters */ + // if (!this.name || !this.location || !this.time) { + // console.log('This is supposed to be an error.'); + // } + // identify of location type can be tested with instanceof operator. + // Example: if (this.location instanceof locations.city) *Do some stuff* +}; -module.exports = Simulation; +module.exports = mongoose.model('Simulation', SimulationSchema); -- GitLab From dbc67855d0f61f6a421e1ec1c072a30eb639d0c3 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Fri, 30 Sep 2016 09:39:42 -0300 Subject: [PATCH 07/50] reference file using libs variable --- src/libs/middlewares/passport.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js index 4b915419..76cdf598 100644 --- a/src/libs/middlewares/passport.js +++ b/src/libs/middlewares/passport.js @@ -2,7 +2,7 @@ const JwtStrategy = require('passport-jwt').Strategy; const ExtractJwt = require('passport-jwt').ExtractJwt; const libs = `${process.cwd()}/libs`; const config = require(`${libs}/config`); -const User = ('../models/user'); +const User = require(`${libs}/models/user`) module.exports = function(passport){ var opts = {}; -- GitLab From d4f0295a65d4bc2e800ce481ccda2fb5a4d40043 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Mon, 3 Oct 2016 09:48:28 -0300 Subject: [PATCH 08/50] set relative route to user model --- src/libs/routes/user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 274e68bb..1323c5ef 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -8,7 +8,7 @@ const config = require(`${libs}/config`); const log = require(`${libs}/log`)(module); -const User = require('../models/user'); +const User = require(`${libs}/models/user`); const jwt = require('jwt-simple'); @@ -55,7 +55,7 @@ userApp.post('/authenticate', (req, res) => { if (err) throw err; if(!user){ - res.send({success: false, msg: 'Authentication failed. User not found.'}); + res.json({success: false, msg: 'Authentication failed. User not found.'}); } else { user.comparePassword(req.body.password, (err, isMatch) => { -- GitLab From 2bfdf1fb0339dbe8649f8ffa3d55e0756a963d26 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 3 Oct 2016 10:52:38 -0300 Subject: [PATCH 09/50] First persistent simulation model --- src/libs/models/simulation.js | 1 + src/libs/routes/api.js | 3 + src/libs/routes/simulation.js | 105 ++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 src/libs/routes/simulation.js diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index dfefc8bc..7d9afbb0 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -1,6 +1,7 @@ const mongoose = require('mongoose') const libs = `${process.cwd()}/libs`; +const config = require(`${libs}/config`); const log = require(`${libs}/log`)(module); const locations = require(`${libs}/models/locations`); diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index 06953296..61c7121d 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -12,6 +12,8 @@ const city = require('./city'); const school = require('./school'); +const simulation = require('./simulation'); + api.get('/api/v1', (req, res) => { res.json({ msg: 'SimCAQ API is running' }); }); @@ -22,5 +24,6 @@ api.use('/api/v1/state', state); api.use('/api/v1/region', region); api.use('/api/v1/city', city); api.use('/api/v1/school', school); +api.use('/api/v1/simulation', simulation); module.exports = api; diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js new file mode 100644 index 00000000..a776795f --- /dev/null +++ b/src/libs/routes/simulation.js @@ -0,0 +1,105 @@ +const express = require('express'); + +const simulationApp = express(); + +const libs = `${process.cwd()}/libs`; + + +const log = require(`${libs}/log`)(module); +const config = require(`${libs}/config`); + +const squel = require('squel'); + +const query = require(`${libs}/middlewares/query`); + +const response = require(`${libs}/middlewares/response`); + +const Simulation = require(`${libs}/models/simulation`); + +simulationApp.get('/', (req, res) => { + res.send({ success: true, msg: 'controller working' }); +}); + + + +simulationApp.post('/', (req, res, next) => { + // This method must associate new entry with user. + /* Creates a new simulation. Requires a name. */ + if (!req.body.name) { + res.send({ success: false, msg: 'Must send a name for new entry' }); + } else { + next(); + } +}, (req, res) => { + let newSimulation = new Simulation({ + name: req.body.name, + }); + newSimulation.save((err) => { + if (err) { + res.send({ success: false, msg: err }); + } else { + res.send({ + success: true, + msg: 'new sim created', + id: newSimulation._id, + }); + } + }); +}); + +simulationApp.get('/:id', (req, res) => { + /* Can be used to check simulation construction status */ + Simulation.findById(req.params.id, (err, simulation) => { + log.debug(req.params.id); + if (err) { + res.send({ success: false, msg: err }); + return; + } + + if (!simulation) { + res.send({ success: false, msg: 'Entry not found' }); + } else { + res.send(JSON.stringify(simulation)); + } + }); +}); + +simulationApp.post('/:id', (req, res, next) => { + if (!req.body) { + res.send({ success: false, msg: 'No field informed to update' }); + } else { + next(); + } +}, (req, res, next) => { + let simulation = Simulation.findById(req.params.id, (err, simulation) => { + if (err) { + res.send({ success: false, msg: err }); + } else { + if (!simulation) { + res.send({ success: false, msg: 'Entry not found' }); + } else { + req.simulation = simulation; + next(); + } + } + }); +}, (req, res) => { + for (let property in req.body) { + if(Simulation.schema.tree.hasOwnProperty(property)) { + req.simulation[property] = req.body[property]; + } + } + req.simulation.save((err) => { + if (err) { + res.send({ success: false, msg: err }); + } else { + res.send({ + success: true, + msg: 'sim updated', + id: req.simulation._id, + }); + } + }); +}); + +module.exports = simulationApp; -- GitLab From 56cee352ce59a500c14ff39b9cdb055e34f45143 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 3 Oct 2016 11:31:50 -0300 Subject: [PATCH 10/50] Changed update to methods --- src/libs/models/simulation.js | 30 +++++++++++++++++++----------- src/libs/routes/simulation.js | 4 ++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index 7d9afbb0..b2c7daef 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -24,30 +24,38 @@ let SimulationSchema = new Schema({ goals_inclusion: Array, }); -SimulationSchema.methods.setTime = (t) => { +SimulationSchema.methods.setTime = function (t) { t = parseInt(t, 10); - if(!t || t>MAX_SIMULATION_TIME){ + if (!t || t > MAX_SIMULATION_TIME) { // Throw an error? return; } this.time = t; }; -SimulationSchema.methods.setLocation = (l) => { +SimulationSchema.methods.setLocation = function (l) { // Should sanitize - if(!(l instanceof locations.location)){ - // Throw an error? - return; - } this.location = l; }; -SimulationSchema.methods.setCareGoals = (g) => { +SimulationSchema.methods.setFailureRate = function (fr) { // Should sanitize - this.goals.care = g; + this.failure_rate = fr; }; -SimulationSchema.methods.setInclusionGoals = (g) => { +SimulationSchema.methods.setCareGoals = function (g) { // Should sanitize - this.goals.inclusion = g; + this.goals_care = g; }; +SimulationSchema.methods.setInclusionGoals = function (g) { + // Should sanitize + this.goals_inclusion = g; +}; +SimulationSchema.methods.update = function (property, value) { + if (property === "time") this.setTime(value); + if (property === "location") this.setLocation(value); + if (property === "failure_rate") this.setFailureRate(value); + if (property === "goals_care") this.setCareGoals(value); + if (property === "goals_inclusion") this.setInclusionGoals(value); +}; + SimulationSchema.methods.run = () => { /* Runs the Simulation with given parameters */ // if (!this.name || !this.location || !this.time) { diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index a776795f..d3fcc2b5 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -85,8 +85,8 @@ simulationApp.post('/:id', (req, res, next) => { }); }, (req, res) => { for (let property in req.body) { - if(Simulation.schema.tree.hasOwnProperty(property)) { - req.simulation[property] = req.body[property]; + if (Simulation.schema.tree.hasOwnProperty(property)) { + req.simulation.update(property, req.body[property]); } } req.simulation.save((err) => { -- GitLab From 68018f8ff76f291d8ceae1ec0684e32fa273b1ba Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 3 Oct 2016 11:42:08 -0300 Subject: [PATCH 11/50] Minor syntax changes --- src/libs/models/simulation.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index b2c7daef..fcfc26d3 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -49,20 +49,18 @@ SimulationSchema.methods.setInclusionGoals = function (g) { this.goals_inclusion = g; }; SimulationSchema.methods.update = function (property, value) { - if (property === "time") this.setTime(value); - if (property === "location") this.setLocation(value); - if (property === "failure_rate") this.setFailureRate(value); - if (property === "goals_care") this.setCareGoals(value); - if (property === "goals_inclusion") this.setInclusionGoals(value); + if (property === 'time') this.setTime(value); + if (property === 'location') this.setLocation(value); + if (property === 'failure_rate') this.setFailureRate(value); + if (property === 'goals_care') this.setCareGoals(value); + if (property === 'goals_inclusion') this.setInclusionGoals(value); }; -SimulationSchema.methods.run = () => { +SimulationSchema.methods.run = function () { /* Runs the Simulation with given parameters */ // if (!this.name || !this.location || !this.time) { // console.log('This is supposed to be an error.'); // } - // identify of location type can be tested with instanceof operator. - // Example: if (this.location instanceof locations.city) *Do some stuff* }; module.exports = mongoose.model('Simulation', SimulationSchema); -- GitLab From 95a9486758509104cf9fb2b70ce2c4ac0d5978db Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 3 Oct 2016 12:05:51 -0300 Subject: [PATCH 12/50] First test for simulation creation - raw --- src/test/test.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/test/test.js b/src/test/test.js index e6bdd1fd..7501e567 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -160,3 +160,20 @@ describe('request cities', () => { }); }); }); + +describe('Create new sim', () => { + it('should return a new simulation id', (done) => { + chai.request(server) + .post('/api/v1/simulation') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({ name: 'test_entry' }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('id'); + res.body.id.should.be.a('string'); + done(); + }); + }); +}); -- GitLab From 68b8c84c989f507d1850ba81c3b4219e908598d6 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Tue, 4 Oct 2016 10:52:55 -0300 Subject: [PATCH 13/50] Added test_config.json --- .gitignore | 1 + gulpfile.babel.js | 2 ++ src/libs/app.js | 2 +- src/libs/config.js | 18 +++++++++++++++++- src/test/test.js | 2 ++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 979717eb..136ccb71 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ build/* config.json docs/ +test_config.json diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 1f23dd9e..3a61dace 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -48,6 +48,8 @@ gulp.task('compile', () => { // copy configuration file to build directory gulp.src('config.json') .pipe(gulp.dest('build')); + gulp.src('test_config.json') + .pipe(gulp.dest('build')); }); gulp.task('build', ['compile']); diff --git a/src/libs/app.js b/src/libs/app.js index 4e3e51c6..bed5deb7 100644 --- a/src/libs/app.js +++ b/src/libs/app.js @@ -10,6 +10,7 @@ const libs = `${process.cwd()}/libs`; const log = require(`${libs}/log`)(module); +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; const config = require(`${libs}/config`); const cache = require('apicache').options({ debug: config.get('debug') }).middleware; @@ -22,7 +23,6 @@ const mongoose = require(`${libs}/db/mongoose`); const db = mongoose(); // Set default node environment -process.env.NODE_ENV = process.env.NODE_ENV || 'development'; // Parse json received in requests app.use(bodyParser.json()); diff --git a/src/libs/config.js b/src/libs/config.js index 5aea5a9c..dd2d88c4 100644 --- a/src/libs/config.js +++ b/src/libs/config.js @@ -1,8 +1,24 @@ const nconf = require('nconf'); +let config_file; + +switch(process.env.NODE_ENV) { + case 'development': + config_file = 'config.json'; + break; + case 'test': + config_file = 'test_config.json'; + break; + case 'production': + config_file = 'config.json'; + break; +} + // Exports the config.json as an object with get functions nconf.argv() .env() - .file({ file: `${process.cwd()}/config.json` }); + .file({ file: `${process.cwd()}/${config_file}` }); + +console.log(nconf.get('mongodb')); module.exports = nconf; diff --git a/src/test/test.js b/src/test/test.js index 7501e567..90103f0a 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -1,3 +1,5 @@ +process.env.NODE_ENV = 'test'; + const chai = require('chai'); const dirtyChai = require('dirty-chai'); -- GitLab From 6e1112e77528b379fb0bb24d960bd37dd97ad837 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Tue, 4 Oct 2016 12:01:09 -0300 Subject: [PATCH 14/50] More simulation testing --- src/libs/routes/simulation.js | 2 +- src/test/test.js | 50 +++++++++++++++++++++++++++++++++++ test_config.json.example | 21 +++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 test_config.json.example diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index d3fcc2b5..9b97e7bb 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -59,7 +59,7 @@ simulationApp.get('/:id', (req, res) => { if (!simulation) { res.send({ success: false, msg: 'Entry not found' }); } else { - res.send(JSON.stringify(simulation)); + res.send(simulation); } }); }); diff --git a/src/test/test.js b/src/test/test.js index 90103f0a..092780a1 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -16,6 +16,9 @@ const should = chai.should(); // actually call the function const server = require('../libs/app'); +const mongoose = require('../libs/db/mongoose'); +const Simulation = require('../libs/models/simulation'); + chai.use(chaiHttp); describe('request enrollments', () => { @@ -164,6 +167,12 @@ describe('request cities', () => { }); describe('Create new sim', () => { + let newSimulation; + + beforeEach(() => { + Simulation.remove(); + }); + it('should return a new simulation id', (done) => { chai.request(server) .post('/api/v1/simulation') @@ -178,4 +187,45 @@ describe('Create new sim', () => { done(); }); }); + it('should find an existing simulation', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .get(`/api/v1/simulation/${id}`) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('_id'); + res.body._id.should.be.a('string'); + res.body.should.have.property('name'); + res.body._id.should.be.a('string'); + done(); + }); + }); + }); + it('should update an existing simulation', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({location: 5}) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('id'); + res.body.id.should.be.a('string'); + Simulation.findById(res.body.id, (err, simulation) => { + simulation.should.have.property('name'); + simulation.name.should.be.a('string'); + simulation.should.have.property('location'); + simulation.location.should.be.a('number'); + }); + done(); + }); + }); + }); }); diff --git a/test_config.json.example b/test_config.json.example new file mode 100644 index 00000000..0a8d9146 --- /dev/null +++ b/test_config.json.example @@ -0,0 +1,21 @@ +{ + "port": 3000, + "ip": "127.0.0.1", + "debug" : true, + "monetdb": { + "host": "simcaqdb1", + "port": 50000, + "dbname": "simcaq_dev", + "user": "monetdb", + "password":"monetdb", + "nrConnections": "16" + }, + "mongodb" : { + "uri": "mongodb://localhost/test_users" + }, + "default": { + "api": { + "version" : "v1" + } + } +} -- GitLab From 90a2f1e87242e52a51c2878ee37c9d9c6325c52e Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Wed, 5 Oct 2016 09:29:42 -0300 Subject: [PATCH 15/50] Better simulation testing --- src/test/test.js | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/test/test.js b/src/test/test.js index 092780a1..55d96515 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -166,14 +166,16 @@ describe('request cities', () => { }); }); -describe('Create new sim', () => { +describe('Requires a simulation', () => { let newSimulation; beforeEach(() => { - Simulation.remove(); + Simulation.remove({}, (err) => { + console.log('Test collection purged'); + }); }); - it('should return a new simulation id', (done) => { + it('should create a new simulation', (done) => { chai.request(server) .post('/api/v1/simulation') .set('content-type', 'application/x-www-form-urlencoded') @@ -184,6 +186,11 @@ describe('Create new sim', () => { res.should.be.json; res.body.should.have.property('id'); res.body.id.should.be.a('string'); + Simulation.findById(res.body.id, (err, simulation) => { + simulation.should.have.property('name'); + simulation.name.should.be.a('string'); + simulation.name.should.equal('test_entry'); + }); done(); }); }); @@ -205,14 +212,14 @@ describe('Create new sim', () => { }); }); }); - it('should update an existing simulation', (done) => { + it('should update an existing simulation\'s location', (done) => { newSimulation = new Simulation(); newSimulation.name = 'test'; newSimulation.save((err, sim) => { let id = sim._id; chai.request(server) .post(`/api/v1/simulation/${id}`) - .send({location: 5}) + .send({ location: 5 }) .end((err, res) => { res.should.have.status(200); res.should.be.json; @@ -223,6 +230,31 @@ describe('Create new sim', () => { simulation.name.should.be.a('string'); simulation.should.have.property('location'); simulation.location.should.be.a('number'); + simulation.location.should.equal(5); + }); + done(); + }); + }); + }); + it('should update an existing simulation\'s time', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ time: 5 }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('id'); + res.body.id.should.be.a('string'); + Simulation.findById(res.body.id, (err, simulation) => { + simulation.should.have.property('name'); + simulation.name.should.be.a('string'); + simulation.should.have.property('time'); + simulation.time.should.be.a('number'); + simulation.time.should.equal(5); }); done(); }); -- GitLab From cd664360afa27bca4336673e9baf9b4417bf35da Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Wed, 5 Oct 2016 09:30:53 -0300 Subject: [PATCH 16/50] Removed location models --- src/libs/models/locations.js | 34 ---------------------------------- src/libs/models/simulation.js | 2 -- 2 files changed, 36 deletions(-) delete mode 100644 src/libs/models/locations.js diff --git a/src/libs/models/locations.js b/src/libs/models/locations.js deleted file mode 100644 index e169e53b..00000000 --- a/src/libs/models/locations.js +++ /dev/null @@ -1,34 +0,0 @@ -/* These classes are defined to allow checking of location type with the -instanceof operator. */ - -class Location {} - -// Location types -class City extends Location { - constructor(id) { - super(); - this.id = id; - } -} - -class State extends Location { - constructor(id) { - super(); - this.id = id; - } -} - -class Region extends Location { - constructor(id) { - super(); - this.id = id; - } -} - -const locations = { - location: Location, - city: City, - state: State, - region: Region }; - -module.exports = locations; diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index fcfc26d3..b2bfe828 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -4,8 +4,6 @@ const libs = `${process.cwd()}/libs`; const config = require(`${libs}/config`); const log = require(`${libs}/log`)(module); -const locations = require(`${libs}/models/locations`); - const Schema = mongoose.Schema; // Should define this somewhere else -- GitLab From fac5408225fc1bd73a10119c70e93aa355beae80 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Wed, 5 Oct 2016 09:56:39 -0300 Subject: [PATCH 17/50] Even more simulation tests --- src/test/test.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/test.js b/src/test/test.js index 55d96515..e3f03fc2 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -194,6 +194,23 @@ describe('Requires a simulation', () => { done(); }); }); + it('should not create a nameless simulation', (done) => { + chai.request(server) + .post('/api/v1/simulation') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.not.have.property('id'); + res.body.should.have.property('success'); + res.body.success.should.equal(false); + Simulation.findById(res.body.id, (err, simulation) => { + expect(simulation).to.not.exist; + }); + done(); + }); + }); it('should find an existing simulation', (done) => { newSimulation = new Simulation(); newSimulation.name = 'test'; @@ -212,6 +229,19 @@ describe('Requires a simulation', () => { }); }); }); + it('should not find an unexisting simulation', (done) => { + newSimulation = new Simulation(); + let id = newSimulation._id; + chai.request(server) + .get(`/api/v1/simulation/${id}`) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + done(); + }); + }); it('should update an existing simulation\'s location', (done) => { newSimulation = new Simulation(); newSimulation.name = 'test'; -- GitLab From bb7f77a56e0dc6a9403858b24ae967d5cc67e818 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Wed, 5 Oct 2016 10:40:50 -0300 Subject: [PATCH 18/50] Moved config files to config folder --- config.json.example => config/config.json.example | 0 .../test_config.json.example | 0 gulpfile.babel.js | 8 ++++---- src/libs/config.js | 9 ++++----- 4 files changed, 8 insertions(+), 9 deletions(-) rename config.json.example => config/config.json.example (100%) rename test_config.json.example => config/test_config.json.example (100%) diff --git a/config.json.example b/config/config.json.example similarity index 100% rename from config.json.example rename to config/config.json.example diff --git a/test_config.json.example b/config/test_config.json.example similarity index 100% rename from test_config.json.example rename to config/test_config.json.example diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 3a61dace..66bc5000 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -46,10 +46,10 @@ gulp.task('compile', () => { .pipe(gulp.dest('build')); // move compiled files to build directory // copy configuration file to build directory - gulp.src('config.json') - .pipe(gulp.dest('build')); - gulp.src('test_config.json') - .pipe(gulp.dest('build')); + gulp.src('config/config.json') + .pipe(gulp.dest('build/config')); + gulp.src('config/test_config.json') + .pipe(gulp.dest('build/config')); }); gulp.task('build', ['compile']); diff --git a/src/libs/config.js b/src/libs/config.js index dd2d88c4..d61eff99 100644 --- a/src/libs/config.js +++ b/src/libs/config.js @@ -1,16 +1,17 @@ const nconf = require('nconf'); +const CONFIG_DIR = `config` let config_file; switch(process.env.NODE_ENV) { case 'development': - config_file = 'config.json'; + config_file = `${CONFIG_DIR}/config.json`; break; case 'test': - config_file = 'test_config.json'; + config_file = `${CONFIG_DIR}/test_config.json`; break; case 'production': - config_file = 'config.json'; + config_file = `${CONFIG_DIR}/config.json`; break; } @@ -19,6 +20,4 @@ nconf.argv() .env() .file({ file: `${process.cwd()}/${config_file}` }); -console.log(nconf.get('mongodb')); - module.exports = nconf; -- GitLab From 873a1406958b7b6c2e74ce168c7ad9be0756c73c Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Thu, 6 Oct 2016 16:18:49 -0300 Subject: [PATCH 19/50] Config file style changed --- .gitignore | 1 - config.json.example | 68 +++++++++++++++++++++++++++++++++ config/config.json.example | 21 ---------- config/test_config.json.example | 21 ---------- gulpfile.babel.js | 6 +-- src/libs/app.js | 2 +- src/libs/config.js | 24 ++---------- src/libs/db/monet.js | 12 +++--- src/libs/db/mongoose.js | 2 +- src/libs/log.js | 2 +- src/libs/models/simulation.js | 1 - src/libs/routes/simulation.js | 1 - src/server.js | 4 +- 13 files changed, 84 insertions(+), 81 deletions(-) create mode 100644 config.json.example delete mode 100644 config/config.json.example delete mode 100644 config/test_config.json.example diff --git a/.gitignore b/.gitignore index 136ccb71..979717eb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,3 @@ build/* config.json docs/ -test_config.json diff --git a/config.json.example b/config.json.example new file mode 100644 index 00000000..67f5a4f1 --- /dev/null +++ b/config.json.example @@ -0,0 +1,68 @@ +{ + "development": + { + "port": 3000, + "ip": "127.0.0.1", + "debug" : true, + "monetdb": { + "host": "simcaqdb1", + "port": 50000, + "dbname": "simcaq_dev", + "user": "monetdb", + "password":"monetdb", + "nrConnections": "16" + }, + "mongodb" : { + "uri": "mongodb://localhost/users" + }, + "default": { + "api": { + "version" : "v1" + } + } + }, + "test": + { + "port": 3000, + "ip": "127.0.0.1", + "debug" : true, + "monetdb": { + "host": "simcaqdb1", + "port": 50000, + "dbname": "simcaq_dev", + "user": "monetdb", + "password":"monetdb", + "nrConnections": "16" + }, + "mongodb" : { + "uri": "mongodb://localhost/test_users" + }, + "default": { + "api": { + "version" : "v1" + } + } + }, + "production": + { + "port": 3000, + "ip": "127.0.0.1", + "debug" : true, + "monetdb": { + "host": "simcaqdb1", + "port": 50000, + "dbname": "simcaq_dev", + "user": "monetdb", + "password":"monetdb", + "nrConnections": "16" + }, + "mongodb" : { + "uri": "mongodb://localhost/users" + }, + "default": { + "api": { + "version" : "v1" + } + } + } +} diff --git a/config/config.json.example b/config/config.json.example deleted file mode 100644 index 136ee928..00000000 --- a/config/config.json.example +++ /dev/null @@ -1,21 +0,0 @@ -{ - "port": 3000, - "ip": "127.0.0.1", - "debug" : false, - "monetdb": { - "host": "simcaqdb1", - "port": 50000, - "dbname": "simcaq_dev", - "user": "monetdb", - "password":"monetdb", - "nrConnections": "16" - }, - "mongodb" : { - "uri": "mongodb://localhost/users" - }, - "default": { - "api": { - "version" : "v1" - } - } -} diff --git a/config/test_config.json.example b/config/test_config.json.example deleted file mode 100644 index 0a8d9146..00000000 --- a/config/test_config.json.example +++ /dev/null @@ -1,21 +0,0 @@ -{ - "port": 3000, - "ip": "127.0.0.1", - "debug" : true, - "monetdb": { - "host": "simcaqdb1", - "port": 50000, - "dbname": "simcaq_dev", - "user": "monetdb", - "password":"monetdb", - "nrConnections": "16" - }, - "mongodb" : { - "uri": "mongodb://localhost/test_users" - }, - "default": { - "api": { - "version" : "v1" - } - } -} diff --git a/gulpfile.babel.js b/gulpfile.babel.js index 66bc5000..1f23dd9e 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -46,10 +46,8 @@ gulp.task('compile', () => { .pipe(gulp.dest('build')); // move compiled files to build directory // copy configuration file to build directory - gulp.src('config/config.json') - .pipe(gulp.dest('build/config')); - gulp.src('config/test_config.json') - .pipe(gulp.dest('build/config')); + gulp.src('config.json') + .pipe(gulp.dest('build')); }); gulp.task('build', ['compile']); diff --git a/src/libs/app.js b/src/libs/app.js index bed5deb7..a1b3ff01 100644 --- a/src/libs/app.js +++ b/src/libs/app.js @@ -12,7 +12,7 @@ const log = require(`${libs}/log`)(module); process.env.NODE_ENV = process.env.NODE_ENV || 'development'; const config = require(`${libs}/config`); -const cache = require('apicache').options({ debug: config.get('debug') }).middleware; +const cache = require('apicache').options({ debug: config.debug }).middleware; const app = express(); diff --git a/src/libs/config.js b/src/libs/config.js index d61eff99..2c07d19e 100644 --- a/src/libs/config.js +++ b/src/libs/config.js @@ -1,23 +1,5 @@ -const nconf = require('nconf'); +let conf = require(`${process.cwd()}/config.json`); -const CONFIG_DIR = `config` -let config_file; +conf = conf[process.env.NODE_ENV]; -switch(process.env.NODE_ENV) { - case 'development': - config_file = `${CONFIG_DIR}/config.json`; - break; - case 'test': - config_file = `${CONFIG_DIR}/test_config.json`; - break; - case 'production': - config_file = `${CONFIG_DIR}/config.json`; - break; -} - -// Exports the config.json as an object with get functions -nconf.argv() - .env() - .file({ file: `${process.cwd()}/${config_file}` }); - -module.exports = nconf; +module.exports = conf; diff --git a/src/libs/db/monet.js b/src/libs/db/monet.js index dd7e620a..d19fb37d 100644 --- a/src/libs/db/monet.js +++ b/src/libs/db/monet.js @@ -6,16 +6,16 @@ const config = require(`${libs}/config`); // Connection options const poolOptions = { - nrConnections: config.get('monetdb:nrConnections'), + nrConnections: config.monetdb.nrConnections, }; // Configuration options const options = { - host: config.get('monetdb:host'), - port: config.get('monetdb:port'), - dbname: config.get('monetdb:dbname'), - user: config.get('monetdb:user'), - password: config.get('monetdb:password'), + host: config.monetdb.host, + port: config.monetdb.port, + dbname: config.monetdb.dbname, + user: config.monetdb.user, + password: config.monetdb.password, }; // Connection singleton diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js index b1a078fd..8571b993 100644 --- a/src/libs/db/mongoose.js +++ b/src/libs/db/mongoose.js @@ -8,7 +8,7 @@ const mongoose = require('mongoose'); module.exports = () => { // Get mongodb URI (ip and port) in config file - const mongoUri = config.get('mongodb:uri'); + const mongoUri = config.mongodb.uri; log.debug(`Connecting to MongDB on URI ${mongoUri}`); // Connection singleton const db = mongoose.connect(mongoUri); diff --git a/src/libs/log.js b/src/libs/log.js index ee975b8d..1cf59931 100644 --- a/src/libs/log.js +++ b/src/libs/log.js @@ -47,7 +47,7 @@ function logger(module) { ], exitOnError: false, }); - if (!config.get('debug')) { + if (!config.debug) { log.remove('debug-log'); } return log; diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index b2bfe828..a445c280 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -1,7 +1,6 @@ const mongoose = require('mongoose') const libs = `${process.cwd()}/libs`; -const config = require(`${libs}/config`); const log = require(`${libs}/log`)(module); const Schema = mongoose.Schema; diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index 9b97e7bb..30aa6b5a 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -6,7 +6,6 @@ const libs = `${process.cwd()}/libs`; const log = require(`${libs}/log`)(module); -const config = require(`${libs}/config`); const squel = require('squel'); diff --git a/src/server.js b/src/server.js index d9e37cac..ea8de70e 100644 --- a/src/server.js +++ b/src/server.js @@ -9,10 +9,10 @@ const log = require(`${libs}/log`)(module); const app = require(`${libs}/app`); // Set default port: first environment variable PORT, then configuration and last 3000 -app.set('port', process.env.PORT || config.get('port') || 3000); +app.set('port', process.env.PORT || config.port || 3000); // Set default ip: first environment variable IOP, then configuration and last '127.0.0.1' -app.set('ip', process.env.IP || config.get('ip') || '127.0.0.1'); +app.set('ip', process.env.IP || config.ip || '127.0.0.1'); const server = app.listen(app.get('port'), () => { log.info(`Express server listening on port ${server.address().port}`); -- GitLab From 35e17fd7c108453b54cf9c8aca03f79f03dc4e6b Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Fri, 7 Oct 2016 10:39:25 -0300 Subject: [PATCH 20/50] Simulation test coverage increase --- src/libs/routes/simulation.js | 2 +- src/test/test.js | 76 +++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index 30aa6b5a..961f6173 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -64,7 +64,7 @@ simulationApp.get('/:id', (req, res) => { }); simulationApp.post('/:id', (req, res, next) => { - if (!req.body) { + if (!Object.keys(req.body).length) { res.send({ success: false, msg: 'No field informed to update' }); } else { next(); diff --git a/src/test/test.js b/src/test/test.js index c25c218b..a5fc30a6 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -492,6 +492,7 @@ describe('Requires a simulation', () => { Simulation.findById(res.body.id, (err, simulation) => { simulation.should.have.property('name'); simulation.name.should.be.a('string'); + simulation.name.should.equal('test'); simulation.should.have.property('location'); simulation.location.should.be.a('number'); simulation.location.should.equal(5); @@ -500,6 +501,63 @@ describe('Requires a simulation', () => { }); }); }); + it('should update multiple fields on a single request', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + location: 5, + time: 3, + failure_rate: [0.1, 0.2, 0.3], + goals_care: [0.3, 0.2, 0.1], + goals_inclusion: [0.8, 0.9, 1] + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('id'); + res.body.id.should.be.a('string'); + Simulation.findById(res.body.id, (err, simulation) => { + simulation.should.have.property('name'); + simulation.name.should.be.a('string'); + simulation.name.should.equal('test'); + simulation.should.have.property('location'); + simulation.location.should.be.a('number'); + simulation.location.should.equal(5); + simulation.should.have.property('time'); + simulation.time.should.be.a('number'); + simulation.time.should.equal(3); + simulation.should.have.property('failure_rate'); + simulation.failure_rate.should.be.a('array'); + simulation.failure_rate.length.should.equal(3); + simulation.should.have.property('goals_care'); + simulation.goals_care.should.be.a('array'); + simulation.goals_care.length.should.equal(3); + simulation.should.have.property('goals_inclusion'); + simulation.goals_inclusion.should.be.a('array'); + simulation.goals_inclusion.length.should.equal(3); + }); + done(); + }); + }); + }); + it('should not update an unexisting simulation', (done) => { + newSimulation = new Simulation(); + let id = newSimulation._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ location: 5 }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + done(); + }); + }); it('should update an existing simulation\'s time', (done) => { newSimulation = new Simulation(); newSimulation.name = 'test'; @@ -524,4 +582,22 @@ describe('Requires a simulation', () => { }); }); }); + it('should not change results for empty post requests', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + done(); + }); + }); + + }); + }); -- GitLab From b118549485b359610792e52246a5ba2c88f41389 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 10 Oct 2016 10:41:39 -0300 Subject: [PATCH 21/50] Sanitization of enrollments for simulation model --- src/libs/models/simulation.js | 47 ++++++++++++++++++++++++++++++----- src/libs/routes/simulation.js | 14 ++++++++++- src/test/test.js | 29 +++++++++++++++++++-- 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index a445c280..cf6ad41c 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -19,38 +19,73 @@ let SimulationSchema = new Schema({ failure_rate: Array, goals_care: Array, goals_inclusion: Array, + enrollments: Array, }); SimulationSchema.methods.setTime = function (t) { t = parseInt(t, 10); if (!t || t > MAX_SIMULATION_TIME) { // Throw an error? - return; + return false; } this.time = t; + return true; }; SimulationSchema.methods.setLocation = function (l) { // Should sanitize this.location = l; + return true; }; SimulationSchema.methods.setFailureRate = function (fr) { // Should sanitize this.failure_rate = fr; + return true; }; SimulationSchema.methods.setCareGoals = function (g) { // Should sanitize this.goals_care = g; + return true; }; SimulationSchema.methods.setInclusionGoals = function (g) { // Should sanitize this.goals_inclusion = g; + return true; }; +SimulationSchema.methods.setEnrollments = function (e) { + e = JSON.parse(e); + for(let i=0; i<e.length; i++){ + if(!(e[i] instanceof Array)){ + return false; + } + if(e[i].length !== this.time){ + return false; + } + for(let n of e[i]) + if(!(n instanceof Number) && (n !== parseInt(n, 10))){ + return false; + } + } + log.debug("rolou"); + this.enrollments = e; + + return true; +} SimulationSchema.methods.update = function (property, value) { - if (property === 'time') this.setTime(value); - if (property === 'location') this.setLocation(value); - if (property === 'failure_rate') this.setFailureRate(value); - if (property === 'goals_care') this.setCareGoals(value); - if (property === 'goals_inclusion') this.setInclusionGoals(value); + let success = true; + if (property === 'time') { + if (!this.setTime(value)) success = false; + } else if (property === 'location') { + if (!this.setLocation(value)) success = false; + } else if (property === 'failure_rate') { + if (!this.setFailureRate(value)) success = false; + } else if (property === 'goals_care') { + if (!this.setCareGoals(value)) success = false; + } else if (property === 'goals_inclusion') { + if (!this.setInclusionGoals(value)) success = false; + } else if (property === 'enrollments') { + if (!this.setEnrollments(value)) success = false; + } else success = false; + return success; }; SimulationSchema.methods.run = function () { diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index 961f6173..ce1a2ff0 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -85,7 +85,19 @@ simulationApp.post('/:id', (req, res, next) => { }, (req, res) => { for (let property in req.body) { if (Simulation.schema.tree.hasOwnProperty(property)) { - req.simulation.update(property, req.body[property]); + if(!req.simulation.update(property, req.body[property])){ + res.send({ + success: false, + msg: 'Invalid format for ' + property, + }); + return ; + } + } else { + res.send({ + success: false, + msg: 'Unknown property ' + property, + }); + return ; } } req.simulation.save((err) => { diff --git a/src/test/test.js b/src/test/test.js index a5fc30a6..d0763cbe 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -597,7 +597,32 @@ describe('Requires a simulation', () => { done(); }); }); - }); - + it('should include consistent enrollment tables', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + time: 5, + enrollments: "[[100, 150, 200, 250, 300]]", + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('id'); + res.body.id.should.be.a('string'); + Simulation.findById(res.body.id, (err, simulation) => { + simulation.should.have.property('name'); + simulation.name.should.be.a('string'); + simulation.should.have.property('time'); + simulation.time.should.be.a('number'); + simulation.time.should.equal(5); + }); + done(); + }); + }); + }); }); -- GitLab From a25508e03c9910a59fdbe895c8c88d6c5d7877c8 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 10 Oct 2016 10:45:44 -0300 Subject: [PATCH 22/50] Changed uggly if chain for switch statement --- src/libs/models/simulation.js | 38 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index cf6ad41c..7d5df97e 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -72,19 +72,31 @@ SimulationSchema.methods.setEnrollments = function (e) { } SimulationSchema.methods.update = function (property, value) { let success = true; - if (property === 'time') { - if (!this.setTime(value)) success = false; - } else if (property === 'location') { - if (!this.setLocation(value)) success = false; - } else if (property === 'failure_rate') { - if (!this.setFailureRate(value)) success = false; - } else if (property === 'goals_care') { - if (!this.setCareGoals(value)) success = false; - } else if (property === 'goals_inclusion') { - if (!this.setInclusionGoals(value)) success = false; - } else if (property === 'enrollments') { - if (!this.setEnrollments(value)) success = false; - } else success = false; + switch(property){ + case 'time': + if (!this.setTime(value)) success = false; + break; + case 'location': + if (!this.setLocation(value)) success = false; + break; + case 'failure_rate': + if (!this.setFailureRate(value)) success = false; + break; + case 'goals_care': + if (!this.setCareGoals(value)) success = false; + break; + case 'goals_inclusion': + if (!this.setInclusionGoals(value)) success = false; + break; + case 'enrollments': + if (!this.setEnrollments(value)) success = false; + break; + case 'name': + this.name = value; + break; + default: + success = false; + } return success; }; -- GitLab From 17bb36270d92522105cb50ccae03d55625170dc3 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 10 Oct 2016 11:12:49 -0300 Subject: [PATCH 23/50] More simulation testing --- src/test/test.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/test/test.js b/src/test/test.js index d0763cbe..bcda16e0 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -509,6 +509,7 @@ describe('Requires a simulation', () => { chai.request(server) .post(`/api/v1/simulation/${id}`) .send({ + name: 'new_name', location: 5, time: 3, failure_rate: [0.1, 0.2, 0.3], @@ -523,7 +524,7 @@ describe('Requires a simulation', () => { Simulation.findById(res.body.id, (err, simulation) => { simulation.should.have.property('name'); simulation.name.should.be.a('string'); - simulation.name.should.equal('test'); + simulation.name.should.equal('new_name'); simulation.should.have.property('location'); simulation.location.should.be.a('number'); simulation.location.should.equal(5); @@ -598,6 +599,29 @@ describe('Requires a simulation', () => { }); }); }); + it('should not update in case of invalid field', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + name: 'other_name', + totally_not_valid_value_for_an_entry: 'not hacking this api', + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + Simulation.findById(id, (err, simulation) => { + simulation.name.should.equal('test'); + done(); + }); + }); + }); + }); it('should include consistent enrollment tables', (done) => { newSimulation = new Simulation(); newSimulation.name = 'test'; @@ -625,4 +649,43 @@ describe('Requires a simulation', () => { }); }); }); + it('should not accept an invalid time', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + time: "I'm an inocent time entry, don't mind me", + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.id.should.equal(false); + }); + done(); + }); + }); + it('should not accept enrollments table different than provided time', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + time: 5, + enrollments: "[[1,2,3]]", + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.id.should.equal(false); + }); + done(); + }); + }); }); -- GitLab From ff3da334bfd4a811d33cc63a3bdc1be343a2b0fb Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 10 Oct 2016 11:49:51 -0300 Subject: [PATCH 24/50] More simulation tests and code cleaning --- src/libs/models/simulation.js | 22 ++++++---- src/test/test.js | 78 +++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index 7d5df97e..aa6589d1 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -52,7 +52,12 @@ SimulationSchema.methods.setInclusionGoals = function (g) { return true; }; SimulationSchema.methods.setEnrollments = function (e) { - e = JSON.parse(e); + try{ + e = JSON.parse(e); + } catch (err) { + return false; + } + let success = true; for(let i=0; i<e.length; i++){ if(!(e[i] instanceof Array)){ return false; @@ -60,15 +65,16 @@ SimulationSchema.methods.setEnrollments = function (e) { if(e[i].length !== this.time){ return false; } - for(let n of e[i]) - if(!(n instanceof Number) && (n !== parseInt(n, 10))){ - return false; + e[i].forEach((n, i, array) => { + if(n !== parseInt(n, 10)){ + success = false; } + }); + } - log.debug("rolou"); - this.enrollments = e; + if (success) this.enrollments = e; - return true; + return success; } SimulationSchema.methods.update = function (property, value) { let success = true; @@ -94,8 +100,6 @@ SimulationSchema.methods.update = function (property, value) { case 'name': this.name = value; break; - default: - success = false; } return success; }; diff --git a/src/test/test.js b/src/test/test.js index bcda16e0..ba617e12 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -424,8 +424,8 @@ describe('Requires a simulation', () => { simulation.should.have.property('name'); simulation.name.should.be.a('string'); simulation.name.should.equal('test_entry'); + done(); }); - done(); }); }); it('should not create a nameless simulation', (done) => { @@ -441,8 +441,8 @@ describe('Requires a simulation', () => { res.body.success.should.equal(false); Simulation.findById(res.body.id, (err, simulation) => { expect(simulation).to.not.exist; + done(); }); - done(); }); }); it('should find an existing simulation', (done) => { @@ -496,8 +496,8 @@ describe('Requires a simulation', () => { simulation.should.have.property('location'); simulation.location.should.be.a('number'); simulation.location.should.equal(5); + done(); }); - done(); }); }); }); @@ -540,8 +540,8 @@ describe('Requires a simulation', () => { simulation.should.have.property('goals_inclusion'); simulation.goals_inclusion.should.be.a('array'); simulation.goals_inclusion.length.should.equal(3); + done(); }); - done(); }); }); }); @@ -578,8 +578,8 @@ describe('Requires a simulation', () => { simulation.should.have.property('time'); simulation.time.should.be.a('number'); simulation.time.should.equal(5); + done(); }); - done(); }); }); }); @@ -644,8 +644,8 @@ describe('Requires a simulation', () => { simulation.should.have.property('time'); simulation.time.should.be.a('number'); simulation.time.should.equal(5); + done(); }); - done(); }); }); }); @@ -663,7 +663,7 @@ describe('Requires a simulation', () => { res.should.have.status(200); res.should.be.json; res.body.should.have.property('success'); - res.body.id.should.equal(false); + res.body.success.should.equal(false); }); done(); }); @@ -683,9 +683,69 @@ describe('Requires a simulation', () => { res.should.have.status(200); res.should.be.json; res.body.should.have.property('success'); - res.body.id.should.equal(false); - }); + res.body.success.should.equal(false); + done(); + }); + }); + }); + it('should not include arrays of non arrays as enrollments', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + time: 5, + enrollments: "[\"Tomato\"]", + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + done(); + }); + }); + }); + it('should not accept non array enrollments', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + time: 5, + enrollments: "Am I still wanted here?", + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); done(); + }); + }); + }); + it('should not accept an enrollment with anything other than a number', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .post(`/api/v1/simulation/${id}`) + .send({ + time: 5, + enrollments: "[[1,2,\"malicious payload\",4,5]]", + }) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + done(); + }); }); }); }); -- GitLab From 2ff94c669e7811ddbfe6ae580b2393176a6aea40 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 11 Oct 2016 10:10:10 -0300 Subject: [PATCH 25/50] small fix on /authenticate --- src/libs/routes/user.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 1323c5ef..1cf6e04e 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -48,7 +48,14 @@ userApp.post('/', (req, res, next) => { }); }); -userApp.post('/authenticate', (req, res) => { +userApp.post('/authenticate', (req, res, next) => { + if (!req.body.email || !req.body.password) { + res.json({success: false, msg: 'Please pass email and password.'}); + } else { + next(); + } + +}, (req, res, next) => { User.findOne({ email: req.body.email }, (err, user) => { @@ -71,9 +78,9 @@ userApp.post('/authenticate', (req, res) => { else { res.json({success: false, msg: 'Authentication failed. Wrong password'}); } - }) + }); } - }) -}) + }); +}); module.exports = userApp; -- GitLab From 079e682a5b2036c4ba41dcb5ee180c1d5e1c2863 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 11 Oct 2016 10:33:23 -0300 Subject: [PATCH 26/50] update user model to contain all required fields --- src/libs/models/user.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/libs/models/user.js b/src/libs/models/user.js index 01124ec2..5e90e114 100644 --- a/src/libs/models/user.js +++ b/src/libs/models/user.js @@ -14,7 +14,48 @@ var UserSchema = new Schema({ password: { type: String, required: true + }, + name: { + type: String, + required: true + }, + cpf:{ + type: String, + unique: true, + required: true + }, + schooling: { + type: String, + required: true + }, + course: { + type: String, + required: true + }, + segment: { + type: String, + required: true + }, + role: { + type: String, + required: true + }, + institution_name: { + type: String, + required: true + }, + state: { + type: String, + required: true + }, + city: { + type: String, + required: true + }, + receive_emails{ + type: Boolean } + }); UserSchema.pre('save', function (next) { -- GitLab From 92308927edbc10bae542cbd41b01733f44ac5569 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 11 Oct 2016 11:06:56 -0300 Subject: [PATCH 27/50] small syntax fix on model --- src/libs/models/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/models/user.js b/src/libs/models/user.js index 5e90e114..8adac2cd 100644 --- a/src/libs/models/user.js +++ b/src/libs/models/user.js @@ -52,7 +52,7 @@ var UserSchema = new Schema({ type: String, required: true }, - receive_emails{ + receive_emails: { type: Boolean } -- GitLab From 58d3fdbd0e5cdce03db8eed09df1707630805752 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 11 Oct 2016 11:29:12 -0300 Subject: [PATCH 28/50] save new fields on post /user --- src/libs/routes/user.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 1cf6e04e..fc2a9b8b 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -35,7 +35,17 @@ userApp.post('/', (req, res, next) => { }, (req, res, next) => { var newUser = new User({ email: req.body.email, - password: req.body.password + password: req.body.password, + name: req.body.name, + cpf: req.body.cpf, + schooling: req.body.schooling, + course: req.body.course, + segment: req.body.segment, + role: req.body.role, + institution_name: req.body.institution_name, + state: req.body.state, + city: req.body.city, + receive_emails: req.body.receive_emails }); // save the user -- GitLab From 8e4b722981d101d763f95e8d279f2045ba45b3b7 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 13 Oct 2016 09:55:08 -0300 Subject: [PATCH 29/50] add checkage for all required fields before saving user --- src/libs/routes/user.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index fc2a9b8b..ccd8ddc6 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -12,6 +12,8 @@ const User = require(`${libs}/models/user`); const jwt = require('jwt-simple'); +const required_fields = ["email", "password", "name", "cpf", "schooling", "course", "segment", "role", "institution_name", "state", "city"]; + function emailSyntax(email) { const regex = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; @@ -19,8 +21,15 @@ function emailSyntax(email) { } userApp.post('/', (req, res, next) => { - if (!req.body.email || !req.body.password) { - res.json({success: false, msg: 'Please pass email and password.'}); + if (!req.body.email) { + res.json({success: false, msg: 'Please pass email.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.password) { + res.json({success: false, msg: 'Please pass password.'}); } else { next(); } @@ -32,6 +41,14 @@ userApp.post('/', (req, res, next) => { next(); } +}, (req, res, next) => { + for (let property of required_fields){ + if(!Object.prototype.hasOwnProperty.call(req.body, property)){ + res.json({success: false, msg: 'Please fill out all mandatory fields.'}); + return; + } + } + next(); }, (req, res, next) => { var newUser = new User({ email: req.body.email, -- GitLab From 20fa0d399ce658e1841508c8193440d214a19bef Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Fri, 14 Oct 2016 11:29:21 -0300 Subject: [PATCH 30/50] made course field not required --- src/libs/models/user.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/models/user.js b/src/libs/models/user.js index 8adac2cd..8c4f92a2 100644 --- a/src/libs/models/user.js +++ b/src/libs/models/user.js @@ -30,7 +30,6 @@ var UserSchema = new Schema({ }, course: { type: String, - required: true }, segment: { type: String, -- GitLab From 3c7962d5ed12568345b1798b0f8a1bccee02cee1 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Fri, 14 Oct 2016 11:29:55 -0300 Subject: [PATCH 31/50] add user route to app (was lost during merge) --- src/libs/routes/api.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index 3faaa926..d0a7aca3 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -12,6 +12,8 @@ const city = require('./city'); const school = require('./school'); +const user = require('./user'); + api.get('/', (req, res) => { res.json({ msg: 'SimCAQ API is running' }); }); @@ -22,5 +24,6 @@ api.use('/state', state); api.use('/region', region); api.use('/city', city); api.use('/school', school); +api.use('/user', user); module.exports = api; -- GitLab From aa59e1c2bedc6512116dd310bfd536541f8e7ddf Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Fri, 14 Oct 2016 11:51:43 -0300 Subject: [PATCH 32/50] add mongoose promise (was lost during merge) --- src/libs/db/mongoose.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js index 30b4d493..4188f5c4 100644 --- a/src/libs/db/mongoose.js +++ b/src/libs/db/mongoose.js @@ -6,6 +6,8 @@ const log = require(`${libs}/log`)(module); const mongoose = require('mongoose'); +mongoose.Promise = global.Promise; + module.exports = () => { const mongoUri = process.env.MONGO_URI || config.get('mongodb:uri'); log.debug(`Connecting to MongDB on URI ${mongoUri}`); -- GitLab From cd6da73bc1458bda7286edc9ce08ba82b538ebc0 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Fri, 14 Oct 2016 11:52:45 -0300 Subject: [PATCH 33/50] remove course from required fields --- src/libs/routes/user.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index ccd8ddc6..c043a66b 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -12,7 +12,7 @@ const User = require(`${libs}/models/user`); const jwt = require('jwt-simple'); -const required_fields = ["email", "password", "name", "cpf", "schooling", "course", "segment", "role", "institution_name", "state", "city"]; +const required_fields = ["email", "password", "name", "cpf", "schooling", "segment", "role", "institution_name", "state", "city"]; function emailSyntax(email) { @@ -43,10 +43,10 @@ userApp.post('/', (req, res, next) => { }, (req, res, next) => { for (let property of required_fields){ - if(!Object.prototype.hasOwnProperty.call(req.body, property)){ - res.json({success: false, msg: 'Please fill out all mandatory fields.'}); - return; - } + // if(!Object.prototype.hasOwnProperty.call(req.body, property)){ + // res.json({success: false, msg: 'Please fill out all mandatory fields.'}); + // return; + // } } next(); }, (req, res, next) => { -- GitLab From 7e65334fb842173641f6451e5d0f23d545afb864 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Fri, 14 Oct 2016 18:08:25 -0300 Subject: [PATCH 34/50] add missing dependencies to package.json --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index acc29cd2..a7056dc9 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "apicache": "0.0.14", + "bcrypt": "^0.8.7", "body-parser": "^1.13.1", "chai": "^3.5.0", "chai-http": "^3.0.0", @@ -23,11 +24,13 @@ "faker": "^2.1.5", "forever": "^0.15.2", "js2xmlparser": "^1.0.0", + "jwt-simple": "^0.5.0", "method-override": "^2.3.3", "mocha": "^2.5.3", "monetdb-pool": "0.0.8", "mongoose": "^4.6.0", "nconf": "^0.6.x", + "passport": "^0.3.2", "squel": "^5.4.2", "winston": "^2.2.0" }, -- GitLab From e1a94382af511564e81060901d65e137512868b0 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Mon, 17 Oct 2016 09:18:09 -0200 Subject: [PATCH 35/50] fix routes --- src/libs/routes/api.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index ac005ffb..7ae5b3e8 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -25,11 +25,11 @@ api.get('/', (req, res) => { }); // mount API routes -api.use('/api/v1/enrollment', cache('1 day'), enrollment); -api.use('/api/v1/state', cache('15 day'), state); -api.use('/api/v1/region', cache('15 day'), region); -api.use('/api/v1/city', cache('15 day'), city); -api.use('/api/v1/school', cache('15 day'), school); -api.use('/api/v1/user', user); +api.use('/user', user); +api.use('/enrollment', cache('1 day'), enrollment); +api.use('/state', cache('15 day'), state); +api.use('/region', cache('15 day'), region); +api.use('/city', cache('15 day'), city); +api.use('/school', cache('15 day'), school); module.exports = api; -- GitLab From d6f3af11c95bff5df134786b2e78bae76778fd2d Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Mon, 17 Oct 2016 10:48:51 -0200 Subject: [PATCH 36/50] update API response for missing fields --- src/libs/routes/user.js | 71 ++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index c043a66b..9ba9be45 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -22,33 +22,81 @@ function emailSyntax(email) { userApp.post('/', (req, res, next) => { if (!req.body.email) { - res.json({success: false, msg: 'Please pass email.'}); + res.json({success: false, msg: 'O campo Email é obrigatório.'}); } else { next(); } }, (req, res, next) => { if (!req.body.password) { - res.json({success: false, msg: 'Please pass password.'}); + res.json({success: false, msg: 'O campo Senha é obrigatório.'}); } else { next(); } }, (req, res, next) => { if(!emailSyntax(req.body.email)){ - res.json({success: false, msg: 'Invalid email syntax.'}); + res.json({success: false, msg: 'O email Informado é inválido.'}); } else { next(); } }, (req, res, next) => { - for (let property of required_fields){ - // if(!Object.prototype.hasOwnProperty.call(req.body, property)){ - // res.json({success: false, msg: 'Please fill out all mandatory fields.'}); - // return; - // } + if (!req.body.name) { + res.json({success: false, msg: 'O campo Nome é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.cpf) { + res.json({success: false, msg: 'O campo CPF é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.schooling) { + res.json({success: false, msg: 'O campo Escolaridade é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.segment) { + res.json({success: false, msg: 'O campo Segmento é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.role) { + res.json({success: false, msg: 'O campo Função é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.institution_name) { + res.json({success: false, msg: 'O campo Intituição em que trabalha é obrigatório.'}); + } else { + next(); } - next(); + +}, (req, res, next) => { + if (!req.body.city) { + res.json({success: false, msg: 'O campo Cidade é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.state) { + res.json({success: false, msg: 'O campo Estado é obrigatório.'}); + } else { + next(); + } + }, (req, res, next) => { var newUser = new User({ email: req.body.email, @@ -68,9 +116,10 @@ userApp.post('/', (req, res, next) => { // save the user newUser.save((err) => { if (err) { - res.json({success: false, msg: 'Email already in use.'}); + //no momento retorna essa mensagem se o email OU CPF já estiver cadastrado + res.json({success: false, msg: 'O email informado já está cadastrado.'}); } else { - res.json({success: true, msg: 'Successful created new user.'}); + res.json({success: true, msg: 'Usuário cadastrado com sucesso!'}); } }); }); -- GitLab From d4647a7f90cea454cec9991b07c775fffaf88c5e Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Mon, 17 Oct 2016 15:48:56 -0200 Subject: [PATCH 37/50] Some extra methods previously ignored for simulations --- src/libs/models/simulation.js | 2 +- src/libs/routes/api.js | 2 +- src/libs/routes/simulation.js | 36 ++++++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index aa6589d1..6ba85b49 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -15,7 +15,7 @@ let SimulationSchema = new Schema({ required: true, }, location: Object, - time: Number, + time: Date, failure_rate: Array, goals_care: Array, goals_inclusion: Array, diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js index 4fc68cf2..2c259bab 100644 --- a/src/libs/routes/api.js +++ b/src/libs/routes/api.js @@ -6,7 +6,7 @@ const libs = `${process.cwd()}/libs`; const config = require(`${libs}/config`); -const cache = require('apicache').options({ debug: config.get('debug') }).middleware; +const cache = require('apicache').options({ debug: config.debug }).middleware; const enrollment = require('./enrollment'); diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index ce1a2ff0..b1599750 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -16,7 +16,14 @@ const response = require(`${libs}/middlewares/response`); const Simulation = require(`${libs}/models/simulation`); simulationApp.get('/', (req, res) => { - res.send({ success: true, msg: 'controller working' }); + let out = { success: true, msg: 'controller working' }; + out.result = new Array() + Simulation.find({}, function(err, sims) { + sims.forEach((sim) => { + out.result.push(sim); + }); + res.send(out); + }); }); @@ -30,8 +37,10 @@ simulationApp.post('/', (req, res, next) => { next(); } }, (req, res) => { + let currentdate = new Date(); let newSimulation = new Simulation({ name: req.body.name, + time: currentdate.getDate(), }); newSimulation.save((err) => { if (err) { @@ -113,4 +122,29 @@ simulationApp.post('/:id', (req, res, next) => { }); }); +simulationApp.delete('/:id', (req, res, next) => { + let simulation = Simulation.findById(req.params.id, (err, simulation) => { + if (err) { + res.send({ success: false, msg: err }); + } else { + if (!simulation) { + res.send({ success: false, msg: 'Entry not found' }); + } else { + next(); + } + } + }); +}, (req, res) => { + Simulation.remove({"_id": req.params.id}, (err) => { + if (err) { + res.send({ success: false, msg: err }); + } else { + res.send({ + success: true, + msg: 'sim removed', + }); + } + }); +}); + module.exports = simulationApp; -- GitLab From aa701c4aa03da5cb2fac7e673be6945e9dbf0b29 Mon Sep 17 00:00:00 2001 From: Rudolf Copi Eckelberg <rce16@inf.ufpr.br> Date: Tue, 18 Oct 2016 09:56:42 -0200 Subject: [PATCH 38/50] Test fixes --- src/libs/models/simulation.js | 3 ++- src/libs/routes/simulation.js | 4 +--- src/test/test.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/libs/models/simulation.js b/src/libs/models/simulation.js index 6ba85b49..e70c93a9 100644 --- a/src/libs/models/simulation.js +++ b/src/libs/models/simulation.js @@ -15,11 +15,12 @@ let SimulationSchema = new Schema({ required: true, }, location: Object, - time: Date, + time: Number, failure_rate: Array, goals_care: Array, goals_inclusion: Array, enrollments: Array, + timestamp: Date, }); SimulationSchema.methods.setTime = function (t) { diff --git a/src/libs/routes/simulation.js b/src/libs/routes/simulation.js index b1599750..16c7dcf8 100644 --- a/src/libs/routes/simulation.js +++ b/src/libs/routes/simulation.js @@ -26,8 +26,6 @@ simulationApp.get('/', (req, res) => { }); }); - - simulationApp.post('/', (req, res, next) => { // This method must associate new entry with user. /* Creates a new simulation. Requires a name. */ @@ -40,7 +38,7 @@ simulationApp.post('/', (req, res, next) => { let currentdate = new Date(); let newSimulation = new Simulation({ name: req.body.name, - time: currentdate.getDate(), + timestamp: currentdate.getDate(), }); newSimulation.save((err) => { if (err) { diff --git a/src/test/test.js b/src/test/test.js index ba617e12..5529e056 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -748,4 +748,33 @@ describe('Requires a simulation', () => { }); }); }); + it('should delete an entry', (done) => { + newSimulation = new Simulation(); + newSimulation.name = 'test'; + newSimulation.save((err, sim) => { + let id = sim._id; + chai.request(server) + .delete(`/api/v1/simulation/${id}`) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(true); + done(); + }); + }); + }); + it('should not delete an unexisting entry', (done) => { + let sim = new Simulation(); + let id = sim._id; + chai.request(server) + .delete(`/api/v1/simulation/${id}`) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + done(); + }); + }); }); -- GitLab From 2f184b19943f68c4e57e038e5bfb584415a8c32a Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 18 Oct 2016 10:38:29 -0200 Subject: [PATCH 39/50] checks for informed email and CPF on db before saving new user --- src/libs/routes/user.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 9ba9be45..9b24fbdc 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -97,6 +97,32 @@ userApp.post('/', (req, res, next) => { next(); } +}, (req, res, next) => { + User.count({'email': req.body.email}, function(err, count){ + if (err){ + console.log('MongoDB error: ' + err); + res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'}); + } + if(count){ + res.json({success: false, msg: 'O email informado já está cadastrado.'}); + } else { + next(); + } + }); + +}, (req, res, next) => { + User.count({'cpf': req.body.cpf}, function(err, count){ + if (err){ + console.log('MongoDB error: ' + err); + res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'}); + } + if(count){ + res.json({success: false, msg: 'O CPF informado já está cadastrado.'}); + } else { + next(); + } + }); + }, (req, res, next) => { var newUser = new User({ email: req.body.email, @@ -116,8 +142,7 @@ userApp.post('/', (req, res, next) => { // save the user newUser.save((err) => { if (err) { - //no momento retorna essa mensagem se o email OU CPF já estiver cadastrado - res.json({success: false, msg: 'O email informado já está cadastrado.'}); + res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'}); } else { res.json({success: true, msg: 'Usuário cadastrado com sucesso!'}); } -- GitLab From daab538b3bd5b08fc0e158c56874fbe746176d01 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 20 Oct 2016 09:35:03 -0200 Subject: [PATCH 40/50] small fix on passport config --- src/libs/middlewares/passport.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js index 76cdf598..4092f146 100644 --- a/src/libs/middlewares/passport.js +++ b/src/libs/middlewares/passport.js @@ -18,10 +18,6 @@ module.exports = function(passport){ return done(null, false, {message: 'Unknown user'}); } - if (!user.comparePassword(password)) { - return done(null, false, {message: 'Invalid password'}); - } - return done(null, user); }); })); -- GitLab From aee72b358acd228e8fd364dadbb9157a1dc66f1d Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 20 Oct 2016 11:09:45 -0200 Subject: [PATCH 41/50] update API responses to match use cases's --- src/libs/routes/user.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 9b24fbdc..2f410fbc 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -150,8 +150,15 @@ userApp.post('/', (req, res, next) => { }); userApp.post('/authenticate', (req, res, next) => { - if (!req.body.email || !req.body.password) { - res.json({success: false, msg: 'Please pass email and password.'}); + if (!req.body.email) { + res.json({success: false, msg: 'O campo Email é obrigatório.'}); + } else { + next(); + } + +}, (req, res, next) => { + if (!req.body.password) { + res.json({success: false, msg: 'O campo Senha é obrigatório.'}); } else { next(); } @@ -163,7 +170,7 @@ userApp.post('/authenticate', (req, res, next) => { if (err) throw err; if(!user){ - res.json({success: false, msg: 'Authentication failed. User not found.'}); + res.json({success: false, msg: 'O Email informado não está cadastrado.'}); } else { user.comparePassword(req.body.password, (err, isMatch) => { @@ -174,10 +181,10 @@ userApp.post('/authenticate', (req, res, next) => { var token = jwt.encode(user, secret); //returns user info including token as json - res.json({success: true, token: 'JWT ' + token}); + res.json({success: true, token: 'JWT ' + token, msg: 'Usuário autenticado com sucesso'}); } else { - res.json({success: false, msg: 'Authentication failed. Wrong password'}); + res.json({success: false, msg: 'A Senha informada é inválida.'}); } }); } -- GitLab From 4e7f70a68d2791258c6e7e95aa18b66593ce5dce Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 20 Oct 2016 11:27:35 -0200 Subject: [PATCH 42/50] update config.json.example --- config.json.example | 1 + 1 file changed, 1 insertion(+) diff --git a/config.json.example b/config.json.example index 136ee928..0a0603ce 100644 --- a/config.json.example +++ b/config.json.example @@ -12,6 +12,7 @@ }, "mongodb" : { "uri": "mongodb://localhost/users" + "secret": "SimCAQC3SL" }, "default": { "api": { -- GitLab From 4753e07efb0d5b8ad68a068bc512d40733bab932 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Mon, 24 Oct 2016 12:03:00 -0200 Subject: [PATCH 43/50] add some tests for user (wip) --- src/libs/routes/user.js | 2 +- src/test/test.js | 268 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 1 deletion(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 2f410fbc..223552a5 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -36,7 +36,7 @@ userApp.post('/', (req, res, next) => { }, (req, res, next) => { if(!emailSyntax(req.body.email)){ - res.json({success: false, msg: 'O email Informado é inválido.'}); + res.json({success: false, msg: 'O email informado é inválido.'}); } else { next(); } diff --git a/src/test/test.js b/src/test/test.js index 5529e056..65187f1c 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -24,6 +24,7 @@ const server = require(`${libs}/app`); const mongoose = require('../libs/db/mongoose'); const Simulation = require('../libs/models/simulation'); +const User = require('../libs/models/user'); chai.use(chaiHttp); @@ -778,3 +779,270 @@ describe('Requires a simulation', () => { }); }); }); + +describe('Saves a user', () => { + + beforeEach(() => { + User.remove({}, (err) => { + console.log('Test collection purged'); + }); + }); + + it('should create a new user', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila Baby', + cpf: '48303270737', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(true); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + if (err){ + console.log('MongoDB error: ' + err); + } + + user.should.have.property('email'); + done(); + }); + }); + }); + + it('should not create a user with an email that is already in use', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila Baby', + cpf: '48303270737', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O email informado já está cadastrado.'); + User.findOne({'cpf': '48303270737'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + }); + + it('should not save an user without email', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({password: '123mudar', + name: 'Tequila Baby', + cpf: '48303270737', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Email é obrigatório.'); + User.findOne({'cpf': '48303270737'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without password', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + name: 'Tequila Baby', + cpf: '48303270737', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Senha é obrigatório.'); + User.findOne({'cpf': '48303270737'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user with invalid email', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'notavalidemail', + password: '123mudar', + name: 'Tequila Baby', + cpf: '48303270737', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O email informado é inválido.'); + User.findOne({'cpf': '48303270737'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without name', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + cpf: '48303270737', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Nome é obrigatório.'); + User.findOne({'cpf': '48303270737'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without CPF', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo CPF é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without CPF', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + cpf: '48303270737', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Escolaridade é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + +}); -- GitLab From 533557c9b65a45b7aaefe39802990b392131776d Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 25 Oct 2016 10:02:12 -0200 Subject: [PATCH 44/50] finish tests for /user route --- src/test/test.js | 197 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 1 deletion(-) diff --git a/src/test/test.js b/src/test/test.js index 65187f1c..854e26ff 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -870,6 +870,56 @@ describe('Saves a user', () => { }); }); + it('should not create a user with a CPF that is already in use', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'dolor@ipsum.com', + password: '123mudar', + name: 'Tequila Baby', + cpf: '08236017907', + schooling: 'Doutorado', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O CPF informado já está cadastrado.'); + User.findOne({'email': 'dolor@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + }); + it('should not save an user without email', (done) => { chai.request(server) .post('/api/v1/user') @@ -1016,7 +1066,36 @@ describe('Saves a user', () => { }); }); - it('should not save an user without CPF', (done) => { + it('should not save an user without segment', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + schooling: 'Doutorado', + cpf: '48303270737', + course: 'Ciência da Computação', + role: 'Pesquisador', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Segmento é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without schooling', (done) => { chai.request(server) .post('/api/v1/user') .set('content-type', 'application/x-www-form-urlencoded') @@ -1045,4 +1124,120 @@ describe('Saves a user', () => { }); }); + it('should not save an user without role', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + schooling: 'Doutorado', + cpf: '48303270737', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + institution_name: 'UFPR', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Função é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without institution', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + schooling: 'Doutorado', + cpf: '48303270737', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + role: 'Pesquisador', + state: 'PR', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Instituição em que trabalha é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without city', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + schooling: 'Doutorado', + cpf: '48303270737', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + institution_name: 'UFPR', + role: 'Pesquisador', + state: 'PR'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Cidade é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + + it('should not save an user without state', (done) => { + chai.request(server) + .post('/api/v1/user') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar', + name: 'Tequila baby', + schooling: 'Doutorado', + cpf: '48303270737', + course: 'Ciência da Computação', + segment: 'Comunidade acadêmica', + institution_name: 'UFPR', + role: 'Pesquisador', + city: 'Cutiriba'}) + .end((err, res) =>{ + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Estado é obrigatório.'); + User.findOne({'email': 'lorem@ipsum.com'}, (err, user) => { + expect(user).to.not.exist; + done(); + }); + }); + }); + }); -- GitLab From bbf84d45c236c9615e156bfd14726fe3bff4efaa Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 25 Oct 2016 10:02:40 -0200 Subject: [PATCH 45/50] small fixes on some msgs --- src/libs/routes/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 223552a5..4239c62b 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -78,7 +78,7 @@ userApp.post('/', (req, res, next) => { }, (req, res, next) => { if (!req.body.institution_name) { - res.json({success: false, msg: 'O campo Intituição em que trabalha é obrigatório.'}); + res.json({success: false, msg: 'O campo Instituição em que trabalha é obrigatório.'}); } else { next(); } -- GitLab From 459a5c280c7ff512d91010dc7902de54e9e5ba4f Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 25 Oct 2016 10:51:55 -0200 Subject: [PATCH 46/50] change info fecthed from config.json --- src/libs/routes/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 4239c62b..05724ab8 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -175,7 +175,7 @@ userApp.post('/authenticate', (req, res, next) => { else { user.comparePassword(req.body.password, (err, isMatch) => { if (isMatch && !err) { - var secret = config.get('mongodb:secret'); + var secret = config.mongodb.secret; // if user is found and password is right create a token var token = jwt.encode(user, secret); -- GitLab From ff65ca4575468ec7fcf453dc931ad8e410f62a8a Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 25 Oct 2016 11:09:24 -0200 Subject: [PATCH 47/50] add tests for /user/authenticate --- src/test/test.js | 200 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/src/test/test.js b/src/test/test.js index 854e26ff..71f9227c 100644 --- a/src/test/test.js +++ b/src/test/test.js @@ -1241,3 +1241,203 @@ describe('Saves a user', () => { }); }); + +describe('Authenticates a user', () => { + + beforeEach(() => { + User.remove({}, (err) => { + console.log('Test collection purged'); + }); + }); + + it('should authenticate a user', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user/authenticate') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: '123mudar'}) + .end((err, res) => { + let token; + + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(true); + res.body.should.have.property('token'); + token = res.body.token; + token.substr(0, 3).should.equal('JWT'); + done(); + }); + }); + }); + + it('should not authenticate a user with wrong password', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user/authenticate') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'lorem@ipsum.com', + password: 'umasenhaerrada'}) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('A Senha informada é inválida.') + done(); + }); + }); + }); + + it('should not authenticate a user with wrong email', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user/authenticate') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email: 'dolor@ipsum.com', + password: '123mudar'}) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O Email informado não está cadastrado.') + done(); + }); + }); + }); + + it('should not authenticate a user with missing email', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user/authenticate') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({password: '123mudar'}) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Email é obrigatório.') + done(); + }); + }); + }); + + it('should not authenticate a user with missing password', (done) => { + let newUser = new User(); + + newUser.email = 'lorem@ipsum.com'; + newUser.password = '123mudar'; + newUser.name = 'Gute'; + newUser.cpf = '08236017907'; + newUser.schooling = 'Doutorado'; + newUser.course = 'Ciência da Computação'; + newUser.segment = 'Comunidade acadêmica'; + newUser.role = 'Pesquisador'; + newUser.institution_name = 'UFPR'; + newUser.state = 'PR'; + newUser.city = 'Curitiba'; + + newUser.save((err) => { + if (err) { + console.log('MongoDB error:' + err); + } + }).then(function(newuser){ + chai.request(server) + .post('/api/v1/user/authenticate') + .set('content-type', 'application/x-www-form-urlencoded') + .set('x-apicache-bypass', 'true') + .send({email:'lorem@ipsum.com'}) + .end((err, res) => { + res.should.have.status(200); + res.should.be.json; + res.body.should.have.property('success'); + res.body.success.should.equal(false); + res.body.should.have.property('msg'); + res.body.msg.should.equal('O campo Senha é obrigatório.') + done(); + }); + }); + }); +}); -- GitLab From 73edd413523181609a2c7ac1385489cf9d7a3408 Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Tue, 1 Nov 2016 12:42:57 -0200 Subject: [PATCH 48/50] replace the console.log with the application logger to log errors/warnings/info --- src/libs/db/mongoose.js | 2 +- src/libs/routes/user.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js index 400898c6..d8594158 100644 --- a/src/libs/db/mongoose.js +++ b/src/libs/db/mongoose.js @@ -11,7 +11,7 @@ mongoose.Promise = global.Promise; module.exports = () => { // Get mongodb URI (ip and port) in config file const mongoUri = process.env.MONGO_URI || config.mongodb.uri; - log.debug(`Connecting to MongDB on URI ${mongoUri}`); + log.debug(`Connecting to MongoDB on URI ${mongoUri}`); // Connection singleton const db = mongoose.connect(mongoUri); diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js index 05724ab8..eb1732b1 100644 --- a/src/libs/routes/user.js +++ b/src/libs/routes/user.js @@ -100,7 +100,7 @@ userApp.post('/', (req, res, next) => { }, (req, res, next) => { User.count({'email': req.body.email}, function(err, count){ if (err){ - console.log('MongoDB error: ' + err); + log.error('MongoDB error: ' + err); res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'}); } if(count){ @@ -113,7 +113,7 @@ userApp.post('/', (req, res, next) => { }, (req, res, next) => { User.count({'cpf': req.body.cpf}, function(err, count){ if (err){ - console.log('MongoDB error: ' + err); + log.error('MongoDB error: ' + err); res.json({success: false, msg: 'Um erro ocorreu no banco de dados.'}); } if(count){ -- GitLab From 434a5106c3f281b054359506bc8dbb98aa56e78e Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 3 Nov 2016 11:20:04 -0200 Subject: [PATCH 49/50] add documentation on how to check if a user is authenticated --- src/libs/middlewares/passport.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js index 4092f146..431eada8 100644 --- a/src/libs/middlewares/passport.js +++ b/src/libs/middlewares/passport.js @@ -9,7 +9,7 @@ module.exports = function(passport){ opts.jwtFromRequest = ExtractJwt.fromAuthHeader(); opts.secretOrKey = config.get('mongodb:secret'); passport.use(new JwtStrategy(opts, function(jwt_payload, done){ - User.find({id: jwt_payload.id}, function(err, user){ + User.find({email: jwt_payload.email}, function(err, user){ if (err) { return done(err); } @@ -22,3 +22,29 @@ module.exports = function(passport){ }); })); }; + +/* To check if a user has access to a route, one must use passport.authenticate() specifying 'JWT' as the strategy in the route declaration, like so: +app.post('/route', passport.authenticate('jwt', { session: false}), function(req, res) { }); + +the user object is then accessible via req.user +---- + +Another way to check if a user is authenticated, is to check the request header for the json web token, like so: + +getToken = function (headers) { + if (headers && headers.authorization) { + var parted = headers.authorization.split(' '); + if (parted.length === 2) { + return parted[1]; + } else { + return null; + } + } else { + return null; + } +}; + +var token = getToken(req.headers); + if (token) { + var decoded = jwt.decode(token, config.get(mongodb.secret)); + } -- GitLab From b71b2fce8e738676a85e543fee17302444c5fccd Mon Sep 17 00:00:00 2001 From: Lucas Gabriel Lima <lgl15@inf.ufpr.br> Date: Thu, 3 Nov 2016 11:23:18 -0200 Subject: [PATCH 50/50] small fix on commentary --- src/libs/middlewares/passport.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js index 431eada8..c9399260 100644 --- a/src/libs/middlewares/passport.js +++ b/src/libs/middlewares/passport.js @@ -24,6 +24,9 @@ module.exports = function(passport){ }; /* To check if a user has access to a route, one must use passport.authenticate() specifying 'JWT' as the strategy in the route declaration, like so: +//pass passportfor configuration +require('./config/passport')(passport); + app.post('/route', passport.authenticate('jwt', { session: false}), function(req, res) { }); the user object is then accessible via req.user @@ -48,3 +51,4 @@ var token = getToken(req.headers); if (token) { var decoded = jwt.decode(token, config.get(mongodb.secret)); } + */ -- GitLab